Bug 746843 - change StackFrame::scopeChain() to return a HandleObject (r=bhackett)

--HG--
extra : rebase_source : 8306a740d784a6f8cb7d8160125fb37e3270a64e
This commit is contained in:
Luke Wagner 2012-04-13 18:06:40 -07:00
parent 955934c3d9
commit 3df006c487
25 changed files with 111 additions and 95 deletions

View File

@ -115,6 +115,16 @@ class Handle
ptr = reinterpret_cast<const T *>(handle.address());
}
/*
* Get a handle to a location that may not be a Root or RootedVar, but is
* marked and updated by the GC.
*/
static Handle fromMarkedLocation(const T *p) {
Handle h;
h.ptr = p;
return h;
}
/* Get a handle from a rooted stack location, with implicit coercion. */
template <typename S> inline Handle(const Root<S> &root);
template <typename S> inline Handle(const RootedVar<S> &root);
@ -125,6 +135,8 @@ class Handle
T operator ->() { return value(); }
private:
Handle() {}
const T *ptr;
T value() { return *ptr; }

View File

@ -1386,7 +1386,7 @@ JS_EnterCrossCompartmentCallStackFrame(JSContext *cx, JSStackFrame *target)
AssertNoGC(cx);
CHECK_REQUEST(cx);
return JS_EnterCrossCompartmentCall(cx, &Valueify(target)->scopeChain().global());
return JS_EnterCrossCompartmentCall(cx, &Valueify(target)->global());
}
JS_PUBLIC_API(void)
@ -1452,7 +1452,7 @@ bool
AutoEnterFrameCompartment::enter(JSContext *cx, JSStackFrame *target)
{
JS_ASSERT(!call);
if (cx->compartment == Valueify(target)->scopeChain().compartment()) {
if (cx->compartment == Valueify(target)->scopeChain()->compartment()) {
call = reinterpret_cast<JSCrossCompartmentCall*>(1);
return true;
}
@ -4539,7 +4539,7 @@ JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent_)
if (!parent) {
if (cx->hasfp())
parent = &cx->fp()->scopeChain();
parent = cx->fp()->scopeChain();
if (!parent)
parent = cx->globalObject;
JS_ASSERT(parent);

View File

@ -995,7 +995,7 @@ JSContext::resetCompartment()
{
JSObject *scopeobj;
if (stack.hasfp()) {
scopeobj = &fp()->scopeChain();
scopeobj = fp()->scopeChain();
} else {
scopeobj = globalObject;
if (!scopeobj)

View File

@ -76,7 +76,7 @@ static inline GlobalObject *
GetGlobalForScopeChain(JSContext *cx)
{
if (cx->hasfp())
return &cx->fp()->scopeChain().global();
return &cx->fp()->global();
JSObject *scope = JS_ObjectToInnerObject(cx, cx->globalObject);
if (!scope)
@ -231,7 +231,7 @@ class CompartmentChecker
void check(StackFrame *fp) {
if (fp)
check(&fp->scopeChain());
check(fp->scopeChain());
}
};

View File

@ -212,7 +212,7 @@ JSCompartment::wrap(JSContext *cx, Value *vp)
*/
JSObject *global;
if (cx->hasfp()) {
global = &cx->fp()->scopeChain().global();
global = &cx->fp()->global();
} else {
global = JS_ObjectToInnerObject(cx, cx->globalObject);
if (!global)

View File

@ -523,7 +523,7 @@ JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fpArg)
{
StackFrame *fp = Valueify(fpArg);
if (fp->annotation() && fp->isScriptFrame()) {
JSPrincipals *principals = fp->scopeChain().principals(cx);
JSPrincipals *principals = fp->scopeChain()->principals(cx);
if (principals) {
/*
@ -555,7 +555,7 @@ JS_GetFrameScopeChain(JSContext *cx, JSStackFrame *fpArg)
StackFrame *fp = Valueify(fpArg);
JS_ASSERT(cx->stack.containsSlow(fp));
js::AutoCompartment ac(cx, &fp->scopeChain());
js::AutoCompartment ac(cx, fp->scopeChain());
if (!ac.enter())
return NULL;
@ -576,7 +576,7 @@ JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fpArg)
if (!fp->isFunctionFrame())
return NULL;
js::AutoCompartment ac(cx, &fp->scopeChain());
js::AutoCompartment ac(cx, fp->scopeChain());
if (!ac.enter())
return NULL;
@ -596,7 +596,7 @@ JS_GetFrameThis(JSContext *cx, JSStackFrame *fpArg, jsval *thisv)
if (fp->isDummyFrame())
return false;
js::AutoCompartment ac(cx, &fp->scopeChain());
js::AutoCompartment ac(cx, fp->scopeChain());
if (!ac.enter())
return false;

View File

@ -98,7 +98,7 @@ JS_GetObjectFunction(JSObject *obj)
JS_FRIEND_API(JSObject *)
JS_GetGlobalForFrame(JSStackFrame *fp)
{
return &Valueify(fp)->scopeChain().global();
return &Valueify(fp)->global();
}
JS_FRIEND_API(JSBool)

View File

@ -5185,7 +5185,7 @@ NestingPrologue(JSContext *cx, StackFrame *fp)
TypeScriptNesting *nesting = script->nesting();
if (nesting->parent)
CheckNestingParent(cx, &fp->scopeChain(), script);
CheckNestingParent(cx, fp->scopeChain(), script);
if (script->isOuterFunction) {
/*

View File

@ -150,7 +150,7 @@ js::GetScopeChain(JSContext *cx, StackFrame *fp)
*/
JS_ASSERT_IF(fp->isNonEvalFunctionFrame() && fp->fun()->isHeavyweight(),
fp->hasCallObj());
return &fp->scopeChain();
return fp->scopeChain();
}
/*
@ -162,7 +162,7 @@ js::GetScopeChain(JSContext *cx, StackFrame *fp)
*/
JSObject *limitBlock, *limitClone;
if (fp->isNonEvalFunctionFrame() && !fp->hasCallObj()) {
JS_ASSERT_IF(fp->scopeChain().isClonedBlock(), fp->scopeChain().getPrivate() != fp);
JS_ASSERT_IF(fp->scopeChain()->isClonedBlock(), fp->scopeChain()->getPrivate() != fp);
if (!CallObject::createForFunction(cx, fp))
return NULL;
@ -175,7 +175,7 @@ js::GetScopeChain(JSContext *cx, StackFrame *fp)
* prototype should appear on blockChain; we'll clone blockChain up
* to, but not including, that prototype.
*/
limitClone = &fp->scopeChain();
limitClone = fp->scopeChain();
while (limitClone->isWith())
limitClone = &limitClone->asWith().enclosingScope();
JS_ASSERT(limitClone);
@ -202,7 +202,7 @@ js::GetScopeChain(JSContext *cx, StackFrame *fp)
/* If the innermost block has already been cloned, we are done. */
if (limitBlock == sharedBlock)
return &fp->scopeChain();
return fp->scopeChain();
}
/*
@ -238,7 +238,7 @@ js::GetScopeChain(JSContext *cx, StackFrame *fp)
return NULL;
newChild = clone;
}
if (!newChild->setEnclosingScope(cx, RootedVarObject(cx, &fp->scopeChain())))
if (!newChild->setEnclosingScope(cx, fp->scopeChain()))
return NULL;
/*
@ -440,7 +440,7 @@ js::RunScript(JSContext *cx, JSScript *script, StackFrame *fp)
/* FIXME: Once bug 470510 is fixed, make this an assert. */
if (script->compileAndGo) {
if (fp->scopeChain().global().isCleared()) {
if (fp->global().isCleared()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CLEARED_SCOPE);
return false;
}
@ -953,7 +953,7 @@ EnterWith(JSContext *cx, int stackIndex)
static void
LeaveWith(JSContext *cx)
{
WithObject &withobj = cx->fp()->scopeChain().asWith();
WithObject &withobj = cx->fp()->scopeChain()->asWith();
JS_ASSERT(withobj.maybeStackFrame() == js_FloatingFrameIfGenerator(cx, cx->fp()));
withobj.setStackFrame(NULL);
cx->fp()->setScopeChainNoCallObj(withobj.enclosingScope());
@ -983,7 +983,7 @@ js::UnwindScope(JSContext *cx, uint32_t stackDepth)
fp->setBlockChain(block);
for (;;) {
JSObject &scopeChain = fp->scopeChain();
JSObject &scopeChain = *fp->scopeChain();
if (!IsActiveWithOrBlock(cx, scopeChain, stackDepth))
break;
if (scopeChain.isClonedBlock())
@ -1847,7 +1847,7 @@ BEGIN_CASE(JSOP_POPN)
JS_ASSERT_IF(block,
block->stackDepth() + block->slotCount()
<= (size_t) (regs.sp - regs.fp()->base()));
for (JSObject *obj = &regs.fp()->scopeChain(); obj; obj = obj->enclosingScope()) {
for (JSObject *obj = regs.fp()->scopeChain(); obj; obj = obj->enclosingScope()) {
if (!obj->isBlock() || !obj->isWith())
continue;
if (obj->getPrivate() != js_FloatingFrameIfGenerator(cx, regs.fp()))
@ -1878,11 +1878,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(regs.fp()->scopeChain());
regs.sp[-1].setObject(*regs.fp()->scopeChain());
END_CASE(JSOP_ENTERWITH)
BEGIN_CASE(JSOP_LEAVEWITH)
JS_ASSERT(regs.sp[-1].toObject() == regs.fp()->scopeChain());
JS_ASSERT(regs.sp[-1].toObject() == *regs.fp()->scopeChain());
regs.sp--;
LeaveWith(cx);
END_CASE(JSOP_LEAVEWITH)
@ -1905,7 +1905,7 @@ BEGIN_CASE(JSOP_STOP)
inline_return:
{
JS_ASSERT(!regs.fp()->hasBlockChain());
JS_ASSERT(!IsActiveWithOrBlock(cx, regs.fp()->scopeChain(), 0));
JS_ASSERT(!IsActiveWithOrBlock(cx, *regs.fp()->scopeChain(), 0));
if (cx->compartment->debugMode())
interpReturnOK = ScriptDebugEpilogue(cx, regs.fp(), interpReturnOK);
@ -2179,7 +2179,7 @@ END_CASE(JSOP_ENUMCONSTELEM)
#endif
BEGIN_CASE(JSOP_BINDGNAME)
PUSH_OBJECT(regs.fp()->scopeChain().global());
PUSH_OBJECT(regs.fp()->global());
END_CASE(JSOP_BINDGNAME)
BEGIN_CASE(JSOP_BINDNAME)
@ -2202,14 +2202,14 @@ BEGIN_CASE(JSOP_BINDNAME)
* the rhs. We desire such resolve hook equivalence between the two
* forms.
*/
obj = &regs.fp()->scopeChain();
obj = regs.fp()->scopeChain();
if (obj->isGlobal())
break;
PropertyName *name;
LOAD_NAME(0, name);
obj = FindIdentifierBase(cx, &regs.fp()->scopeChain(), name);
obj = FindIdentifierBase(cx, regs.fp()->scopeChain(), name);
if (!obj)
goto error;
} while (0);
@ -2719,7 +2719,7 @@ END_CASE(JSOP_ENUMELEM)
BEGIN_CASE(JSOP_EVAL)
{
CallArgs args = CallArgsFromSp(GET_ARGC(regs.pc), regs.sp);
if (IsBuiltinEvalForScope(&regs.fp()->scopeChain(), args.calleev())) {
if (IsBuiltinEvalForScope(regs.fp()->scopeChain(), args.calleev())) {
if (!DirectEval(cx, args))
goto error;
} else {
@ -2921,7 +2921,7 @@ BEGIN_CASE(JSOP_REGEXP)
* bytecode at pc.
*/
uint32_t index = GET_UINT32_INDEX(regs.pc);
JSObject *proto = regs.fp()->scopeChain().global().getOrCreateRegExpPrototype(cx);
JSObject *proto = regs.fp()->global().getOrCreateRegExpPrototype(cx);
if (!proto)
goto error;
JSObject *obj = CloneRegExpObject(cx, script->getRegExp(index), proto);
@ -3168,7 +3168,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 = &regs.fp()->scopeChain();
obj2 = regs.fp()->scopeChain();
} else {
obj2 = GetScopeChain(cx, regs.fp());
if (!obj2)
@ -3274,7 +3274,7 @@ BEGIN_CASE(JSOP_LAMBDA)
do {
RootedVarObject &parent = rootObject0;
if (fun->isNullClosure()) {
parent = &regs.fp()->scopeChain();
parent = regs.fp()->scopeChain();
} else {
parent = GetScopeChain(cx, regs.fp());
if (!parent)
@ -3948,7 +3948,7 @@ BEGIN_CASE(JSOP_GETFUNNS)
JS_ASSERT(!script->strictModeCode);
Value rval;
if (!cx->fp()->scopeChain().global().getFunctionNamespace(cx, &rval))
if (!cx->fp()->global().getFunctionNamespace(cx, &rval))
goto error;
PUSH_COPY(rval);
}
@ -3987,7 +3987,7 @@ BEGIN_CASE(JSOP_ENTERLET1)
* anything else we should have popped off fp->scopeChain when we left its
* static scope.
*/
JSObject *obj2 = &regs.fp()->scopeChain();
JSObject *obj2 = regs.fp()->scopeChain();
while (obj2->isWith())
obj2 = &obj2->asWith().enclosingScope();
if (obj2->isBlock() &&
@ -4016,7 +4016,7 @@ BEGIN_CASE(JSOP_LEAVEBLOCKEXPR)
* cloned onto fp->scopeChain, clear its private data, move its locals from
* the stack into the clone, and pop it off the chain.
*/
JSObject &scope = regs.fp()->scopeChain();
JSObject &scope = *regs.fp()->scopeChain();
if (scope.getProto() == &blockObj)
scope.asClonedBlock().put(cx);
@ -4280,7 +4280,7 @@ END_CASE(JSOP_ARRAYPUSH)
*/
JS_ASSERT(entryFrame == regs.fp());
if (!regs.fp()->isGeneratorFrame()) {
JS_ASSERT(!IsActiveWithOrBlock(cx, regs.fp()->scopeChain(), 0));
JS_ASSERT(!IsActiveWithOrBlock(cx, *regs.fp()->scopeChain(), 0));
JS_ASSERT(!regs.fp()->hasBlockChain());
}

View File

@ -143,7 +143,7 @@ ValuePropertyBearer(JSContext *cx, StackFrame *fp, const Value &v, int spindex)
if (v.isObject())
return &v.toObject();
GlobalObject &global = fp->scopeChain().global();
GlobalObject &global = fp->global();
if (v.isString())
return global.getOrCreateStringPrototype(cx);
@ -288,7 +288,7 @@ SetPropertyOperation(JSContext *cx, jsbytecode *pc, const Value &lval, const Val
return false;
JS_ASSERT_IF(*pc == JSOP_SETNAME || *pc == JSOP_SETGNAME, lval.isObject());
JS_ASSERT_IF(*pc == JSOP_SETGNAME, obj == &cx->fp()->scopeChain().global());
JS_ASSERT_IF(*pc == JSOP_SETGNAME, obj == &cx->fp()->global());
PropertyCacheEntry *entry;
JSObject *obj2;

View File

@ -1440,7 +1440,7 @@ js_NewGenerator(JSContext *cx)
JS_ASSERT(stackfp->base() == cx->regs().sp);
JS_ASSERT(stackfp->actualArgs() <= stackfp->formalArgs());
GlobalObject *global = &stackfp->scopeChain().global();
GlobalObject *global = &stackfp->global();
JSObject *proto = global->getOrCreateGeneratorPrototype(cx);
if (!proto)
return NULL;

View File

@ -1096,7 +1096,7 @@ DirectEval(JSContext *cx, const CallArgs &args)
/* Direct eval can assume it was called from an interpreted frame. */
StackFrame *caller = cx->fp();
JS_ASSERT(caller->isScriptFrame());
JS_ASSERT(IsBuiltinEvalForScope(&caller->scopeChain(), args.calleev()));
JS_ASSERT(IsBuiltinEvalForScope(caller->scopeChain(), args.calleev()));
JS_ASSERT(JSOp(*cx->regs().pc) == JSOP_EVAL);
AutoFunctionCallProbe callProbe(cx, args.callee().toFunction(), caller->script());
@ -6304,7 +6304,7 @@ js_DumpStackFrame(JSContext *cx, StackFrame *start)
fprintf(stderr, " generator");
fputc('\n', stderr);
fprintf(stderr, " scopeChain: (JSObject *) %p\n", (void *) &fp->scopeChain());
fprintf(stderr, " scopeChain: (JSObject *) %p\n", (void *) fp->scopeChain());
fputc('\n', stderr);
}

View File

@ -1529,7 +1529,7 @@ NewBuiltinClassInstance(JSContext *cx, Class *clasp)
inline GlobalObject *
GetCurrentGlobal(JSContext *cx)
{
JSObject *scopeChain = (cx->hasfp()) ? &cx->fp()->scopeChain() : cx->globalObject;
JSObject *scopeChain = (cx->hasfp()) ? cx->fp()->scopeChain() : cx->globalObject;
return scopeChain ? &scopeChain->global() : NULL;
}

View File

@ -2825,7 +2825,7 @@ ASTSerializer::literal(ParseNode *pn, Value *dst)
LOCAL_ASSERT(re1 && re1->isRegExp());
JSObject *proto;
if (!js_GetClassPrototype(cx, &cx->fp()->scopeChain(), JSProto_RegExp, &proto))
if (!js_GetClassPrototype(cx, cx->fp()->scopeChain(), JSProto_RegExp, &proto))
return false;
JSObject *re2 = CloneRegExpObject(cx, re1, proto);

View File

@ -1722,7 +1722,7 @@ static JSObject *
GetCurrentScopeChain(JSContext *cx)
{
if (cx->hasfp())
return &cx->fp()->scopeChain();
return cx->fp()->scopeChain();
return JS_ObjectToInnerObject(cx, cx->globalObject);
}
@ -7703,7 +7703,7 @@ js_ValueToXMLString(JSContext *cx, const Value &v)
JSBool
js_GetAnyName(JSContext *cx, jsid *idp)
{
JSObject *global = cx->hasfp() ? &cx->fp()->scopeChain().global() : cx->globalObject;
JSObject *global = cx->hasfp() ? &cx->fp()->global() : cx->globalObject;
Value v = global->getReservedSlot(JSProto_AnyName);
if (v.isUndefined()) {
JSObject *obj = NewObjectWithGivenProto(cx, &AnyNameClass, NULL, global);

View File

@ -156,7 +156,7 @@ static void
InlineReturn(VMFrame &f)
{
JS_ASSERT(f.fp() != f.entryfp);
JS_ASSERT(!IsActiveWithOrBlock(f.cx, f.fp()->scopeChain(), 0));
JS_ASSERT(!IsActiveWithOrBlock(f.cx, *f.fp()->scopeChain(), 0));
JS_ASSERT(!f.fp()->hasBlockChain());
f.cx->stack.popInlineFrame(f.regs);
@ -430,7 +430,7 @@ stubs::Eval(VMFrame &f, uint32_t argc)
{
CallArgs args = CallArgsFromSp(argc, f.regs.sp);
if (!IsBuiltinEvalForScope(&f.fp()->scopeChain(), args.calleev())) {
if (!IsBuiltinEvalForScope(f.fp()->scopeChain(), args.calleev())) {
if (!InvokeKernel(f.cx, args))
THROW();

View File

@ -86,7 +86,7 @@ PatchGetFallback(VMFrame &f, ic::GetGlobalNameIC *ic)
void JS_FASTCALL
ic::GetGlobalName(VMFrame &f, ic::GetGlobalNameIC *ic)
{
JSObject &obj = f.fp()->scopeChain().global();
JSObject &obj = f.fp()->global();
PropertyName *name = f.script()->getName(GET_UINT32_INDEX(f.pc()));
RecompilationMonitor monitor(f.cx);
@ -190,7 +190,7 @@ UpdateSetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic, JSObject *obj, const Sh
void JS_FASTCALL
ic::SetGlobalName(VMFrame &f, ic::SetGlobalNameIC *ic)
{
JSObject &obj = f.fp()->scopeChain().global();
JSObject &obj = f.fp()->global();
JSScript *script = f.script();
PropertyName *name = script->getName(GET_UINT32_INDEX(f.pc()));

View File

@ -910,7 +910,7 @@ class GetPropCompiler : public PICStubCompiler
RecompilationMonitor monitor(f.cx);
JSObject *obj = f.fp()->scopeChain().global().getOrCreateStringPrototype(f.cx);
JSObject *obj = f.fp()->global().getOrCreateStringPrototype(f.cx);
if (!obj)
return error();
@ -1953,7 +1953,7 @@ ic::Name(VMFrame &f, ic::PICInfo *pic)
{
JSScript *script = f.fp()->script();
ScopeNameCompiler cc(f, script, &f.fp()->scopeChain(), *pic, pic->name, DisabledNameIC);
ScopeNameCompiler cc(f, script, f.fp()->scopeChain(), *pic, pic->name, DisabledNameIC);
LookupStatus status = cc.updateForName();
if (status == Lookup_Error)
@ -1977,7 +1977,7 @@ ic::BindName(VMFrame &f, ic::PICInfo *pic)
JSScript *script = f.fp()->script();
VoidStubPIC stub = DisabledBindNameIC;
BindNameCompiler cc(f, script, &f.fp()->scopeChain(), *pic, pic->name, stub);
BindNameCompiler cc(f, script, f.fp()->scopeChain(), *pic, pic->name, stub);
JSObject *obj = cc.update();
if (!obj)

View File

@ -85,7 +85,7 @@ using namespace JSC;
void JS_FASTCALL
stubs::BindName(VMFrame &f, PropertyName *name)
{
JSObject *obj = FindIdentifierBase(f.cx, &f.fp()->scopeChain(), name);
JSObject *obj = FindIdentifierBase(f.cx, f.fp()->scopeChain(), name);
if (!obj)
THROW();
f.regs.sp[0].setObject(*obj);
@ -94,7 +94,7 @@ stubs::BindName(VMFrame &f, PropertyName *name)
JSObject * JS_FASTCALL
stubs::BindGlobalName(VMFrame &f)
{
return &f.fp()->scopeChain().global();
return &f.fp()->global();
}
template<JSBool strict>
@ -343,7 +343,7 @@ stubs::DefFun(VMFrame &f, JSFunction *fun_)
* FIXME: bug 476950, although debugger users may also demand some kind
* of scope link for debugger-assisted eval-in-frame.
*/
obj2 = &fp->scopeChain();
obj2 = fp->scopeChain();
} else {
obj2 = GetScopeChain(cx, fp);
if (!obj2)
@ -994,7 +994,7 @@ stubs::RegExp(VMFrame &f, JSObject *regex)
* Push a regexp object cloned from the regexp literal object mapped by the
* bytecode at pc.
*/
JSObject *proto = f.fp()->scopeChain().global().getOrCreateRegExpPrototype(f.cx);
JSObject *proto = f.fp()->global().getOrCreateRegExpPrototype(f.cx);
if (!proto)
THROW();
JS_ASSERT(proto);
@ -1011,7 +1011,7 @@ stubs::Lambda(VMFrame &f, JSFunction *fun_)
RootedVarObject parent(f.cx);
if (fun->isNullClosure()) {
parent = &f.fp()->scopeChain();
parent = f.fp()->scopeChain();
} else {
parent = GetScopeChain(f.cx, f.fp());
if (!parent)
@ -1253,7 +1253,7 @@ stubs::EnterBlock(VMFrame &f, JSObject *obj)
* anything else we should have popped off fp->scopeChain() when we left its
* static scope.
*/
JSObject *obj2 = &fp->scopeChain();
JSObject *obj2 = fp->scopeChain();
while (obj2->isWith())
obj2 = &obj2->asWith().enclosingScope();
if (obj2->isBlock() &&
@ -1282,7 +1282,7 @@ stubs::LeaveBlock(VMFrame &f)
* 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->scopeChain();
JSObject &obj = *fp->scopeChain();
if (obj.getProto() == &blockObj)
obj.asClonedBlock().put(cx);

View File

@ -77,7 +77,7 @@ js_PutArgsObject(StackFrame *fp)
ArgumentsObject &argsobj = fp->argsObj();
if (argsobj.isNormalArguments()) {
JS_ASSERT(argsobj.maybeStackFrame() == fp);
JSCompartment *comp = fp->scopeChain().compartment();
JSCompartment *comp = fp->compartment();
fp->forEachCanonicalActualArg(PutArg(comp, argsobj));
argsobj.setStackFrame(NULL);
} else {
@ -343,7 +343,7 @@ NormalArgumentsObject::optimizedGetElem(JSContext *cx, StackFrame *fp, const Val
return true;
}
JSObject *proto = fp->scopeChain().global().getOrCreateObjectPrototype(cx);
JSObject *proto = fp->global().getOrCreateObjectPrototype(cx);
if (!proto)
return false;

View File

@ -190,10 +190,10 @@ class Debugger::FrameRange {
/* Find our global, if we were not given one. */
if (!global)
global = &fp->scopeChain().global();
global = &fp->global();
/* The frame and global must match. */
JS_ASSERT(&fp->scopeChain().global() == global);
JS_ASSERT(&fp->global() == global);
/* Find the list of debuggers we'll iterate over. There may be none. */
debuggers = global->getDebuggers();
@ -278,7 +278,7 @@ ScriptGlobal(JSContext *cx, JSScript *script, GlobalObject *scriptGlobal)
for (AllFramesIter i(cx->stack.space()); ; ++i) {
JS_ASSERT(!i.done());
if (i.fp()->maybeScript() == script)
return &i.fp()->scopeChain().global();
return &i.fp()->global();
}
JS_NOT_REACHED("ScriptGlobal: live non-held script not on stack");
}
@ -525,7 +525,7 @@ Debugger::slowPathOnEnterFrame(JSContext *cx, Value *vp)
{
/* Build the list of recipients. */
AutoValueVector triggered(cx);
GlobalObject *global = &cx->fp()->scopeChain().global();
GlobalObject *global = &cx->fp()->global();
if (GlobalObject::DebuggerVector *debuggers = global->getDebuggers()) {
for (Debugger **p = debuggers->begin(); p != debuggers->end(); p++) {
Debugger *dbg = *p;
@ -557,7 +557,7 @@ bool
Debugger::slowPathOnLeaveFrame(JSContext *cx, bool frameOk)
{
StackFrame *fp = cx->fp();
GlobalObject *global = &fp->scopeChain().global();
GlobalObject *global = &fp->global();
/* Save the frame's completion value. */
JSTrapStatus status;
@ -1025,7 +1025,7 @@ Debugger::dispatchHook(JSContext *cx, Value *vp, Hook which)
* different compartments--every compartment *except* this one.
*/
AutoValueVector triggered(cx);
GlobalObject *global = &cx->fp()->scopeChain().global();
GlobalObject *global = &cx->fp()->global();
if (GlobalObject::DebuggerVector *debuggers = global->getDebuggers()) {
for (Debugger **p = debuggers->begin(); p != debuggers->end(); p++) {
Debugger *dbg = *p;
@ -1113,7 +1113,7 @@ Debugger::onTrap(JSContext *cx, Value *vp)
{
StackFrame *fp = cx->fp();
JSScript *script = fp->script();
GlobalObject *scriptGlobal = &fp->scopeChain().global();
GlobalObject *scriptGlobal = &fp->global();
jsbytecode *pc = cx->regs().pc;
BreakpointSite *site = script->getBreakpointSite(pc);
JSOp op = JSOp(*pc);
@ -1211,7 +1211,7 @@ Debugger::onSingleStep(JSContext *cx, Value *vp)
{
uint32_t stepperCount = 0;
JSScript *trappingScript = fp->script();
GlobalObject *global = &fp->scopeChain().global();
GlobalObject *global = &fp->global();
if (GlobalObject::DebuggerVector *debuggers = global->getDebuggers()) {
for (Debugger **p = debuggers->begin(); p != debuggers->end(); p++) {
Debugger *dbg = *p;
@ -1945,7 +1945,7 @@ Debugger::removeDebuggeeGlobal(FreeOp *fop, GlobalObject *global,
*/
for (FrameMap::Enum e(frames); !e.empty(); e.popFront()) {
StackFrame *fp = e.front().key;
if (&fp->scopeChain().global() == global) {
if (&fp->global() == global) {
e.front().value->setPrivate(NULL);
e.removeFront();
}
@ -2120,7 +2120,7 @@ class Debugger::ScriptQuery {
*/
JS_ASSERT(!script->getGlobalObjectOrNull());
GlobalObject *global = &fri.fp()->scopeChain().global();
GlobalObject *global = &fri.fp()->global();
if (!consider(script, global, vector))
return false;
}
@ -3051,7 +3051,7 @@ DebuggerFrame_getEnvironment(JSContext *cx, unsigned argc, Value *vp)
Env *env;
{
AutoCompartment ac(cx, &fp->scopeChain());
AutoCompartment ac(cx, fp->scopeChain());
if (!ac.enter())
return false;
env = Frame_GetEnv(cx, fp);
@ -3095,7 +3095,7 @@ DebuggerFrame_getThis(JSContext *cx, unsigned argc, Value *vp)
THIS_FRAME(cx, argc, vp, "get this", args, thisobj, fp);
Value thisv;
{
AutoCompartment ac(cx, &fp->scopeChain());
AutoCompartment ac(cx, fp->scopeChain());
if (!ac.enter())
return false;
if (!ComputeThis(cx, fp))
@ -3316,7 +3316,7 @@ DebuggerFrame_setOnStep(JSContext *cx, unsigned argc, Value *vp)
int delta = !args[0].isUndefined() - !prior.isUndefined();
if (delta != 0) {
/* Try to adjust this frame's script single-step mode count. */
AutoCompartment ac(cx, &fp->scopeChain());
AutoCompartment ac(cx, fp->scopeChain());
if (!ac.enter())
return false;
if (!fp->script()->changeStepModeCount(cx, delta))
@ -3379,7 +3379,7 @@ EvaluateInEnv(JSContext *cx, Env *env, StackFrame *fp, const jschar *chars,
* we use a static level that will cause us not to attempt to optimize
* variable references made by this frame.
*/
JSPrincipals *prin = fp->scopeChain().principals(cx);
JSPrincipals *prin = fp->scopeChain()->principals(cx);
JSScript *script = frontend::CompileScript(cx, env, fp, prin, prin,
TCF_COMPILE_N_GO | TCF_NEED_SCRIPT_GLOBAL,
chars, length, filename, lineno,
@ -3442,7 +3442,7 @@ DebuggerFrameEval(JSContext *cx, unsigned argc, Value *vp, EvalBindingsMode mode
}
}
AutoCompartment ac(cx, &fp->scopeChain());
AutoCompartment ac(cx, fp->scopeChain());
if (!ac.enter())
return false;

View File

@ -514,7 +514,7 @@ Debugger::observesGlobal(GlobalObject *global) const
bool
Debugger::observesFrame(StackFrame *fp) const
{
return !fp->isDummyFrame() && observesGlobal(&fp->scopeChain().global());
return !fp->isDummyFrame() && observesGlobal(&fp->global());
}
JSTrapStatus

View File

@ -218,7 +218,7 @@ CallObject::createForFunction(JSContext *cx, StackFrame *fp)
JS_ASSERT(fp->isNonEvalFunctionFrame());
JS_ASSERT(!fp->hasCallObj());
RootedVarObject scopeChain(cx, &fp->scopeChain());
RootedVarObject scopeChain(cx, fp->scopeChain());
JS_ASSERT_IF(scopeChain->isWith() || scopeChain->isBlock() || scopeChain->isCall(),
scopeChain->getPrivate() != fp);
@ -250,9 +250,7 @@ CallObject::createForFunction(JSContext *cx, StackFrame *fp)
CallObject *
CallObject::createForStrictEval(JSContext *cx, StackFrame *fp)
{
CallObject *callobj = create(cx, fp->script(),
RootedVarObject(cx, &fp->scopeChain()),
RootedVarObject(cx));
CallObject *callobj = create(cx, fp->script(), fp->scopeChain(), RootedVarObject(cx));
if (!callobj)
return NULL;
@ -421,8 +419,7 @@ DeclEnvObject::create(JSContext *cx, StackFrame *fp)
RootedVarShape emptyDeclEnvShape(cx);
emptyDeclEnvShape = EmptyShape::getInitialShape(cx, &DeclEnvClass, NULL,
&fp->scopeChain().global(),
FINALIZE_KIND);
&fp->global(), FINALIZE_KIND);
if (!emptyDeclEnvShape)
return NULL;
@ -431,7 +428,7 @@ DeclEnvObject::create(JSContext *cx, StackFrame *fp)
return NULL;
obj->setPrivate(fp);
if (!obj->asScope().setEnclosingScope(cx, RootedVarObject(cx, &fp->scopeChain())))
if (!obj->asScope().setEnclosingScope(cx, fp->scopeChain()))
return NULL;
return &obj->asDeclEnv();
@ -717,7 +714,7 @@ ClonedBlockObject::create(JSContext *cx, StaticBlockObject &block, StackFrame *f
return NULL;
/* Set the parent if necessary, as for call objects. */
JSObject &global = fp->scopeChain().global();
JSObject &global = fp->global();
if (&global != obj->getParent()) {
JS_ASSERT(obj->getParent() == NULL);
if (!obj->setParent(cx, &global))

View File

@ -69,7 +69,7 @@ IsCacheableNonGlobalScope(JSObject *obj)
return cacheable;
}
inline JSObject &
inline HandleObject
StackFrame::scopeChain() const
{
JS_ASSERT_IF(!(flags_ & HAS_SCOPECHAIN), isFunctionFrame());
@ -77,13 +77,19 @@ StackFrame::scopeChain() const
scopeChain_ = callee().toFunction()->environment();
flags_ |= HAS_SCOPECHAIN;
}
return *scopeChain_;
return HandleObject::fromMarkedLocation(&scopeChain_);
}
inline GlobalObject &
StackFrame::global() const
{
return scopeChain()->global();
}
inline JSObject &
StackFrame::varObj()
{
JSObject *obj = &scopeChain();
JSObject *obj = scopeChain();
while (!obj->isVarObj())
obj = obj->enclosingScope();
return *obj;
@ -92,8 +98,8 @@ StackFrame::varObj()
inline JSCompartment *
StackFrame::compartment() const
{
JS_ASSERT_IF(isScriptFrame(), scopeChain().compartment() == script()->compartment());
return scopeChain().compartment();
JS_ASSERT_IF(isScriptFrame(), scopeChain()->compartment() == script()->compartment());
return scopeChain()->compartment();
}
inline void
@ -330,7 +336,7 @@ StackFrame::callObj() const
{
JS_ASSERT_IF(isNonEvalFunctionFrame() || isStrictEvalFrame(), hasCallObj());
JSObject *pobj = &scopeChain();
JSObject *pobj = scopeChain();
while (JS_UNLIKELY(!pobj->isCall()))
pobj = pobj->enclosingScope();
return pobj->asCall();
@ -645,10 +651,10 @@ ContextStack::currentScriptWithDiagnostics(jsbytecode **ppc) const
return script;
}
inline JSObject *
inline HandleObject
ContextStack::currentScriptedScopeChain() const
{
return &fp()->scopeChain();
return fp()->scopeChain();
}
} /* namespace js */

View File

@ -861,7 +861,8 @@ class StackFrame
* !fp->hasCall() && fp->scopeChain().isCall()
*/
inline JSObject &scopeChain() const;
inline HandleObject scopeChain() const;
inline GlobalObject &global() const;
bool hasCallObj() const {
bool ret = !!(flags_ & HAS_CALL_OBJ);
@ -1695,7 +1696,7 @@ class ContextStack
inline JSScript *currentScriptWithDiagnostics(jsbytecode **pc = NULL) const;
/* Get the scope chain for the topmost scripted call on the stack. */
inline JSObject *currentScriptedScopeChain() const;
inline HandleObject currentScriptedScopeChain() const;
/*
* Called by the methodjit for an arity mismatch. Arity mismatch can be