зеркало из https://github.com/mozilla/pjs.git
Backed out changeset 1406935fced4. Brian Hackett – Put JSStackFrame.scopeChain/blockChain behind an interface, bug 586533. r=lw.
This commit is contained in:
Родитель
2a6f0439d6
Коммит
ea02e5caf2
|
@ -1823,7 +1823,7 @@ JS_GetGlobalForScopeChain(JSContext *cx)
|
|||
VOUCH_DOES_NOT_REQUIRE_STACK();
|
||||
|
||||
if (cx->fp)
|
||||
return cx->fp->getScopeChain()->getGlobal();
|
||||
return cx->fp->scopeChain->getGlobal();
|
||||
|
||||
JSObject *scope = cx->globalObject;
|
||||
if (!scope) {
|
||||
|
|
|
@ -351,7 +351,7 @@ js_PopInterpFrame(JSContext* cx, TracerState* state)
|
|||
return JS_FALSE;
|
||||
if (fp->imacpc)
|
||||
return JS_FALSE;
|
||||
if (fp->hasBlockChain())
|
||||
if (fp->blockChain)
|
||||
return JS_FALSE;
|
||||
|
||||
fp->putActivationObjects(cx);
|
||||
|
|
|
@ -685,7 +685,7 @@ js_watch_set(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
|||
fp->script = script;
|
||||
fp->fun = fun;
|
||||
fp->argv = vp + 2;
|
||||
fp->setScopeChain(closure->getParent());
|
||||
fp->scopeChain = closure->getParent();
|
||||
fp->setArgsObj(NULL);
|
||||
|
||||
/* Initialize regs. */
|
||||
|
@ -1204,7 +1204,7 @@ JS_IsNativeFrame(JSContext *cx, JSStackFrame *fp)
|
|||
JS_PUBLIC_API(JSObject *)
|
||||
JS_GetFrameObject(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
return fp->maybeScopeChain();
|
||||
return fp->scopeChain;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
|
@ -1564,7 +1564,7 @@ SetupFakeFrame(JSContext *cx, ExecuteFrameGuard &frame, JSFrameRegs ®s, JSObj
|
|||
PodZero(fp);
|
||||
fp->fun = fun;
|
||||
fp->argv = vp + 2;
|
||||
fp->setScopeChain(scopeobj->getGlobal());
|
||||
fp->scopeChain = scopeobj->getGlobal();
|
||||
|
||||
regs.pc = NULL;
|
||||
regs.sp = fp->slots();
|
||||
|
|
|
@ -215,7 +215,7 @@ js_GetArgsObject(JSContext *cx, JSStackFrame *fp)
|
|||
return fp->getArgsObj();
|
||||
|
||||
/* Compute the arguments object's parent slot from fp's scope chain. */
|
||||
JSObject *global = fp->getScopeChain()->getGlobal();
|
||||
JSObject *global = fp->scopeChain->getGlobal();
|
||||
JSObject *argsobj = NewArguments(cx, global, fp->argc, &fp->argv[-2].toObject());
|
||||
if (!argsobj)
|
||||
return argsobj;
|
||||
|
@ -763,7 +763,7 @@ NewDeclEnvObject(JSContext *cx, JSStackFrame *fp)
|
|||
return NULL;
|
||||
|
||||
/* Init immediately to avoid GC seeing a half-init'ed object. */
|
||||
envobj->init(&js_DeclEnvClass, NULL, fp->maybeScopeChain(), PrivateValue(fp));
|
||||
envobj->init(&js_DeclEnvClass, NULL, fp->scopeChain, PrivateValue(fp));
|
||||
envobj->map = cx->runtime->emptyDeclEnvScope->hold();
|
||||
return envobj;
|
||||
}
|
||||
|
@ -778,11 +778,11 @@ js_GetCallObject(JSContext *cx, JSStackFrame *fp)
|
|||
|
||||
#ifdef DEBUG
|
||||
/* A call object should be a frame's outermost scope chain element. */
|
||||
Class *classp = fp->getScopeChain()->getClass();
|
||||
Class *classp = fp->scopeChain->getClass();
|
||||
if (classp == &js_WithClass || classp == &js_BlockClass)
|
||||
JS_ASSERT(fp->getScopeChain()->getPrivate() != js_FloatingFrameIfGenerator(cx, fp));
|
||||
JS_ASSERT(fp->scopeChain->getPrivate() != js_FloatingFrameIfGenerator(cx, fp));
|
||||
else if (classp == &js_CallClass)
|
||||
JS_ASSERT(fp->getScopeChain()->getPrivate() != fp);
|
||||
JS_ASSERT(fp->scopeChain->getPrivate() != fp);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -798,9 +798,9 @@ js_GetCallObject(JSContext *cx, JSStackFrame *fp)
|
|||
return NULL;
|
||||
|
||||
/* Root envobj before js_DefineNativeProperty (-> JSClass.addProperty). */
|
||||
fp->setScopeChain(envobj);
|
||||
fp->scopeChain = envobj;
|
||||
JS_ASSERT(fp->argv);
|
||||
if (!js_DefineNativeProperty(cx, fp->getScopeChain(), ATOM_TO_JSID(lambdaName),
|
||||
if (!js_DefineNativeProperty(cx, fp->scopeChain, ATOM_TO_JSID(lambdaName),
|
||||
fp->calleeValue(),
|
||||
CalleeGetter, NULL,
|
||||
JSPROP_PERMANENT | JSPROP_READONLY,
|
||||
|
@ -809,7 +809,7 @@ js_GetCallObject(JSContext *cx, JSStackFrame *fp)
|
|||
}
|
||||
}
|
||||
|
||||
JSObject *callobj = NewCallObject(cx, fp->fun, fp->getScopeChain());
|
||||
JSObject *callobj = NewCallObject(cx, fp->fun, fp->scopeChain);
|
||||
if (!callobj)
|
||||
return NULL;
|
||||
|
||||
|
@ -823,7 +823,7 @@ js_GetCallObject(JSContext *cx, JSStackFrame *fp)
|
|||
* Push callobj on the top of the scope chain, and make it the
|
||||
* variables object.
|
||||
*/
|
||||
fp->setScopeChain(callobj);
|
||||
fp->scopeChain = callobj;
|
||||
return callobj;
|
||||
}
|
||||
|
||||
|
|
|
@ -2260,8 +2260,8 @@ js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp)
|
|||
/* Allow for primitive this parameter due to JSFUN_THISP_* flags. */
|
||||
MarkValue(trc, fp->thisv, "this");
|
||||
MarkValue(trc, fp->rval, "rval");
|
||||
if (fp->hasScopeChain())
|
||||
JS_CALL_OBJECT_TRACER(trc, fp->getScopeChain(), "scope chain");
|
||||
if (fp->scopeChain)
|
||||
JS_CALL_OBJECT_TRACER(trc, fp->scopeChain, "scope chain");
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -103,7 +103,7 @@ jsbytecode *const JSStackFrame::sInvalidPC = (jsbytecode *)0xbeef;
|
|||
JSObject *
|
||||
js_GetScopeChain(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
JSObject *sharedBlock = fp->maybeBlockChain();
|
||||
JSObject *sharedBlock = fp->blockChain;
|
||||
|
||||
if (!sharedBlock) {
|
||||
/*
|
||||
|
@ -113,8 +113,8 @@ js_GetScopeChain(JSContext *cx, JSStackFrame *fp)
|
|||
JS_ASSERT(!fp->fun ||
|
||||
!(fp->fun->flags & JSFUN_HEAVYWEIGHT) ||
|
||||
fp->hasCallObj());
|
||||
JS_ASSERT(fp->hasScopeChain());
|
||||
return fp->getScopeChain();
|
||||
JS_ASSERT(fp->scopeChain);
|
||||
return fp->scopeChain;
|
||||
}
|
||||
|
||||
/* We don't handle cloning blocks on trace. */
|
||||
|
@ -129,8 +129,8 @@ js_GetScopeChain(JSContext *cx, JSStackFrame *fp)
|
|||
*/
|
||||
JSObject *limitBlock, *limitClone;
|
||||
if (fp->fun && !fp->hasCallObj()) {
|
||||
JS_ASSERT_IF(fp->getScopeChain()->getClass() == &js_BlockClass,
|
||||
fp->getScopeChain()->getPrivate() != js_FloatingFrameIfGenerator(cx, fp));
|
||||
JS_ASSERT_IF(fp->scopeChain->getClass() == &js_BlockClass,
|
||||
fp->scopeChain->getPrivate() != js_FloatingFrameIfGenerator(cx, fp));
|
||||
if (!js_GetCallObject(cx, fp))
|
||||
return NULL;
|
||||
|
||||
|
@ -143,7 +143,7 @@ js_GetScopeChain(JSContext *cx, JSStackFrame *fp)
|
|||
* prototype should appear on blockChain; we'll clone blockChain up
|
||||
* to, but not including, that prototype.
|
||||
*/
|
||||
limitClone = fp->getScopeChain();
|
||||
limitClone = fp->scopeChain;
|
||||
while (limitClone->getClass() == &js_WithClass)
|
||||
limitClone = limitClone->getParent();
|
||||
JS_ASSERT(limitClone);
|
||||
|
@ -170,7 +170,7 @@ js_GetScopeChain(JSContext *cx, JSStackFrame *fp)
|
|||
|
||||
/* If the innermost block has already been cloned, we are done. */
|
||||
if (limitBlock == sharedBlock)
|
||||
return fp->getScopeChain();
|
||||
return fp->scopeChain;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -206,7 +206,7 @@ js_GetScopeChain(JSContext *cx, JSStackFrame *fp)
|
|||
newChild->setParent(clone);
|
||||
newChild = clone;
|
||||
}
|
||||
newChild->setParent(fp->getScopeChain());
|
||||
newChild->setParent(fp->scopeChain);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -219,7 +219,7 @@ js_GetScopeChain(JSContext *cx, JSStackFrame *fp)
|
|||
sharedBlock);
|
||||
|
||||
/* Place our newly cloned blocks at the head of the scope chain. */
|
||||
fp->setScopeChain(innermostNewChild);
|
||||
fp->scopeChain = innermostNewChild;
|
||||
return innermostNewChild;
|
||||
}
|
||||
|
||||
|
@ -507,8 +507,8 @@ InvokeCommon(JSContext *cx, JSFunction *fun, JSScript *script, T native,
|
|||
fp->argv = args.argv();
|
||||
fp->rval = (flags & JSINVOKE_CONSTRUCT) ? fp->thisv : UndefinedValue();
|
||||
fp->annotation = NULL;
|
||||
fp->setScopeChain(NULL);
|
||||
fp->setBlockChain(NULL);
|
||||
fp->scopeChain = NULL;
|
||||
fp->blockChain = NULL;
|
||||
fp->imacpc = NULL;
|
||||
fp->flags = flags;
|
||||
|
||||
|
@ -530,14 +530,14 @@ InvokeCommon(JSContext *cx, JSFunction *fun, JSScript *script, T native,
|
|||
if (native) {
|
||||
/* Slow natives and call ops expect the caller's scopeChain as their scopeChain. */
|
||||
if (JSStackFrame *down = fp->down)
|
||||
fp->setScopeChain(down->maybeScopeChain());
|
||||
fp->scopeChain = down->scopeChain;
|
||||
|
||||
/* Ensure that we have a scope chain. */
|
||||
if (!fp->hasScopeChain())
|
||||
fp->setScopeChain(parent);
|
||||
if (!fp->scopeChain)
|
||||
fp->scopeChain = parent;
|
||||
} else {
|
||||
/* Use parent scope so js_GetCallObject can find the right "Call". */
|
||||
fp->setScopeChain(parent);
|
||||
fp->scopeChain = parent;
|
||||
if (fun->isHeavyweight() && !js_GetCallObject(cx, fp))
|
||||
return false;
|
||||
}
|
||||
|
@ -824,7 +824,7 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
|||
fp->argc = down->argc;
|
||||
fp->argv = down->argv;
|
||||
fp->annotation = down->annotation;
|
||||
fp->setScopeChain(chain);
|
||||
fp->scopeChain = chain;
|
||||
|
||||
/*
|
||||
* We want to call |down->varobj()|, but this requires knowing the
|
||||
|
@ -850,7 +850,7 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
|||
OBJ_TO_INNER_OBJECT(cx, innerizedChain);
|
||||
if (!innerizedChain)
|
||||
return false;
|
||||
fp->setScopeChain(innerizedChain);
|
||||
fp->scopeChain = innerizedChain;
|
||||
|
||||
initialVarObj = (cx->options & JSOPTION_VAROBJFIX)
|
||||
? chain->getGlobal()
|
||||
|
@ -861,7 +861,7 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
|||
fp->script = script;
|
||||
fp->imacpc = NULL;
|
||||
fp->rval.setUndefined();
|
||||
fp->setBlockChain(NULL);
|
||||
fp->blockChain = NULL;
|
||||
|
||||
/* Initialize regs. */
|
||||
regs.pc = script->code;
|
||||
|
@ -1245,7 +1245,7 @@ js_EnterWith(JSContext *cx, jsint stackIndex)
|
|||
if (!withobj)
|
||||
return JS_FALSE;
|
||||
|
||||
fp->setScopeChain(withobj);
|
||||
fp->scopeChain = withobj;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -1254,11 +1254,11 @@ js_LeaveWith(JSContext *cx)
|
|||
{
|
||||
JSObject *withobj;
|
||||
|
||||
withobj = cx->fp->getScopeChain();
|
||||
withobj = cx->fp->scopeChain;
|
||||
JS_ASSERT(withobj->getClass() == &js_WithClass);
|
||||
JS_ASSERT(withobj->getPrivate() == js_FloatingFrameIfGenerator(cx, cx->fp));
|
||||
JS_ASSERT(OBJ_BLOCK_DEPTH(cx, withobj) >= 0);
|
||||
cx->fp->setScopeChain(withobj->getParent());
|
||||
cx->fp->scopeChain = withobj->getParent();
|
||||
withobj->setPrivate(NULL);
|
||||
}
|
||||
|
||||
|
@ -1290,15 +1290,15 @@ js_UnwindScope(JSContext *cx, jsint stackDepth, JSBool normalUnwind)
|
|||
JS_ASSERT(cx->fp->base() + stackDepth <= cx->regs->sp);
|
||||
|
||||
JSStackFrame *fp = cx->fp;
|
||||
for (obj = fp->maybeBlockChain(); obj; obj = obj->getParent()) {
|
||||
for (obj = fp->blockChain; obj; obj = obj->getParent()) {
|
||||
JS_ASSERT(obj->getClass() == &js_BlockClass);
|
||||
if (OBJ_BLOCK_DEPTH(cx, obj) < stackDepth)
|
||||
break;
|
||||
}
|
||||
fp->setBlockChain(obj);
|
||||
fp->blockChain = obj;
|
||||
|
||||
for (;;) {
|
||||
obj = fp->getScopeChain();
|
||||
obj = fp->scopeChain;
|
||||
clasp = js_IsActiveWithOrBlock(cx, obj, stackDepth);
|
||||
if (!clasp)
|
||||
break;
|
||||
|
@ -2525,11 +2525,11 @@ BEGIN_CASE(JSOP_POPN)
|
|||
regs.sp -= GET_UINT16(regs.pc);
|
||||
#ifdef DEBUG
|
||||
JS_ASSERT(fp->base() <= regs.sp);
|
||||
JSObject *obj = fp->maybeBlockChain();
|
||||
JSObject *obj = fp->blockChain;
|
||||
JS_ASSERT_IF(obj,
|
||||
OBJ_BLOCK_DEPTH(cx, obj) + OBJ_BLOCK_COUNT(cx, obj)
|
||||
<= (size_t) (regs.sp - fp->base()));
|
||||
for (obj = fp->maybeScopeChain(); obj; obj = obj->getParent()) {
|
||||
for (obj = fp->scopeChain; obj; obj = obj->getParent()) {
|
||||
Class *clasp = obj->getClass();
|
||||
if (clasp != &js_BlockClass && clasp != &js_WithClass)
|
||||
continue;
|
||||
|
@ -2564,11 +2564,11 @@ BEGIN_CASE(JSOP_ENTERWITH)
|
|||
* We set sp[-1] to the current "with" object to help asserting the
|
||||
* enter/leave balance in [leavewith].
|
||||
*/
|
||||
regs.sp[-1].setObject(*fp->getScopeChain());
|
||||
regs.sp[-1].setObject(*fp->scopeChain);
|
||||
END_CASE(JSOP_ENTERWITH)
|
||||
|
||||
BEGIN_CASE(JSOP_LEAVEWITH)
|
||||
JS_ASSERT(®s.sp[-1].toObject() == fp->getScopeChain());
|
||||
JS_ASSERT(®s.sp[-1].toObject() == fp->scopeChain);
|
||||
regs.sp--;
|
||||
js_LeaveWith(cx);
|
||||
END_CASE(JSOP_LEAVEWITH)
|
||||
|
@ -2609,8 +2609,8 @@ BEGIN_CASE(JSOP_STOP)
|
|||
if (inlineCallCount)
|
||||
inline_return:
|
||||
{
|
||||
JS_ASSERT(!fp->hasBlockChain());
|
||||
JS_ASSERT(!js_IsActiveWithOrBlock(cx, fp->getScopeChain(), 0));
|
||||
JS_ASSERT(!fp->blockChain);
|
||||
JS_ASSERT(!js_IsActiveWithOrBlock(cx, fp->scopeChain, 0));
|
||||
|
||||
void *hookData = fp->hookData;
|
||||
if (JS_UNLIKELY(hookData != NULL)) {
|
||||
|
@ -3136,7 +3136,7 @@ BEGIN_CASE(JSOP_BINDNAME)
|
|||
* the rhs. We desire such resolve hook equivalence between the two
|
||||
* forms.
|
||||
*/
|
||||
obj = fp->getScopeChain();
|
||||
obj = fp->scopeChain;
|
||||
if (!obj->getParent())
|
||||
break;
|
||||
|
||||
|
@ -3150,7 +3150,7 @@ BEGIN_CASE(JSOP_BINDNAME)
|
|||
}
|
||||
|
||||
jsid id = ATOM_TO_JSID(atom);
|
||||
obj = js_FindIdentifierBase(cx, fp->getScopeChain(), id);
|
||||
obj = js_FindIdentifierBase(cx, fp->scopeChain, id);
|
||||
if (!obj)
|
||||
goto error;
|
||||
} while (0);
|
||||
|
@ -3705,7 +3705,7 @@ BEGIN_CASE(JSOP_DECNAME)
|
|||
BEGIN_CASE(JSOP_NAMEINC)
|
||||
BEGIN_CASE(JSOP_NAMEDEC)
|
||||
{
|
||||
obj = fp->getScopeChain();
|
||||
obj = fp->scopeChain;
|
||||
|
||||
JSObject *obj2;
|
||||
PropertyCacheEntry *entry;
|
||||
|
@ -4617,9 +4617,9 @@ BEGIN_CASE(JSOP_APPLY)
|
|||
newfp->argv = vp + 2;
|
||||
newfp->rval.setUndefined();
|
||||
newfp->annotation = NULL;
|
||||
newfp->setScopeChain(obj->getParent());
|
||||
newfp->scopeChain = obj->getParent();
|
||||
newfp->flags = flags;
|
||||
newfp->setBlockChain(NULL);
|
||||
newfp->blockChain = NULL;
|
||||
JS_ASSERT(!JSFUN_BOUND_METHOD_TEST(fun->flags));
|
||||
newfp->thisv = vp[1];
|
||||
newfp->imacpc = NULL;
|
||||
|
@ -4734,7 +4734,7 @@ END_CASE(JSOP_SETCALL)
|
|||
BEGIN_CASE(JSOP_NAME)
|
||||
BEGIN_CASE(JSOP_CALLNAME)
|
||||
{
|
||||
JSObject *obj = fp->getScopeChain();
|
||||
JSObject *obj = fp->scopeChain;
|
||||
|
||||
JSScopeProperty *sprop;
|
||||
Value rval;
|
||||
|
@ -4874,7 +4874,7 @@ BEGIN_CASE(JSOP_REGEXP)
|
|||
*/
|
||||
jsatomid index = GET_FULL_INDEX(0);
|
||||
JSObject *proto;
|
||||
if (!js_GetClassPrototype(cx, fp->getScopeChain(), JSProto_RegExp, &proto))
|
||||
if (!js_GetClassPrototype(cx, fp->scopeChain, JSProto_RegExp, &proto))
|
||||
goto error;
|
||||
JS_ASSERT(proto);
|
||||
JSObject *obj = js_CloneRegExpObject(cx, script->getRegExp(index), proto);
|
||||
|
@ -5393,7 +5393,7 @@ BEGIN_CASE(JSOP_DEFFUN)
|
|||
* FIXME: bug 476950, although debugger users may also demand some kind
|
||||
* of scope link for debugger-assisted eval-in-frame.
|
||||
*/
|
||||
obj2 = fp->getScopeChain();
|
||||
obj2 = fp->scopeChain;
|
||||
} else {
|
||||
JS_ASSERT(!FUN_FLAT_CLOSURE(fun));
|
||||
|
||||
|
@ -5401,8 +5401,8 @@ BEGIN_CASE(JSOP_DEFFUN)
|
|||
* Inline js_GetScopeChain a bit to optimize for the case of a
|
||||
* top-level function.
|
||||
*/
|
||||
if (!fp->hasBlockChain()) {
|
||||
obj2 = fp->getScopeChain();
|
||||
if (!fp->blockChain) {
|
||||
obj2 = fp->scopeChain;
|
||||
} else {
|
||||
obj2 = js_GetScopeChain(cx, fp);
|
||||
if (!obj2)
|
||||
|
@ -5431,7 +5431,7 @@ BEGIN_CASE(JSOP_DEFFUN)
|
|||
* fp->scopeChain code below the parent->defineProperty call.
|
||||
*/
|
||||
MUST_FLOW_THROUGH("restore_scope");
|
||||
fp->setScopeChain(obj);
|
||||
fp->scopeChain = obj;
|
||||
|
||||
Value rval = ObjectValue(*obj);
|
||||
|
||||
|
@ -5501,7 +5501,7 @@ BEGIN_CASE(JSOP_DEFFUN)
|
|||
|
||||
restore_scope:
|
||||
/* Restore fp->scopeChain now that obj is defined in fp->callobj. */
|
||||
fp->setScopeChain(obj2);
|
||||
fp->scopeChain = obj2;
|
||||
if (!ok)
|
||||
goto error;
|
||||
}
|
||||
|
@ -5556,7 +5556,7 @@ BEGIN_CASE(JSOP_DEFLOCALFUN)
|
|||
JSObject *obj = FUN_OBJECT(fun);
|
||||
|
||||
if (FUN_NULL_CLOSURE(fun)) {
|
||||
obj = CloneFunctionObject(cx, fun, fp->getScopeChain());
|
||||
obj = CloneFunctionObject(cx, fun, fp->scopeChain);
|
||||
if (!obj)
|
||||
goto error;
|
||||
} else {
|
||||
|
@ -5623,7 +5623,7 @@ BEGIN_CASE(JSOP_LAMBDA)
|
|||
do {
|
||||
JSObject *parent;
|
||||
if (FUN_NULL_CLOSURE(fun)) {
|
||||
parent = fp->getScopeChain();
|
||||
parent = fp->scopeChain;
|
||||
|
||||
if (obj->getParent() == parent) {
|
||||
jsbytecode *pc2 = regs.pc + JSOP_LAMBDA_LENGTH;
|
||||
|
@ -6624,7 +6624,7 @@ BEGIN_CASE(JSOP_ENTERBLOCK)
|
|||
regs.sp = vp;
|
||||
|
||||
#ifdef DEBUG
|
||||
JS_ASSERT(fp->maybeBlockChain() == obj->getParent());
|
||||
JS_ASSERT(fp->blockChain == obj->getParent());
|
||||
|
||||
/*
|
||||
* The young end of fp->scopeChain may omit blocks if we haven't closed
|
||||
|
@ -6633,7 +6633,7 @@ BEGIN_CASE(JSOP_ENTERBLOCK)
|
|||
* anything else we should have popped off fp->scopeChain when we left its
|
||||
* static scope.
|
||||
*/
|
||||
JSObject *obj2 = fp->getScopeChain();
|
||||
JSObject *obj2 = fp->scopeChain;
|
||||
Class *clasp;
|
||||
while ((clasp = obj2->getClass()) == &js_WithClass)
|
||||
obj2 = obj2->getParent();
|
||||
|
@ -6647,7 +6647,7 @@ BEGIN_CASE(JSOP_ENTERBLOCK)
|
|||
}
|
||||
#endif
|
||||
|
||||
fp->setBlockChain(obj);
|
||||
fp->blockChain = obj;
|
||||
}
|
||||
END_CASE(JSOP_ENTERBLOCK)
|
||||
|
||||
|
@ -6655,8 +6655,8 @@ BEGIN_CASE(JSOP_LEAVEBLOCKEXPR)
|
|||
BEGIN_CASE(JSOP_LEAVEBLOCK)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
JS_ASSERT(fp->getBlockChain()->getClass() == &js_BlockClass);
|
||||
uintN blockDepth = OBJ_BLOCK_DEPTH(cx, fp->getBlockChain());
|
||||
JS_ASSERT(fp->blockChain->getClass() == &js_BlockClass);
|
||||
uintN blockDepth = OBJ_BLOCK_DEPTH(cx, fp->blockChain);
|
||||
|
||||
JS_ASSERT(blockDepth <= StackDepth(script));
|
||||
#endif
|
||||
|
@ -6665,15 +6665,15 @@ BEGIN_CASE(JSOP_LEAVEBLOCK)
|
|||
* cloned onto fp->scopeChain, clear its private data, move its locals from
|
||||
* the stack into the clone, and pop it off the chain.
|
||||
*/
|
||||
JSObject *obj = fp->getScopeChain();
|
||||
if (obj->getProto() == fp->getBlockChain()) {
|
||||
JSObject *obj = fp->scopeChain;
|
||||
if (obj->getProto() == fp->blockChain) {
|
||||
JS_ASSERT(obj->getClass() == &js_BlockClass);
|
||||
if (!js_PutBlockObject(cx, JS_TRUE))
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Pop the block chain, too. */
|
||||
fp->setBlockChain(fp->getBlockChain()->getParent());
|
||||
fp->blockChain = fp->blockChain->getParent();
|
||||
|
||||
/* Move the result of the expression to the new topmost stack slot. */
|
||||
Value *vp = NULL; /* silence GCC warnings */
|
||||
|
@ -7006,8 +7006,8 @@ END_CASE(JSOP_ARRAYPUSH)
|
|||
AbortRecording(cx, "recording out of Interpret");
|
||||
#endif
|
||||
|
||||
JS_ASSERT_IF(!fp->isGenerator(), !fp->hasBlockChain());
|
||||
JS_ASSERT_IF(!fp->isGenerator(), !js_IsActiveWithOrBlock(cx, fp->getScopeChain(), 0));
|
||||
JS_ASSERT_IF(!fp->isGenerator(), !fp->blockChain);
|
||||
JS_ASSERT_IF(!fp->isGenerator(), !js_IsActiveWithOrBlock(cx, fp->scopeChain, 0));
|
||||
|
||||
/* Undo the remaining effects committed on entry to Interpret. */
|
||||
if (cx->version == currentVersion && currentVersion != originalVersion)
|
||||
|
|
|
@ -86,8 +86,6 @@ struct JSStackFrame
|
|||
private:
|
||||
JSObject *callobj; /* lazily created Call object */
|
||||
JSObject *argsobj; /* lazily created arguments object */
|
||||
JSObject *scopeChain; /* current scope chain */
|
||||
JSObject *blockChain; /* current static block */
|
||||
|
||||
public:
|
||||
jsbytecode *imacpc; /* null or interpreter macro call pc */
|
||||
|
@ -107,6 +105,45 @@ struct JSStackFrame
|
|||
static jsbytecode *const sInvalidPC;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We can't determine in advance which local variables can live on
|
||||
* the stack and be freed when their dynamic scope ends, and which
|
||||
* will be closed over and need to live in the heap. So we place
|
||||
* variables on the stack initially, note when they are closed
|
||||
* over, and copy those that are out to the heap when we leave
|
||||
* their dynamic scope.
|
||||
*
|
||||
* The bytecode compiler produces a tree of block objects
|
||||
* accompanying each JSScript representing those lexical blocks in
|
||||
* the script that have let-bound variables associated with them.
|
||||
* These block objects are never modified, and never become part
|
||||
* of any function's scope chain. Their parent slots point to the
|
||||
* innermost block that encloses them, or are NULL in the
|
||||
* outermost blocks within a function or in eval or global code.
|
||||
*
|
||||
* When we are in the static scope of such a block, blockChain
|
||||
* points to its compiler-allocated block object; otherwise, it is
|
||||
* NULL.
|
||||
*
|
||||
* scopeChain is the current scope chain, including 'call' and
|
||||
* 'block' objects for those function calls and lexical blocks
|
||||
* whose static scope we are currently executing in, and 'with'
|
||||
* objects for with statements; the chain is typically terminated
|
||||
* by a global object. However, as an optimization, the young end
|
||||
* of the chain omits block objects we have not yet cloned. To
|
||||
* create a closure, we clone the missing blocks from blockChain
|
||||
* (which is always current), place them at the head of
|
||||
* scopeChain, and use that for the closure's scope chain. If we
|
||||
* never close over a lexical block, we never place a mutable
|
||||
* clone of it on scopeChain.
|
||||
*
|
||||
* This lazy cloning is implemented in js_GetScopeChain, which is
|
||||
* also used in some other cases --- entering 'with' blocks, for
|
||||
* example.
|
||||
*/
|
||||
JSObject *scopeChain;
|
||||
JSObject *blockChain;
|
||||
|
||||
uint32 flags; /* frame flags -- see below */
|
||||
|
||||
/* Members only needed for inline calls. */
|
||||
|
@ -180,89 +217,6 @@ struct JSStackFrame
|
|||
return offsetof(JSStackFrame, argsobj);
|
||||
}
|
||||
|
||||
/*
|
||||
* We can't determine in advance which local variables can live on
|
||||
* the stack and be freed when their dynamic scope ends, and which
|
||||
* will be closed over and need to live in the heap. So we place
|
||||
* variables on the stack initially, note when they are closed
|
||||
* over, and copy those that are out to the heap when we leave
|
||||
* their dynamic scope.
|
||||
*
|
||||
* The bytecode compiler produces a tree of block objects
|
||||
* accompanying each JSScript representing those lexical blocks in
|
||||
* the script that have let-bound variables associated with them.
|
||||
* These block objects are never modified, and never become part
|
||||
* of any function's scope chain. Their parent slots point to the
|
||||
* innermost block that encloses them, or are NULL in the
|
||||
* outermost blocks within a function or in eval or global code.
|
||||
*
|
||||
* When we are in the static scope of such a block, blockChain
|
||||
* points to its compiler-allocated block object; otherwise, it is
|
||||
* NULL.
|
||||
*
|
||||
* scopeChain is the current scope chain, including 'call' and
|
||||
* 'block' objects for those function calls and lexical blocks
|
||||
* whose static scope we are currently executing in, and 'with'
|
||||
* objects for with statements; the chain is typically terminated
|
||||
* by a global object. However, as an optimization, the young end
|
||||
* of the chain omits block objects we have not yet cloned. To
|
||||
* create a closure, we clone the missing blocks from blockChain
|
||||
* (which is always current), place them at the head of
|
||||
* scopeChain, and use that for the closure's scope chain. If we
|
||||
* never close over a lexical block, we never place a mutable
|
||||
* clone of it on scopeChain.
|
||||
*
|
||||
* This lazy cloning is implemented in js_GetScopeChain, which is
|
||||
* also used in some other cases --- entering 'with' blocks, for
|
||||
* example.
|
||||
*/
|
||||
|
||||
/* Scope chain accessors */
|
||||
|
||||
bool hasScopeChain() const {
|
||||
return scopeChain != NULL;
|
||||
}
|
||||
|
||||
JSObject* getScopeChain() const {
|
||||
JS_ASSERT(hasScopeChain());
|
||||
return scopeChain;
|
||||
}
|
||||
|
||||
JSObject* maybeScopeChain() const {
|
||||
return scopeChain;
|
||||
}
|
||||
|
||||
void setScopeChain(JSObject *obj) {
|
||||
scopeChain = obj;
|
||||
}
|
||||
|
||||
JSObject** addressScopeChain() {
|
||||
return &scopeChain;
|
||||
}
|
||||
|
||||
static size_t offsetScopeChain() {
|
||||
return offsetof(JSStackFrame, scopeChain);
|
||||
}
|
||||
|
||||
/* Block chain accessors */
|
||||
|
||||
bool hasBlockChain() const {
|
||||
return blockChain != NULL;
|
||||
}
|
||||
|
||||
JSObject* getBlockChain() const {
|
||||
JS_ASSERT(hasBlockChain());
|
||||
return blockChain;
|
||||
}
|
||||
|
||||
JSObject* maybeBlockChain() const {
|
||||
return blockChain;
|
||||
}
|
||||
|
||||
void setBlockChain(JSObject *obj) {
|
||||
blockChain = obj;
|
||||
}
|
||||
|
||||
/* Other accessors */
|
||||
|
||||
void putActivationObjects(JSContext *cx) {
|
||||
|
|
|
@ -1144,9 +1144,9 @@ js_NewGenerator(JSContext *cx)
|
|||
newfp->argv = vp + 2;
|
||||
newfp->rval = fp->rval;
|
||||
newfp->annotation = NULL;
|
||||
newfp->setScopeChain(fp->maybeScopeChain());
|
||||
JS_ASSERT(!fp->hasBlockChain());
|
||||
newfp->setBlockChain(NULL);
|
||||
newfp->scopeChain = fp->scopeChain;
|
||||
JS_ASSERT(!fp->blockChain);
|
||||
newfp->blockChain = NULL;
|
||||
newfp->flags = fp->flags | JSFRAME_GENERATOR | JSFRAME_FLOATING_GENERATOR;
|
||||
|
||||
/* Copy in arguments and slots. */
|
||||
|
|
|
@ -2967,7 +2967,7 @@ js_PutBlockObject(JSContext *cx, JSBool normalUnwind)
|
|||
JS_STATIC_ASSERT(JS_INITIAL_NSLOTS == JSSLOT_BLOCK_DEPTH + 2);
|
||||
|
||||
JSStackFrame *const fp = cx->fp;
|
||||
JSObject *obj = fp->getScopeChain();
|
||||
JSObject *obj = fp->scopeChain;
|
||||
JS_ASSERT(obj->getClass() == &js_BlockClass);
|
||||
JS_ASSERT(obj->getPrivate() == js_FloatingFrameIfGenerator(cx, cx->fp));
|
||||
JS_ASSERT(OBJ_IS_CLONED_BLOCK(obj));
|
||||
|
@ -3001,7 +3001,7 @@ js_PutBlockObject(JSContext *cx, JSBool normalUnwind)
|
|||
|
||||
/* We must clear the private slot even with errors. */
|
||||
obj->setPrivate(NULL);
|
||||
fp->setScopeChain(obj->getParent());
|
||||
fp->scopeChain = obj->getParent();
|
||||
return normalUnwind;
|
||||
}
|
||||
|
||||
|
@ -3750,7 +3750,7 @@ js_FindClassObject(JSContext *cx, JSObject *start, JSProtoKey protoKey,
|
|||
*/
|
||||
VOUCH_DOES_NOT_REQUIRE_STACK();
|
||||
if (!start && (fp = cx->fp) != NULL)
|
||||
start = fp->maybeScopeChain();
|
||||
start = fp->scopeChain;
|
||||
|
||||
if (start) {
|
||||
/* Find the topmost object in the scope chain. */
|
||||
|
@ -4469,7 +4469,7 @@ js_FindPropertyHelper(JSContext *cx, jsid id, JSBool cacheResult,
|
|||
JSProperty *prop;
|
||||
|
||||
JS_ASSERT_IF(cacheResult, !JS_ON_TRACE(cx));
|
||||
scopeChain = js_GetTopStackFrame(cx)->getScopeChain();
|
||||
scopeChain = js_GetTopStackFrame(cx)->scopeChain;
|
||||
|
||||
/* Scan entries on the scope chain that we can cache across. */
|
||||
entry = JS_NO_PROP_CACHE_FILL;
|
||||
|
@ -5575,7 +5575,7 @@ js_GetClassPrototype(JSContext *cx, JSObject *scope, JSProtoKey protoKey,
|
|||
if (protoKey != JSProto_Null) {
|
||||
if (!scope) {
|
||||
if (cx->fp)
|
||||
scope = cx->fp->maybeScopeChain();
|
||||
scope = cx->fp->scopeChain;
|
||||
if (!scope) {
|
||||
scope = cx->globalObject;
|
||||
if (!scope) {
|
||||
|
@ -6440,10 +6440,10 @@ js_DumpStackFrame(JSContext *cx, JSStackFrame *start)
|
|||
fprintf(stderr, " overridden_args");
|
||||
fputc('\n', stderr);
|
||||
|
||||
if (fp->hasScopeChain())
|
||||
fprintf(stderr, " scopeChain: (JSObject *) %p\n", (void *) fp->getScopeChain());
|
||||
if (fp->hasBlockChain())
|
||||
fprintf(stderr, " blockChain: (JSObject *) %p\n", (void *) fp->getBlockChain());
|
||||
if (fp->scopeChain)
|
||||
fprintf(stderr, " scopeChain: (JSObject *) %p\n", (void *) fp->scopeChain);
|
||||
if (fp->blockChain)
|
||||
fprintf(stderr, " blockChain: (JSObject *) %p\n", (void *) fp->blockChain);
|
||||
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
|
|
@ -611,7 +611,7 @@ NewBuiltinClassInstance(JSContext *cx, Class *clasp)
|
|||
if (!global)
|
||||
return NULL;
|
||||
} else {
|
||||
global = cx->fp->getScopeChain()->getGlobal();
|
||||
global = cx->fp->scopeChain->getGlobal();
|
||||
}
|
||||
JS_ASSERT(global->getClass()->flags & JSCLASS_IS_GLOBAL);
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ TraceRecorder::downSnapshot(FrameInfo* downFrame)
|
|||
exit->numStackSlotsBelowCurrentFrame = cx->fp->down->argv ?
|
||||
nativeStackOffset(&cx->fp->argv[-2]) / sizeof(double) : 0;
|
||||
exit->exitType = UNSTABLE_LOOP_EXIT;
|
||||
exit->block = cx->fp->down->maybeBlockChain();
|
||||
exit->block = cx->fp->down->blockChain;
|
||||
exit->pc = downFrame->pc + JSOP_CALL_LENGTH;
|
||||
exit->imacpc = NULL;
|
||||
exit->sp_adj = ((downPostSlots + 1) * sizeof(double)) - tree->nativeStackBase;
|
||||
|
@ -596,7 +596,7 @@ TraceRecorder::slurpDownFrames(jsbytecode* return_pc)
|
|||
/* argsobj */
|
||||
slurpFrameObjPtrSlot(fp_ins, JSStackFrame::offsetArgsObj(), fp->addressArgsObj(), &info);
|
||||
/* scopeChain */
|
||||
slurpFrameObjPtrSlot(fp_ins, JSStackFrame::offsetScopeChain(), fp->addressScopeChain(), &info);
|
||||
slurpFrameObjPtrSlot(fp_ins, offsetof(JSStackFrame, scopeChain), &fp->scopeChain, &info);
|
||||
/* vars */
|
||||
LIns* slots_ins = addName(lir->ins2(LIR_addp, fp_ins, INS_CONSTWORD(sizeof(JSStackFrame))),
|
||||
"slots");
|
||||
|
|
|
@ -1201,7 +1201,7 @@ GlobalSlotHash(JSContext* cx, unsigned slot)
|
|||
fp = fp->down;
|
||||
|
||||
HashAccum(h, uintptr_t(fp->script), ORACLE_MASK);
|
||||
HashAccum(h, uintptr_t(fp->getScopeChain()->getGlobal()->shape()), ORACLE_MASK);
|
||||
HashAccum(h, uintptr_t(fp->scopeChain->getGlobal()->shape()), ORACLE_MASK);
|
||||
HashAccum(h, uintptr_t(slot), ORACLE_MASK);
|
||||
return int(h);
|
||||
}
|
||||
|
@ -1821,7 +1821,7 @@ VisitFrameSlots(Visitor &visitor, JSContext *cx, unsigned depth,
|
|||
// requires type |Value|. But the bits are the same, so we can import
|
||||
// it with a cast and the (identity function) unboxing will be OK.
|
||||
visitor.setStackSlotKind("scopeChain");
|
||||
if (!visitor.visitFrameObjPtr(fp->addressScopeChain(), fp))
|
||||
if (!visitor.visitFrameObjPtr(&fp->scopeChain, fp))
|
||||
return false;
|
||||
visitor.setStackSlotKind("var");
|
||||
if (!visitor.visitStackSlots(fp->slots(), fp->script->nfixed, fp))
|
||||
|
@ -1873,7 +1873,7 @@ template <typename Visitor>
|
|||
static JS_REQUIRES_STACK JS_ALWAYS_INLINE void
|
||||
VisitGlobalSlots(Visitor &visitor, JSContext *cx, SlotList &gslots)
|
||||
{
|
||||
VisitGlobalSlots(visitor, cx, cx->fp->getScopeChain()->getGlobal(),
|
||||
VisitGlobalSlots(visitor, cx, cx->fp->scopeChain->getGlobal(),
|
||||
gslots.length(), gslots.data());
|
||||
}
|
||||
|
||||
|
@ -1892,7 +1892,7 @@ static JS_REQUIRES_STACK JS_ALWAYS_INLINE void
|
|||
VisitSlots(Visitor& visitor, JSContext* cx, unsigned callDepth,
|
||||
unsigned ngslots, uint16* gslots)
|
||||
{
|
||||
VisitSlots(visitor, cx, cx->fp->getScopeChain()->getGlobal(),
|
||||
VisitSlots(visitor, cx, cx->fp->scopeChain->getGlobal(),
|
||||
callDepth, ngslots, gslots);
|
||||
}
|
||||
|
||||
|
@ -1910,7 +1910,7 @@ static JS_REQUIRES_STACK JS_ALWAYS_INLINE void
|
|||
VisitSlots(Visitor &visitor, JSContext *cx, unsigned callDepth,
|
||||
const SlotList& slots)
|
||||
{
|
||||
VisitSlots(visitor, cx, cx->fp->getScopeChain()->getGlobal(),
|
||||
VisitSlots(visitor, cx, cx->fp->scopeChain->getGlobal(),
|
||||
callDepth, slots.length(), slots.data());
|
||||
}
|
||||
|
||||
|
@ -2224,7 +2224,7 @@ TraceRecorder::TraceRecorder(JSContext* cx, VMSideExit* anchor, VMFragment* frag
|
|||
globalObj(tree->globalObj),
|
||||
outer(outer),
|
||||
outerArgc(outerArgc),
|
||||
lexicalBlock(cx->fp->maybeBlockChain()),
|
||||
lexicalBlock(cx->fp->blockChain),
|
||||
anchor(anchor),
|
||||
lir(NULL),
|
||||
cx_ins(NULL),
|
||||
|
@ -2255,7 +2255,7 @@ TraceRecorder::TraceRecorder(JSContext* cx, VMSideExit* anchor, VMFragment* frag
|
|||
generatedSpecializedNative(),
|
||||
tempTypeMap(cx)
|
||||
{
|
||||
JS_ASSERT(globalObj == cx->fp->getScopeChain()->getGlobal());
|
||||
JS_ASSERT(globalObj == cx->fp->scopeChain->getGlobal());
|
||||
JS_ASSERT(globalObj->scope()->hasOwnShape());
|
||||
JS_ASSERT(cx->regs->pc == (jsbytecode*)fragment->ip);
|
||||
|
||||
|
@ -3461,15 +3461,15 @@ FlushNativeStackFrame(JSContext* cx, unsigned callDepth, const JSValueType* mp,
|
|||
// Iff these fields are NULL, then |fp| was synthesized on trace exit, so
|
||||
// we need to update the frame fields.
|
||||
if (!fp->hasCallObj())
|
||||
fp->setCallObj(fp->getScopeChain());
|
||||
fp->setCallObj(fp->scopeChain);
|
||||
|
||||
// Iff scope chain's private is NULL, then |fp->scopeChain| was created
|
||||
// on trace for a call, so we set the private field now. (Call objects
|
||||
// that correspond to returned frames also have a NULL private, but such
|
||||
// a call object would not occur as the |scopeChain| member of a frame,
|
||||
// so we cannot be in that case here.)
|
||||
if (!fp->getScopeChain()->getPrivate())
|
||||
fp->getScopeChain()->setPrivate(fp);
|
||||
if (!fp->scopeChain->getPrivate())
|
||||
fp->scopeChain->setPrivate(fp);
|
||||
}
|
||||
fp->thisv = fp->argv[-1];
|
||||
if (fp->flags & JSFRAME_CONSTRUCTING) // constructors always compute 'this'
|
||||
|
@ -3863,7 +3863,7 @@ TraceRecorder::isValidFrameObjPtr(JSObject **p)
|
|||
{
|
||||
JSStackFrame *fp = cx->fp;
|
||||
for (; fp; fp = fp->down) {
|
||||
if (fp->addressScopeChain() == p || fp->addressArgsObj() == p)
|
||||
if (&fp->scopeChain == p || fp->addressArgsObj() == p)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -4273,9 +4273,9 @@ TraceRecorder::snapshot(ExitType exitType)
|
|||
nativeStackOffset(&cx->fp->argv[-2]) / sizeof(double) :
|
||||
0;
|
||||
exit->exitType = exitType;
|
||||
exit->block = fp->maybeBlockChain();
|
||||
if (fp->hasBlockChain())
|
||||
tree->gcthings.addUnique(ObjectValue(*fp->getBlockChain()));
|
||||
exit->block = fp->blockChain;
|
||||
if (fp->blockChain)
|
||||
tree->gcthings.addUnique(ObjectValue(*fp->blockChain));
|
||||
exit->pc = pc;
|
||||
exit->imacpc = fp->imacpc;
|
||||
exit->sp_adj = (stackSlots * sizeof(double)) - tree->nativeStackBase;
|
||||
|
@ -5671,7 +5671,14 @@ SynthesizeFrame(JSContext* cx, const FrameInfo& fi, JSObject* callee)
|
|||
cx->regs->sp = sp;
|
||||
cx->regs->pc = fi.pc;
|
||||
fp->imacpc = fi.imacpc;
|
||||
fp->setBlockChain(fi.block);
|
||||
fp->blockChain = fi.block;
|
||||
fp->blockChain = fi.block;
|
||||
#ifdef DEBUG
|
||||
if (fi.block != fp->blockChain) {
|
||||
for (JSObject* obj = fi.block; obj != fp->blockChain; obj = obj->getParent())
|
||||
JS_ASSERT(obj);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get pointer to new frame/slots, without changing global state.
|
||||
|
@ -5709,9 +5716,9 @@ SynthesizeFrame(JSContext* cx, const FrameInfo& fi, JSObject* callee)
|
|||
#endif
|
||||
newfp->rval = UndefinedValue();
|
||||
newfp->annotation = NULL;
|
||||
newfp->setScopeChain(NULL); // will be updated in FlushNativeStackFrame
|
||||
newfp->scopeChain = NULL; // will be updated in FlushNativeStackFrame
|
||||
newfp->flags = fi.is_constructing() ? JSFRAME_CONSTRUCTING : 0;
|
||||
newfp->setBlockChain(NULL);
|
||||
newfp->blockChain = NULL;
|
||||
newfp->thisv.setNull(); // will be updated in FlushNativeStackFrame
|
||||
newfp->imacpc = NULL;
|
||||
|
||||
|
@ -5781,8 +5788,9 @@ SynthesizeSlowNativeFrame(TracerState& state, JSContext *cx, VMSideExit *exit)
|
|||
fp->fun = GET_FUNCTION_PRIVATE(cx, fp->callee());
|
||||
fp->rval = UndefinedValue();
|
||||
fp->annotation = NULL;
|
||||
fp->setScopeChain(cx->fp->maybeScopeChain());
|
||||
fp->setBlockChain(NULL);
|
||||
JS_ASSERT(cx->fp->scopeChain);
|
||||
fp->scopeChain = cx->fp->scopeChain;
|
||||
fp->blockChain = NULL;
|
||||
fp->flags = exit->constructing() ? JSFRAME_CONSTRUCTING : 0;
|
||||
|
||||
state.bailedSlowNativeRegs = *cx->regs;
|
||||
|
@ -6149,7 +6157,7 @@ TraceRecorder::recordLoopEdge(JSContext* cx, TraceRecorder* r, uintN& inlineCall
|
|||
* Make sure the shape of the global object still matches (this might flush
|
||||
* the JIT cache).
|
||||
*/
|
||||
JSObject* globalObj = cx->fp->getScopeChain()->getGlobal();
|
||||
JSObject* globalObj = cx->fp->scopeChain->getGlobal();
|
||||
uint32 globalShape = -1;
|
||||
SlotList* globalSlots = NULL;
|
||||
if (!CheckGlobalObjectShape(cx, tm, globalObj, &globalShape, &globalSlots)) {
|
||||
|
@ -6655,7 +6663,7 @@ ExecuteTrace(JSContext* cx, Fragment* f, TracerState& state)
|
|||
static JS_REQUIRES_STACK JS_ALWAYS_INLINE bool
|
||||
ScopeChainCheck(JSContext* cx, TreeFragment* f)
|
||||
{
|
||||
JS_ASSERT(f->globalObj == cx->fp->getScopeChain()->getGlobal());
|
||||
JS_ASSERT(f->globalObj == cx->fp->scopeChain->getGlobal());
|
||||
|
||||
/*
|
||||
* The JIT records and expects to execute with two scope-chain
|
||||
|
@ -6673,7 +6681,7 @@ ScopeChainCheck(JSContext* cx, TreeFragment* f)
|
|||
* class types; once a global is found, it's checked for #1. Failing
|
||||
* either check causes an early return from execution.
|
||||
*/
|
||||
JSObject* child = cx->fp->getScopeChain();
|
||||
JSObject* child = cx->fp->scopeChain;
|
||||
while (JSObject* parent = child->getParent()) {
|
||||
if (!js_IsCacheableNonGlobalScope(child)) {
|
||||
debug_only_print0(LC_TMTracer,"Blacklist: non-cacheable object on scope chain.\n");
|
||||
|
@ -7012,7 +7020,7 @@ LeaveTree(TraceMonitor *tm, TracerState& state, VMSideExit* lr)
|
|||
*/
|
||||
JSStackFrame* const fp = cx->fp;
|
||||
|
||||
fp->setBlockChain(innermost->block);
|
||||
fp->blockChain = innermost->block;
|
||||
|
||||
/*
|
||||
* If we are not exiting from an inlined frame, the state->sp is spbase.
|
||||
|
@ -7162,7 +7170,7 @@ MonitorLoopEdge(JSContext* cx, uintN& inlineCallCount, RecordReason reason)
|
|||
* Make sure the shape of the global object still matches (this might flush
|
||||
* the JIT cache).
|
||||
*/
|
||||
JSObject* globalObj = cx->fp->getScopeChain()->getGlobal();
|
||||
JSObject* globalObj = cx->fp->scopeChain->getGlobal();
|
||||
uint32 globalShape = -1;
|
||||
SlotList* globalSlots = NULL;
|
||||
|
||||
|
@ -8078,7 +8086,7 @@ JS_REQUIRES_STACK LIns*
|
|||
TraceRecorder::scopeChain()
|
||||
{
|
||||
return cx->fp->callee()
|
||||
? getFrameObjPtr(cx->fp->addressScopeChain())
|
||||
? getFrameObjPtr(&cx->fp->scopeChain)
|
||||
: entryScopeChain();
|
||||
}
|
||||
|
||||
|
@ -8092,7 +8100,7 @@ TraceRecorder::entryScopeChain() const
|
|||
{
|
||||
return lir->insLoad(LIR_ldp,
|
||||
lir->insLoad(LIR_ldp, cx_ins, offsetof(JSContext, fp), ACCSET_OTHER),
|
||||
JSStackFrame::offsetScopeChain(), ACCSET_OTHER);
|
||||
offsetof(JSStackFrame, scopeChain), ACCSET_OTHER);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -8134,7 +8142,7 @@ JS_DEFINE_CALLINFO_4(extern, UINT32, GetClosureArg, CONTEXT, OBJECT, CVIPTR, DOU
|
|||
JS_REQUIRES_STACK AbortableRecordingStatus
|
||||
TraceRecorder::scopeChainProp(JSObject* chainHead, Value*& vp, LIns*& ins, NameResult& nr)
|
||||
{
|
||||
JS_ASSERT(chainHead == cx->fp->getScopeChain());
|
||||
JS_ASSERT(chainHead == cx->fp->scopeChain);
|
||||
JS_ASSERT(chainHead != globalObj);
|
||||
|
||||
TraceMonitor &localtm = *traceMonitor;
|
||||
|
@ -10233,7 +10241,7 @@ TraceRecorder::clearFrameSlotsFromTracker(Tracker& which, JSStackFrame* fp, unsi
|
|||
while (vp < vpstop)
|
||||
which.set(vp++, (LIns*)0);
|
||||
which.set(fp->addressArgsObj(), (LIns*)0);
|
||||
which.set(fp->addressScopeChain(), (LIns*)0);
|
||||
which.set(&fp->scopeChain, (LIns*)0);
|
||||
}
|
||||
vp = &fp->slots()[0];
|
||||
vpstop = &fp->slots()[nslots];
|
||||
|
@ -10312,7 +10320,7 @@ TraceRecorder::putActivationObjects()
|
|||
slots_ins = INS_CONSTPTR(0);
|
||||
}
|
||||
|
||||
LIns* scopeChain_ins = getFrameObjPtr(cx->fp->addressScopeChain());
|
||||
LIns* scopeChain_ins = getFrameObjPtr(&cx->fp->scopeChain);
|
||||
LIns* args[] = { slots_ins, INS_CONST(nslots), args_ins,
|
||||
INS_CONST(cx->fp->fun->nargs), scopeChain_ins, cx_ins };
|
||||
lir->insCall(&js_PutCallObjectOnTrace_ci, args);
|
||||
|
@ -10336,7 +10344,7 @@ IsTraceableRecursion(JSContext *cx)
|
|||
return false;
|
||||
if ((fp->flags & JSFRAME_CONSTRUCTING) || (down->flags & JSFRAME_CONSTRUCTING))
|
||||
return false;
|
||||
if (fp->hasBlockChain() || down->hasBlockChain())
|
||||
if (fp->blockChain || down->blockChain)
|
||||
return false;
|
||||
if (*fp->script->code != JSOP_TRACE)
|
||||
return false;
|
||||
|
@ -10384,7 +10392,7 @@ TraceRecorder::record_EnterFrame(uintN& inlineCallCount)
|
|||
|
||||
nativeFrameTracker.set(fp->addressArgsObj(), NULL);
|
||||
setFrameObjPtr(fp->addressArgsObj(), INS_NULL());
|
||||
nativeFrameTracker.set(fp->addressScopeChain(), NULL);
|
||||
nativeFrameTracker.set(&fp->scopeChain, NULL);
|
||||
|
||||
vp = fp->slots();
|
||||
vpstop = vp + fp->script->nfixed;
|
||||
|
@ -10404,7 +10412,7 @@ TraceRecorder::record_EnterFrame(uintN& inlineCallCount)
|
|||
if (cx->fp->fun && JSFUN_HEAVYWEIGHT_TEST(cx->fp->fun->flags)) {
|
||||
// We need to make sure every part of the frame is known to the tracker
|
||||
// before taking a snapshot.
|
||||
setFrameObjPtr(fp->addressScopeChain(), INS_NULL());
|
||||
setFrameObjPtr(&fp->scopeChain, INS_NULL());
|
||||
|
||||
if (js_IsNamedLambda(cx->fp->fun))
|
||||
RETURN_STOP_A("can't call named lambda heavyweight on trace");
|
||||
|
@ -10415,9 +10423,9 @@ TraceRecorder::record_EnterFrame(uintN& inlineCallCount)
|
|||
LIns* call_ins = lir->insCall(&js_CreateCallObjectOnTrace_ci, args);
|
||||
guard(false, lir->insEqP_0(call_ins), snapshot(OOM_EXIT));
|
||||
|
||||
setFrameObjPtr(fp->addressScopeChain(), call_ins);
|
||||
setFrameObjPtr(&fp->scopeChain, call_ins);
|
||||
} else {
|
||||
setFrameObjPtr(fp->addressScopeChain(), scopeChain_ins);
|
||||
setFrameObjPtr(&fp->scopeChain, scopeChain_ins);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -10473,7 +10481,7 @@ TraceRecorder::record_EnterFrame(uintN& inlineCallCount)
|
|||
* Make sure the shape of the global object still matches (this might
|
||||
* flush the JIT cache).
|
||||
*/
|
||||
JSObject* globalObj = cx->fp->getScopeChain()->getGlobal();
|
||||
JSObject* globalObj = cx->fp->scopeChain->getGlobal();
|
||||
uint32 globalShape = -1;
|
||||
SlotList* globalSlots = NULL;
|
||||
if (!CheckGlobalObjectShape(cx, traceMonitor, globalObj, &globalShape, &globalSlots))
|
||||
|
@ -13074,7 +13082,7 @@ TraceRecorder::record_JSOP_SETELEM()
|
|||
JS_REQUIRES_STACK AbortableRecordingStatus
|
||||
TraceRecorder::record_JSOP_CALLNAME()
|
||||
{
|
||||
JSObject* obj = cx->fp->getScopeChain();
|
||||
JSObject* obj = cx->fp->scopeChain;
|
||||
if (obj != globalObj) {
|
||||
Value* vp;
|
||||
LIns* ins;
|
||||
|
@ -13370,9 +13378,9 @@ TraceRecorder::interpretedFunctionCall(Value& fval, JSFunction* fun, uintN argc,
|
|||
JS_ASSERT(argc < FrameInfo::CONSTRUCTING_FLAG);
|
||||
|
||||
tree->gcthings.addUnique(fval);
|
||||
fi->block = fp->maybeBlockChain();
|
||||
if (fp->hasBlockChain())
|
||||
tree->gcthings.addUnique(ObjectValue(*fp->getBlockChain()));
|
||||
fi->block = fp->blockChain;
|
||||
if (fp->blockChain)
|
||||
tree->gcthings.addUnique(ObjectValue(*fp->blockChain));
|
||||
fi->pc = cx->regs->pc;
|
||||
fi->imacpc = fp->imacpc;
|
||||
fi->spdist = cx->regs->sp - fp->slots();
|
||||
|
@ -13616,7 +13624,7 @@ TraceRecorder::record_NativeCallComplete()
|
|||
JS_REQUIRES_STACK AbortableRecordingStatus
|
||||
TraceRecorder::name(Value*& vp, LIns*& ins, NameResult& nr)
|
||||
{
|
||||
JSObject* obj = cx->fp->getScopeChain();
|
||||
JSObject* obj = cx->fp->scopeChain;
|
||||
if (obj != globalObj)
|
||||
return scopeChainProp(obj, vp, ins, nr);
|
||||
|
||||
|
@ -14718,7 +14726,7 @@ TraceRecorder::record_JSOP_BINDNAME()
|
|||
JSObject *obj;
|
||||
|
||||
if (!fp->fun) {
|
||||
obj = fp->getScopeChain();
|
||||
obj = fp->scopeChain;
|
||||
|
||||
#ifdef DEBUG
|
||||
JSStackFrame *fp2 = fp;
|
||||
|
@ -14779,7 +14787,7 @@ TraceRecorder::record_JSOP_BINDNAME()
|
|||
JSAtom *atom = atoms[GET_INDEX(cx->regs->pc)];
|
||||
jsid id = ATOM_TO_JSID(atom);
|
||||
JSContext *localCx = cx;
|
||||
JSObject *obj2 = js_FindIdentifierBase(cx, fp->getScopeChain(), id);
|
||||
JSObject *obj2 = js_FindIdentifierBase(cx, fp->scopeChain, id);
|
||||
if (!obj2)
|
||||
RETURN_ERROR_A("error in js_FindIdentifierBase");
|
||||
if (!TRACE_RECORDER(localCx))
|
||||
|
@ -15846,7 +15854,7 @@ JS_REQUIRES_STACK AbortableRecordingStatus
|
|||
TraceRecorder::record_JSOP_LEAVEBLOCK()
|
||||
{
|
||||
/* We mustn't exit the lexical block we began recording in. */
|
||||
if (cx->fp->getBlockChain() == lexicalBlock)
|
||||
if (cx->fp->blockChain == lexicalBlock)
|
||||
return ARECORD_STOP;
|
||||
return ARECORD_CONTINUE;
|
||||
}
|
||||
|
|
|
@ -381,7 +381,7 @@ JSCompartment::wrap(JSContext *cx, Value *vp)
|
|||
* we parent all wrappers to the global object in their home compartment.
|
||||
* This loses us some transparency, and is generally very cheesy.
|
||||
*/
|
||||
JSObject *global = cx->fp ? cx->fp->getScopeChain()->getGlobal() : cx->globalObject;
|
||||
JSObject *global = cx->fp ? cx->fp->scopeChain->getGlobal() : cx->globalObject;
|
||||
wrapper->setParent(global);
|
||||
return true;
|
||||
}
|
||||
|
@ -489,7 +489,7 @@ SetupFakeFrame(JSContext *cx, ExecuteFrameGuard &frame, JSFrameRegs ®s, JSObj
|
|||
JSStackFrame *fp = frame.getFrame();
|
||||
PodZero(fp); // fp->fun and fp->script are both NULL
|
||||
fp->argv = vp + 2;
|
||||
fp->setScopeChain(obj->getGlobal());
|
||||
fp->scopeChain = obj->getGlobal();
|
||||
fp->flags = JSFRAME_DUMMY;
|
||||
|
||||
regs.pc = NULL;
|
||||
|
|
|
@ -1735,7 +1735,7 @@ ParseXMLSource(JSContext *cx, JSString *src)
|
|||
{
|
||||
Parser parser(cx);
|
||||
if (parser.init(chars, length, NULL, filename, lineno)) {
|
||||
JSObject *scopeChain = js_GetTopStackFrame(cx)->getScopeChain();
|
||||
JSObject *scopeChain = js_GetTopStackFrame(cx)->scopeChain;
|
||||
JSParseNode *pn = parser.parseXMLText(scopeChain, false);
|
||||
uintN flags;
|
||||
if (pn && GetXMLSettingFlags(cx, &flags)) {
|
||||
|
@ -7227,7 +7227,7 @@ js_GetDefaultXMLNamespace(JSContext *cx, jsval *vp)
|
|||
fp = js_GetTopStackFrame(cx);
|
||||
|
||||
obj = NULL;
|
||||
for (tmp = fp->getScopeChain(); tmp; tmp = tmp->getParent()) {
|
||||
for (tmp = fp->scopeChain; tmp; tmp = tmp->getParent()) {
|
||||
Class *clasp = tmp->getClass();
|
||||
if (clasp == &js_BlockClass || clasp == &js_WithClass)
|
||||
continue;
|
||||
|
@ -7440,7 +7440,7 @@ js_FindXMLProperty(JSContext *cx, const Value &nameval, JSObject **objp, jsid *i
|
|||
if (!IsFunctionQName(cx, qn, &funid))
|
||||
return JS_FALSE;
|
||||
|
||||
obj = js_GetTopStackFrame(cx)->getScopeChain();
|
||||
obj = js_GetTopStackFrame(cx)->scopeChain;
|
||||
do {
|
||||
/* Skip any With object that can wrap XML. */
|
||||
target = obj;
|
||||
|
|
Загрузка…
Ссылка в новой задаче