mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 446386 - removal of the compiler pseud-frames. r=brendan,mrbkap
This commit is contained in:
parent
b78b594ba0
commit
4509b7601e
@ -4569,7 +4569,7 @@ JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj,
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
tcflags = JS_OPTIONS_TO_TCFLAGS(cx);
|
||||
script = js_CompileScript(cx, obj, principals, tcflags,
|
||||
script = js_CompileScript(cx, obj, NULL, principals, tcflags,
|
||||
chars, length, NULL, filename, lineno);
|
||||
LAST_FRAME_CHECKS(cx, script);
|
||||
return script;
|
||||
@ -4596,7 +4596,8 @@ JS_BufferIsCompilableUnit(JSContext *cx, JSObject *obj,
|
||||
*/
|
||||
result = JS_TRUE;
|
||||
exnState = JS_SaveExceptionState(cx);
|
||||
if (js_InitParseContext(cx, &pc, NULL, chars, length, NULL, NULL, 1)) {
|
||||
if (js_InitParseContext(cx, &pc, NULL, NULL, chars, length, NULL, NULL,
|
||||
1)) {
|
||||
older = JS_SetErrorReporter(cx, NULL);
|
||||
if (!js_ParseScript(cx, obj, &pc) &&
|
||||
(pc.tokenStream.flags & TSF_UNEXPECTED_EOF)) {
|
||||
@ -4635,7 +4636,7 @@ JS_CompileFile(JSContext *cx, JSObject *obj, const char *filename)
|
||||
}
|
||||
|
||||
tcflags = JS_OPTIONS_TO_TCFLAGS(cx);
|
||||
script = js_CompileScript(cx, obj, NULL, tcflags,
|
||||
script = js_CompileScript(cx, obj, NULL, NULL, tcflags,
|
||||
NULL, 0, fp, filename, 1);
|
||||
if (fp != stdin)
|
||||
fclose(fp);
|
||||
@ -4660,7 +4661,7 @@ JS_CompileFileHandleForPrincipals(JSContext *cx, JSObject *obj,
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
tcflags = JS_OPTIONS_TO_TCFLAGS(cx);
|
||||
script = js_CompileScript(cx, obj, principals, tcflags,
|
||||
script = js_CompileScript(cx, obj, NULL, principals, tcflags,
|
||||
NULL, 0, file, filename, 1);
|
||||
LAST_FRAME_CHECKS(cx, script);
|
||||
return script;
|
||||
@ -4998,7 +4999,7 @@ JS_EvaluateUCScriptForPrincipals(JSContext *cx, JSObject *obj,
|
||||
JSBool ok;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
script = js_CompileScript(cx, obj, principals,
|
||||
script = js_CompileScript(cx, obj, NULL, principals,
|
||||
!rval
|
||||
? TCF_COMPILE_N_GO | TCF_NO_SCRIPT_RVAL
|
||||
: TCF_COMPILE_N_GO,
|
||||
|
@ -1155,19 +1155,12 @@ JS_GetFrameFunction(JSContext *cx, JSStackFrame *fp)
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_GetFrameFunctionObject(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
/*
|
||||
* Test both fp->fun and fp->argv to defend against any control flow from
|
||||
* the compiler reaching this API entry point, where fp is a frame pushed
|
||||
* by the compiler that has non-null fun but null argv.
|
||||
*/
|
||||
if (fp->fun && fp->argv) {
|
||||
JSObject *obj = fp->callee;
|
||||
if (!fp->fun)
|
||||
return NULL;
|
||||
|
||||
JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_FunctionClass);
|
||||
JS_ASSERT(OBJ_GET_PRIVATE(cx, obj) == fp->fun);
|
||||
return obj;
|
||||
}
|
||||
return NULL;
|
||||
JS_ASSERT(OBJ_GET_CLASS(cx, fp->callee) == &js_FunctionClass);
|
||||
JS_ASSERT(OBJ_GET_PRIVATE(cx, fp->callee) == fp->fun);
|
||||
return fp->callee;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
@ -1252,7 +1245,6 @@ JS_EvaluateUCInStackFrame(JSContext *cx, JSStackFrame *fp,
|
||||
jsval *rval)
|
||||
{
|
||||
JSObject *scobj;
|
||||
uint32 flags;
|
||||
JSScript *script;
|
||||
JSBool ok;
|
||||
|
||||
@ -1260,18 +1252,11 @@ JS_EvaluateUCInStackFrame(JSContext *cx, JSStackFrame *fp,
|
||||
if (!scobj)
|
||||
return JS_FALSE;
|
||||
|
||||
/*
|
||||
* XXX Hack around ancient compiler API to propagate the JSFRAME_SPECIAL
|
||||
* flags to the code generator.
|
||||
*/
|
||||
flags = fp->flags;
|
||||
fp->flags |= JSFRAME_DEBUGGER | JSFRAME_EVAL;
|
||||
script = js_CompileScript(cx, scobj, JS_StackFramePrincipals(cx, fp),
|
||||
script = js_CompileScript(cx, scobj, fp, JS_StackFramePrincipals(cx, fp),
|
||||
TCF_COMPILE_N_GO |
|
||||
TCF_PUT_STATIC_DEPTH(fp->script->staticDepth + 1),
|
||||
chars, length, NULL,
|
||||
filename, lineno);
|
||||
fp->flags = flags;
|
||||
if (!script)
|
||||
return JS_FALSE;
|
||||
|
||||
|
@ -1575,8 +1575,7 @@ LookupCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
|
||||
*/
|
||||
*vp = JSVAL_HOLE;
|
||||
do {
|
||||
if ((cg->treeContext.flags & TCF_IN_FUNCTION) ||
|
||||
cx->fp->varobj == cx->fp->scopeChain) {
|
||||
if (cg->treeContext.flags & (TCF_IN_FUNCTION | TCF_COMPILE_N_GO)) {
|
||||
/* XXX this will need revising when 'let const' is added. */
|
||||
stmt = js_LexicalLookup(&cg->treeContext, atom, NULL);
|
||||
if (stmt)
|
||||
@ -1597,12 +1596,13 @@ LookupCompileTimeConstant(JSContext *cx, JSCodeGenerator *cg, JSAtom *atom,
|
||||
* nor can prop be deleted.
|
||||
*/
|
||||
if (cg->treeContext.flags & TCF_IN_FUNCTION) {
|
||||
if (js_LookupLocal(cx, cg->treeContext.fun, atom, NULL) !=
|
||||
if (js_LookupLocal(cx, cg->treeContext.u.fun, atom, NULL) !=
|
||||
JSLOCAL_NONE) {
|
||||
break;
|
||||
}
|
||||
} else if (cg->treeContext.flags & TCF_COMPILE_N_GO) {
|
||||
obj = cx->fp->varobj;
|
||||
} else {
|
||||
JS_ASSERT(cg->treeContext.flags & TCF_COMPILE_N_GO);
|
||||
obj = cg->treeContext.u.scopeChain;
|
||||
ok = OBJ_LOOKUP_PROPERTY(cx, obj, ATOM_TO_JSID(atom), &pobj,
|
||||
&prop);
|
||||
if (!ok)
|
||||
@ -1780,7 +1780,7 @@ AdjustBlockSlot(JSContext *cx, JSCodeGenerator *cg, jsint slot)
|
||||
{
|
||||
JS_ASSERT((jsuint) slot < cg->maxStackDepth);
|
||||
if (cg->treeContext.flags & TCF_IN_FUNCTION) {
|
||||
slot += cg->treeContext.fun->u.i.nvars;
|
||||
slot += cg->treeContext.u.fun->u.i.nvars;
|
||||
if ((uintN) slot >= SLOTNO_LIMIT) {
|
||||
js_ReportCompileErrorNumber(cx, CG_TS(cg), NULL,
|
||||
JSREPORT_ERROR,
|
||||
@ -1817,7 +1817,6 @@ BindNameToSlot(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
||||
JSStmtInfo *stmt;
|
||||
jsint slot;
|
||||
JSOp op;
|
||||
JSStackFrame *fp;
|
||||
JSLocalKind localKind;
|
||||
uintN index;
|
||||
JSAtomListElement *ale;
|
||||
@ -1877,80 +1876,65 @@ BindNameToSlot(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
||||
return JS_TRUE;
|
||||
|
||||
if (!(tc->flags & TCF_IN_FUNCTION)) {
|
||||
if ((cx->fp->flags & JSFRAME_SPECIAL) && cx->fp->fun) {
|
||||
if (cg->staticDepth > JS_DISPLAY_SIZE)
|
||||
goto out;
|
||||
JSStackFrame *caller;
|
||||
|
||||
localKind = js_LookupLocal(cx, cx->fp->fun, atom, &index);
|
||||
if (localKind != JSLOCAL_NONE) {
|
||||
if (PN_OP(pn) == JSOP_NAME) {
|
||||
ATOM_LIST_SEARCH(ale, &cg->upvarList, atom);
|
||||
if (!ale) {
|
||||
uint32 cookie, length, *vector;
|
||||
caller = tc->parseContext->callerFrame;
|
||||
if (caller) {
|
||||
JS_ASSERT(tc->flags & TCF_COMPILE_N_GO);
|
||||
JS_ASSERT(caller->script);
|
||||
if (!caller->fun || caller->varobj != tc->u.scopeChain)
|
||||
return JS_TRUE;
|
||||
|
||||
ale = js_IndexAtom(cx, atom, &cg->upvarList);
|
||||
if (!ale)
|
||||
return JS_FALSE;
|
||||
JS_ASSERT(ALE_INDEX(ale) == cg->upvarList.count - 1);
|
||||
/*
|
||||
* We are compiling eval or debug script inside a function frame
|
||||
* and the scope chain matches function's variable object.
|
||||
* Optimize access to function's arguments and variable and the
|
||||
* arguments object.
|
||||
*/
|
||||
if (PN_OP(pn) != JSOP_NAME || cg->staticDepth > JS_DISPLAY_SIZE)
|
||||
goto arguments_check;
|
||||
localKind = js_LookupLocal(cx, caller->fun, atom, &index);
|
||||
if (localKind == JSLOCAL_NONE)
|
||||
goto arguments_check;
|
||||
|
||||
length = cg->upvarMap.length;
|
||||
JS_ASSERT(ALE_INDEX(ale) <= length);
|
||||
if (ALE_INDEX(ale) == length) {
|
||||
length = 2 * JS_MAX(2, length);
|
||||
vector = (uint32 *)
|
||||
JS_realloc(cx, cg->upvarMap.vector,
|
||||
length * sizeof *vector);
|
||||
if (!vector)
|
||||
return JS_FALSE;
|
||||
cg->upvarMap.vector = vector;
|
||||
cg->upvarMap.length = length;
|
||||
}
|
||||
ATOM_LIST_SEARCH(ale, &cg->upvarList, atom);
|
||||
if (!ale) {
|
||||
uint32 cookie, length, *vector;
|
||||
|
||||
if (localKind != JSLOCAL_ARG)
|
||||
index += cx->fp->fun->nargs;
|
||||
if (index >= JS_BIT(16)) {
|
||||
cg->treeContext.flags |= TCF_FUN_USES_NONLOCALS;
|
||||
return JS_TRUE;
|
||||
}
|
||||
ale = js_IndexAtom(cx, atom, &cg->upvarList);
|
||||
if (!ale)
|
||||
return JS_FALSE;
|
||||
JS_ASSERT(ALE_INDEX(ale) == cg->upvarList.count - 1);
|
||||
|
||||
cookie = MAKE_UPVAR_COOKIE(1, index);
|
||||
cg->upvarMap.vector[ALE_INDEX(ale)] = cookie;
|
||||
}
|
||||
length = cg->upvarMap.length;
|
||||
JS_ASSERT(ALE_INDEX(ale) <= length);
|
||||
if (ALE_INDEX(ale) == length) {
|
||||
length = 2 * JS_MAX(2, length);
|
||||
vector = (uint32 *)
|
||||
JS_realloc(cx, cg->upvarMap.vector,
|
||||
length * sizeof *vector);
|
||||
if (!vector)
|
||||
return JS_FALSE;
|
||||
cg->upvarMap.vector = vector;
|
||||
cg->upvarMap.length = length;
|
||||
}
|
||||
|
||||
pn->pn_op = JSOP_GETUPVAR;
|
||||
pn->pn_slot = ALE_INDEX(ale);
|
||||
if (localKind != JSLOCAL_ARG)
|
||||
index += caller->fun->nargs;
|
||||
if (index >= JS_BIT(16)) {
|
||||
cg->treeContext.flags |= TCF_FUN_USES_NONLOCALS;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
cookie = MAKE_UPVAR_COOKIE(1, index);
|
||||
cg->upvarMap.vector[ALE_INDEX(ale)] = cookie;
|
||||
}
|
||||
goto out;
|
||||
|
||||
pn->pn_op = JSOP_GETUPVAR;
|
||||
pn->pn_slot = ALE_INDEX(ale);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are compiling a script or eval, and eval is not inside a function
|
||||
* activation.
|
||||
*/
|
||||
fp = cx->fp;
|
||||
if (fp->scopeChain != fp->varobj)
|
||||
return JS_TRUE;
|
||||
|
||||
/*
|
||||
* A Script object can be used to split an eval into a compile step
|
||||
* done at construction time, and an execute step done separately,
|
||||
* possibly in a different scope altogether. We therefore cannot do
|
||||
* any name-to-slot optimizations, but must lookup names at runtime.
|
||||
* Note that script_exec ensures that its caller's frame has a Call
|
||||
* object, so arg and var name lookups will succeed.
|
||||
*/
|
||||
if (fp->flags & JSFRAME_SCRIPT_OBJECT)
|
||||
return JS_TRUE;
|
||||
|
||||
/*
|
||||
* We cannot optimize the name access when compiling with an eval or
|
||||
* debugger frame.
|
||||
*/
|
||||
if (fp->flags & JSFRAME_SPECIAL)
|
||||
return JS_TRUE;
|
||||
|
||||
/*
|
||||
* We are optimizing global variables and there may be no pre-existing
|
||||
* global property named atom. If atom was declared via const or var,
|
||||
@ -2003,7 +1987,7 @@ BindNameToSlot(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
||||
* to stack slot. Look for an argument or variable in the function and
|
||||
* rewrite pn_op and update pn accordingly.
|
||||
*/
|
||||
localKind = js_LookupLocal(cx, tc->fun, atom, &index);
|
||||
localKind = js_LookupLocal(cx, tc->u.fun, atom, &index);
|
||||
if (localKind != JSLOCAL_NONE) {
|
||||
op = PN_OP(pn);
|
||||
if (localKind == JSLOCAL_ARG) {
|
||||
@ -2043,17 +2027,17 @@ BindNameToSlot(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
||||
tc->flags |= TCF_FUN_USES_NONLOCALS;
|
||||
}
|
||||
|
||||
out:
|
||||
arguments_check:
|
||||
/*
|
||||
* Here we either compiling a function body or an eval script inside a
|
||||
* function and couldn't optimize pn, so it's not a global or local slot
|
||||
* name.
|
||||
*
|
||||
* Now we must check for the predefined arguments variable. It may be
|
||||
* overridden by assignment, in which case the function is heavyweight
|
||||
* and the interpreter will look up 'arguments' in the function's call
|
||||
* object.
|
||||
* Here we either compiling a function body or an eval or debug script
|
||||
* inside a function and couldn't optimize pn, so it's not a global or
|
||||
* local slot name. We are also outside of any with blocks. Check if we
|
||||
* can optimize the predefined arguments variable.
|
||||
*/
|
||||
JS_ASSERT((tc->flags & TCF_IN_FUNCTION) ||
|
||||
(tc->parseContext->callerFrame &&
|
||||
tc->parseContext->callerFrame->fun &&
|
||||
tc->parseContext->callerFrame->varobj == tc->u.scopeChain));
|
||||
if (pn->pn_op == JSOP_NAME &&
|
||||
atom == cx->runtime->atomState.argumentsAtom) {
|
||||
pn->pn_op = JSOP_ARGUMENTS;
|
||||
@ -3182,11 +3166,6 @@ js_EmitFunctionScript(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body)
|
||||
CG_SWITCH_TO_MAIN(cg);
|
||||
}
|
||||
|
||||
if (!(cg->treeContext.flags & TCF_FUN_HEAVYWEIGHT) &&
|
||||
(cg->treeContext.flags & TCF_COMPILE_N_GO)) {
|
||||
STOBJ_SET_PARENT(FUN_OBJECT(cg->treeContext.fun), cx->fp->scopeChain);
|
||||
}
|
||||
|
||||
return js_EmitTree(cx, cg, body) &&
|
||||
js_Emit1(cx, cg, JSOP_STOP) >= 0 &&
|
||||
js_NewScriptFromCG(cx, cg);
|
||||
@ -4011,7 +3990,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
||||
cg->codePool, cg->notePool,
|
||||
pn->pn_pos.begin.lineno);
|
||||
cg2->treeContext.flags = (uint16) (pn->pn_flags | TCF_IN_FUNCTION);
|
||||
cg2->treeContext.fun = fun;
|
||||
cg2->treeContext.u.fun = fun;
|
||||
cg2->staticDepth = cg->staticDepth + 1;
|
||||
cg2->parent = cg;
|
||||
|
||||
@ -4066,7 +4045,9 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
||||
* instantiating top-level functions in the non-eval case.
|
||||
*/
|
||||
JS_ASSERT(!cg->treeContext.topStmt);
|
||||
op = (cx->fp->flags & JSFRAME_EVAL) ? JSOP_CLOSURE : JSOP_DEFFUN;
|
||||
op = (cg->treeContext.parseContext->callerFrame)
|
||||
? JSOP_CLOSURE
|
||||
: JSOP_DEFFUN;
|
||||
EMIT_INDEX_OP(op, index);
|
||||
CG_SWITCH_TO_MAIN(cg);
|
||||
|
||||
@ -4077,7 +4058,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
||||
#ifdef DEBUG
|
||||
JSLocalKind localKind =
|
||||
#endif
|
||||
js_LookupLocal(cx, cg->treeContext.fun, fun->atom, &slot);
|
||||
js_LookupLocal(cx, cg->treeContext.u.fun, fun->atom, &slot);
|
||||
JS_ASSERT(localKind == JSLOCAL_VAR || localKind == JSLOCAL_CONST);
|
||||
JS_ASSERT(pn->pn_index == (uint32) -1);
|
||||
pn->pn_index = index;
|
||||
|
@ -171,8 +171,14 @@ struct JSTreeContext { /* tree context for semantic checks */
|
||||
XXX combine with blockChain? */
|
||||
JSAtomList decls; /* function, const, and var declarations */
|
||||
JSParseContext *parseContext;
|
||||
JSFunction *fun; /* function to store argument and variable
|
||||
|
||||
union {
|
||||
|
||||
JSFunction *fun; /* function to store argument and variable
|
||||
names when flags & TCF_IN_FUNCTION */
|
||||
JSObject *scopeChain; /* scope chain object for the script */
|
||||
} u;
|
||||
|
||||
#ifdef JS_SCOPE_DEPTH_METER
|
||||
uint16 scopeDepth; /* current lexical scope chain depth */
|
||||
uint16 maxScopeDepth; /* maximum lexical scope chain depth */
|
||||
@ -195,7 +201,6 @@ struct JSTreeContext { /* tree context for semantic checks */
|
||||
chain */
|
||||
#define TCF_NO_SCRIPT_RVAL 0x1000 /* API caller does not want result value
|
||||
from global script */
|
||||
|
||||
/*
|
||||
* Flags to propagate out of the blocks.
|
||||
*/
|
||||
@ -230,7 +235,7 @@ struct JSTreeContext { /* tree context for semantic checks */
|
||||
ATOM_LIST_INIT(&(tc)->decls), \
|
||||
(tc)->blockNode = NULL, \
|
||||
(tc)->parseContext = (pc), \
|
||||
(tc)->fun = NULL, \
|
||||
(tc)->u.scopeChain = NULL, \
|
||||
JS_SCOPE_DEPTH_METERING((tc)->scopeDepth = (tc)->maxScopeDepth = 0))
|
||||
|
||||
/*
|
||||
|
@ -791,7 +791,7 @@ CallPropertyOp(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
|
||||
}
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
JS_ASSERT((int16) JSVAL_TO_INT(id) == JSVAL_TO_INT(id));
|
||||
i = (uint16) JSVAL_TO_INT(id);
|
||||
|
@ -128,12 +128,11 @@ typedef struct JSInlineFrame {
|
||||
is currently assigning to a property */
|
||||
#define JSFRAME_DEBUGGER 0x08 /* frame for JS_EvaluateInStackFrame */
|
||||
#define JSFRAME_EVAL 0x10 /* frame for obj_eval */
|
||||
#define JSFRAME_SCRIPT_OBJECT 0x20 /* compiling source for a Script object */
|
||||
#define JSFRAME_ROOTED_ARGV 0x20 /* frame.argv is rooted by the caller */
|
||||
#define JSFRAME_YIELDING 0x40 /* js_Interpret dispatched JSOP_YIELD */
|
||||
#define JSFRAME_ITERATOR 0x80 /* trying to get an iterator for for-in */
|
||||
#define JSFRAME_POP_BLOCKS 0x100 /* scope chain contains blocks to pop */
|
||||
#define JSFRAME_GENERATOR 0x200 /* frame belongs to generator-iterator */
|
||||
#define JSFRAME_ROOTED_ARGV 0x400 /* frame.argv is rooted by the caller */
|
||||
|
||||
#define JSFRAME_OVERRIDE_SHIFT 24 /* override bit-set params; see jsfun.c */
|
||||
#define JSFRAME_OVERRIDE_BITS 8
|
||||
|
@ -1176,6 +1176,7 @@ js_obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
const char *file;
|
||||
uintN line;
|
||||
JSPrincipals *principals;
|
||||
uint32 tcflags;
|
||||
JSScript *script;
|
||||
JSBool ok;
|
||||
#if JS_HAS_EVAL_THIS_SCOPE
|
||||
@ -1306,21 +1307,10 @@ js_obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
principals = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set JSFRAME_EVAL on fp and any frames (e.g., fun_call if eval.call was
|
||||
* invoked) between fp and its scripted caller, to help the compiler easily
|
||||
* find the same caller whose scope and var obj we've set.
|
||||
*
|
||||
* XXX this nonsense could, and perhaps should, go away with a better way
|
||||
* to pass params to the compiler than via the top-most frame.
|
||||
*/
|
||||
do {
|
||||
fp->flags |= JSFRAME_EVAL;
|
||||
} while ((fp = fp->down) != caller);
|
||||
|
||||
script = js_CompileScript(cx, scopeobj, principals,
|
||||
TCF_COMPILE_N_GO |
|
||||
TCF_PUT_STATIC_DEPTH(caller->script->staticDepth + 1),
|
||||
tcflags = TCF_COMPILE_N_GO;
|
||||
if (caller)
|
||||
tcflags |= TCF_PUT_STATIC_DEPTH(caller->script->staticDepth + 1);
|
||||
script = js_CompileScript(cx, scopeobj, caller, principals, tcflags,
|
||||
JSSTRING_CHARS(str), JSSTRING_LENGTH(str),
|
||||
NULL, file, line);
|
||||
if (!script) {
|
||||
|
@ -158,9 +158,12 @@ static uint32 recyclednodes = 0;
|
||||
|
||||
JSBool
|
||||
js_InitParseContext(JSContext *cx, JSParseContext *pc, JSPrincipals *principals,
|
||||
JSStackFrame *callerFrame,
|
||||
const jschar *base, size_t length,
|
||||
FILE *fp, const char *filename, uintN lineno)
|
||||
{
|
||||
JS_ASSERT_IF(callerFrame, callerFrame->script);
|
||||
|
||||
pc->tempPoolMark = JS_ARENA_MARK(&cx->tempPool);
|
||||
if (!js_InitTokenStream(cx, TS(pc), base, length, fp, filename, lineno)) {
|
||||
JS_ARENA_RELEASE(&cx->tempPool, pc->tempPoolMark);
|
||||
@ -169,6 +172,7 @@ js_InitParseContext(JSContext *cx, JSParseContext *pc, JSPrincipals *principals,
|
||||
if (principals)
|
||||
JSPRINCIPALS_HOLD(cx, principals);
|
||||
pc->principals = principals;
|
||||
pc->callerFrame = callerFrame;
|
||||
pc->nodeList = NULL;
|
||||
pc->traceListHead = NULL;
|
||||
|
||||
@ -455,70 +459,15 @@ CheckGetterOrSetter(JSContext *cx, JSTokenStream *ts, JSTokenType tt)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
MaybeSetupFrame(JSContext *cx, JSObject *chain, JSStackFrame *oldfp,
|
||||
JSStackFrame *newfp)
|
||||
{
|
||||
/*
|
||||
* Always push a new frame if the current frame is special, so that
|
||||
* Variables gets the correct variables object: the one from the special
|
||||
* frame's caller.
|
||||
*/
|
||||
if (oldfp &&
|
||||
oldfp->varobj &&
|
||||
oldfp->scopeChain == chain &&
|
||||
!(oldfp->flags & JSFRAME_SPECIAL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(newfp, 0, sizeof *newfp);
|
||||
|
||||
/* Default to sharing the same variables object and scope chain. */
|
||||
newfp->varobj = newfp->scopeChain = chain;
|
||||
if (cx->options & JSOPTION_VAROBJFIX) {
|
||||
while ((chain = JS_GetParent(cx, chain)) != NULL)
|
||||
newfp->varobj = chain;
|
||||
}
|
||||
newfp->down = oldfp;
|
||||
if (oldfp) {
|
||||
/*
|
||||
* In the case of eval and debugger frames, we need to dig down and find
|
||||
* the real variables objects and function that our new stack frame is
|
||||
* going to use.
|
||||
*/
|
||||
newfp->flags = oldfp->flags & (JSFRAME_SPECIAL | JSFRAME_SCRIPT_OBJECT);
|
||||
while (oldfp->flags & JSFRAME_SPECIAL) {
|
||||
oldfp = oldfp->down;
|
||||
if (!oldfp)
|
||||
break;
|
||||
}
|
||||
if (oldfp && (newfp->flags & JSFRAME_SPECIAL)) {
|
||||
newfp->varobj = oldfp->varobj;
|
||||
newfp->callee = oldfp->callee;
|
||||
newfp->fun = oldfp->fun;
|
||||
}
|
||||
}
|
||||
cx->fp = newfp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a top-level JS script.
|
||||
*/
|
||||
JSParseNode *
|
||||
js_ParseScript(JSContext *cx, JSObject *chain, JSParseContext *pc)
|
||||
{
|
||||
JSStackFrame *fp, frame;
|
||||
JSTreeContext tc;
|
||||
JSParseNode *pn;
|
||||
|
||||
/*
|
||||
* Push a compiler frame if we have no frames, or if the top frame is a
|
||||
* lightweight function activation, or if its scope chain doesn't match
|
||||
* the one passed to us.
|
||||
*/
|
||||
fp = cx->fp;
|
||||
MaybeSetupFrame(cx, chain, fp, &frame);
|
||||
|
||||
/*
|
||||
* Protect atoms from being collected by a GC activation, which might
|
||||
* - nest on this thread due to out of memory (the so-called "last ditch"
|
||||
@ -528,6 +477,7 @@ js_ParseScript(JSContext *cx, JSObject *chain, JSParseContext *pc)
|
||||
* protected from the GC by a root or a stack frame reference.
|
||||
*/
|
||||
TREE_CONTEXT_INIT(&tc, pc);
|
||||
tc.u.scopeChain = chain;
|
||||
pn = Statements(cx, TS(pc), &tc);
|
||||
if (pn) {
|
||||
if (!js_MatchToken(cx, TS(pc), TOK_EOF)) {
|
||||
@ -542,20 +492,19 @@ js_ParseScript(JSContext *cx, JSObject *chain, JSParseContext *pc)
|
||||
}
|
||||
|
||||
TREE_CONTEXT_FINISH(cx, &tc);
|
||||
cx->fp = fp;
|
||||
return pn;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compile a top-level script.
|
||||
*/
|
||||
JSScript *
|
||||
js_CompileScript(JSContext *cx, JSObject *obj, JSPrincipals *principals,
|
||||
uint32 tcflags, const jschar *chars, size_t length,
|
||||
extern JSScript *
|
||||
js_CompileScript(JSContext *cx, JSObject *scopeChain, JSStackFrame *callerFrame,
|
||||
JSPrincipals *principals, uint32 tcflags,
|
||||
const jschar *chars, size_t length,
|
||||
FILE *file, const char *filename, uintN lineno)
|
||||
{
|
||||
JSParseContext pc;
|
||||
JSStackFrame *fp, frame;
|
||||
JSArenaPool codePool, notePool;
|
||||
JSCodeGenerator cg;
|
||||
JSTokenType tt;
|
||||
@ -566,22 +515,20 @@ js_CompileScript(JSContext *cx, JSObject *obj, JSPrincipals *principals,
|
||||
void *sbrk(ptrdiff_t), *before = sbrk(0);
|
||||
#endif
|
||||
|
||||
JS_ASSERT(!(tcflags & ~(TCF_COMPILE_N_GO | TCF_NO_SCRIPT_RVAL | TCF_STATIC_DEPTH_MASK)));
|
||||
|
||||
if (!js_InitParseContext(cx, &pc, principals, chars, length, file,
|
||||
filename, lineno)) {
|
||||
return NULL;
|
||||
}
|
||||
JS_ASSERT(!(tcflags & ~(TCF_COMPILE_N_GO | TCF_NO_SCRIPT_RVAL |
|
||||
TCF_STATIC_DEPTH_MASK)));
|
||||
|
||||
/*
|
||||
* From this point the control must flow through the label out.
|
||||
*
|
||||
* Push a compiler frame if we have no frames, or if the top frame is a
|
||||
* lightweight function activation, or if its scope chain doesn't match
|
||||
* the one passed to us.
|
||||
* The scripted callerFrame can only be given for compile-and-go scripts
|
||||
* and non-zero static depth requires callerFrame.
|
||||
*/
|
||||
fp = cx->fp;
|
||||
MaybeSetupFrame(cx, obj, fp, &frame);
|
||||
JS_ASSERT_IF(callerFrame, tcflags & TCF_COMPILE_N_GO);
|
||||
JS_ASSERT_IF(TCF_GET_STATIC_DEPTH(tcflags) != 0, callerFrame);
|
||||
|
||||
if (!js_InitParseContext(cx, &pc, principals, callerFrame, chars, length,
|
||||
file, filename, lineno)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JS_INIT_ARENA_POOL(&codePool, "code", 1024, sizeof(jsbytecode),
|
||||
&cx->scriptStackQuota);
|
||||
@ -592,11 +539,10 @@ js_CompileScript(JSContext *cx, JSObject *obj, JSPrincipals *principals,
|
||||
|
||||
/* From this point the control must flow via the label out. */
|
||||
cg.treeContext.flags |= (uint16) tcflags;
|
||||
cg.treeContext.u.scopeChain = scopeChain;
|
||||
cg.staticDepth = TCF_GET_STATIC_DEPTH(tcflags);
|
||||
|
||||
/*
|
||||
* Inline Statements() to emit as we go to save space.
|
||||
*/
|
||||
/* Inline Statements() to emit as we go to save space. */
|
||||
for (;;) {
|
||||
pc.tokenStream.flags |= TSF_OPERAND;
|
||||
tt = js_PeekToken(cx, &pc.tokenStream);
|
||||
@ -614,7 +560,6 @@ js_CompileScript(JSContext *cx, JSObject *obj, JSPrincipals *principals,
|
||||
script = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
JS_ASSERT(!cg.treeContext.blockNode);
|
||||
|
||||
if (!js_FoldConstants(cx, pn, &cg.treeContext) ||
|
||||
@ -692,9 +637,9 @@ js_CompileScript(JSContext *cx, JSObject *obj, JSPrincipals *principals,
|
||||
|
||||
#ifdef JS_SCOPE_DEPTH_METER
|
||||
if (script) {
|
||||
JSObject *pobj = obj;
|
||||
JSObject *obj = scopeChain;
|
||||
uintN depth = 1;
|
||||
while ((pobj = OBJ_GET_PARENT(cx, pobj)) != NULL)
|
||||
while ((obj = OBJ_GET_PARENT(cx, obj)) != NULL)
|
||||
++depth;
|
||||
JS_BASIC_STATS_ACCUM(&cx->runtime->hostenvScopeDepthStats, depth);
|
||||
}
|
||||
@ -704,7 +649,6 @@ js_CompileScript(JSContext *cx, JSObject *obj, JSPrincipals *principals,
|
||||
js_FinishCodeGenerator(cx, &cg);
|
||||
JS_FinishArenaPool(&codePool);
|
||||
JS_FinishArenaPool(¬ePool);
|
||||
cx->fp = fp;
|
||||
js_FinishParseContext(cx, &pc);
|
||||
return script;
|
||||
|
||||
@ -849,8 +793,8 @@ ReportBadReturn(JSContext *cx, JSTreeContext *tc, uintN flags, uintN errnum,
|
||||
const char *name;
|
||||
|
||||
JS_ASSERT(tc->flags & TCF_IN_FUNCTION);
|
||||
if (tc->fun->atom) {
|
||||
name = js_AtomToPrintableString(cx, tc->fun->atom);
|
||||
if (tc->u.fun->atom) {
|
||||
name = js_AtomToPrintableString(cx, tc->u.fun->atom);
|
||||
} else {
|
||||
errnum = anonerrnum;
|
||||
name = NULL;
|
||||
@ -944,7 +888,7 @@ js_CompileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *principals,
|
||||
JSCodeGenerator funcg;
|
||||
JSParseNode *pn;
|
||||
|
||||
if (!js_InitParseContext(cx, &pc, principals, chars, length, NULL,
|
||||
if (!js_InitParseContext(cx, &pc, principals, NULL, chars, length, NULL,
|
||||
filename, lineno)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
@ -957,7 +901,7 @@ js_CompileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *principals,
|
||||
js_InitCodeGenerator(cx, &funcg, &pc, &codePool, ¬ePool,
|
||||
pc.tokenStream.lineno);
|
||||
funcg.treeContext.flags |= TCF_IN_FUNCTION;
|
||||
funcg.treeContext.fun = fun;
|
||||
funcg.treeContext.u.fun = fun;
|
||||
|
||||
/*
|
||||
* Farble the body so that it looks like a block statement to js_EmitTree,
|
||||
@ -1025,7 +969,7 @@ BindArg(JSContext *cx, JSAtom *atom, JSTreeContext *tc)
|
||||
* Check for a duplicate parameter name, a "feature" required by ECMA-262.
|
||||
*/
|
||||
JS_ASSERT(tc->flags & TCF_IN_FUNCTION);
|
||||
if (js_LookupLocal(cx, tc->fun, atom, NULL) != JSLOCAL_NONE) {
|
||||
if (js_LookupLocal(cx, tc->u.fun, atom, NULL) != JSLOCAL_NONE) {
|
||||
name = js_AtomToPrintableString(cx, atom);
|
||||
if (!name ||
|
||||
!js_ReportCompileErrorNumber(cx, TS(tc->parseContext), NULL,
|
||||
@ -1036,7 +980,7 @@ BindArg(JSContext *cx, JSAtom *atom, JSTreeContext *tc)
|
||||
}
|
||||
}
|
||||
|
||||
return js_AddLocal(cx, tc->fun, atom, JSLOCAL_ARG);
|
||||
return js_AddLocal(cx, tc->u.fun, atom, JSLOCAL_ARG);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -1081,7 +1025,7 @@ BindDestructuringArg(JSContext *cx, BindData *data, JSAtom *atom,
|
||||
ALE_SET_JSOP(ale, data->op);
|
||||
}
|
||||
|
||||
if (js_LookupLocal(cx, tc->fun, atom, NULL) != JSLOCAL_NONE) {
|
||||
if (js_LookupLocal(cx, tc->u.fun, atom, NULL) != JSLOCAL_NONE) {
|
||||
name = js_AtomToPrintableString(cx, atom);
|
||||
if (!name ||
|
||||
!js_ReportCompileErrorNumber(cx, TS(tc->parseContext), data->pn,
|
||||
@ -1091,7 +1035,7 @@ BindDestructuringArg(JSContext *cx, BindData *data, JSAtom *atom,
|
||||
return JS_FALSE;
|
||||
}
|
||||
} else {
|
||||
if (!BindLocalVariable(cx, tc->fun, atom, JSLOCAL_VAR))
|
||||
if (!BindLocalVariable(cx, tc->u.fun, atom, JSLOCAL_VAR))
|
||||
return JS_FALSE;
|
||||
}
|
||||
return JS_TRUE;
|
||||
@ -1106,7 +1050,9 @@ NewCompilerFunction(JSContext *cx, JSTreeContext *tc, JSAtom *atom,
|
||||
JSFunction *fun;
|
||||
|
||||
JS_ASSERT((lambda & ~JSFUN_LAMBDA) == 0);
|
||||
parent = (tc->flags & TCF_IN_FUNCTION) ? FUN_OBJECT(tc->fun) : cx->fp->varobj;
|
||||
parent = (tc->flags & TCF_IN_FUNCTION)
|
||||
? FUN_OBJECT(tc->u.fun)
|
||||
: tc->u.scopeChain;
|
||||
fun = js_NewFunction(cx, NULL, NULL, 0, JSFUN_INTERPRETED | lambda,
|
||||
parent, atom);
|
||||
if (fun && !(tc->flags & TCF_COMPILE_N_GO)) {
|
||||
@ -1213,9 +1159,9 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
||||
* variable even if the parameter with the given name already
|
||||
* exists.
|
||||
*/
|
||||
localKind = js_LookupLocal(cx, tc->fun, funAtom, NULL);
|
||||
localKind = js_LookupLocal(cx, tc->u.fun, funAtom, NULL);
|
||||
if (localKind == JSLOCAL_NONE || localKind == JSLOCAL_ARG) {
|
||||
if (!js_AddLocal(cx, tc->fun, funAtom, JSLOCAL_VAR))
|
||||
if (!js_AddLocal(cx, tc->u.fun, funAtom, JSLOCAL_VAR))
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -1241,7 +1187,7 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
||||
/* Initialize early for possible flags mutation via DestructuringExpr. */
|
||||
TREE_CONTEXT_INIT(&funtc, tc->parseContext);
|
||||
funtc.flags |= TCF_IN_FUNCTION | (tc->flags & TCF_COMPILE_N_GO);
|
||||
funtc.fun = fun;
|
||||
funtc.u.fun = fun;
|
||||
|
||||
/* Now parse formal argument list and compute fun->nargs. */
|
||||
MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_FORMAL);
|
||||
@ -1680,7 +1626,7 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
localKind = js_LookupLocal(cx, tc->fun, atom, NULL);
|
||||
localKind = js_LookupLocal(cx, tc->u.fun, atom, NULL);
|
||||
if (localKind == JSLOCAL_NONE) {
|
||||
/*
|
||||
* Property not found in current variable scope: we have not seen this
|
||||
@ -1692,7 +1638,7 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
|
||||
*/
|
||||
localKind = (data->op == JSOP_DEFCONST) ? JSLOCAL_CONST : JSLOCAL_VAR;
|
||||
if (!js_InWithStatement(tc) &&
|
||||
!BindLocalVariable(cx, tc->fun, atom, localKind)) {
|
||||
!BindLocalVariable(cx, tc->u.fun, atom, localKind)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
} else if (localKind == JSLOCAL_ARG) {
|
||||
@ -3455,7 +3401,6 @@ Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
||||
JSStmtInfo *scopeStmt;
|
||||
BindData data;
|
||||
JSParseNode *pn, *pn2;
|
||||
JSStackFrame *fp;
|
||||
JSAtom *atom;
|
||||
|
||||
/*
|
||||
@ -3495,7 +3440,6 @@ Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
||||
* this by looking up the variable's id in the current variable object.
|
||||
* Fortunately, we can avoid doing this for let declared variables.
|
||||
*/
|
||||
fp = cx->fp;
|
||||
if (let) {
|
||||
JS_ASSERT(tc->blockChain == scopeStmt->u.blockObj);
|
||||
data.binder = BindLet;
|
||||
@ -5206,7 +5150,6 @@ JS_FRIEND_API(JSParseNode *)
|
||||
js_ParseXMLText(JSContext *cx, JSObject *chain, JSParseContext *pc,
|
||||
JSBool allowList)
|
||||
{
|
||||
JSStackFrame *fp, frame;
|
||||
JSParseNode *pn;
|
||||
JSTreeContext tc;
|
||||
JSTokenType tt;
|
||||
@ -5216,9 +5159,8 @@ js_ParseXMLText(JSContext *cx, JSObject *chain, JSParseContext *pc,
|
||||
* lightweight function activation, or if its scope chain doesn't match
|
||||
* the one passed to us.
|
||||
*/
|
||||
fp = cx->fp;
|
||||
MaybeSetupFrame(cx, chain, fp, &frame);
|
||||
TREE_CONTEXT_INIT(&tc, pc);
|
||||
tc.u.scopeChain = chain;
|
||||
|
||||
/* Set XML-only mode to turn off special treatment of {expr} in XML. */
|
||||
TS(pc)->flags |= TSF_OPERAND | TSF_XMLONLYMODE;
|
||||
@ -5235,7 +5177,6 @@ js_ParseXMLText(JSContext *cx, JSObject *chain, JSParseContext *pc,
|
||||
|
||||
TS(pc)->flags &= ~TSF_XMLONLYMODE;
|
||||
TREE_CONTEXT_FINISH(cx, &tc);
|
||||
cx->fp = fp;
|
||||
return pn;
|
||||
}
|
||||
|
||||
|
@ -432,6 +432,8 @@ struct JSParseContext {
|
||||
JSTokenStream tokenStream;
|
||||
void *tempPoolMark; /* initial JSContext.tempPool mark */
|
||||
JSPrincipals *principals; /* principals associated with source */
|
||||
JSStackFrame *callerFrame; /* scripted caller frame for eval and
|
||||
debug scripts */
|
||||
JSParseNode *nodeList; /* list of recyclable parse-node
|
||||
structs */
|
||||
JSParsedObjectBox *traceListHead; /* list of parsed object for GC
|
||||
@ -451,8 +453,9 @@ extern JSParseNode *
|
||||
js_ParseScript(JSContext *cx, JSObject *chain, JSParseContext *pc);
|
||||
|
||||
extern JSScript *
|
||||
js_CompileScript(JSContext *cx, JSObject *obj, JSPrincipals *principals,
|
||||
uint32 tcflags, const jschar *chars, size_t length,
|
||||
js_CompileScript(JSContext *cx, JSObject *scopeChain, JSStackFrame *callerFrame,
|
||||
JSPrincipals *principals, uint32 tcflags,
|
||||
const jschar *chars, size_t length,
|
||||
FILE *file, const char *filename, uintN lineno);
|
||||
|
||||
extern JSBool
|
||||
@ -479,6 +482,7 @@ js_ParseXMLText(JSContext *cx, JSObject *chain, JSParseContext *pc,
|
||||
*/
|
||||
extern JSBool
|
||||
js_InitParseContext(JSContext *cx, JSParseContext *pc, JSPrincipals *principals,
|
||||
JSStackFrame *callerFrame,
|
||||
const jschar *base, size_t length, FILE *fp,
|
||||
const char *filename, uintN lineno);
|
||||
|
||||
|
@ -58,6 +58,7 @@
|
||||
#include "jsnum.h"
|
||||
#include "jsopcode.h"
|
||||
#include "jsparse.h"
|
||||
#include "jsscope.h"
|
||||
#include "jsscript.h"
|
||||
#if JS_HAS_XDR
|
||||
#include "jsxdrapi.h"
|
||||
@ -200,7 +201,7 @@ script_compile_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
JSObject *scopeobj;
|
||||
jsval v;
|
||||
JSScript *script, *oldscript;
|
||||
JSStackFrame *fp, *caller;
|
||||
JSStackFrame *caller;
|
||||
const char *file;
|
||||
uintN line;
|
||||
JSPrincipals *principals;
|
||||
@ -229,19 +230,17 @@ script_compile_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
}
|
||||
|
||||
/* Compile using the caller's scope chain, which js_Invoke passes to fp. */
|
||||
fp = cx->fp;
|
||||
caller = JS_GetScriptedCaller(cx, fp);
|
||||
JS_ASSERT(!caller || fp->scopeChain == caller->scopeChain);
|
||||
caller = JS_GetScriptedCaller(cx, cx->fp);
|
||||
JS_ASSERT(!caller || cx->fp->scopeChain == caller->scopeChain);
|
||||
|
||||
if (caller) {
|
||||
if (!scopeobj) {
|
||||
scopeobj = js_GetScopeChain(cx, caller);
|
||||
if (!scopeobj)
|
||||
return JS_FALSE;
|
||||
fp->scopeChain = scopeobj; /* for the compiler's benefit */
|
||||
}
|
||||
|
||||
principals = JS_EvalFramePrincipals(cx, fp, caller);
|
||||
principals = JS_EvalFramePrincipals(cx, cx->fp, caller);
|
||||
file = js_ComputeFilename(cx, caller, principals, &line);
|
||||
} else {
|
||||
file = NULL;
|
||||
@ -257,14 +256,13 @@ script_compile_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
/*
|
||||
* Compile the new script using the caller's scope chain, a la eval().
|
||||
* Unlike jsobj.c:obj_eval, however, we do not pass TCF_COMPILE_N_GO in
|
||||
* tcflags, because compilation is here separated from execution, and the
|
||||
* run-time scope chain may not match the compile-time. JSFRAME_EVAL is
|
||||
* tested in jsemit.c and jsscan.c to optimize based on identity of run-
|
||||
* and compile-time scope.
|
||||
* tcflags and use NULL for the callerFrame argument, because compilation
|
||||
* is here separated from execution, and the run-time scope chain may not
|
||||
* match the compile-time. TCF_COMPILE_N_GO is tested in jsemit.c and
|
||||
* jsparse.c to optimize based on identity of run- and compile-time scope.
|
||||
*/
|
||||
fp->flags |= JSFRAME_SCRIPT_OBJECT;
|
||||
tcflags = caller ? TCF_PUT_STATIC_DEPTH(caller->staticDepth + 1) : 0;
|
||||
script = js_CompileScript(cx, scopeobj, principals, tcflags,
|
||||
tcflags = 0;
|
||||
script = js_CompileScript(cx, scopeobj, NULL, principals, tcflags,
|
||||
JSSTRING_CHARS(str), JSSTRING_LENGTH(str),
|
||||
NULL, file, line);
|
||||
if (!script)
|
||||
@ -839,14 +837,14 @@ static const char js_thaw_str[] = "thaw";
|
||||
|
||||
static JSFunctionSpec script_methods[] = {
|
||||
#if JS_HAS_TOSOURCE
|
||||
JS_FN(js_toSource_str, script_toSource, 0,0,0),
|
||||
JS_FN(js_toSource_str, script_toSource, 0,0),
|
||||
#endif
|
||||
JS_FN(js_toString_str, script_toString, 0,0,0),
|
||||
JS_FN("compile", script_compile, 0,2,0),
|
||||
JS_FN("exec", script_exec, 0,1,0),
|
||||
JS_FN(js_toString_str, script_toString, 0,0),
|
||||
JS_FN("compile", script_compile, 2,0),
|
||||
JS_FN("exec", script_exec, 1,0),
|
||||
#if JS_HAS_XDR_FREEZE_THAW
|
||||
JS_FN("freeze", script_freeze, 0,0,0),
|
||||
JS_FN(js_thaw_str, script_thaw, 0,1,0),
|
||||
JS_FN("freeze", script_freeze, 0,0),
|
||||
JS_FN(js_thaw_str, script_thaw, 1,0),
|
||||
#endif /* JS_HAS_XDR_FREEZE_THAW */
|
||||
JS_FS_END
|
||||
};
|
||||
@ -932,14 +930,14 @@ script_static_thaw(JSContext *cx, uintN argc, jsval *vp)
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
vp[1] = OBJECT_TO_JSVAL(obj);
|
||||
if (!script_thaw(cx, vp))
|
||||
if (!script_thaw(cx, argc, vp))
|
||||
return JS_FALSE;
|
||||
*vp = OBJECT_TO_JSVAL(obj);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSFunctionSpec script_static_methods[] = {
|
||||
JS_FN(js_thaw_str, script_static_thaw, 1,1,0),
|
||||
JS_FN(js_thaw_str, script_static_thaw, 1,0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
@ -1473,7 +1471,7 @@ js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg)
|
||||
memcpy(script->code, CG_PROLOG_BASE(cg), prologLength * sizeof(jsbytecode));
|
||||
memcpy(script->main, CG_BASE(cg), mainLength * sizeof(jsbytecode));
|
||||
nfixed = (cg->treeContext.flags & TCF_IN_FUNCTION)
|
||||
? cg->treeContext.fun->u.i.nvars
|
||||
? cg->treeContext.u.fun->u.i.nvars
|
||||
: cg->treeContext.ngvars + cg->regexpList.length;
|
||||
JS_ASSERT(nfixed < SLOTNO_LIMIT);
|
||||
script->nfixed = (uint16) nfixed;
|
||||
@ -1523,7 +1521,7 @@ js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg)
|
||||
*/
|
||||
fun = NULL;
|
||||
if (cg->treeContext.flags & TCF_IN_FUNCTION) {
|
||||
fun = cg->treeContext.fun;
|
||||
fun = cg->treeContext.u.fun;
|
||||
JS_ASSERT(FUN_INTERPRETED(fun) && !FUN_SCRIPT(fun));
|
||||
JS_ASSERT_IF(script->upvarsOffset != 0,
|
||||
JS_SCRIPT_UPVARS(script)->length == fun->u.i.nupvars);
|
||||
|
@ -1887,7 +1887,7 @@ ParseXMLSource(JSContext *cx, JSString *src)
|
||||
}
|
||||
}
|
||||
|
||||
if (!js_InitParseContext(cx, &pc, NULL, chars, length, NULL,
|
||||
if (!js_InitParseContext(cx, &pc, NULL, NULL, chars, length, NULL,
|
||||
filename, lineno))
|
||||
goto out;
|
||||
pn = js_ParseXMLText(cx, cx->fp->scopeChain, &pc, JS_FALSE);
|
||||
|
Loading…
Reference in New Issue
Block a user