mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 12:25:53 +00:00
Rename js::CodeGenerator to js::BytecodeEmitter. Bug 696876, part 1 of 3. r=dvander.
--HG-- rename : js/src/frontend/BytecodeGenerator.cpp => js/src/frontend/BytecodeEmitter.cpp rename : js/src/frontend/BytecodeGenerator.h => js/src/frontend/BytecodeEmitter.h extra : rebase_source : 2cc974e15cdf9e4dce36599b45914bab56825611
This commit is contained in:
parent
7bf54dce87
commit
cac7aed1e3
@ -163,7 +163,7 @@ CPPSRCS = \
|
||||
Stack.cpp \
|
||||
String.cpp \
|
||||
BytecodeCompiler.cpp \
|
||||
BytecodeGenerator.cpp \
|
||||
BytecodeEmitter.cpp \
|
||||
FoldConstants.cpp \
|
||||
ParseMaps.cpp \
|
||||
ParseNode.cpp \
|
||||
|
@ -42,7 +42,7 @@
|
||||
|
||||
#include "jsprobes.h"
|
||||
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
#include "frontend/FoldConstants.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
|
||||
@ -88,8 +88,8 @@ BytecodeCompiler::compileScript(JSContext *cx, JSObject *scopeChain, StackFrame
|
||||
Parser &parser = compiler.parser;
|
||||
TokenStream &tokenStream = parser.tokenStream;
|
||||
|
||||
CodeGenerator cg(&parser, tokenStream.getLineno());
|
||||
if (!cg.init(cx, TreeContext::USED_AS_TREE_CONTEXT))
|
||||
BytecodeEmitter bce(&parser, tokenStream.getLineno());
|
||||
if (!bce.init(cx, TreeContext::USED_AS_TREE_CONTEXT))
|
||||
return NULL;
|
||||
|
||||
Probes::compileScriptBegin(cx, filename, lineno);
|
||||
@ -107,18 +107,18 @@ BytecodeCompiler::compileScript(JSContext *cx, JSObject *scopeChain, StackFrame
|
||||
/* Null script early in case of error, to reduce our code footprint. */
|
||||
script = NULL;
|
||||
|
||||
GlobalScope globalScope(cx, globalObj, &cg);
|
||||
cg.flags |= tcflags;
|
||||
cg.setScopeChain(scopeChain);
|
||||
GlobalScope globalScope(cx, globalObj, &bce);
|
||||
bce.flags |= tcflags;
|
||||
bce.setScopeChain(scopeChain);
|
||||
compiler.globalScope = &globalScope;
|
||||
if (!SetStaticLevel(&cg, staticLevel))
|
||||
if (!SetStaticLevel(&bce, staticLevel))
|
||||
goto out;
|
||||
|
||||
/* If this is a direct call to eval, inherit the caller's strictness. */
|
||||
if (callerFrame &&
|
||||
callerFrame->isScriptFrame() &&
|
||||
callerFrame->script()->strictModeCode) {
|
||||
cg.flags |= TCF_STRICT_MODE_CODE;
|
||||
bce.flags |= TCF_STRICT_MODE_CODE;
|
||||
tokenStream.setStrictMode();
|
||||
}
|
||||
|
||||
@ -134,7 +134,7 @@ BytecodeCompiler::compileScript(JSContext *cx, JSObject *scopeChain, StackFrame
|
||||
*/
|
||||
JSAtom *atom = js_AtomizeString(cx, source);
|
||||
jsatomid _;
|
||||
if (!atom || !cg.makeAtomIndex(atom, &_))
|
||||
if (!atom || !bce.makeAtomIndex(atom, &_))
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -147,9 +147,9 @@ BytecodeCompiler::compileScript(JSContext *cx, JSObject *scopeChain, StackFrame
|
||||
ObjectBox *funbox = parser.newObjectBox(callerFrame->fun());
|
||||
if (!funbox)
|
||||
goto out;
|
||||
funbox->emitLink = cg.objectList.lastbox;
|
||||
cg.objectList.lastbox = funbox;
|
||||
cg.objectList.length++;
|
||||
funbox->emitLink = bce.objectList.lastbox;
|
||||
bce.objectList.lastbox = funbox;
|
||||
bce.objectList.length++;
|
||||
#ifdef DEBUG
|
||||
savedCallerFun = true;
|
||||
#endif
|
||||
@ -161,9 +161,9 @@ BytecodeCompiler::compileScript(JSContext *cx, JSObject *scopeChain, StackFrame
|
||||
* generate our script-body blockid since we aren't calling Statements.
|
||||
*/
|
||||
uint32 bodyid;
|
||||
if (!GenerateBlockId(&cg, bodyid))
|
||||
if (!GenerateBlockId(&bce, bodyid))
|
||||
goto out;
|
||||
cg.bodyid = bodyid;
|
||||
bce.bodyid = bodyid;
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
pn = NULL;
|
||||
@ -185,26 +185,26 @@ BytecodeCompiler::compileScript(JSContext *cx, JSObject *scopeChain, StackFrame
|
||||
pn = parser.statement();
|
||||
if (!pn)
|
||||
goto out;
|
||||
JS_ASSERT(!cg.blockNode);
|
||||
JS_ASSERT(!bce.blockNode);
|
||||
|
||||
if (inDirectivePrologue && !parser.recognizeDirectivePrologue(pn, &inDirectivePrologue))
|
||||
goto out;
|
||||
|
||||
if (!FoldConstants(cx, pn, &cg))
|
||||
if (!FoldConstants(cx, pn, &bce))
|
||||
goto out;
|
||||
|
||||
if (!parser.analyzeFunctions(&cg))
|
||||
if (!parser.analyzeFunctions(&bce))
|
||||
goto out;
|
||||
cg.functionList = NULL;
|
||||
bce.functionList = NULL;
|
||||
|
||||
if (!EmitTree(cx, &cg, pn))
|
||||
if (!EmitTree(cx, &bce, pn))
|
||||
goto out;
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
if (!pn->isKind(TOK_SEMI) || !pn->pn_kid || !TreeTypeIsXML(pn->pn_kid->getKind()))
|
||||
onlyXML = false;
|
||||
#endif
|
||||
cg.freeTree(pn);
|
||||
bce.freeTree(pn);
|
||||
}
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
@ -225,14 +225,14 @@ BytecodeCompiler::compileScript(JSContext *cx, JSObject *scopeChain, StackFrame
|
||||
* incremental code generation we need to patch the bytecode to adjust the
|
||||
* local references to skip the globals.
|
||||
*/
|
||||
if (cg.hasSharps()) {
|
||||
if (bce.hasSharps()) {
|
||||
jsbytecode *code, *end;
|
||||
JSOp op;
|
||||
const JSCodeSpec *cs;
|
||||
uintN len, slot;
|
||||
|
||||
code = CG_BASE(&cg);
|
||||
for (end = code + CG_OFFSET(&cg); code != end; code += len) {
|
||||
code = CG_BASE(&bce);
|
||||
for (end = code + CG_OFFSET(&bce); code != end; code += len) {
|
||||
JS_ASSERT(code < end);
|
||||
op = (JSOp) *code;
|
||||
cs = &js_CodeSpec[op];
|
||||
@ -246,7 +246,7 @@ BytecodeCompiler::compileScript(JSContext *cx, JSObject *scopeChain, StackFrame
|
||||
JOF_TYPE(cs->format) != JOF_SLOTATOM);
|
||||
slot = GET_SLOTNO(code);
|
||||
if (!(cs->format & JOF_SHARPSLOT))
|
||||
slot += cg.sharpSlots();
|
||||
slot += bce.sharpSlots();
|
||||
if (slot >= SLOTNO_LIMIT)
|
||||
goto too_many_slots;
|
||||
SET_SLOTNO(code, slot);
|
||||
@ -258,12 +258,12 @@ BytecodeCompiler::compileScript(JSContext *cx, JSObject *scopeChain, StackFrame
|
||||
* Nowadays the threaded interpreter needs a stop instruction, so we
|
||||
* do have to emit that here.
|
||||
*/
|
||||
if (Emit1(cx, &cg, JSOP_STOP) < 0)
|
||||
if (Emit1(cx, &bce, JSOP_STOP) < 0)
|
||||
goto out;
|
||||
|
||||
JS_ASSERT(cg.version() == version);
|
||||
JS_ASSERT(bce.version() == version);
|
||||
|
||||
script = JSScript::NewScriptFromCG(cx, &cg);
|
||||
script = JSScript::NewScriptFromCG(cx, &bce);
|
||||
if (!script)
|
||||
goto out;
|
||||
|
||||
@ -401,20 +401,20 @@ BytecodeCompiler::compileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipa
|
||||
Parser &parser = compiler.parser;
|
||||
TokenStream &tokenStream = parser.tokenStream;
|
||||
|
||||
CodeGenerator funcg(&parser, tokenStream.getLineno());
|
||||
if (!funcg.init(cx, TreeContext::USED_AS_TREE_CONTEXT))
|
||||
BytecodeEmitter funbce(&parser, tokenStream.getLineno());
|
||||
if (!funbce.init(cx, TreeContext::USED_AS_TREE_CONTEXT))
|
||||
return false;
|
||||
|
||||
funcg.flags |= TCF_IN_FUNCTION;
|
||||
funcg.setFunction(fun);
|
||||
funcg.bindings.transfer(cx, bindings);
|
||||
fun->setArgCount(funcg.bindings.countArgs());
|
||||
if (!GenerateBlockId(&funcg, funcg.bodyid))
|
||||
funbce.flags |= TCF_IN_FUNCTION;
|
||||
funbce.setFunction(fun);
|
||||
funbce.bindings.transfer(cx, bindings);
|
||||
fun->setArgCount(funbce.bindings.countArgs());
|
||||
if (!GenerateBlockId(&funbce, funbce.bodyid))
|
||||
return false;
|
||||
|
||||
/* FIXME: make Function format the source for a function definition. */
|
||||
tokenStream.mungeCurrentToken(TOK_NAME);
|
||||
ParseNode *fn = FunctionNode::create(&funcg);
|
||||
ParseNode *fn = FunctionNode::create(&funbce);
|
||||
if (fn) {
|
||||
fn->pn_body = NULL;
|
||||
fn->pn_cookie.makeFree();
|
||||
@ -426,11 +426,11 @@ BytecodeCompiler::compileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipa
|
||||
* allocated from cx->tempLifoAlloc by DefineArg.
|
||||
*/
|
||||
Vector<JSAtom *> names(cx);
|
||||
if (!funcg.bindings.getLocalNameArray(cx, &names)) {
|
||||
if (!funbce.bindings.getLocalNameArray(cx, &names)) {
|
||||
fn = NULL;
|
||||
} else {
|
||||
for (uintN i = 0; i < nargs; i++) {
|
||||
if (!DefineArg(fn, names[i], i, &funcg)) {
|
||||
if (!DefineArg(fn, names[i], i, &funbce)) {
|
||||
fn = NULL;
|
||||
break;
|
||||
}
|
||||
@ -441,7 +441,7 @@ BytecodeCompiler::compileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipa
|
||||
|
||||
/*
|
||||
* Farble the body so that it looks like a block statement to EmitTree,
|
||||
* which is called from EmitFunctionBody (see BytecodeGenerator.cpp).
|
||||
* which is called from EmitFunctionBody (see BytecodeEmitter.cpp).
|
||||
* After we're done parsing, we must fold constants, analyze any nested
|
||||
* functions, and generate code for this function, including a stop opcode
|
||||
* at the end.
|
||||
@ -449,15 +449,15 @@ BytecodeCompiler::compileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipa
|
||||
tokenStream.mungeCurrentToken(TOK_LC);
|
||||
ParseNode *pn = fn ? parser.functionBody() : NULL;
|
||||
if (pn) {
|
||||
if (!CheckStrictParameters(cx, &funcg)) {
|
||||
if (!CheckStrictParameters(cx, &funbce)) {
|
||||
pn = NULL;
|
||||
} else if (!tokenStream.matchToken(TOK_EOF)) {
|
||||
parser.reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_SYNTAX_ERROR);
|
||||
pn = NULL;
|
||||
} else if (!FoldConstants(cx, pn, &funcg)) {
|
||||
} else if (!FoldConstants(cx, pn, &funbce)) {
|
||||
/* FoldConstants reported the error already. */
|
||||
pn = NULL;
|
||||
} else if (!parser.analyzeFunctions(&funcg)) {
|
||||
} else if (!parser.analyzeFunctions(&funbce)) {
|
||||
pn = NULL;
|
||||
} else {
|
||||
if (fn->pn_body) {
|
||||
@ -467,7 +467,7 @@ BytecodeCompiler::compileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipa
|
||||
pn = fn->pn_body;
|
||||
}
|
||||
|
||||
if (!EmitFunctionScript(cx, &funcg, pn))
|
||||
if (!EmitFunctionScript(cx, &funbce, pn))
|
||||
pn = NULL;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -38,8 +38,8 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef BytecodeGenerator_h__
|
||||
#define BytecodeGenerator_h__
|
||||
#ifndef BytecodeEmitter_h__
|
||||
#define BytecodeEmitter_h__
|
||||
|
||||
/*
|
||||
* JS bytecode generation.
|
||||
@ -64,7 +64,7 @@ namespace js {
|
||||
* non-looping statement enumerators, add them before STMT_DO_LOOP or you will
|
||||
* break the STMT_TYPE_IS_LOOP macro.
|
||||
*
|
||||
* Also remember to keep the statementName array in BytecodeGenerator.cpp in
|
||||
* Also remember to keep the statementName array in BytecodeEmitter.cpp in
|
||||
* sync.
|
||||
*/
|
||||
enum StmtType {
|
||||
@ -159,7 +159,7 @@ struct StmtInfo {
|
||||
#define SET_STATEMENT_TOP(stmt, top) \
|
||||
((stmt)->update = (top), (stmt)->breaks = (stmt)->continues = (-1))
|
||||
|
||||
#define TCF_COMPILING 0x01 /* TreeContext is CodeGenerator */
|
||||
#define TCF_COMPILING 0x01 /* TreeContext is BytecodeEmitter */
|
||||
#define TCF_IN_FUNCTION 0x02 /* parsing inside function body */
|
||||
#define TCF_RETURN_EXPR 0x04 /* function has 'return expr;' */
|
||||
#define TCF_RETURN_VOID 0x08 /* function has 'return;' */
|
||||
@ -196,7 +196,7 @@ struct StmtInfo {
|
||||
|
||||
/*
|
||||
* A request flag passed to BytecodeCompiler::compileScript and then down via
|
||||
* CodeGenerator to JSScript::NewScriptFromCG, from script_compile_sub and any
|
||||
* BytecodeEmitter to JSScript::NewScriptFromCG, from script_compile_sub and any
|
||||
* kindred functions that need to make mutable scripts (even empty ones; i.e.,
|
||||
* they can't share the const JSScript::emptyScript() singleton).
|
||||
*/
|
||||
@ -298,7 +298,7 @@ struct StmtInfo {
|
||||
TCF_STRICT_MODE_CODE | \
|
||||
TCF_FUN_EXTENSIBLE_SCOPE)
|
||||
|
||||
struct CodeGenerator;
|
||||
struct BytecodeEmitter;
|
||||
|
||||
struct TreeContext { /* tree context for semantic checks */
|
||||
uint32 flags; /* statement state flags, see above */
|
||||
@ -387,8 +387,8 @@ struct TreeContext { /* tree context for semantic checks */
|
||||
}
|
||||
|
||||
/*
|
||||
* js::CodeGenerator derives from js::TreeContext; however, only the
|
||||
* top-level CodeGenerators are actually used as full-fledged tree contexts
|
||||
* js::BytecodeEmitter derives from js::TreeContext; however, only the
|
||||
* top-level BytecodeEmitters are actually used as full-fledged tree contexts
|
||||
* (to hold decls and lexdeps). We can avoid allocation overhead by making
|
||||
* this distinction explicit.
|
||||
*/
|
||||
@ -446,7 +446,7 @@ struct TreeContext { /* tree context for semantic checks */
|
||||
bool inFunction() const { return flags & TCF_IN_FUNCTION; }
|
||||
|
||||
bool compiling() const { return flags & TCF_COMPILING; }
|
||||
inline CodeGenerator *asCodeGenerator();
|
||||
inline BytecodeEmitter *asBytecodeEmitter();
|
||||
|
||||
bool usesArguments() const {
|
||||
return flags & TCF_FUN_USES_ARGUMENTS;
|
||||
@ -609,7 +609,7 @@ class GCConstList {
|
||||
void finish(JSConstArray *array);
|
||||
};
|
||||
|
||||
struct CodeGenerator : public TreeContext
|
||||
struct BytecodeEmitter : public TreeContext
|
||||
{
|
||||
struct {
|
||||
jsbytecode *base; /* base of JS bytecode vector */
|
||||
@ -670,7 +670,7 @@ struct CodeGenerator : public TreeContext
|
||||
uint16 traceIndex; /* index for the next JSOP_TRACE instruction */
|
||||
uint16 typesetCount; /* Number of JOF_TYPESET opcodes generated */
|
||||
|
||||
CodeGenerator(Parser *parser, uintN lineno);
|
||||
BytecodeEmitter(Parser *parser, uintN lineno);
|
||||
bool init(JSContext *cx, TreeContext::InitBehavior ib = USED_AS_CODE_GENERATOR);
|
||||
|
||||
JSContext *context() {
|
||||
@ -678,12 +678,12 @@ struct CodeGenerator : public TreeContext
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that cgs are magic: they own the arena "top-of-stack" space
|
||||
* above their tempMark points. This means that you cannot alloc from
|
||||
* tempLifoAlloc and save the pointer beyond the next CodeGenerator
|
||||
* Note that BytecodeEmitters are magic: they own the arena "top-of-stack"
|
||||
* space above their tempMark points. This means that you cannot alloc from
|
||||
* tempLifoAlloc and save the pointer beyond the next BytecodeEmitter
|
||||
* destructor call.
|
||||
*/
|
||||
~CodeGenerator();
|
||||
~BytecodeEmitter();
|
||||
|
||||
/*
|
||||
* Adds a use of a variable that is statically known to exist on the
|
||||
@ -693,7 +693,7 @@ struct CodeGenerator : public TreeContext
|
||||
* until after compilation. Properties must be resolved before being
|
||||
* added, to avoid aliasing properties that should be resolved. This makes
|
||||
* slot prediction based on the global object's free slot impossible. So,
|
||||
* we use the slot to index into cg->globalScope->defs, and perform a
|
||||
* we use the slot to index into bce->globalScope->defs, and perform a
|
||||
* fixup of the script at the very end of compilation.
|
||||
*
|
||||
* If the global use can be cached, |cookie| will be set to |slot|.
|
||||
@ -748,34 +748,34 @@ struct CodeGenerator : public TreeContext
|
||||
}
|
||||
};
|
||||
|
||||
#define CG_TS(cg) TS((cg)->parser)
|
||||
#define CG_TS(bce) TS((bce)->parser)
|
||||
|
||||
#define CG_BASE(cg) ((cg)->current->base)
|
||||
#define CG_LIMIT(cg) ((cg)->current->limit)
|
||||
#define CG_NEXT(cg) ((cg)->current->next)
|
||||
#define CG_CODE(cg,offset) (CG_BASE(cg) + (offset))
|
||||
#define CG_OFFSET(cg) (CG_NEXT(cg) - CG_BASE(cg))
|
||||
#define CG_BASE(bce) ((bce)->current->base)
|
||||
#define CG_LIMIT(bce) ((bce)->current->limit)
|
||||
#define CG_NEXT(bce) ((bce)->current->next)
|
||||
#define CG_CODE(bce,offset) (CG_BASE(bce) + (offset))
|
||||
#define CG_OFFSET(bce) (CG_NEXT(bce) - CG_BASE(bce))
|
||||
|
||||
#define CG_NOTES(cg) ((cg)->current->notes)
|
||||
#define CG_NOTE_COUNT(cg) ((cg)->current->noteCount)
|
||||
#define CG_NOTE_LIMIT(cg) ((cg)->current->noteLimit)
|
||||
#define CG_LAST_NOTE_OFFSET(cg) ((cg)->current->lastNoteOffset)
|
||||
#define CG_CURRENT_LINE(cg) ((cg)->current->currentLine)
|
||||
#define CG_NOTES(bce) ((bce)->current->notes)
|
||||
#define CG_NOTE_COUNT(bce) ((bce)->current->noteCount)
|
||||
#define CG_NOTE_LIMIT(bce) ((bce)->current->noteLimit)
|
||||
#define CG_LAST_NOTE_OFFSET(bce) ((bce)->current->lastNoteOffset)
|
||||
#define CG_CURRENT_LINE(bce) ((bce)->current->currentLine)
|
||||
|
||||
#define CG_PROLOG_BASE(cg) ((cg)->prolog.base)
|
||||
#define CG_PROLOG_LIMIT(cg) ((cg)->prolog.limit)
|
||||
#define CG_PROLOG_NEXT(cg) ((cg)->prolog.next)
|
||||
#define CG_PROLOG_CODE(cg,poff) (CG_PROLOG_BASE(cg) + (poff))
|
||||
#define CG_PROLOG_OFFSET(cg) (CG_PROLOG_NEXT(cg) - CG_PROLOG_BASE(cg))
|
||||
#define CG_PROLOG_BASE(bce) ((bce)->prolog.base)
|
||||
#define CG_PROLOG_LIMIT(bce) ((bce)->prolog.limit)
|
||||
#define CG_PROLOG_NEXT(bce) ((bce)->prolog.next)
|
||||
#define CG_PROLOG_CODE(bce,poff) (CG_PROLOG_BASE(bce) + (poff))
|
||||
#define CG_PROLOG_OFFSET(bce) (CG_PROLOG_NEXT(bce) - CG_PROLOG_BASE(bce))
|
||||
|
||||
#define CG_SWITCH_TO_MAIN(cg) ((cg)->current = &(cg)->main)
|
||||
#define CG_SWITCH_TO_PROLOG(cg) ((cg)->current = &(cg)->prolog)
|
||||
#define CG_SWITCH_TO_MAIN(bce) ((bce)->current = &(bce)->main)
|
||||
#define CG_SWITCH_TO_PROLOG(bce) ((bce)->current = &(bce)->prolog)
|
||||
|
||||
inline CodeGenerator *
|
||||
TreeContext::asCodeGenerator()
|
||||
inline BytecodeEmitter *
|
||||
TreeContext::asBytecodeEmitter()
|
||||
{
|
||||
JS_ASSERT(compiling());
|
||||
return static_cast<CodeGenerator *>(this);
|
||||
return static_cast<BytecodeEmitter *>(this);
|
||||
}
|
||||
|
||||
namespace frontend {
|
||||
@ -784,56 +784,54 @@ namespace frontend {
|
||||
* Emit one bytecode.
|
||||
*/
|
||||
ptrdiff_t
|
||||
Emit1(JSContext *cx, CodeGenerator *cg, JSOp op);
|
||||
Emit1(JSContext *cx, BytecodeEmitter *bce, JSOp op);
|
||||
|
||||
/*
|
||||
* Emit two bytecodes, an opcode (op) with a byte of immediate operand (op1).
|
||||
*/
|
||||
ptrdiff_t
|
||||
Emit2(JSContext *cx, CodeGenerator *cg, JSOp op, jsbytecode op1);
|
||||
Emit2(JSContext *cx, BytecodeEmitter *bce, JSOp op, jsbytecode op1);
|
||||
|
||||
/*
|
||||
* Emit three bytecodes, an opcode with two bytes of immediate operands.
|
||||
*/
|
||||
ptrdiff_t
|
||||
Emit3(JSContext *cx, CodeGenerator *cg, JSOp op, jsbytecode op1,
|
||||
jsbytecode op2);
|
||||
Emit3(JSContext *cx, BytecodeEmitter *bce, JSOp op, jsbytecode op1, jsbytecode op2);
|
||||
|
||||
/*
|
||||
* Emit five bytecodes, an opcode with two 16-bit immediates.
|
||||
*/
|
||||
ptrdiff_t
|
||||
Emit5(JSContext *cx, CodeGenerator *cg, JSOp op, uint16 op1,
|
||||
uint16 op2);
|
||||
Emit5(JSContext *cx, BytecodeEmitter *bce, JSOp op, uint16 op1, uint16 op2);
|
||||
|
||||
/*
|
||||
* Emit (1 + extra) bytecodes, for N bytes of op and its immediate operand.
|
||||
*/
|
||||
ptrdiff_t
|
||||
EmitN(JSContext *cx, CodeGenerator *cg, JSOp op, size_t extra);
|
||||
EmitN(JSContext *cx, BytecodeEmitter *bce, JSOp op, size_t extra);
|
||||
|
||||
/*
|
||||
* Unsafe macro to call SetJumpOffset and return false if it does.
|
||||
*/
|
||||
#define CHECK_AND_SET_JUMP_OFFSET_CUSTOM(cx,cg,pc,off,BAD_EXIT) \
|
||||
#define CHECK_AND_SET_JUMP_OFFSET_CUSTOM(cx,bce,pc,off,BAD_EXIT) \
|
||||
JS_BEGIN_MACRO \
|
||||
if (!SetJumpOffset(cx, cg, pc, off)) { \
|
||||
if (!SetJumpOffset(cx, bce, pc, off)) { \
|
||||
BAD_EXIT; \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define CHECK_AND_SET_JUMP_OFFSET(cx,cg,pc,off) \
|
||||
CHECK_AND_SET_JUMP_OFFSET_CUSTOM(cx,cg,pc,off,return JS_FALSE)
|
||||
#define CHECK_AND_SET_JUMP_OFFSET(cx,bce,pc,off) \
|
||||
CHECK_AND_SET_JUMP_OFFSET_CUSTOM(cx,bce,pc,off,return JS_FALSE)
|
||||
|
||||
#define CHECK_AND_SET_JUMP_OFFSET_AT_CUSTOM(cx,cg,off,BAD_EXIT) \
|
||||
CHECK_AND_SET_JUMP_OFFSET_CUSTOM(cx, cg, CG_CODE(cg,off), \
|
||||
CG_OFFSET(cg) - (off), BAD_EXIT)
|
||||
#define CHECK_AND_SET_JUMP_OFFSET_AT_CUSTOM(cx,bce,off,BAD_EXIT) \
|
||||
CHECK_AND_SET_JUMP_OFFSET_CUSTOM(cx, bce, CG_CODE(bce,off), \
|
||||
CG_OFFSET(bce) - (off), BAD_EXIT)
|
||||
|
||||
#define CHECK_AND_SET_JUMP_OFFSET_AT(cx,cg,off) \
|
||||
CHECK_AND_SET_JUMP_OFFSET_AT_CUSTOM(cx, cg, off, return JS_FALSE)
|
||||
#define CHECK_AND_SET_JUMP_OFFSET_AT(cx,bce,off) \
|
||||
CHECK_AND_SET_JUMP_OFFSET_AT_CUSTOM(cx, bce, off, return JS_FALSE)
|
||||
|
||||
JSBool
|
||||
SetJumpOffset(JSContext *cx, CodeGenerator *cg, jsbytecode *pc, ptrdiff_t off);
|
||||
SetJumpOffset(JSContext *cx, BytecodeEmitter *bce, jsbytecode *pc, ptrdiff_t off);
|
||||
|
||||
/*
|
||||
* Push the C-stack-allocated struct at stmt onto the stmtInfo stack.
|
||||
@ -857,17 +855,17 @@ void
|
||||
PopStatementTC(TreeContext *tc);
|
||||
|
||||
/*
|
||||
* Like PopStatementTC(cg), also patch breaks and continues unless the top
|
||||
* Like PopStatementTC(bce), also patch breaks and continues unless the top
|
||||
* statement info record represents a try-catch-finally suite. May fail if a
|
||||
* jump offset overflows.
|
||||
*/
|
||||
JSBool
|
||||
PopStatementCG(JSContext *cx, CodeGenerator *cg);
|
||||
PopStatementCG(JSContext *cx, BytecodeEmitter *bce);
|
||||
|
||||
/*
|
||||
* Define and lookup a primitive jsval associated with the const named by atom.
|
||||
* DefineCompileTimeConstant analyzes the constant-folded initializer at pn
|
||||
* and saves the const's value in cg->constList, if it can be used at compile
|
||||
* and saves the const's value in bce->constList, if it can be used at compile
|
||||
* time. It returns true unless an error occurred.
|
||||
*
|
||||
* If the initializer's value could not be saved, DefineCompileTimeConstant
|
||||
@ -877,7 +875,7 @@ PopStatementCG(JSContext *cx, CodeGenerator *cg);
|
||||
* JSVAL_VOID if not found, and false on error.
|
||||
*/
|
||||
JSBool
|
||||
DefineCompileTimeConstant(JSContext *cx, CodeGenerator *cg, JSAtom *atom, ParseNode *pn);
|
||||
DefineCompileTimeConstant(JSContext *cx, BytecodeEmitter *bce, JSAtom *atom, ParseNode *pn);
|
||||
|
||||
/*
|
||||
* Find a lexically scoped variable (one declared by let, catch, or an array
|
||||
@ -897,16 +895,16 @@ StmtInfo *
|
||||
LexicalLookup(TreeContext *tc, JSAtom *atom, jsint *slotp, StmtInfo *stmt = NULL);
|
||||
|
||||
/*
|
||||
* Emit code into cg for the tree rooted at pn.
|
||||
* Emit code into bce for the tree rooted at pn.
|
||||
*/
|
||||
JSBool
|
||||
EmitTree(JSContext *cx, CodeGenerator *cg, ParseNode *pn);
|
||||
EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn);
|
||||
|
||||
/*
|
||||
* Emit function code using cg for the tree rooted at body.
|
||||
* Emit function code using bce for the tree rooted at body.
|
||||
*/
|
||||
JSBool
|
||||
EmitFunctionScript(JSContext *cx, CodeGenerator *cg, ParseNode *body);
|
||||
EmitFunctionScript(JSContext *cx, BytecodeEmitter *bce, ParseNode *body);
|
||||
|
||||
} /* namespace frontend */
|
||||
|
||||
@ -926,7 +924,7 @@ EmitFunctionScript(JSContext *cx, CodeGenerator *cg, ParseNode *body);
|
||||
* At most one "gettable" note (i.e., a note of type other than SRC_NEWLINE,
|
||||
* SRC_SETLINE, and SRC_XDELTA) applies to a given bytecode.
|
||||
*
|
||||
* NB: the js_SrcNoteSpec array in BytecodeGenerator.cpp is indexed by this
|
||||
* NB: the js_SrcNoteSpec array in BytecodeEmitter.cpp is indexed by this
|
||||
* enum, so its initializers need to match the order here.
|
||||
*
|
||||
* Note on adding new source notes: every pair of bytecodes (A, B) where A and
|
||||
@ -1056,26 +1054,26 @@ enum SrcNoteType {
|
||||
namespace frontend {
|
||||
|
||||
/*
|
||||
* Append a new source note of the given type (and therefore size) to cg's
|
||||
* notes dynamic array, updating cg->noteCount. Return the new note's index
|
||||
* within the array pointed at by cg->current->notes. Return -1 if out of
|
||||
* Append a new source note of the given type (and therefore size) to bce's
|
||||
* notes dynamic array, updating bce->noteCount. Return the new note's index
|
||||
* within the array pointed at by bce->current->notes. Return -1 if out of
|
||||
* memory.
|
||||
*/
|
||||
intN
|
||||
NewSrcNote(JSContext *cx, CodeGenerator *cg, SrcNoteType type);
|
||||
NewSrcNote(JSContext *cx, BytecodeEmitter *bce, SrcNoteType type);
|
||||
|
||||
intN
|
||||
NewSrcNote2(JSContext *cx, CodeGenerator *cg, SrcNoteType type, ptrdiff_t offset);
|
||||
NewSrcNote2(JSContext *cx, BytecodeEmitter *bce, SrcNoteType type, ptrdiff_t offset);
|
||||
|
||||
intN
|
||||
NewSrcNote3(JSContext *cx, CodeGenerator *cg, SrcNoteType type, ptrdiff_t offset1,
|
||||
NewSrcNote3(JSContext *cx, BytecodeEmitter *bce, SrcNoteType type, ptrdiff_t offset1,
|
||||
ptrdiff_t offset2);
|
||||
|
||||
/*
|
||||
* NB: this function can add at most one extra extended delta note.
|
||||
*/
|
||||
jssrcnote *
|
||||
AddToSrcNoteDelta(JSContext *cx, CodeGenerator *cg, jssrcnote *sn, ptrdiff_t delta);
|
||||
AddToSrcNoteDelta(JSContext *cx, BytecodeEmitter *bce, jssrcnote *sn, ptrdiff_t delta);
|
||||
|
||||
/*
|
||||
* Finish taking source notes in cx's notePool, copying final notes to the new
|
||||
@ -1087,18 +1085,19 @@ AddToSrcNoteDelta(JSContext *cx, CodeGenerator *cg, jssrcnote *sn, ptrdiff_t del
|
||||
* FinishTakingSrcNotes, so DON'T CHANGE js::frontend::FinishTakingSrcNotes
|
||||
* WITHOUT CHECKING WHETHER THIS MACRO NEEDS CORRESPONDING CHANGES!
|
||||
*/
|
||||
#define CG_COUNT_FINAL_SRCNOTES(cg, cnt) \
|
||||
#define CG_COUNT_FINAL_SRCNOTES(bce, cnt) \
|
||||
JS_BEGIN_MACRO \
|
||||
ptrdiff_t diff_ = CG_PROLOG_OFFSET(cg) - (cg)->prolog.lastNoteOffset; \
|
||||
cnt = (cg)->prolog.noteCount + (cg)->main.noteCount + 1; \
|
||||
if ((cg)->prolog.noteCount && \
|
||||
(cg)->prolog.currentLine != (cg)->firstLine) { \
|
||||
ptrdiff_t diff_ = \
|
||||
CG_PROLOG_OFFSET(bce) - (bce)->prolog.lastNoteOffset; \
|
||||
cnt = (bce)->prolog.noteCount + (bce)->main.noteCount + 1; \
|
||||
if ((bce)->prolog.noteCount && \
|
||||
(bce)->prolog.currentLine != (bce)->firstLine) { \
|
||||
if (diff_ > SN_DELTA_MASK) \
|
||||
cnt += JS_HOWMANY(diff_ - SN_DELTA_MASK, SN_XDELTA_MASK); \
|
||||
cnt += 2 + (((cg)->firstLine > SN_3BYTE_OFFSET_MASK) << 1); \
|
||||
cnt += 2 + (((bce)->firstLine > SN_3BYTE_OFFSET_MASK) << 1); \
|
||||
} else if (diff_ > 0) { \
|
||||
if (cg->main.noteCount) { \
|
||||
jssrcnote *sn_ = (cg)->main.notes; \
|
||||
if ((bce)->main.noteCount) { \
|
||||
jssrcnote *sn_ = (bce)->main.notes; \
|
||||
diff_ -= SN_IS_XDELTA(sn_) \
|
||||
? SN_XDELTA_MASK - (*sn_ & SN_XDELTA_MASK) \
|
||||
: SN_DELTA_MASK - (*sn_ & SN_DELTA_MASK); \
|
||||
@ -1109,10 +1108,10 @@ AddToSrcNoteDelta(JSContext *cx, CodeGenerator *cg, jssrcnote *sn, ptrdiff_t del
|
||||
JS_END_MACRO
|
||||
|
||||
JSBool
|
||||
FinishTakingSrcNotes(JSContext *cx, CodeGenerator *cg, jssrcnote *notes);
|
||||
FinishTakingSrcNotes(JSContext *cx, BytecodeEmitter *bce, jssrcnote *notes);
|
||||
|
||||
void
|
||||
FinishTakingTryNotes(CodeGenerator *cg, JSTryNoteArray *array);
|
||||
FinishTakingTryNotes(BytecodeEmitter *bce, JSTryNoteArray *array);
|
||||
|
||||
} /* namespace frontend */
|
||||
} /* namespace js */
|
||||
@ -1134,4 +1133,4 @@ extern JS_FRIEND_API(uintN) js_SrcNoteLength(jssrcnote *sn);
|
||||
extern JS_FRIEND_API(ptrdiff_t)
|
||||
js_GetSrcNoteOffset(jssrcnote *sn, uintN which);
|
||||
|
||||
#endif /* BytecodeGenerator_h__ */
|
||||
#endif /* BytecodeEmitter_h__ */
|
@ -42,7 +42,7 @@
|
||||
|
||||
#include "jslibmath.h"
|
||||
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
#include "frontend/ParseNode.h"
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
|
@ -41,7 +41,7 @@
|
||||
#define ParseNode_inl_h__
|
||||
|
||||
#include "frontend/ParseNode.h"
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
#include "frontend/TokenStream.h"
|
||||
|
||||
namespace js {
|
||||
|
@ -836,7 +836,7 @@ CloneLeftHandSide(ParseNode *opn, TreeContext *tc);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* See frontend/BytecodeGenerator.h for js::TreeContext and its top*Stmt,
|
||||
* See frontend/BytecodeEmitter.h for js::TreeContext and its top*Stmt,
|
||||
* decls, and lexdeps members.
|
||||
*
|
||||
* Notes:
|
||||
|
@ -47,7 +47,7 @@
|
||||
* induced by the recursive parsing (not precise syntax trees, see Parser.h).
|
||||
* After tree construction, it rewrites trees to fold constants and evaluate
|
||||
* compile-time expressions. Finally, it calls js::frontend::EmitTree (see
|
||||
* CodeGenerator.h) to generate bytecode.
|
||||
* BytecodeEmitter.h) to generate bytecode.
|
||||
*
|
||||
* This parser attempts no error recovery.
|
||||
*/
|
||||
@ -78,7 +78,7 @@
|
||||
#include "jsstr.h"
|
||||
|
||||
#include "frontend/BytecodeCompiler.h"
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
#include "frontend/FoldConstants.h"
|
||||
#include "frontend/ParseMaps.h"
|
||||
#include "frontend/TokenStream.h"
|
||||
@ -1852,7 +1852,7 @@ LeaveFunction(ParseNode *fn, TreeContext *funtc, PropertyName *funName = NULL,
|
||||
}
|
||||
|
||||
static bool
|
||||
DefineGlobal(ParseNode *pn, CodeGenerator *cg, PropertyName *name);
|
||||
DefineGlobal(ParseNode *pn, BytecodeEmitter *bce, PropertyName *name);
|
||||
|
||||
/*
|
||||
* FIXME? this Parser method was factored from Parser::functionDef with minimal
|
||||
@ -2092,7 +2092,7 @@ Parser::functionDef(PropertyName *funName, FunctionType type, FunctionSyntaxKind
|
||||
* variable to bind its name to its value, and not an activation object
|
||||
* property (it might also need the activation property, if the outer
|
||||
* function contains with statements, e.g., but the stack slot wins
|
||||
* when BytecodeGenerator.cpp's BindNameToSlot can optimize a JSOP_NAME
|
||||
* when BytecodeEmitter.cpp's BindNameToSlot can optimize a JSOP_NAME
|
||||
* into a JSOP_GETLOCAL bytecode).
|
||||
*/
|
||||
if (bodyLevel && tc->inFunction()) {
|
||||
@ -2309,7 +2309,7 @@ Parser::functionDef(PropertyName *funName, FunctionType type, FunctionSyntaxKind
|
||||
|
||||
if (!outertc->inFunction() && bodyLevel && kind == Statement && outertc->compiling()) {
|
||||
JS_ASSERT(pn->pn_cookie.isFree());
|
||||
if (!DefineGlobal(pn, outertc->asCodeGenerator(), funName))
|
||||
if (!DefineGlobal(pn, outertc->asBytecodeEmitter(), funName))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -2619,7 +2619,7 @@ BindLet(JSContext *cx, BindData *data, JSAtom *atom, TreeContext *tc)
|
||||
* Store pn temporarily in what would be shape-mapped slots in a cloned
|
||||
* block object (once the prototype's final population is known, after all
|
||||
* 'let' bindings for this block have been parsed). We free these slots in
|
||||
* BytecodeGenerator.cpp:EmitEnterBlock so they don't tie up unused space
|
||||
* BytecodeEmitter.cpp:EmitEnterBlock so they don't tie up unused space
|
||||
* in the so-called "static" prototype Block.
|
||||
*/
|
||||
blockObj->setSlot(shape->slot, PrivateValue(pn));
|
||||
@ -2676,17 +2676,17 @@ OuterLet(TreeContext *tc, StmtInfo *stmt, JSAtom *atom)
|
||||
* stack frame slots.
|
||||
*/
|
||||
static bool
|
||||
DefineGlobal(ParseNode *pn, CodeGenerator *cg, PropertyName *name)
|
||||
DefineGlobal(ParseNode *pn, BytecodeEmitter *bce, PropertyName *name)
|
||||
{
|
||||
GlobalScope *globalScope = cg->compiler()->globalScope;
|
||||
GlobalScope *globalScope = bce->compiler()->globalScope;
|
||||
JSObject *globalObj = globalScope->globalObj;
|
||||
|
||||
if (!cg->compileAndGo() || !globalObj || cg->compilingForEval())
|
||||
if (!bce->compileAndGo() || !globalObj || bce->compilingForEval())
|
||||
return true;
|
||||
|
||||
AtomIndexAddPtr p = globalScope->names.lookupForAdd(name);
|
||||
if (!p) {
|
||||
JSContext *cx = cg->parser->context;
|
||||
JSContext *cx = bce->parser->context;
|
||||
|
||||
JSObject *holder;
|
||||
JSProperty *prop;
|
||||
@ -2802,7 +2802,7 @@ BindTopLevelVar(JSContext *cx, BindData *data, ParseNode *pn, TreeContext *tc)
|
||||
* is present, try to bake in either an already available slot or a
|
||||
* predicted slot that will be defined after compiling is completed.
|
||||
*/
|
||||
return DefineGlobal(pn, tc->asCodeGenerator(), pn->pn_atom->asPropertyName());
|
||||
return DefineGlobal(pn, tc->asBytecodeEmitter(), pn->pn_atom->asPropertyName());
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -57,8 +57,8 @@
|
||||
namespace js {
|
||||
|
||||
struct GlobalScope {
|
||||
GlobalScope(JSContext *cx, JSObject *globalObj, CodeGenerator *cg)
|
||||
: globalObj(globalObj), cg(cg), defs(cx), names(cx)
|
||||
GlobalScope(JSContext *cx, JSObject *globalObj, BytecodeEmitter *bce)
|
||||
: globalObj(globalObj), bce(bce), defs(cx), names(cx)
|
||||
{ }
|
||||
|
||||
struct GlobalDef {
|
||||
@ -73,7 +73,7 @@ struct GlobalScope {
|
||||
};
|
||||
|
||||
JSObject *globalObj;
|
||||
CodeGenerator *cg;
|
||||
BytecodeEmitter *bce;
|
||||
|
||||
/*
|
||||
* This is the table of global names encountered during parsing. Each
|
||||
|
@ -65,7 +65,7 @@
|
||||
#include "jsopcode.h"
|
||||
#include "jsscript.h"
|
||||
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
#include "frontend/Parser.h"
|
||||
#include "frontend/TokenStream.h"
|
||||
#include "vm/RegExpObject.h"
|
||||
|
@ -87,7 +87,7 @@
|
||||
#include "ds/LifoAlloc.h"
|
||||
#include "builtin/RegExp.h"
|
||||
#include "frontend/BytecodeCompiler.h"
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
|
||||
#include "jsatominlines.h"
|
||||
#include "jsinferinlines.h"
|
||||
|
@ -66,7 +66,7 @@
|
||||
#include "jswatchpoint.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
#include "frontend/Parser.h"
|
||||
#include "vm/Debugger.h"
|
||||
|
||||
|
@ -72,7 +72,7 @@
|
||||
#include "jstracer.h"
|
||||
|
||||
#include "frontend/BytecodeCompiler.h"
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
#include "frontend/TokenStream.h"
|
||||
#include "vm/CallObject.h"
|
||||
#include "vm/Debugger.h"
|
||||
|
@ -72,7 +72,7 @@
|
||||
#include "jstracer.h"
|
||||
#include "jslibmath.h"
|
||||
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
#ifdef JS_METHODJIT
|
||||
#include "methodjit/MethodJIT.h"
|
||||
#include "methodjit/MethodJIT-inl.h"
|
||||
|
@ -82,7 +82,7 @@
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "frontend/BytecodeCompiler.h"
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
#include "frontend/Parser.h"
|
||||
|
||||
#include "jsarrayinlines.h"
|
||||
|
@ -69,7 +69,7 @@
|
||||
#include "jsscript.h"
|
||||
#include "jsstr.h"
|
||||
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
#include "frontend/TokenStream.h"
|
||||
#include "vm/Debugger.h"
|
||||
|
||||
@ -962,7 +962,7 @@ js_GetPrinterOutput(JSPrinter *jp)
|
||||
}
|
||||
|
||||
/*
|
||||
* NB: Indexed by SRC_DECL_* defines from frontend/BytecodeGenerator.h.
|
||||
* NB: Indexed by SRC_DECL_* defines from frontend/BytecodeEmitter.h.
|
||||
*/
|
||||
static const char * const var_prefix[] = {"var ", "const ", "let "};
|
||||
|
||||
|
@ -178,7 +178,7 @@ typedef enum JSOp {
|
||||
* operand is an unsigned index of a span-dependency record, maintained until
|
||||
* code generation finishes -- after which some (but we hope not nearly all)
|
||||
* span-dependent jumps must be extended (see js::frontend::OptimizeSpanDeps in
|
||||
* frontend/BytecodeGenerator.cpp).
|
||||
* frontend/BytecodeEmitter.cpp).
|
||||
*
|
||||
* If the span-dependency record index overflows SPANDEP_INDEX_MAX, the jump
|
||||
* offset will contain SPANDEP_INDEX_HUGE, indicating that the record must be
|
||||
@ -245,7 +245,7 @@ typedef enum JSOp {
|
||||
(pc)[3] = (jsbytecode)((uint32)(i) >> 8), \
|
||||
(pc)[4] = (jsbytecode)(uint32)(i))
|
||||
|
||||
/* Index limit is determined by SN_3BYTE_OFFSET_FLAG, see frontend/BytecodeGenerator.h. */
|
||||
/* Index limit is determined by SN_3BYTE_OFFSET_FLAG, see frontend/BytecodeEmitter.h. */
|
||||
#define INDEX_LIMIT_LOG2 23
|
||||
#define INDEX_LIMIT ((uint32)1 << INDEX_LIMIT_LOG2)
|
||||
|
||||
|
@ -162,7 +162,7 @@ class CallReceiver;
|
||||
class CallArgs;
|
||||
|
||||
struct BytecodeCompiler;
|
||||
struct CodeGenerator;
|
||||
struct BytecodeEmitter;
|
||||
struct Definition;
|
||||
struct FunctionBox;
|
||||
struct ObjectBox;
|
||||
|
@ -58,7 +58,7 @@
|
||||
#include "jsarray.h"
|
||||
#include "jsnum.h"
|
||||
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
#include "frontend/Parser.h"
|
||||
#include "frontend/TokenStream.h"
|
||||
#include "vm/RegExpObject.h"
|
||||
|
@ -67,7 +67,7 @@
|
||||
#include "jsxdrapi.h"
|
||||
#endif
|
||||
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
#include "frontend/Parser.h"
|
||||
#include "methodjit/MethodJIT.h"
|
||||
#include "methodjit/Retcon.h"
|
||||
@ -1058,7 +1058,7 @@ JSScript::NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natom
|
||||
}
|
||||
|
||||
JSScript *
|
||||
JSScript::NewScriptFromCG(JSContext *cx, CodeGenerator *cg)
|
||||
JSScript::NewScriptFromCG(JSContext *cx, BytecodeEmitter *bce)
|
||||
{
|
||||
uint32 mainLength, prologLength, nsrcnotes, nfixed;
|
||||
JSScript *script;
|
||||
@ -1066,121 +1066,121 @@ JSScript::NewScriptFromCG(JSContext *cx, CodeGenerator *cg)
|
||||
JSFunction *fun;
|
||||
|
||||
/* The counts of indexed things must be checked during code generation. */
|
||||
JS_ASSERT(cg->atomIndices->count() <= INDEX_LIMIT);
|
||||
JS_ASSERT(cg->objectList.length <= INDEX_LIMIT);
|
||||
JS_ASSERT(cg->regexpList.length <= INDEX_LIMIT);
|
||||
JS_ASSERT(bce->atomIndices->count() <= INDEX_LIMIT);
|
||||
JS_ASSERT(bce->objectList.length <= INDEX_LIMIT);
|
||||
JS_ASSERT(bce->regexpList.length <= INDEX_LIMIT);
|
||||
|
||||
mainLength = CG_OFFSET(cg);
|
||||
prologLength = CG_PROLOG_OFFSET(cg);
|
||||
mainLength = CG_OFFSET(bce);
|
||||
prologLength = CG_PROLOG_OFFSET(bce);
|
||||
|
||||
if (!cg->bindings.ensureShape(cx))
|
||||
if (!bce->bindings.ensureShape(cx))
|
||||
return NULL;
|
||||
|
||||
CG_COUNT_FINAL_SRCNOTES(cg, nsrcnotes);
|
||||
uint16 nClosedArgs = uint16(cg->closedArgs.length());
|
||||
JS_ASSERT(nClosedArgs == cg->closedArgs.length());
|
||||
uint16 nClosedVars = uint16(cg->closedVars.length());
|
||||
JS_ASSERT(nClosedVars == cg->closedVars.length());
|
||||
size_t upvarIndexCount = cg->upvarIndices.hasMap() ? cg->upvarIndices->count() : 0;
|
||||
CG_COUNT_FINAL_SRCNOTES(bce, nsrcnotes);
|
||||
uint16 nClosedArgs = uint16(bce->closedArgs.length());
|
||||
JS_ASSERT(nClosedArgs == bce->closedArgs.length());
|
||||
uint16 nClosedVars = uint16(bce->closedVars.length());
|
||||
JS_ASSERT(nClosedVars == bce->closedVars.length());
|
||||
size_t upvarIndexCount = bce->upvarIndices.hasMap() ? bce->upvarIndices->count() : 0;
|
||||
script = NewScript(cx, prologLength + mainLength, nsrcnotes,
|
||||
cg->atomIndices->count(), cg->objectList.length,
|
||||
upvarIndexCount, cg->regexpList.length,
|
||||
cg->ntrynotes, cg->constList.length(),
|
||||
cg->globalUses.length(), nClosedArgs, nClosedVars,
|
||||
cg->typesetCount, cg->version());
|
||||
bce->atomIndices->count(), bce->objectList.length,
|
||||
upvarIndexCount, bce->regexpList.length,
|
||||
bce->ntrynotes, bce->constList.length(),
|
||||
bce->globalUses.length(), nClosedArgs, nClosedVars,
|
||||
bce->typesetCount, bce->version());
|
||||
if (!script)
|
||||
return NULL;
|
||||
|
||||
cg->bindings.makeImmutable();
|
||||
bce->bindings.makeImmutable();
|
||||
|
||||
JS_ASSERT(script->mainOffset == 0);
|
||||
script->mainOffset = prologLength;
|
||||
memcpy(script->code, CG_PROLOG_BASE(cg), prologLength * sizeof(jsbytecode));
|
||||
memcpy(script->main(), CG_BASE(cg), mainLength * sizeof(jsbytecode));
|
||||
nfixed = cg->inFunction()
|
||||
? cg->bindings.countVars()
|
||||
: cg->sharpSlots();
|
||||
memcpy(script->code, CG_PROLOG_BASE(bce), prologLength * sizeof(jsbytecode));
|
||||
memcpy(script->main(), CG_BASE(bce), mainLength * sizeof(jsbytecode));
|
||||
nfixed = bce->inFunction()
|
||||
? bce->bindings.countVars()
|
||||
: bce->sharpSlots();
|
||||
JS_ASSERT(nfixed < SLOTNO_LIMIT);
|
||||
script->nfixed = (uint16) nfixed;
|
||||
js_InitAtomMap(cx, cg->atomIndices.getMap(), script->atoms);
|
||||
js_InitAtomMap(cx, bce->atomIndices.getMap(), script->atoms);
|
||||
|
||||
filename = cg->parser->tokenStream.getFilename();
|
||||
filename = bce->parser->tokenStream.getFilename();
|
||||
if (filename) {
|
||||
script->filename = SaveScriptFilename(cx, filename);
|
||||
if (!script->filename)
|
||||
return NULL;
|
||||
}
|
||||
script->lineno = cg->firstLine;
|
||||
if (script->nfixed + cg->maxStackDepth >= JS_BIT(16)) {
|
||||
ReportCompileErrorNumber(cx, CG_TS(cg), NULL, JSREPORT_ERROR, JSMSG_NEED_DIET, "script");
|
||||
script->lineno = bce->firstLine;
|
||||
if (script->nfixed + bce->maxStackDepth >= JS_BIT(16)) {
|
||||
ReportCompileErrorNumber(cx, CG_TS(bce), NULL, JSREPORT_ERROR, JSMSG_NEED_DIET, "script");
|
||||
return NULL;
|
||||
}
|
||||
script->nslots = script->nfixed + cg->maxStackDepth;
|
||||
script->staticLevel = uint16(cg->staticLevel);
|
||||
script->principals = cg->parser->principals;
|
||||
script->nslots = script->nfixed + bce->maxStackDepth;
|
||||
script->staticLevel = uint16(bce->staticLevel);
|
||||
script->principals = bce->parser->principals;
|
||||
if (script->principals)
|
||||
JSPRINCIPALS_HOLD(cx, script->principals);
|
||||
|
||||
script->sourceMap = (jschar *) cg->parser->tokenStream.releaseSourceMap();
|
||||
script->sourceMap = (jschar *) bce->parser->tokenStream.releaseSourceMap();
|
||||
|
||||
if (!FinishTakingSrcNotes(cx, cg, script->notes()))
|
||||
if (!FinishTakingSrcNotes(cx, bce, script->notes()))
|
||||
return NULL;
|
||||
if (cg->ntrynotes != 0)
|
||||
FinishTakingTryNotes(cg, script->trynotes());
|
||||
if (cg->objectList.length != 0)
|
||||
cg->objectList.finish(script->objects());
|
||||
if (cg->regexpList.length != 0)
|
||||
cg->regexpList.finish(script->regexps());
|
||||
if (cg->constList.length() != 0)
|
||||
cg->constList.finish(script->consts());
|
||||
if (cg->flags & TCF_NO_SCRIPT_RVAL)
|
||||
if (bce->ntrynotes != 0)
|
||||
FinishTakingTryNotes(bce, script->trynotes());
|
||||
if (bce->objectList.length != 0)
|
||||
bce->objectList.finish(script->objects());
|
||||
if (bce->regexpList.length != 0)
|
||||
bce->regexpList.finish(script->regexps());
|
||||
if (bce->constList.length() != 0)
|
||||
bce->constList.finish(script->consts());
|
||||
if (bce->flags & TCF_NO_SCRIPT_RVAL)
|
||||
script->noScriptRval = true;
|
||||
if (cg->hasSharps())
|
||||
if (bce->hasSharps())
|
||||
script->hasSharps = true;
|
||||
if (cg->flags & TCF_STRICT_MODE_CODE)
|
||||
if (bce->flags & TCF_STRICT_MODE_CODE)
|
||||
script->strictModeCode = true;
|
||||
if (cg->flags & TCF_COMPILE_N_GO) {
|
||||
if (bce->flags & TCF_COMPILE_N_GO) {
|
||||
script->compileAndGo = true;
|
||||
const StackFrame *fp = cg->parser->callerFrame;
|
||||
const StackFrame *fp = bce->parser->callerFrame;
|
||||
if (fp && fp->isFunctionFrame())
|
||||
script->savedCallerFun = true;
|
||||
}
|
||||
if (cg->callsEval())
|
||||
if (bce->callsEval())
|
||||
script->usesEval = true;
|
||||
if (cg->flags & TCF_FUN_USES_ARGUMENTS)
|
||||
if (bce->flags & TCF_FUN_USES_ARGUMENTS)
|
||||
script->usesArguments = true;
|
||||
if (cg->flags & TCF_HAS_SINGLETONS)
|
||||
if (bce->flags & TCF_HAS_SINGLETONS)
|
||||
script->hasSingletons = true;
|
||||
|
||||
if (cg->hasUpvarIndices()) {
|
||||
JS_ASSERT(cg->upvarIndices->count() <= cg->upvarMap.length());
|
||||
memcpy(script->upvars()->vector, cg->upvarMap.begin(),
|
||||
cg->upvarIndices->count() * sizeof(cg->upvarMap[0]));
|
||||
cg->upvarIndices->clear();
|
||||
cg->upvarMap.clear();
|
||||
if (bce->hasUpvarIndices()) {
|
||||
JS_ASSERT(bce->upvarIndices->count() <= bce->upvarMap.length());
|
||||
memcpy(script->upvars()->vector, bce->upvarMap.begin(),
|
||||
bce->upvarIndices->count() * sizeof(bce->upvarMap[0]));
|
||||
bce->upvarIndices->clear();
|
||||
bce->upvarMap.clear();
|
||||
}
|
||||
|
||||
if (cg->globalUses.length()) {
|
||||
memcpy(script->globals()->vector, &cg->globalUses[0],
|
||||
cg->globalUses.length() * sizeof(GlobalSlotArray::Entry));
|
||||
if (bce->globalUses.length()) {
|
||||
memcpy(script->globals()->vector, &bce->globalUses[0],
|
||||
bce->globalUses.length() * sizeof(GlobalSlotArray::Entry));
|
||||
}
|
||||
|
||||
if (script->nClosedArgs)
|
||||
memcpy(script->closedSlots, &cg->closedArgs[0], script->nClosedArgs * sizeof(uint32));
|
||||
memcpy(script->closedSlots, &bce->closedArgs[0], script->nClosedArgs * sizeof(uint32));
|
||||
if (script->nClosedVars) {
|
||||
memcpy(&script->closedSlots[script->nClosedArgs], &cg->closedVars[0],
|
||||
memcpy(&script->closedSlots[script->nClosedArgs], &bce->closedVars[0],
|
||||
script->nClosedVars * sizeof(uint32));
|
||||
}
|
||||
|
||||
script->bindings.transfer(cx, &cg->bindings);
|
||||
script->bindings.transfer(cx, &bce->bindings);
|
||||
|
||||
fun = NULL;
|
||||
if (cg->inFunction()) {
|
||||
if (bce->inFunction()) {
|
||||
/*
|
||||
* We initialize fun->script() to be the script constructed above
|
||||
* so that the debugger has a valid fun->script().
|
||||
*/
|
||||
fun = cg->fun();
|
||||
fun = bce->fun();
|
||||
JS_ASSERT(fun->isInterpreted());
|
||||
JS_ASSERT(!fun->script());
|
||||
#ifdef DEBUG
|
||||
@ -1189,13 +1189,13 @@ JSScript::NewScriptFromCG(JSContext *cx, CodeGenerator *cg)
|
||||
else
|
||||
JS_ASSERT(script->bindings.countUpvars() == 0);
|
||||
#endif
|
||||
if (cg->flags & TCF_FUN_HEAVYWEIGHT)
|
||||
if (bce->flags & TCF_FUN_HEAVYWEIGHT)
|
||||
fun->flags |= JSFUN_HEAVYWEIGHT;
|
||||
|
||||
/* Watch for scripts whose functions will not be cloned. These are singletons. */
|
||||
bool singleton =
|
||||
cx->typeInferenceEnabled() && cg->parent && cg->parent->compiling() &&
|
||||
cg->parent->asCodeGenerator()->checkSingletonContext();
|
||||
cx->typeInferenceEnabled() && bce->parent && bce->parent->compiling() &&
|
||||
bce->parent->asBytecodeEmitter()->checkSingletonContext();
|
||||
|
||||
if (!script->typeSetFunction(cx, fun, singleton))
|
||||
return NULL;
|
||||
@ -1207,18 +1207,18 @@ JSScript::NewScriptFromCG(JSContext *cx, CodeGenerator *cg)
|
||||
* Initialize script->object, if necessary, so that the debugger has a
|
||||
* valid holder object.
|
||||
*/
|
||||
if (cg->flags & TCF_NEED_SCRIPT_GLOBAL)
|
||||
if (bce->flags & TCF_NEED_SCRIPT_GLOBAL)
|
||||
script->u.globalObject = GetCurrentGlobal(cx);
|
||||
}
|
||||
|
||||
/* Tell the debugger about this compiled script. */
|
||||
js_CallNewScriptHook(cx, script, fun);
|
||||
if (!cg->parent) {
|
||||
if (!bce->parent) {
|
||||
GlobalObject *compileAndGoGlobal = NULL;
|
||||
if (script->compileAndGo) {
|
||||
compileAndGoGlobal = script->u.globalObject;
|
||||
if (!compileAndGoGlobal)
|
||||
compileAndGoGlobal = cg->scopeChain()->getGlobal();
|
||||
compileAndGoGlobal = bce->scopeChain()->getGlobal();
|
||||
}
|
||||
Debugger::onNewScript(cx, script, compileAndGoGlobal);
|
||||
}
|
||||
|
@ -444,7 +444,7 @@ struct JSScript : public js::gc::Cell {
|
||||
uint16 nClosedArgs, uint16 nClosedVars, uint32 nTypeSets,
|
||||
JSVersion version);
|
||||
|
||||
static JSScript *NewScriptFromCG(JSContext *cx, js::CodeGenerator *cg);
|
||||
static JSScript *NewScriptFromCG(JSContext *cx, js::BytecodeEmitter *bce);
|
||||
|
||||
#ifdef JS_CRASH_DIAGNOSTICS
|
||||
/*
|
||||
|
@ -79,7 +79,7 @@
|
||||
#include "jstypedarray.h"
|
||||
|
||||
#include "builtin/RegExp.h"
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
|
||||
#include "jsatominlines.h"
|
||||
#include "jscntxtinlines.h"
|
||||
|
@ -61,7 +61,7 @@
|
||||
#include "jshotloop.h"
|
||||
|
||||
#include "builtin/RegExp.h"
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
#include "vm/RegExpStatics.h"
|
||||
#include "vm/RegExpObject.h"
|
||||
|
||||
|
@ -47,7 +47,7 @@
|
||||
#include "jsscriptinlines.h"
|
||||
#include "jstypedarrayinlines.h"
|
||||
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
#include "methodjit/MethodJIT.h"
|
||||
#include "methodjit/Compiler.h"
|
||||
#include "methodjit/StubCalls.h"
|
||||
|
@ -79,7 +79,7 @@
|
||||
#include "jsxml.h"
|
||||
#include "jsperf.h"
|
||||
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
#include "frontend/Parser.h"
|
||||
#include "methodjit/MethodJIT.h"
|
||||
|
||||
|
@ -51,7 +51,7 @@
|
||||
#include "jsopcodeinlines.h"
|
||||
|
||||
#include "frontend/BytecodeCompiler.h"
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
#include "methodjit/Retcon.h"
|
||||
|
||||
#include "vm/Stack-inl.h"
|
||||
|
@ -46,7 +46,7 @@
|
||||
#include "json.h"
|
||||
|
||||
#include "builtin/RegExp.h"
|
||||
#include "frontend/BytecodeGenerator.h"
|
||||
#include "frontend/BytecodeEmitter.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
#include "vm/RegExpObject-inl.h"
|
||||
|
Loading…
Reference in New Issue
Block a user