mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-05 00:25:27 +00:00
[JAEGER] Merge from Tracemonkey. scopeChain and blockChain are still public so I can check one thing at a time--this merge is brutal.
This commit is contained in:
commit
7463868bb1
@ -1823,7 +1823,7 @@ JS_GetGlobalForScopeChain(JSContext *cx)
|
|||||||
VOUCH_DOES_NOT_REQUIRE_STACK();
|
VOUCH_DOES_NOT_REQUIRE_STACK();
|
||||||
|
|
||||||
if (cx->fp)
|
if (cx->fp)
|
||||||
return cx->fp->scopeChain->getGlobal();
|
return cx->fp->getScopeChain()->getGlobal();
|
||||||
|
|
||||||
JSObject *scope = cx->globalObject;
|
JSObject *scope = cx->globalObject;
|
||||||
if (!scope) {
|
if (!scope) {
|
||||||
|
@ -351,7 +351,7 @@ js_PopInterpFrame(JSContext* cx, TracerState* state)
|
|||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
if (fp->imacpc)
|
if (fp->imacpc)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
if (fp->blockChain)
|
if (fp->hasBlockChain())
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
|
|
||||||
fp->putActivationObjects(cx);
|
fp->putActivationObjects(cx);
|
||||||
|
@ -779,7 +779,7 @@ js_watch_set(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
|||||||
fp->script = script;
|
fp->script = script;
|
||||||
fp->fun = fun;
|
fp->fun = fun;
|
||||||
fp->argv = vp + 2;
|
fp->argv = vp + 2;
|
||||||
fp->scopeChain = closure->getParent();
|
fp->setScopeChain(closure->getParent());
|
||||||
fp->setArgsObj(NULL);
|
fp->setArgsObj(NULL);
|
||||||
|
|
||||||
/* Initialize regs. */
|
/* Initialize regs. */
|
||||||
@ -1298,7 +1298,7 @@ JS_IsNativeFrame(JSContext *cx, JSStackFrame *fp)
|
|||||||
JS_PUBLIC_API(JSObject *)
|
JS_PUBLIC_API(JSObject *)
|
||||||
JS_GetFrameObject(JSContext *cx, JSStackFrame *fp)
|
JS_GetFrameObject(JSContext *cx, JSStackFrame *fp)
|
||||||
{
|
{
|
||||||
return fp->scopeChain;
|
return fp->maybeScopeChain();
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(JSObject *)
|
JS_PUBLIC_API(JSObject *)
|
||||||
@ -1664,7 +1664,7 @@ SetupFakeFrame(JSContext *cx, ExecuteFrameGuard &frame, JSFrameRegs ®s, JSObj
|
|||||||
PodZero(fp);
|
PodZero(fp);
|
||||||
fp->fun = fun;
|
fp->fun = fun;
|
||||||
fp->argv = vp + 2;
|
fp->argv = vp + 2;
|
||||||
fp->scopeChain = scopeobj->getGlobal();
|
fp->setScopeChain(scopeobj->getGlobal());
|
||||||
|
|
||||||
regs.pc = NULL;
|
regs.pc = NULL;
|
||||||
regs.sp = fp->slots();
|
regs.sp = fp->slots();
|
||||||
|
@ -215,7 +215,7 @@ js_GetArgsObject(JSContext *cx, JSStackFrame *fp)
|
|||||||
return fp->getArgsObj();
|
return fp->getArgsObj();
|
||||||
|
|
||||||
/* Compute the arguments object's parent slot from fp's scope chain. */
|
/* Compute the arguments object's parent slot from fp's scope chain. */
|
||||||
JSObject *global = fp->scopeChain->getGlobal();
|
JSObject *global = fp->getScopeChain()->getGlobal();
|
||||||
JSObject *argsobj = NewArguments(cx, global, fp->argc, &fp->argv[-2].toObject());
|
JSObject *argsobj = NewArguments(cx, global, fp->argc, &fp->argv[-2].toObject());
|
||||||
if (!argsobj)
|
if (!argsobj)
|
||||||
return argsobj;
|
return argsobj;
|
||||||
@ -770,7 +770,7 @@ NewDeclEnvObject(JSContext *cx, JSStackFrame *fp)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Init immediately to avoid GC seeing a half-init'ed object. */
|
/* Init immediately to avoid GC seeing a half-init'ed object. */
|
||||||
envobj->init(&js_DeclEnvClass, NULL, fp->scopeChain, PrivateValue(fp));
|
envobj->init(&js_DeclEnvClass, NULL, fp->maybeScopeChain(), PrivateValue(fp));
|
||||||
envobj->map = cx->runtime->emptyDeclEnvScope->hold();
|
envobj->map = cx->runtime->emptyDeclEnvScope->hold();
|
||||||
return envobj;
|
return envobj;
|
||||||
}
|
}
|
||||||
@ -785,11 +785,11 @@ js_GetCallObject(JSContext *cx, JSStackFrame *fp)
|
|||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/* A call object should be a frame's outermost scope chain element. */
|
/* A call object should be a frame's outermost scope chain element. */
|
||||||
Class *classp = fp->scopeChain->getClass();
|
Class *classp = fp->getScopeChain()->getClass();
|
||||||
if (classp == &js_WithClass || classp == &js_BlockClass)
|
if (classp == &js_WithClass || classp == &js_BlockClass)
|
||||||
JS_ASSERT(fp->scopeChain->getPrivate() != js_FloatingFrameIfGenerator(cx, fp));
|
JS_ASSERT(fp->getScopeChain()->getPrivate() != js_FloatingFrameIfGenerator(cx, fp));
|
||||||
else if (classp == &js_CallClass)
|
else if (classp == &js_CallClass)
|
||||||
JS_ASSERT(fp->scopeChain->getPrivate() != fp);
|
JS_ASSERT(fp->getScopeChain()->getPrivate() != fp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -805,9 +805,9 @@ js_GetCallObject(JSContext *cx, JSStackFrame *fp)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Root envobj before js_DefineNativeProperty (-> JSClass.addProperty). */
|
/* Root envobj before js_DefineNativeProperty (-> JSClass.addProperty). */
|
||||||
fp->scopeChain = envobj;
|
fp->setScopeChain(envobj);
|
||||||
JS_ASSERT(fp->argv);
|
JS_ASSERT(fp->argv);
|
||||||
if (!js_DefineNativeProperty(cx, fp->scopeChain, ATOM_TO_JSID(lambdaName),
|
if (!js_DefineNativeProperty(cx, fp->getScopeChain(), ATOM_TO_JSID(lambdaName),
|
||||||
fp->calleeValue(),
|
fp->calleeValue(),
|
||||||
CalleeGetter, NULL,
|
CalleeGetter, NULL,
|
||||||
JSPROP_PERMANENT | JSPROP_READONLY,
|
JSPROP_PERMANENT | JSPROP_READONLY,
|
||||||
@ -816,7 +816,7 @@ js_GetCallObject(JSContext *cx, JSStackFrame *fp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject *callobj = NewCallObject(cx, fp->fun, fp->scopeChain);
|
JSObject *callobj = NewCallObject(cx, fp->fun, fp->getScopeChain());
|
||||||
if (!callobj)
|
if (!callobj)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -830,7 +830,7 @@ js_GetCallObject(JSContext *cx, JSStackFrame *fp)
|
|||||||
* Push callobj on the top of the scope chain, and make it the
|
* Push callobj on the top of the scope chain, and make it the
|
||||||
* variables object.
|
* variables object.
|
||||||
*/
|
*/
|
||||||
fp->scopeChain = callobj;
|
fp->setScopeChain(callobj);
|
||||||
return callobj;
|
return callobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2278,8 +2278,8 @@ js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp)
|
|||||||
/* Allow for primitive this parameter due to JSFUN_THISP_* flags. */
|
/* Allow for primitive this parameter due to JSFUN_THISP_* flags. */
|
||||||
MarkValue(trc, fp->thisv, "this");
|
MarkValue(trc, fp->thisv, "this");
|
||||||
MarkValue(trc, fp->rval, "rval");
|
MarkValue(trc, fp->rval, "rval");
|
||||||
if (fp->scopeChain)
|
if (fp->hasScopeChain())
|
||||||
JS_CALL_OBJECT_TRACER(trc, fp->scopeChain, "scope chain");
|
JS_CALL_OBJECT_TRACER(trc, fp->getScopeChain(), "scope chain");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -105,7 +105,7 @@ jsbytecode *const JSStackFrame::sInvalidPC = (jsbytecode *)0xbeef;
|
|||||||
JSObject *
|
JSObject *
|
||||||
js_GetScopeChain(JSContext *cx, JSStackFrame *fp)
|
js_GetScopeChain(JSContext *cx, JSStackFrame *fp)
|
||||||
{
|
{
|
||||||
JSObject *sharedBlock = fp->blockChain;
|
JSObject *sharedBlock = fp->maybeBlockChain();
|
||||||
|
|
||||||
if (!sharedBlock) {
|
if (!sharedBlock) {
|
||||||
/*
|
/*
|
||||||
@ -115,8 +115,8 @@ js_GetScopeChain(JSContext *cx, JSStackFrame *fp)
|
|||||||
JS_ASSERT(!fp->fun ||
|
JS_ASSERT(!fp->fun ||
|
||||||
!(fp->fun->flags & JSFUN_HEAVYWEIGHT) ||
|
!(fp->fun->flags & JSFUN_HEAVYWEIGHT) ||
|
||||||
fp->hasCallObj());
|
fp->hasCallObj());
|
||||||
JS_ASSERT(fp->scopeChain);
|
JS_ASSERT(fp->hasScopeChain());
|
||||||
return fp->scopeChain;
|
return fp->getScopeChain();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We don't handle cloning blocks on trace. */
|
/* We don't handle cloning blocks on trace. */
|
||||||
@ -131,8 +131,8 @@ js_GetScopeChain(JSContext *cx, JSStackFrame *fp)
|
|||||||
*/
|
*/
|
||||||
JSObject *limitBlock, *limitClone;
|
JSObject *limitBlock, *limitClone;
|
||||||
if (fp->fun && !fp->hasCallObj()) {
|
if (fp->fun && !fp->hasCallObj()) {
|
||||||
JS_ASSERT_IF(fp->scopeChain->getClass() == &js_BlockClass,
|
JS_ASSERT_IF(fp->getScopeChain()->getClass() == &js_BlockClass,
|
||||||
fp->scopeChain->getPrivate() != js_FloatingFrameIfGenerator(cx, fp));
|
fp->getScopeChain()->getPrivate() != js_FloatingFrameIfGenerator(cx, fp));
|
||||||
if (!js_GetCallObject(cx, fp))
|
if (!js_GetCallObject(cx, fp))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ js_GetScopeChain(JSContext *cx, JSStackFrame *fp)
|
|||||||
* prototype should appear on blockChain; we'll clone blockChain up
|
* prototype should appear on blockChain; we'll clone blockChain up
|
||||||
* to, but not including, that prototype.
|
* to, but not including, that prototype.
|
||||||
*/
|
*/
|
||||||
limitClone = fp->scopeChain;
|
limitClone = fp->getScopeChain();
|
||||||
while (limitClone->getClass() == &js_WithClass)
|
while (limitClone->getClass() == &js_WithClass)
|
||||||
limitClone = limitClone->getParent();
|
limitClone = limitClone->getParent();
|
||||||
JS_ASSERT(limitClone);
|
JS_ASSERT(limitClone);
|
||||||
@ -172,7 +172,7 @@ js_GetScopeChain(JSContext *cx, JSStackFrame *fp)
|
|||||||
|
|
||||||
/* If the innermost block has already been cloned, we are done. */
|
/* If the innermost block has already been cloned, we are done. */
|
||||||
if (limitBlock == sharedBlock)
|
if (limitBlock == sharedBlock)
|
||||||
return fp->scopeChain;
|
return fp->getScopeChain();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -208,7 +208,7 @@ js_GetScopeChain(JSContext *cx, JSStackFrame *fp)
|
|||||||
newChild->setParent(clone);
|
newChild->setParent(clone);
|
||||||
newChild = clone;
|
newChild = clone;
|
||||||
}
|
}
|
||||||
newChild->setParent(fp->scopeChain);
|
newChild->setParent(fp->getScopeChain());
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -221,7 +221,7 @@ js_GetScopeChain(JSContext *cx, JSStackFrame *fp)
|
|||||||
sharedBlock);
|
sharedBlock);
|
||||||
|
|
||||||
/* Place our newly cloned blocks at the head of the scope chain. */
|
/* Place our newly cloned blocks at the head of the scope chain. */
|
||||||
fp->scopeChain = innermostNewChild;
|
fp->setScopeChain(innermostNewChild);
|
||||||
return innermostNewChild;
|
return innermostNewChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,8 +544,8 @@ InvokeCommon(JSContext *cx, JSFunction *fun, JSScript *script, T native,
|
|||||||
fp->argv = args.argv();
|
fp->argv = args.argv();
|
||||||
fp->rval = (flags & JSINVOKE_CONSTRUCT) ? fp->thisv : UndefinedValue();
|
fp->rval = (flags & JSINVOKE_CONSTRUCT) ? fp->thisv : UndefinedValue();
|
||||||
fp->annotation = NULL;
|
fp->annotation = NULL;
|
||||||
fp->scopeChain = NULL;
|
fp->setScopeChain(NULL);
|
||||||
fp->blockChain = NULL;
|
fp->setBlockChain(NULL);
|
||||||
fp->imacpc = NULL;
|
fp->imacpc = NULL;
|
||||||
fp->flags = flags;
|
fp->flags = flags;
|
||||||
|
|
||||||
@ -567,14 +567,14 @@ InvokeCommon(JSContext *cx, JSFunction *fun, JSScript *script, T native,
|
|||||||
if (native) {
|
if (native) {
|
||||||
/* Slow natives and call ops expect the caller's scopeChain as their scopeChain. */
|
/* Slow natives and call ops expect the caller's scopeChain as their scopeChain. */
|
||||||
if (JSStackFrame *down = fp->down)
|
if (JSStackFrame *down = fp->down)
|
||||||
fp->scopeChain = down->scopeChain;
|
fp->setScopeChain(down->maybeScopeChain());
|
||||||
|
|
||||||
/* Ensure that we have a scope chain. */
|
/* Ensure that we have a scope chain. */
|
||||||
if (!fp->scopeChain)
|
if (!fp->hasScopeChain())
|
||||||
fp->scopeChain = parent;
|
fp->setScopeChain(parent);
|
||||||
} else {
|
} else {
|
||||||
/* Use parent scope so js_GetCallObject can find the right "Call". */
|
/* Use parent scope so js_GetCallObject can find the right "Call". */
|
||||||
fp->scopeChain = parent;
|
fp->setScopeChain(parent);
|
||||||
if (fun->isHeavyweight() && !js_GetCallObject(cx, fp))
|
if (fun->isHeavyweight() && !js_GetCallObject(cx, fp))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -885,7 +885,7 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
|||||||
fp->argc = down->argc;
|
fp->argc = down->argc;
|
||||||
fp->argv = down->argv;
|
fp->argv = down->argv;
|
||||||
fp->annotation = down->annotation;
|
fp->annotation = down->annotation;
|
||||||
fp->scopeChain = chain;
|
fp->setScopeChain(chain);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We want to call |down->varobj()|, but this requires knowing the
|
* We want to call |down->varobj()|, but this requires knowing the
|
||||||
@ -911,7 +911,7 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
|||||||
OBJ_TO_INNER_OBJECT(cx, innerizedChain);
|
OBJ_TO_INNER_OBJECT(cx, innerizedChain);
|
||||||
if (!innerizedChain)
|
if (!innerizedChain)
|
||||||
return false;
|
return false;
|
||||||
fp->scopeChain = innerizedChain;
|
fp->setScopeChain(innerizedChain);
|
||||||
|
|
||||||
initialVarObj = (cx->options & JSOPTION_VAROBJFIX)
|
initialVarObj = (cx->options & JSOPTION_VAROBJFIX)
|
||||||
? chain->getGlobal()
|
? chain->getGlobal()
|
||||||
@ -922,7 +922,7 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
|||||||
fp->script = script;
|
fp->script = script;
|
||||||
fp->imacpc = NULL;
|
fp->imacpc = NULL;
|
||||||
fp->rval.setUndefined();
|
fp->rval.setUndefined();
|
||||||
fp->blockChain = NULL;
|
fp->setBlockChain(NULL);
|
||||||
|
|
||||||
/* Initialize regs. */
|
/* Initialize regs. */
|
||||||
regs.pc = script->code;
|
regs.pc = script->code;
|
||||||
@ -1308,7 +1308,7 @@ js_EnterWith(JSContext *cx, jsint stackIndex)
|
|||||||
if (!withobj)
|
if (!withobj)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
|
|
||||||
fp->scopeChain = withobj;
|
fp->setScopeChain(withobj);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1317,11 +1317,11 @@ js_LeaveWith(JSContext *cx)
|
|||||||
{
|
{
|
||||||
JSObject *withobj;
|
JSObject *withobj;
|
||||||
|
|
||||||
withobj = cx->fp->scopeChain;
|
withobj = cx->fp->getScopeChain();
|
||||||
JS_ASSERT(withobj->getClass() == &js_WithClass);
|
JS_ASSERT(withobj->getClass() == &js_WithClass);
|
||||||
JS_ASSERT(withobj->getPrivate() == js_FloatingFrameIfGenerator(cx, cx->fp));
|
JS_ASSERT(withobj->getPrivate() == js_FloatingFrameIfGenerator(cx, cx->fp));
|
||||||
JS_ASSERT(OBJ_BLOCK_DEPTH(cx, withobj) >= 0);
|
JS_ASSERT(OBJ_BLOCK_DEPTH(cx, withobj) >= 0);
|
||||||
cx->fp->scopeChain = withobj->getParent();
|
cx->fp->setScopeChain(withobj->getParent());
|
||||||
withobj->setPrivate(NULL);
|
withobj->setPrivate(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1353,15 +1353,15 @@ js_UnwindScope(JSContext *cx, jsint stackDepth, JSBool normalUnwind)
|
|||||||
JS_ASSERT(cx->fp->base() + stackDepth <= cx->regs->sp);
|
JS_ASSERT(cx->fp->base() + stackDepth <= cx->regs->sp);
|
||||||
|
|
||||||
JSStackFrame *fp = cx->fp;
|
JSStackFrame *fp = cx->fp;
|
||||||
for (obj = fp->blockChain; obj; obj = obj->getParent()) {
|
for (obj = fp->maybeBlockChain(); obj; obj = obj->getParent()) {
|
||||||
JS_ASSERT(obj->getClass() == &js_BlockClass);
|
JS_ASSERT(obj->getClass() == &js_BlockClass);
|
||||||
if (OBJ_BLOCK_DEPTH(cx, obj) < stackDepth)
|
if (OBJ_BLOCK_DEPTH(cx, obj) < stackDepth)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fp->blockChain = obj;
|
fp->setBlockChain(obj);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
obj = fp->scopeChain;
|
obj = fp->getScopeChain();
|
||||||
clasp = js_IsActiveWithOrBlock(cx, obj, stackDepth);
|
clasp = js_IsActiveWithOrBlock(cx, obj, stackDepth);
|
||||||
if (!clasp)
|
if (!clasp)
|
||||||
break;
|
break;
|
||||||
@ -2643,11 +2643,11 @@ BEGIN_CASE(JSOP_POPN)
|
|||||||
regs.sp -= GET_UINT16(regs.pc);
|
regs.sp -= GET_UINT16(regs.pc);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
JS_ASSERT(fp->base() <= regs.sp);
|
JS_ASSERT(fp->base() <= regs.sp);
|
||||||
JSObject *obj = fp->blockChain;
|
JSObject *obj = fp->maybeBlockChain();
|
||||||
JS_ASSERT_IF(obj,
|
JS_ASSERT_IF(obj,
|
||||||
OBJ_BLOCK_DEPTH(cx, obj) + OBJ_BLOCK_COUNT(cx, obj)
|
OBJ_BLOCK_DEPTH(cx, obj) + OBJ_BLOCK_COUNT(cx, obj)
|
||||||
<= (size_t) (regs.sp - fp->base()));
|
<= (size_t) (regs.sp - fp->base()));
|
||||||
for (obj = fp->scopeChain; obj; obj = obj->getParent()) {
|
for (obj = fp->maybeScopeChain(); obj; obj = obj->getParent()) {
|
||||||
Class *clasp = obj->getClass();
|
Class *clasp = obj->getClass();
|
||||||
if (clasp != &js_BlockClass && clasp != &js_WithClass)
|
if (clasp != &js_BlockClass && clasp != &js_WithClass)
|
||||||
continue;
|
continue;
|
||||||
@ -2682,11 +2682,11 @@ BEGIN_CASE(JSOP_ENTERWITH)
|
|||||||
* We set sp[-1] to the current "with" object to help asserting the
|
* We set sp[-1] to the current "with" object to help asserting the
|
||||||
* enter/leave balance in [leavewith].
|
* enter/leave balance in [leavewith].
|
||||||
*/
|
*/
|
||||||
regs.sp[-1].setObject(*fp->scopeChain);
|
regs.sp[-1].setObject(*fp->getScopeChain());
|
||||||
END_CASE(JSOP_ENTERWITH)
|
END_CASE(JSOP_ENTERWITH)
|
||||||
|
|
||||||
BEGIN_CASE(JSOP_LEAVEWITH)
|
BEGIN_CASE(JSOP_LEAVEWITH)
|
||||||
JS_ASSERT(®s.sp[-1].toObject() == fp->scopeChain);
|
JS_ASSERT(®s.sp[-1].toObject() == fp->getScopeChain());
|
||||||
regs.sp--;
|
regs.sp--;
|
||||||
js_LeaveWith(cx);
|
js_LeaveWith(cx);
|
||||||
END_CASE(JSOP_LEAVEWITH)
|
END_CASE(JSOP_LEAVEWITH)
|
||||||
@ -2742,8 +2742,8 @@ BEGIN_CASE(JSOP_STOP)
|
|||||||
if (entryFrame != fp)
|
if (entryFrame != fp)
|
||||||
inline_return:
|
inline_return:
|
||||||
{
|
{
|
||||||
JS_ASSERT(!fp->blockChain);
|
JS_ASSERT(!fp->hasBlockChain());
|
||||||
JS_ASSERT(!js_IsActiveWithOrBlock(cx, fp->scopeChain, 0));
|
JS_ASSERT(!js_IsActiveWithOrBlock(cx, fp->getScopeChain(), 0));
|
||||||
void *hookData = fp->hookData;
|
void *hookData = fp->hookData;
|
||||||
if (JS_UNLIKELY(hookData != NULL)) {
|
if (JS_UNLIKELY(hookData != NULL)) {
|
||||||
if (JSInterpreterHook hook = cx->debugHooks->callHook) {
|
if (JSInterpreterHook hook = cx->debugHooks->callHook) {
|
||||||
@ -3276,7 +3276,7 @@ BEGIN_CASE(JSOP_BINDNAME)
|
|||||||
* the rhs. We desire such resolve hook equivalence between the two
|
* the rhs. We desire such resolve hook equivalence between the two
|
||||||
* forms.
|
* forms.
|
||||||
*/
|
*/
|
||||||
obj = fp->scopeChain;
|
obj = fp->getScopeChain();
|
||||||
if (!obj->getParent())
|
if (!obj->getParent())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3290,7 +3290,7 @@ BEGIN_CASE(JSOP_BINDNAME)
|
|||||||
}
|
}
|
||||||
|
|
||||||
jsid id = ATOM_TO_JSID(atom);
|
jsid id = ATOM_TO_JSID(atom);
|
||||||
obj = js_FindIdentifierBase(cx, fp->scopeChain, id);
|
obj = js_FindIdentifierBase(cx, fp->getScopeChain(), id);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
goto error;
|
goto error;
|
||||||
} while (0);
|
} while (0);
|
||||||
@ -3849,7 +3849,7 @@ BEGIN_CASE(JSOP_DECGNAME)
|
|||||||
BEGIN_CASE(JSOP_GNAMEINC)
|
BEGIN_CASE(JSOP_GNAMEINC)
|
||||||
BEGIN_CASE(JSOP_GNAMEDEC)
|
BEGIN_CASE(JSOP_GNAMEDEC)
|
||||||
{
|
{
|
||||||
obj = fp->scopeChain;
|
obj = fp->getScopeChain();
|
||||||
if (js_CodeSpec[op].format & JOF_GNAME)
|
if (js_CodeSpec[op].format & JOF_GNAME)
|
||||||
obj = obj->getGlobal();
|
obj = obj->getGlobal();
|
||||||
|
|
||||||
@ -4728,9 +4728,9 @@ BEGIN_CASE(JSOP_APPLY)
|
|||||||
newfp->argv = vp + 2;
|
newfp->argv = vp + 2;
|
||||||
newfp->rval.setUndefined();
|
newfp->rval.setUndefined();
|
||||||
newfp->annotation = NULL;
|
newfp->annotation = NULL;
|
||||||
newfp->scopeChain = obj->getParent();
|
newfp->setScopeChain(obj->getParent());
|
||||||
newfp->flags = flags;
|
newfp->flags = flags;
|
||||||
newfp->blockChain = NULL;
|
newfp->setBlockChain(NULL);
|
||||||
JS_ASSERT(!JSFUN_BOUND_METHOD_TEST(fun->flags));
|
JS_ASSERT(!JSFUN_BOUND_METHOD_TEST(fun->flags));
|
||||||
JS_ASSERT_IF(!vp[1].isPrimitive(), IsSaneThisObject(vp[1].toObject()));
|
JS_ASSERT_IF(!vp[1].isPrimitive(), IsSaneThisObject(vp[1].toObject()));
|
||||||
newfp->thisv = vp[1];
|
newfp->thisv = vp[1];
|
||||||
@ -4879,7 +4879,7 @@ BEGIN_CASE(JSOP_CALLGNAME)
|
|||||||
BEGIN_CASE(JSOP_NAME)
|
BEGIN_CASE(JSOP_NAME)
|
||||||
BEGIN_CASE(JSOP_CALLNAME)
|
BEGIN_CASE(JSOP_CALLNAME)
|
||||||
{
|
{
|
||||||
JSObject *obj = fp->scopeChain;
|
JSObject *obj = fp->getScopeChain();
|
||||||
if (op == JSOP_GETGNAME || op == JSOP_CALLGNAME)
|
if (op == JSOP_GETGNAME || op == JSOP_CALLGNAME)
|
||||||
obj = obj->getGlobal();
|
obj = obj->getGlobal();
|
||||||
|
|
||||||
@ -5036,7 +5036,7 @@ BEGIN_CASE(JSOP_REGEXP)
|
|||||||
*/
|
*/
|
||||||
jsatomid index = GET_FULL_INDEX(0);
|
jsatomid index = GET_FULL_INDEX(0);
|
||||||
JSObject *proto;
|
JSObject *proto;
|
||||||
if (!js_GetClassPrototype(cx, fp->scopeChain, JSProto_RegExp, &proto))
|
if (!js_GetClassPrototype(cx, fp->getScopeChain(), JSProto_RegExp, &proto))
|
||||||
goto error;
|
goto error;
|
||||||
JS_ASSERT(proto);
|
JS_ASSERT(proto);
|
||||||
JSObject *obj = js_CloneRegExpObject(cx, script->getRegExp(index), proto);
|
JSObject *obj = js_CloneRegExpObject(cx, script->getRegExp(index), proto);
|
||||||
@ -5521,7 +5521,7 @@ BEGIN_CASE(JSOP_DEFFUN)
|
|||||||
* FIXME: bug 476950, although debugger users may also demand some kind
|
* FIXME: bug 476950, although debugger users may also demand some kind
|
||||||
* of scope link for debugger-assisted eval-in-frame.
|
* of scope link for debugger-assisted eval-in-frame.
|
||||||
*/
|
*/
|
||||||
obj2 = fp->scopeChain;
|
obj2 = fp->getScopeChain();
|
||||||
} else {
|
} else {
|
||||||
JS_ASSERT(!FUN_FLAT_CLOSURE(fun));
|
JS_ASSERT(!FUN_FLAT_CLOSURE(fun));
|
||||||
|
|
||||||
@ -5529,8 +5529,8 @@ BEGIN_CASE(JSOP_DEFFUN)
|
|||||||
* Inline js_GetScopeChain a bit to optimize for the case of a
|
* Inline js_GetScopeChain a bit to optimize for the case of a
|
||||||
* top-level function.
|
* top-level function.
|
||||||
*/
|
*/
|
||||||
if (!fp->blockChain) {
|
if (!fp->hasBlockChain()) {
|
||||||
obj2 = fp->scopeChain;
|
obj2 = fp->getScopeChain();
|
||||||
} else {
|
} else {
|
||||||
obj2 = js_GetScopeChain(cx, fp);
|
obj2 = js_GetScopeChain(cx, fp);
|
||||||
if (!obj2)
|
if (!obj2)
|
||||||
@ -5559,7 +5559,7 @@ BEGIN_CASE(JSOP_DEFFUN)
|
|||||||
* fp->scopeChain code below the parent->defineProperty call.
|
* fp->scopeChain code below the parent->defineProperty call.
|
||||||
*/
|
*/
|
||||||
MUST_FLOW_THROUGH("restore_scope");
|
MUST_FLOW_THROUGH("restore_scope");
|
||||||
fp->scopeChain = obj;
|
fp->setScopeChain(obj);
|
||||||
|
|
||||||
Value rval = ObjectValue(*obj);
|
Value rval = ObjectValue(*obj);
|
||||||
|
|
||||||
@ -5629,7 +5629,7 @@ BEGIN_CASE(JSOP_DEFFUN)
|
|||||||
|
|
||||||
restore_scope:
|
restore_scope:
|
||||||
/* Restore fp->scopeChain now that obj is defined in fp->callobj. */
|
/* Restore fp->scopeChain now that obj is defined in fp->callobj. */
|
||||||
fp->scopeChain = obj2;
|
fp->setScopeChain(obj2);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -5684,7 +5684,7 @@ BEGIN_CASE(JSOP_DEFLOCALFUN)
|
|||||||
JSObject *obj = FUN_OBJECT(fun);
|
JSObject *obj = FUN_OBJECT(fun);
|
||||||
|
|
||||||
if (FUN_NULL_CLOSURE(fun)) {
|
if (FUN_NULL_CLOSURE(fun)) {
|
||||||
obj = CloneFunctionObject(cx, fun, fp->scopeChain);
|
obj = CloneFunctionObject(cx, fun, fp->getScopeChain());
|
||||||
if (!obj)
|
if (!obj)
|
||||||
goto error;
|
goto error;
|
||||||
} else {
|
} else {
|
||||||
@ -5751,7 +5751,7 @@ BEGIN_CASE(JSOP_LAMBDA)
|
|||||||
do {
|
do {
|
||||||
JSObject *parent;
|
JSObject *parent;
|
||||||
if (FUN_NULL_CLOSURE(fun)) {
|
if (FUN_NULL_CLOSURE(fun)) {
|
||||||
parent = fp->scopeChain;
|
parent = fp->getScopeChain();
|
||||||
|
|
||||||
if (obj->getParent() == parent) {
|
if (obj->getParent() == parent) {
|
||||||
jsbytecode *pc2 = regs.pc + JSOP_LAMBDA_LENGTH;
|
jsbytecode *pc2 = regs.pc + JSOP_LAMBDA_LENGTH;
|
||||||
@ -6753,7 +6753,7 @@ BEGIN_CASE(JSOP_ENTERBLOCK)
|
|||||||
regs.sp = vp;
|
regs.sp = vp;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
JS_ASSERT(fp->blockChain == obj->getParent());
|
JS_ASSERT(fp->maybeBlockChain() == obj->getParent());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The young end of fp->scopeChain may omit blocks if we haven't closed
|
* The young end of fp->scopeChain may omit blocks if we haven't closed
|
||||||
@ -6762,7 +6762,7 @@ BEGIN_CASE(JSOP_ENTERBLOCK)
|
|||||||
* anything else we should have popped off fp->scopeChain when we left its
|
* anything else we should have popped off fp->scopeChain when we left its
|
||||||
* static scope.
|
* static scope.
|
||||||
*/
|
*/
|
||||||
JSObject *obj2 = fp->scopeChain;
|
JSObject *obj2 = fp->getScopeChain();
|
||||||
Class *clasp;
|
Class *clasp;
|
||||||
while ((clasp = obj2->getClass()) == &js_WithClass)
|
while ((clasp = obj2->getClass()) == &js_WithClass)
|
||||||
obj2 = obj2->getParent();
|
obj2 = obj2->getParent();
|
||||||
@ -6776,7 +6776,7 @@ BEGIN_CASE(JSOP_ENTERBLOCK)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fp->blockChain = obj;
|
fp->setBlockChain(obj);
|
||||||
}
|
}
|
||||||
END_CASE(JSOP_ENTERBLOCK)
|
END_CASE(JSOP_ENTERBLOCK)
|
||||||
|
|
||||||
@ -6784,8 +6784,8 @@ BEGIN_CASE(JSOP_LEAVEBLOCKEXPR)
|
|||||||
BEGIN_CASE(JSOP_LEAVEBLOCK)
|
BEGIN_CASE(JSOP_LEAVEBLOCK)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
JS_ASSERT(fp->blockChain->getClass() == &js_BlockClass);
|
JS_ASSERT(fp->getBlockChain()->getClass() == &js_BlockClass);
|
||||||
uintN blockDepth = OBJ_BLOCK_DEPTH(cx, fp->blockChain);
|
uintN blockDepth = OBJ_BLOCK_DEPTH(cx, fp->getBlockChain());
|
||||||
|
|
||||||
JS_ASSERT(blockDepth <= StackDepth(script));
|
JS_ASSERT(blockDepth <= StackDepth(script));
|
||||||
#endif
|
#endif
|
||||||
@ -6794,15 +6794,15 @@ BEGIN_CASE(JSOP_LEAVEBLOCK)
|
|||||||
* cloned onto fp->scopeChain, clear its private data, move its locals from
|
* cloned onto fp->scopeChain, clear its private data, move its locals from
|
||||||
* the stack into the clone, and pop it off the chain.
|
* the stack into the clone, and pop it off the chain.
|
||||||
*/
|
*/
|
||||||
JSObject *obj = fp->scopeChain;
|
JSObject *obj = fp->getScopeChain();
|
||||||
if (obj->getProto() == fp->blockChain) {
|
if (obj->getProto() == fp->getBlockChain()) {
|
||||||
JS_ASSERT(obj->getClass() == &js_BlockClass);
|
JS_ASSERT(obj->getClass() == &js_BlockClass);
|
||||||
if (!js_PutBlockObject(cx, JS_TRUE))
|
if (!js_PutBlockObject(cx, JS_TRUE))
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pop the block chain, too. */
|
/* Pop the block chain, too. */
|
||||||
fp->blockChain = fp->blockChain->getParent();
|
fp->setBlockChain(fp->getBlockChain()->getParent());
|
||||||
|
|
||||||
/* Move the result of the expression to the new topmost stack slot. */
|
/* Move the result of the expression to the new topmost stack slot. */
|
||||||
Value *vp = NULL; /* silence GCC warnings */
|
Value *vp = NULL; /* silence GCC warnings */
|
||||||
@ -7133,8 +7133,8 @@ END_CASE(JSOP_ARRAYPUSH)
|
|||||||
AbortRecording(cx, "recording out of Interpret");
|
AbortRecording(cx, "recording out of Interpret");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JS_ASSERT_IF(!fp->isGenerator(), !fp->blockChain);
|
JS_ASSERT_IF(!fp->isGenerator(), !fp->hasBlockChain());
|
||||||
JS_ASSERT_IF(!fp->isGenerator(), !js_IsActiveWithOrBlock(cx, fp->scopeChain, 0));
|
JS_ASSERT_IF(!fp->isGenerator(), !js_IsActiveWithOrBlock(cx, fp->getScopeChain(), 0));
|
||||||
|
|
||||||
/* Undo the remaining effects committed on entry to Interpret. */
|
/* Undo the remaining effects committed on entry to Interpret. */
|
||||||
if (cx->version == currentVersion && currentVersion != originalVersion)
|
if (cx->version == currentVersion && currentVersion != originalVersion)
|
||||||
|
@ -122,44 +122,10 @@ struct JSStackFrame
|
|||||||
|
|
||||||
void *ncode; /* jit return pc */
|
void *ncode; /* jit return pc */
|
||||||
|
|
||||||
/*
|
public:
|
||||||
* 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 *scopeChain;
|
||||||
JSObject *blockChain;
|
JSObject *blockChain;
|
||||||
|
public:
|
||||||
|
|
||||||
uint32 flags; /* frame flags -- see below */
|
uint32 flags; /* frame flags -- see below */
|
||||||
|
|
||||||
@ -232,6 +198,89 @@ struct JSStackFrame
|
|||||||
return offsetof(JSStackFrame, argsobj);
|
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 */
|
/* Other accessors */
|
||||||
|
|
||||||
void putActivationObjects(JSContext *cx) {
|
void putActivationObjects(JSContext *cx) {
|
||||||
|
@ -1190,9 +1190,9 @@ js_NewGenerator(JSContext *cx)
|
|||||||
newfp->argv = vp + 2;
|
newfp->argv = vp + 2;
|
||||||
newfp->rval = fp->rval;
|
newfp->rval = fp->rval;
|
||||||
newfp->annotation = NULL;
|
newfp->annotation = NULL;
|
||||||
newfp->scopeChain = fp->scopeChain;
|
newfp->setScopeChain(fp->maybeScopeChain());
|
||||||
JS_ASSERT(!fp->blockChain);
|
JS_ASSERT(!fp->hasBlockChain());
|
||||||
newfp->blockChain = NULL;
|
newfp->setBlockChain(NULL);
|
||||||
newfp->flags = fp->flags | JSFRAME_GENERATOR | JSFRAME_FLOATING_GENERATOR;
|
newfp->flags = fp->flags | JSFRAME_GENERATOR | JSFRAME_FLOATING_GENERATOR;
|
||||||
|
|
||||||
/* Copy in arguments and slots. */
|
/* Copy in arguments and slots. */
|
||||||
@ -1320,7 +1320,7 @@ SendToGenerator(JSContext *cx, JSGeneratorOp op, JSObject *obj,
|
|||||||
JSObject *enumerators = cx->enumerators;
|
JSObject *enumerators = cx->enumerators;
|
||||||
cx->enumerators = gen->enumerators;
|
cx->enumerators = gen->enumerators;
|
||||||
|
|
||||||
ok = RunScript(cx, fp->script, fp->fun, fp->scopeChain);
|
ok = RunScript(cx, fp->script, fp->fun, fp->getScopeChain());
|
||||||
|
|
||||||
/* Restore the original enumerators stack. */
|
/* Restore the original enumerators stack. */
|
||||||
gen->enumerators = cx->enumerators;
|
gen->enumerators = cx->enumerators;
|
||||||
|
@ -2954,7 +2954,7 @@ js_PutBlockObject(JSContext *cx, JSBool normalUnwind)
|
|||||||
JS_STATIC_ASSERT(JS_INITIAL_NSLOTS == JSSLOT_BLOCK_DEPTH + 2);
|
JS_STATIC_ASSERT(JS_INITIAL_NSLOTS == JSSLOT_BLOCK_DEPTH + 2);
|
||||||
|
|
||||||
JSStackFrame *const fp = cx->fp;
|
JSStackFrame *const fp = cx->fp;
|
||||||
JSObject *obj = fp->scopeChain;
|
JSObject *obj = fp->getScopeChain();
|
||||||
JS_ASSERT(obj->getClass() == &js_BlockClass);
|
JS_ASSERT(obj->getClass() == &js_BlockClass);
|
||||||
JS_ASSERT(obj->getPrivate() == js_FloatingFrameIfGenerator(cx, cx->fp));
|
JS_ASSERT(obj->getPrivate() == js_FloatingFrameIfGenerator(cx, cx->fp));
|
||||||
JS_ASSERT(OBJ_IS_CLONED_BLOCK(obj));
|
JS_ASSERT(OBJ_IS_CLONED_BLOCK(obj));
|
||||||
@ -2988,7 +2988,7 @@ js_PutBlockObject(JSContext *cx, JSBool normalUnwind)
|
|||||||
|
|
||||||
/* We must clear the private slot even with errors. */
|
/* We must clear the private slot even with errors. */
|
||||||
obj->setPrivate(NULL);
|
obj->setPrivate(NULL);
|
||||||
fp->scopeChain = obj->getParent();
|
fp->setScopeChain(obj->getParent());
|
||||||
return normalUnwind;
|
return normalUnwind;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3737,7 +3737,7 @@ js_FindClassObject(JSContext *cx, JSObject *start, JSProtoKey protoKey,
|
|||||||
*/
|
*/
|
||||||
VOUCH_DOES_NOT_REQUIRE_STACK();
|
VOUCH_DOES_NOT_REQUIRE_STACK();
|
||||||
if (!start && (fp = cx->fp) != NULL)
|
if (!start && (fp = cx->fp) != NULL)
|
||||||
start = fp->scopeChain;
|
start = fp->maybeScopeChain();
|
||||||
|
|
||||||
if (start) {
|
if (start) {
|
||||||
/* Find the topmost object in the scope chain. */
|
/* Find the topmost object in the scope chain. */
|
||||||
@ -4456,7 +4456,7 @@ js_FindPropertyHelper(JSContext *cx, jsid id, JSBool cacheResult,
|
|||||||
JSProperty *prop;
|
JSProperty *prop;
|
||||||
|
|
||||||
JS_ASSERT_IF(cacheResult, !JS_ON_TRACE(cx));
|
JS_ASSERT_IF(cacheResult, !JS_ON_TRACE(cx));
|
||||||
scopeChain = js_GetTopStackFrame(cx)->scopeChain;
|
scopeChain = js_GetTopStackFrame(cx)->getScopeChain();
|
||||||
|
|
||||||
/* Scan entries on the scope chain that we can cache across. */
|
/* Scan entries on the scope chain that we can cache across. */
|
||||||
entry = JS_NO_PROP_CACHE_FILL;
|
entry = JS_NO_PROP_CACHE_FILL;
|
||||||
@ -5562,7 +5562,7 @@ js_GetClassPrototype(JSContext *cx, JSObject *scope, JSProtoKey protoKey,
|
|||||||
if (protoKey != JSProto_Null) {
|
if (protoKey != JSProto_Null) {
|
||||||
if (!scope) {
|
if (!scope) {
|
||||||
if (cx->fp)
|
if (cx->fp)
|
||||||
scope = cx->fp->scopeChain;
|
scope = cx->fp->maybeScopeChain();
|
||||||
if (!scope) {
|
if (!scope) {
|
||||||
scope = cx->globalObject;
|
scope = cx->globalObject;
|
||||||
if (!scope) {
|
if (!scope) {
|
||||||
@ -6425,10 +6425,10 @@ js_DumpStackFrame(JSContext *cx, JSStackFrame *start)
|
|||||||
fprintf(stderr, " overridden_args");
|
fprintf(stderr, " overridden_args");
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
|
|
||||||
if (fp->scopeChain)
|
if (fp->hasScopeChain())
|
||||||
fprintf(stderr, " scopeChain: (JSObject *) %p\n", (void *) fp->scopeChain);
|
fprintf(stderr, " scopeChain: (JSObject *) %p\n", (void *) fp->getScopeChain());
|
||||||
if (fp->blockChain)
|
if (fp->hasBlockChain())
|
||||||
fprintf(stderr, " blockChain: (JSObject *) %p\n", (void *) fp->blockChain);
|
fprintf(stderr, " blockChain: (JSObject *) %p\n", (void *) fp->getBlockChain());
|
||||||
|
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
}
|
}
|
||||||
|
@ -611,7 +611,7 @@ NewBuiltinClassInstance(JSContext *cx, Class *clasp)
|
|||||||
if (!global)
|
if (!global)
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
global = cx->fp->scopeChain->getGlobal();
|
global = cx->fp->getScopeChain()->getGlobal();
|
||||||
}
|
}
|
||||||
JS_ASSERT(global->getClass()->flags & JSCLASS_IS_GLOBAL);
|
JS_ASSERT(global->getClass()->flags & JSCLASS_IS_GLOBAL);
|
||||||
|
|
||||||
|
@ -186,7 +186,7 @@ TraceRecorder::downSnapshot(FrameInfo* downFrame)
|
|||||||
exit->numStackSlotsBelowCurrentFrame = cx->fp->down->argv ?
|
exit->numStackSlotsBelowCurrentFrame = cx->fp->down->argv ?
|
||||||
nativeStackOffset(&cx->fp->argv[-2]) / sizeof(double) : 0;
|
nativeStackOffset(&cx->fp->argv[-2]) / sizeof(double) : 0;
|
||||||
exit->exitType = UNSTABLE_LOOP_EXIT;
|
exit->exitType = UNSTABLE_LOOP_EXIT;
|
||||||
exit->block = cx->fp->down->blockChain;
|
exit->block = cx->fp->down->maybeBlockChain();
|
||||||
exit->pc = downFrame->pc + JSOP_CALL_LENGTH;
|
exit->pc = downFrame->pc + JSOP_CALL_LENGTH;
|
||||||
exit->imacpc = NULL;
|
exit->imacpc = NULL;
|
||||||
exit->sp_adj = ((downPostSlots + 1) * sizeof(double)) - tree->nativeStackBase;
|
exit->sp_adj = ((downPostSlots + 1) * sizeof(double)) - tree->nativeStackBase;
|
||||||
@ -596,7 +596,7 @@ TraceRecorder::slurpDownFrames(jsbytecode* return_pc)
|
|||||||
/* argsobj */
|
/* argsobj */
|
||||||
slurpFrameObjPtrSlot(fp_ins, JSStackFrame::offsetArgsObj(), fp->addressArgsObj(), &info);
|
slurpFrameObjPtrSlot(fp_ins, JSStackFrame::offsetArgsObj(), fp->addressArgsObj(), &info);
|
||||||
/* scopeChain */
|
/* scopeChain */
|
||||||
slurpFrameObjPtrSlot(fp_ins, offsetof(JSStackFrame, scopeChain), &fp->scopeChain, &info);
|
slurpFrameObjPtrSlot(fp_ins, JSStackFrame::offsetScopeChain(), fp->addressScopeChain(), &info);
|
||||||
/* vars */
|
/* vars */
|
||||||
LIns* slots_ins = addName(lir->ins2(LIR_addp, fp_ins, INS_CONSTWORD(sizeof(JSStackFrame))),
|
LIns* slots_ins = addName(lir->ins2(LIR_addp, fp_ins, INS_CONSTWORD(sizeof(JSStackFrame))),
|
||||||
"slots");
|
"slots");
|
||||||
|
@ -1204,7 +1204,7 @@ GlobalSlotHash(JSContext* cx, unsigned slot)
|
|||||||
fp = fp->down;
|
fp = fp->down;
|
||||||
|
|
||||||
HashAccum(h, uintptr_t(fp->script), ORACLE_MASK);
|
HashAccum(h, uintptr_t(fp->script), ORACLE_MASK);
|
||||||
HashAccum(h, uintptr_t(fp->scopeChain->getGlobal()->shape()), ORACLE_MASK);
|
HashAccum(h, uintptr_t(fp->getScopeChain()->getGlobal()->shape()), ORACLE_MASK);
|
||||||
HashAccum(h, uintptr_t(slot), ORACLE_MASK);
|
HashAccum(h, uintptr_t(slot), ORACLE_MASK);
|
||||||
return int(h);
|
return int(h);
|
||||||
}
|
}
|
||||||
@ -1825,7 +1825,7 @@ VisitFrameSlots(Visitor &visitor, JSContext *cx, unsigned depth,
|
|||||||
// requires type |Value|. But the bits are the same, so we can import
|
// 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.
|
// it with a cast and the (identity function) unboxing will be OK.
|
||||||
visitor.setStackSlotKind("scopeChain");
|
visitor.setStackSlotKind("scopeChain");
|
||||||
if (!visitor.visitFrameObjPtr(&fp->scopeChain, fp))
|
if (!visitor.visitFrameObjPtr(fp->addressScopeChain(), fp))
|
||||||
return false;
|
return false;
|
||||||
visitor.setStackSlotKind("var");
|
visitor.setStackSlotKind("var");
|
||||||
if (!visitor.visitStackSlots(fp->slots(), fp->script->nfixed, fp))
|
if (!visitor.visitStackSlots(fp->slots(), fp->script->nfixed, fp))
|
||||||
@ -1877,7 +1877,7 @@ template <typename Visitor>
|
|||||||
static JS_REQUIRES_STACK JS_ALWAYS_INLINE void
|
static JS_REQUIRES_STACK JS_ALWAYS_INLINE void
|
||||||
VisitGlobalSlots(Visitor &visitor, JSContext *cx, SlotList &gslots)
|
VisitGlobalSlots(Visitor &visitor, JSContext *cx, SlotList &gslots)
|
||||||
{
|
{
|
||||||
VisitGlobalSlots(visitor, cx, cx->fp->scopeChain->getGlobal(),
|
VisitGlobalSlots(visitor, cx, cx->fp->getScopeChain()->getGlobal(),
|
||||||
gslots.length(), gslots.data());
|
gslots.length(), gslots.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1896,7 +1896,7 @@ static JS_REQUIRES_STACK JS_ALWAYS_INLINE void
|
|||||||
VisitSlots(Visitor& visitor, JSContext* cx, unsigned callDepth,
|
VisitSlots(Visitor& visitor, JSContext* cx, unsigned callDepth,
|
||||||
unsigned ngslots, uint16* gslots)
|
unsigned ngslots, uint16* gslots)
|
||||||
{
|
{
|
||||||
VisitSlots(visitor, cx, cx->fp->scopeChain->getGlobal(),
|
VisitSlots(visitor, cx, cx->fp->getScopeChain()->getGlobal(),
|
||||||
callDepth, ngslots, gslots);
|
callDepth, ngslots, gslots);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1914,7 +1914,7 @@ static JS_REQUIRES_STACK JS_ALWAYS_INLINE void
|
|||||||
VisitSlots(Visitor &visitor, JSContext *cx, unsigned callDepth,
|
VisitSlots(Visitor &visitor, JSContext *cx, unsigned callDepth,
|
||||||
const SlotList& slots)
|
const SlotList& slots)
|
||||||
{
|
{
|
||||||
VisitSlots(visitor, cx, cx->fp->scopeChain->getGlobal(),
|
VisitSlots(visitor, cx, cx->fp->getScopeChain()->getGlobal(),
|
||||||
callDepth, slots.length(), slots.data());
|
callDepth, slots.length(), slots.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2228,7 +2228,7 @@ TraceRecorder::TraceRecorder(JSContext* cx, VMSideExit* anchor, VMFragment* frag
|
|||||||
globalObj(tree->globalObj),
|
globalObj(tree->globalObj),
|
||||||
outer(outer),
|
outer(outer),
|
||||||
outerArgc(outerArgc),
|
outerArgc(outerArgc),
|
||||||
lexicalBlock(cx->fp->blockChain),
|
lexicalBlock(cx->fp->maybeBlockChain()),
|
||||||
anchor(anchor),
|
anchor(anchor),
|
||||||
lir(NULL),
|
lir(NULL),
|
||||||
cx_ins(NULL),
|
cx_ins(NULL),
|
||||||
@ -2259,7 +2259,7 @@ TraceRecorder::TraceRecorder(JSContext* cx, VMSideExit* anchor, VMFragment* frag
|
|||||||
generatedSpecializedNative(),
|
generatedSpecializedNative(),
|
||||||
tempTypeMap(cx)
|
tempTypeMap(cx)
|
||||||
{
|
{
|
||||||
JS_ASSERT(globalObj == cx->fp->scopeChain->getGlobal());
|
JS_ASSERT(globalObj == cx->fp->getScopeChain()->getGlobal());
|
||||||
JS_ASSERT(globalObj->scope()->hasOwnShape());
|
JS_ASSERT(globalObj->scope()->hasOwnShape());
|
||||||
JS_ASSERT(cx->regs->pc == (jsbytecode*)fragment->ip);
|
JS_ASSERT(cx->regs->pc == (jsbytecode*)fragment->ip);
|
||||||
|
|
||||||
@ -3465,15 +3465,15 @@ FlushNativeStackFrame(JSContext* cx, unsigned callDepth, const JSValueType* mp,
|
|||||||
// Iff these fields are NULL, then |fp| was synthesized on trace exit, so
|
// Iff these fields are NULL, then |fp| was synthesized on trace exit, so
|
||||||
// we need to update the frame fields.
|
// we need to update the frame fields.
|
||||||
if (!fp->hasCallObj())
|
if (!fp->hasCallObj())
|
||||||
fp->setCallObj(fp->scopeChain);
|
fp->setCallObj(fp->getScopeChain());
|
||||||
|
|
||||||
// Iff scope chain's private is NULL, then |fp->scopeChain| was created
|
// 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
|
// 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
|
// 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,
|
// a call object would not occur as the |scopeChain| member of a frame,
|
||||||
// so we cannot be in that case here.)
|
// so we cannot be in that case here.)
|
||||||
if (!fp->scopeChain->getPrivate())
|
if (!fp->getScopeChain()->getPrivate())
|
||||||
fp->scopeChain->setPrivate(fp);
|
fp->getScopeChain()->setPrivate(fp);
|
||||||
}
|
}
|
||||||
fp->thisv = fp->argv[-1];
|
fp->thisv = fp->argv[-1];
|
||||||
}
|
}
|
||||||
@ -3865,7 +3865,7 @@ TraceRecorder::isValidFrameObjPtr(JSObject **p)
|
|||||||
{
|
{
|
||||||
JSStackFrame *fp = cx->fp;
|
JSStackFrame *fp = cx->fp;
|
||||||
for (; fp; fp = fp->down) {
|
for (; fp; fp = fp->down) {
|
||||||
if (&fp->scopeChain == p || fp->addressArgsObj() == p)
|
if (fp->addressScopeChain() == p || fp->addressArgsObj() == p)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -4275,9 +4275,9 @@ TraceRecorder::snapshot(ExitType exitType)
|
|||||||
nativeStackOffset(&cx->fp->argv[-2]) / sizeof(double) :
|
nativeStackOffset(&cx->fp->argv[-2]) / sizeof(double) :
|
||||||
0;
|
0;
|
||||||
exit->exitType = exitType;
|
exit->exitType = exitType;
|
||||||
exit->block = fp->blockChain;
|
exit->block = fp->maybeBlockChain();
|
||||||
if (fp->blockChain)
|
if (fp->hasBlockChain())
|
||||||
tree->gcthings.addUnique(ObjectValue(*fp->blockChain));
|
tree->gcthings.addUnique(ObjectValue(*fp->getBlockChain()));
|
||||||
exit->pc = pc;
|
exit->pc = pc;
|
||||||
exit->imacpc = fp->imacpc;
|
exit->imacpc = fp->imacpc;
|
||||||
exit->sp_adj = (stackSlots * sizeof(double)) - tree->nativeStackBase;
|
exit->sp_adj = (stackSlots * sizeof(double)) - tree->nativeStackBase;
|
||||||
@ -5673,14 +5673,7 @@ SynthesizeFrame(JSContext* cx, const FrameInfo& fi, JSObject* callee)
|
|||||||
cx->regs->sp = sp;
|
cx->regs->sp = sp;
|
||||||
cx->regs->pc = fi.pc;
|
cx->regs->pc = fi.pc;
|
||||||
fp->imacpc = fi.imacpc;
|
fp->imacpc = fi.imacpc;
|
||||||
fp->blockChain = fi.block;
|
fp->setBlockChain(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.
|
* Get pointer to new frame/slots, without changing global state.
|
||||||
@ -5718,9 +5711,9 @@ SynthesizeFrame(JSContext* cx, const FrameInfo& fi, JSObject* callee)
|
|||||||
#endif
|
#endif
|
||||||
newfp->rval = UndefinedValue();
|
newfp->rval = UndefinedValue();
|
||||||
newfp->annotation = NULL;
|
newfp->annotation = NULL;
|
||||||
newfp->scopeChain = NULL; // will be updated in FlushNativeStackFrame
|
newfp->setScopeChain(NULL); // will be updated in FlushNativeStackFrame
|
||||||
newfp->flags = fi.is_constructing() ? JSFRAME_CONSTRUCTING : 0;
|
newfp->flags = fi.is_constructing() ? JSFRAME_CONSTRUCTING : 0;
|
||||||
newfp->blockChain = NULL;
|
newfp->setBlockChain(NULL);
|
||||||
newfp->thisv.setNull(); // will be updated in FlushNativeStackFrame
|
newfp->thisv.setNull(); // will be updated in FlushNativeStackFrame
|
||||||
newfp->imacpc = NULL;
|
newfp->imacpc = NULL;
|
||||||
|
|
||||||
@ -5790,9 +5783,8 @@ SynthesizeSlowNativeFrame(TracerState& state, JSContext *cx, VMSideExit *exit)
|
|||||||
fp->fun = GET_FUNCTION_PRIVATE(cx, fp->callee());
|
fp->fun = GET_FUNCTION_PRIVATE(cx, fp->callee());
|
||||||
fp->rval = UndefinedValue();
|
fp->rval = UndefinedValue();
|
||||||
fp->annotation = NULL;
|
fp->annotation = NULL;
|
||||||
JS_ASSERT(cx->fp->scopeChain);
|
fp->setScopeChain(cx->fp->maybeScopeChain());
|
||||||
fp->scopeChain = cx->fp->scopeChain;
|
fp->setBlockChain(NULL);
|
||||||
fp->blockChain = NULL;
|
|
||||||
fp->flags = exit->constructing() ? JSFRAME_CONSTRUCTING : 0;
|
fp->flags = exit->constructing() ? JSFRAME_CONSTRUCTING : 0;
|
||||||
|
|
||||||
state.bailedSlowNativeRegs = *cx->regs;
|
state.bailedSlowNativeRegs = *cx->regs;
|
||||||
@ -6136,7 +6128,7 @@ JS_REQUIRES_STACK MonitorResult
|
|||||||
TraceRecorder::recordLoopEdge(JSContext* cx, TraceRecorder* r, uintN& inlineCallCount)
|
TraceRecorder::recordLoopEdge(JSContext* cx, TraceRecorder* r, uintN& inlineCallCount)
|
||||||
{
|
{
|
||||||
#ifdef JS_THREADSAFE
|
#ifdef JS_THREADSAFE
|
||||||
if (cx->fp->scopeChain->getGlobal()->scope()->title.ownercx != cx) {
|
if (cx->fp->getScopeChain()->getGlobal()->scope()->title.ownercx != cx) {
|
||||||
AbortRecording(cx, "Global object not owned by this context");
|
AbortRecording(cx, "Global object not owned by this context");
|
||||||
return MONITOR_NOT_RECORDING; /* we stay away from shared global objects */
|
return MONITOR_NOT_RECORDING; /* we stay away from shared global objects */
|
||||||
}
|
}
|
||||||
@ -6159,7 +6151,7 @@ TraceRecorder::recordLoopEdge(JSContext* cx, TraceRecorder* r, uintN& inlineCall
|
|||||||
* Make sure the shape of the global object still matches (this might flush
|
* Make sure the shape of the global object still matches (this might flush
|
||||||
* the JIT cache).
|
* the JIT cache).
|
||||||
*/
|
*/
|
||||||
JSObject* globalObj = cx->fp->scopeChain->getGlobal();
|
JSObject* globalObj = cx->fp->getScopeChain()->getGlobal();
|
||||||
uint32 globalShape = -1;
|
uint32 globalShape = -1;
|
||||||
SlotList* globalSlots = NULL;
|
SlotList* globalSlots = NULL;
|
||||||
if (!CheckGlobalObjectShape(cx, tm, globalObj, &globalShape, &globalSlots)) {
|
if (!CheckGlobalObjectShape(cx, tm, globalObj, &globalShape, &globalSlots)) {
|
||||||
@ -6665,7 +6657,7 @@ ExecuteTrace(JSContext* cx, Fragment* f, TracerState& state)
|
|||||||
static JS_REQUIRES_STACK JS_ALWAYS_INLINE bool
|
static JS_REQUIRES_STACK JS_ALWAYS_INLINE bool
|
||||||
ScopeChainCheck(JSContext* cx, TreeFragment* f)
|
ScopeChainCheck(JSContext* cx, TreeFragment* f)
|
||||||
{
|
{
|
||||||
JS_ASSERT(f->globalObj == cx->fp->scopeChain->getGlobal());
|
JS_ASSERT(f->globalObj == cx->fp->getScopeChain()->getGlobal());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The JIT records and expects to execute with two scope-chain
|
* The JIT records and expects to execute with two scope-chain
|
||||||
@ -6683,7 +6675,7 @@ ScopeChainCheck(JSContext* cx, TreeFragment* f)
|
|||||||
* class types; once a global is found, it's checked for #1. Failing
|
* class types; once a global is found, it's checked for #1. Failing
|
||||||
* either check causes an early return from execution.
|
* either check causes an early return from execution.
|
||||||
*/
|
*/
|
||||||
JSObject* child = cx->fp->scopeChain;
|
JSObject* child = cx->fp->getScopeChain();
|
||||||
while (JSObject* parent = child->getParent()) {
|
while (JSObject* parent = child->getParent()) {
|
||||||
if (!js_IsCacheableNonGlobalScope(child)) {
|
if (!js_IsCacheableNonGlobalScope(child)) {
|
||||||
debug_only_print0(LC_TMTracer,"Blacklist: non-cacheable object on scope chain.\n");
|
debug_only_print0(LC_TMTracer,"Blacklist: non-cacheable object on scope chain.\n");
|
||||||
@ -7021,7 +7013,7 @@ LeaveTree(TraceMonitor *tm, TracerState& state, VMSideExit* lr)
|
|||||||
*/
|
*/
|
||||||
JSStackFrame* const fp = cx->fp;
|
JSStackFrame* const fp = cx->fp;
|
||||||
|
|
||||||
fp->blockChain = innermost->block;
|
fp->setBlockChain(innermost->block);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we are not exiting from an inlined frame, the state->sp is spbase.
|
* If we are not exiting from an inlined frame, the state->sp is spbase.
|
||||||
@ -7184,7 +7176,7 @@ MonitorLoopEdge(JSContext* cx, uintN& inlineCallCount, RecordReason reason)
|
|||||||
* Make sure the shape of the global object still matches (this might flush
|
* Make sure the shape of the global object still matches (this might flush
|
||||||
* the JIT cache).
|
* the JIT cache).
|
||||||
*/
|
*/
|
||||||
JSObject* globalObj = cx->fp->scopeChain->getGlobal();
|
JSObject* globalObj = cx->fp->getScopeChain()->getGlobal();
|
||||||
uint32 globalShape = -1;
|
uint32 globalShape = -1;
|
||||||
SlotList* globalSlots = NULL;
|
SlotList* globalSlots = NULL;
|
||||||
|
|
||||||
@ -8103,7 +8095,7 @@ JS_REQUIRES_STACK LIns*
|
|||||||
TraceRecorder::scopeChain()
|
TraceRecorder::scopeChain()
|
||||||
{
|
{
|
||||||
return cx->fp->callee()
|
return cx->fp->callee()
|
||||||
? getFrameObjPtr(&cx->fp->scopeChain)
|
? getFrameObjPtr(cx->fp->addressScopeChain())
|
||||||
: entryScopeChain();
|
: entryScopeChain();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8117,7 +8109,7 @@ TraceRecorder::entryScopeChain() const
|
|||||||
{
|
{
|
||||||
return lir->insLoad(LIR_ldp,
|
return lir->insLoad(LIR_ldp,
|
||||||
lir->insLoad(LIR_ldp, cx_ins, offsetof(JSContext, fp), ACCSET_OTHER),
|
lir->insLoad(LIR_ldp, cx_ins, offsetof(JSContext, fp), ACCSET_OTHER),
|
||||||
offsetof(JSStackFrame, scopeChain), ACCSET_OTHER);
|
JSStackFrame::offsetScopeChain(), ACCSET_OTHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -8159,7 +8151,7 @@ JS_DEFINE_CALLINFO_4(extern, UINT32, GetClosureArg, CONTEXT, OBJECT, CVIPTR, DOU
|
|||||||
JS_REQUIRES_STACK AbortableRecordingStatus
|
JS_REQUIRES_STACK AbortableRecordingStatus
|
||||||
TraceRecorder::scopeChainProp(JSObject* chainHead, Value*& vp, LIns*& ins, NameResult& nr)
|
TraceRecorder::scopeChainProp(JSObject* chainHead, Value*& vp, LIns*& ins, NameResult& nr)
|
||||||
{
|
{
|
||||||
JS_ASSERT(chainHead == cx->fp->scopeChain);
|
JS_ASSERT(chainHead == cx->fp->getScopeChain());
|
||||||
JS_ASSERT(chainHead != globalObj);
|
JS_ASSERT(chainHead != globalObj);
|
||||||
|
|
||||||
TraceMonitor &localtm = *traceMonitor;
|
TraceMonitor &localtm = *traceMonitor;
|
||||||
@ -10258,7 +10250,7 @@ TraceRecorder::clearFrameSlotsFromTracker(Tracker& which, JSStackFrame* fp, unsi
|
|||||||
while (vp < vpstop)
|
while (vp < vpstop)
|
||||||
which.set(vp++, (LIns*)0);
|
which.set(vp++, (LIns*)0);
|
||||||
which.set(fp->addressArgsObj(), (LIns*)0);
|
which.set(fp->addressArgsObj(), (LIns*)0);
|
||||||
which.set(&fp->scopeChain, (LIns*)0);
|
which.set(fp->addressScopeChain(), (LIns*)0);
|
||||||
}
|
}
|
||||||
vp = &fp->slots()[0];
|
vp = &fp->slots()[0];
|
||||||
vpstop = &fp->slots()[nslots];
|
vpstop = &fp->slots()[nslots];
|
||||||
@ -10337,7 +10329,7 @@ TraceRecorder::putActivationObjects()
|
|||||||
slots_ins = INS_CONSTPTR(0);
|
slots_ins = INS_CONSTPTR(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
LIns* scopeChain_ins = getFrameObjPtr(&cx->fp->scopeChain);
|
LIns* scopeChain_ins = getFrameObjPtr(cx->fp->addressScopeChain());
|
||||||
LIns* args[] = { slots_ins, INS_CONST(nslots), args_ins,
|
LIns* args[] = { slots_ins, INS_CONST(nslots), args_ins,
|
||||||
INS_CONST(cx->fp->fun->nargs), scopeChain_ins, cx_ins };
|
INS_CONST(cx->fp->fun->nargs), scopeChain_ins, cx_ins };
|
||||||
lir->insCall(&js_PutCallObjectOnTrace_ci, args);
|
lir->insCall(&js_PutCallObjectOnTrace_ci, args);
|
||||||
@ -10361,7 +10353,7 @@ IsTraceableRecursion(JSContext *cx)
|
|||||||
return false;
|
return false;
|
||||||
if ((fp->flags & JSFRAME_CONSTRUCTING) || (down->flags & JSFRAME_CONSTRUCTING))
|
if ((fp->flags & JSFRAME_CONSTRUCTING) || (down->flags & JSFRAME_CONSTRUCTING))
|
||||||
return false;
|
return false;
|
||||||
if (fp->blockChain || down->blockChain)
|
if (fp->hasBlockChain() || down->hasBlockChain())
|
||||||
return false;
|
return false;
|
||||||
if (*fp->script->code != JSOP_TRACE)
|
if (*fp->script->code != JSOP_TRACE)
|
||||||
return false;
|
return false;
|
||||||
@ -10409,7 +10401,7 @@ TraceRecorder::record_EnterFrame(uintN& inlineCallCount)
|
|||||||
|
|
||||||
nativeFrameTracker.set(fp->addressArgsObj(), NULL);
|
nativeFrameTracker.set(fp->addressArgsObj(), NULL);
|
||||||
setFrameObjPtr(fp->addressArgsObj(), INS_NULL());
|
setFrameObjPtr(fp->addressArgsObj(), INS_NULL());
|
||||||
nativeFrameTracker.set(&fp->scopeChain, NULL);
|
nativeFrameTracker.set(fp->addressScopeChain(), NULL);
|
||||||
|
|
||||||
vp = fp->slots();
|
vp = fp->slots();
|
||||||
vpstop = vp + fp->script->nfixed;
|
vpstop = vp + fp->script->nfixed;
|
||||||
@ -10429,7 +10421,7 @@ TraceRecorder::record_EnterFrame(uintN& inlineCallCount)
|
|||||||
if (cx->fp->fun && JSFUN_HEAVYWEIGHT_TEST(cx->fp->fun->flags)) {
|
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
|
// We need to make sure every part of the frame is known to the tracker
|
||||||
// before taking a snapshot.
|
// before taking a snapshot.
|
||||||
setFrameObjPtr(&fp->scopeChain, INS_NULL());
|
setFrameObjPtr(fp->addressScopeChain(), INS_NULL());
|
||||||
|
|
||||||
if (js_IsNamedLambda(cx->fp->fun))
|
if (js_IsNamedLambda(cx->fp->fun))
|
||||||
RETURN_STOP_A("can't call named lambda heavyweight on trace");
|
RETURN_STOP_A("can't call named lambda heavyweight on trace");
|
||||||
@ -10440,9 +10432,9 @@ TraceRecorder::record_EnterFrame(uintN& inlineCallCount)
|
|||||||
LIns* call_ins = lir->insCall(&js_CreateCallObjectOnTrace_ci, args);
|
LIns* call_ins = lir->insCall(&js_CreateCallObjectOnTrace_ci, args);
|
||||||
guard(false, lir->insEqP_0(call_ins), snapshot(OOM_EXIT));
|
guard(false, lir->insEqP_0(call_ins), snapshot(OOM_EXIT));
|
||||||
|
|
||||||
setFrameObjPtr(&fp->scopeChain, call_ins);
|
setFrameObjPtr(fp->addressScopeChain(), call_ins);
|
||||||
} else {
|
} else {
|
||||||
setFrameObjPtr(&fp->scopeChain, scopeChain_ins);
|
setFrameObjPtr(fp->addressScopeChain(), scopeChain_ins);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -10501,7 +10493,7 @@ TraceRecorder::record_EnterFrame(uintN& inlineCallCount)
|
|||||||
* Make sure the shape of the global object still matches (this might
|
* Make sure the shape of the global object still matches (this might
|
||||||
* flush the JIT cache).
|
* flush the JIT cache).
|
||||||
*/
|
*/
|
||||||
JSObject* globalObj = cx->fp->scopeChain->getGlobal();
|
JSObject* globalObj = cx->fp->getScopeChain()->getGlobal();
|
||||||
uint32 globalShape = -1;
|
uint32 globalShape = -1;
|
||||||
SlotList* globalSlots = NULL;
|
SlotList* globalSlots = NULL;
|
||||||
if (!CheckGlobalObjectShape(cx, traceMonitor, globalObj, &globalShape, &globalSlots))
|
if (!CheckGlobalObjectShape(cx, traceMonitor, globalObj, &globalShape, &globalSlots))
|
||||||
@ -13107,7 +13099,7 @@ TraceRecorder::record_JSOP_SETELEM()
|
|||||||
JS_REQUIRES_STACK AbortableRecordingStatus
|
JS_REQUIRES_STACK AbortableRecordingStatus
|
||||||
TraceRecorder::record_JSOP_CALLNAME()
|
TraceRecorder::record_JSOP_CALLNAME()
|
||||||
{
|
{
|
||||||
JSObject* obj = cx->fp->scopeChain;
|
JSObject* obj = cx->fp->getScopeChain();
|
||||||
if (obj != globalObj) {
|
if (obj != globalObj) {
|
||||||
Value* vp;
|
Value* vp;
|
||||||
LIns* ins;
|
LIns* ins;
|
||||||
@ -13403,9 +13395,9 @@ TraceRecorder::interpretedFunctionCall(Value& fval, JSFunction* fun, uintN argc,
|
|||||||
JS_ASSERT(argc < FrameInfo::CONSTRUCTING_FLAG);
|
JS_ASSERT(argc < FrameInfo::CONSTRUCTING_FLAG);
|
||||||
|
|
||||||
tree->gcthings.addUnique(fval);
|
tree->gcthings.addUnique(fval);
|
||||||
fi->block = fp->blockChain;
|
fi->block = fp->maybeBlockChain();
|
||||||
if (fp->blockChain)
|
if (fp->hasBlockChain())
|
||||||
tree->gcthings.addUnique(ObjectValue(*fp->blockChain));
|
tree->gcthings.addUnique(ObjectValue(*fp->getBlockChain()));
|
||||||
fi->pc = cx->regs->pc;
|
fi->pc = cx->regs->pc;
|
||||||
fi->imacpc = fp->imacpc;
|
fi->imacpc = fp->imacpc;
|
||||||
fi->spdist = cx->regs->sp - fp->slots();
|
fi->spdist = cx->regs->sp - fp->slots();
|
||||||
@ -13649,7 +13641,7 @@ TraceRecorder::record_NativeCallComplete()
|
|||||||
JS_REQUIRES_STACK AbortableRecordingStatus
|
JS_REQUIRES_STACK AbortableRecordingStatus
|
||||||
TraceRecorder::name(Value*& vp, LIns*& ins, NameResult& nr)
|
TraceRecorder::name(Value*& vp, LIns*& ins, NameResult& nr)
|
||||||
{
|
{
|
||||||
JSObject* obj = cx->fp->scopeChain;
|
JSObject* obj = cx->fp->getScopeChain();
|
||||||
JSOp op = JSOp(*cx->regs->pc);
|
JSOp op = JSOp(*cx->regs->pc);
|
||||||
if (js_CodeSpec[op].format & JOF_GNAME)
|
if (js_CodeSpec[op].format & JOF_GNAME)
|
||||||
obj = obj->getGlobal();
|
obj = obj->getGlobal();
|
||||||
@ -14769,7 +14761,7 @@ TraceRecorder::record_JSOP_BINDNAME()
|
|||||||
JSObject *obj;
|
JSObject *obj;
|
||||||
|
|
||||||
if (!fp->fun) {
|
if (!fp->fun) {
|
||||||
obj = fp->scopeChain;
|
obj = fp->getScopeChain();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
JSStackFrame *fp2 = fp;
|
JSStackFrame *fp2 = fp;
|
||||||
@ -14830,7 +14822,7 @@ TraceRecorder::record_JSOP_BINDNAME()
|
|||||||
JSAtom *atom = atoms[GET_INDEX(cx->regs->pc)];
|
JSAtom *atom = atoms[GET_INDEX(cx->regs->pc)];
|
||||||
jsid id = ATOM_TO_JSID(atom);
|
jsid id = ATOM_TO_JSID(atom);
|
||||||
JSContext *localCx = cx;
|
JSContext *localCx = cx;
|
||||||
JSObject *obj2 = js_FindIdentifierBase(cx, fp->scopeChain, id);
|
JSObject *obj2 = js_FindIdentifierBase(cx, fp->getScopeChain(), id);
|
||||||
if (!obj2)
|
if (!obj2)
|
||||||
RETURN_ERROR_A("error in js_FindIdentifierBase");
|
RETURN_ERROR_A("error in js_FindIdentifierBase");
|
||||||
if (!TRACE_RECORDER(localCx))
|
if (!TRACE_RECORDER(localCx))
|
||||||
@ -15803,7 +15795,7 @@ JS_REQUIRES_STACK AbortableRecordingStatus
|
|||||||
TraceRecorder::record_JSOP_LEAVEBLOCK()
|
TraceRecorder::record_JSOP_LEAVEBLOCK()
|
||||||
{
|
{
|
||||||
/* We mustn't exit the lexical block we began recording in. */
|
/* We mustn't exit the lexical block we began recording in. */
|
||||||
if (cx->fp->blockChain == lexicalBlock)
|
if (cx->fp->getBlockChain() == lexicalBlock)
|
||||||
return ARECORD_STOP;
|
return ARECORD_STOP;
|
||||||
return ARECORD_CONTINUE;
|
return ARECORD_CONTINUE;
|
||||||
}
|
}
|
||||||
|
@ -387,7 +387,7 @@ JSCompartment::wrap(JSContext *cx, Value *vp)
|
|||||||
* we parent all wrappers to the global object in their home compartment.
|
* we parent all wrappers to the global object in their home compartment.
|
||||||
* This loses us some transparency, and is generally very cheesy.
|
* This loses us some transparency, and is generally very cheesy.
|
||||||
*/
|
*/
|
||||||
JSObject *global = cx->fp ? cx->fp->scopeChain->getGlobal() : cx->globalObject;
|
JSObject *global = cx->fp ? cx->fp->getScopeChain()->getGlobal() : cx->globalObject;
|
||||||
wrapper->setParent(global);
|
wrapper->setParent(global);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -515,7 +515,7 @@ SetupFakeFrame(JSContext *cx, ExecuteFrameGuard &frame, JSFrameRegs ®s, JSObj
|
|||||||
JSStackFrame *fp = frame.getFrame();
|
JSStackFrame *fp = frame.getFrame();
|
||||||
PodZero(fp); // fp->fun and fp->script are both NULL
|
PodZero(fp); // fp->fun and fp->script are both NULL
|
||||||
fp->argv = vp + 2;
|
fp->argv = vp + 2;
|
||||||
fp->scopeChain = obj->getGlobal();
|
fp->setScopeChain(obj->getGlobal());
|
||||||
fp->flags = JSFRAME_DUMMY;
|
fp->flags = JSFRAME_DUMMY;
|
||||||
|
|
||||||
regs.pc = NULL;
|
regs.pc = NULL;
|
||||||
|
@ -1735,7 +1735,7 @@ ParseXMLSource(JSContext *cx, JSString *src)
|
|||||||
{
|
{
|
||||||
Parser parser(cx);
|
Parser parser(cx);
|
||||||
if (parser.init(chars, length, NULL, filename, lineno)) {
|
if (parser.init(chars, length, NULL, filename, lineno)) {
|
||||||
JSObject *scopeChain = js_GetTopStackFrame(cx)->scopeChain;
|
JSObject *scopeChain = js_GetTopStackFrame(cx)->getScopeChain();
|
||||||
JSParseNode *pn = parser.parseXMLText(scopeChain, false);
|
JSParseNode *pn = parser.parseXMLText(scopeChain, false);
|
||||||
uintN flags;
|
uintN flags;
|
||||||
if (pn && GetXMLSettingFlags(cx, &flags)) {
|
if (pn && GetXMLSettingFlags(cx, &flags)) {
|
||||||
@ -7227,7 +7227,7 @@ js_GetDefaultXMLNamespace(JSContext *cx, jsval *vp)
|
|||||||
fp = js_GetTopStackFrame(cx);
|
fp = js_GetTopStackFrame(cx);
|
||||||
|
|
||||||
obj = NULL;
|
obj = NULL;
|
||||||
for (tmp = fp->scopeChain; tmp; tmp = tmp->getParent()) {
|
for (tmp = fp->getScopeChain(); tmp; tmp = tmp->getParent()) {
|
||||||
Class *clasp = tmp->getClass();
|
Class *clasp = tmp->getClass();
|
||||||
if (clasp == &js_BlockClass || clasp == &js_WithClass)
|
if (clasp == &js_BlockClass || clasp == &js_WithClass)
|
||||||
continue;
|
continue;
|
||||||
@ -7440,7 +7440,7 @@ js_FindXMLProperty(JSContext *cx, const Value &nameval, JSObject **objp, jsid *i
|
|||||||
if (!IsFunctionQName(cx, qn, &funid))
|
if (!IsFunctionQName(cx, qn, &funid))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
|
|
||||||
obj = js_GetTopStackFrame(cx)->scopeChain;
|
obj = js_GetTopStackFrame(cx)->getScopeChain();
|
||||||
do {
|
do {
|
||||||
/* Skip any With object that can wrap XML. */
|
/* Skip any With object that can wrap XML. */
|
||||||
target = obj;
|
target = obj;
|
||||||
|
Loading…
Reference in New Issue
Block a user