Bug 828020 - exactly root StaticScopeIter. r=terrence
authorTom Schuster <evilpies@gmail.com>
Thu, 10 Jan 2013 13:31:40 +0100
changeset 128253 9a93bc7b059bf7f97ccb412cea5f04e5c8415f1d
parent 128252 f3b6bc4b25904d62588fd33ba347741872b7fc2d
child 128254 e06f05ff1edc89552802f997c30075a3c088d4c2
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs828020
milestone21.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 828020 - exactly root StaticScopeIter. r=terrence
js/src/ion/IonBuilder.cpp
js/src/jsfriendapi.cpp
js/src/jsopcode.cpp
js/src/jsscript.cpp
js/src/methodjit/Compiler.cpp
js/src/vm/ScopeObject.cpp
js/src/vm/ScopeObject.h
js/src/vm/Stack.cpp
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -6705,17 +6705,17 @@ IonBuilder::walkScopeChain(unsigned hops
 bool
 IonBuilder::jsop_getaliasedvar(ScopeCoordinate sc)
 {
     types::StackTypeSet *barrier;
     types::StackTypeSet *actual = oracle->aliasedVarBarrier(script(), pc, &barrier);
 
     MDefinition *obj = walkScopeChain(sc.hops);
 
-    RootedShape shape(cx, ScopeCoordinateToStaticScope(script(), pc).scopeShape());
+    RootedShape shape(cx, ScopeCoordinateToStaticScopeShape(cx, script(), pc));
 
     MInstruction *load;
     if (shape->numFixedSlots() <= sc.slot) {
         MInstruction *slots = MSlots::New(obj);
         current->add(slots);
 
         load = MLoadSlot::New(slots, sc.slot - shape->numFixedSlots());
     } else {
@@ -6739,17 +6739,17 @@ IonBuilder::jsop_getaliasedvar(ScopeCoor
 }
 
 bool
 IonBuilder::jsop_setaliasedvar(ScopeCoordinate sc)
 {
     MDefinition *rval = current->peek(-1);
     MDefinition *obj = walkScopeChain(sc.hops);
 
-    RootedShape shape(cx, ScopeCoordinateToStaticScope(script(), pc).scopeShape());
+    RootedShape shape(cx, ScopeCoordinateToStaticScopeShape(cx, script(), pc));
 
     MInstruction *store;
     if (shape->numFixedSlots() <= sc.slot) {
         MInstruction *slots = MSlots::New(obj);
         current->add(slots);
 
         store = MStoreSlot::NewBarriered(slots, sc.slot - shape->numFixedSlots(), rval);
     } else {
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -384,19 +384,19 @@ js::GetOutermostEnclosingFunctionOfScrip
 {
     if (!cx->hasfp())
         return NULL;
 
     StackFrame *fp = cx->fp();
     if (!fp->isFunctionFrame())
         return NULL;
 
-    JSFunction *scriptedCaller = fp->fun();
+    RootedFunction scriptedCaller(cx, fp->fun());
     RootedScript outermost(cx, scriptedCaller->nonLazyScript());
-    for (StaticScopeIter i(scriptedCaller); !i.done(); i++) {
+    for (StaticScopeIter i(cx, scriptedCaller); !i.done(); i++) {
         if (i.type() == StaticScopeIter::FUNCTION)
             outermost = i.funScript();
     }
     return outermost;
 }
 
 JS_FRIEND_API(JSFunction *)
 js::DefineFunctionWithReserved(JSContext *cx, JSObject *objArg, const char *name, JSNative call,
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -578,17 +578,17 @@ js_Disassemble1(JSContext *cx, HandleScr
 
       case JOF_JUMP: {
         ptrdiff_t off = GET_JUMP_OFFSET(pc);
         Sprint(sp, " %u (%+d)", loc + (int) off, (int) off);
         break;
       }
 
       case JOF_SCOPECOORD: {
-        Value v = StringValue(ScopeCoordinateName(cx->runtime, script, pc));
+        Value v = StringValue(ScopeCoordinateName(cx, script, pc));
         JSAutoByteString bytes;
         if (!ToDisassemblySource(cx, v, &bytes))
             return 0;
         ScopeCoordinate sc(pc);
         Sprint(sp, " %s (hops = %u, slot = %u)", bytes.ptr(), sc.hops, sc.slot);
         break;
       }
 
@@ -1921,17 +1921,17 @@ GetLocal(SprintStack *ss, int i)
  * the stack depth of the associated slot is returned in *localSlot.
  */
 static bool
 IsVarSlot(JSPrinter *jp, jsbytecode *pc, JSAtom **varAtom, int *localSlot)
 {
     *localSlot = -1;
 
     if (JOF_OPTYPE(*pc) == JOF_SCOPECOORD) {
-        *varAtom = ScopeCoordinateName(jp->sprinter.context->runtime, jp->script, pc);
+        *varAtom = ScopeCoordinateName(jp->sprinter.context, jp->script, pc);
         LOCAL_ASSERT_RV(*varAtom, false);
         return true;
     }
 
     unsigned slot = GET_SLOTNO(pc);
     if (slot < jp->script->nfixed) {
         *varAtom = GetArgOrVarAtom(jp, jp->fun->nargs + slot);
         LOCAL_ASSERT_RV(*varAtom, false);
@@ -5968,17 +5968,17 @@ ExpressionDecompiler::decompilePC(jsbyte
         } else {
             atom = getVar(i);
         }
         JS_ASSERT(atom);
         return write(atom);
       }
       case JSOP_CALLALIASEDVAR:
       case JSOP_GETALIASEDVAR: {
-        JSAtom *atom = ScopeCoordinateName(cx->runtime, script, pc);
+        JSAtom *atom = ScopeCoordinateName(cx, script, pc);
         JS_ASSERT(atom);
         return write(atom);
       }
       case JSOP_LENGTH:
       case JSOP_GETPROP:
       case JSOP_CALLPROP: {
         JSAtom *prop = (op == JSOP_LENGTH) ? cx->names().length : loadAtom(pc);
         if (!decompilePC(pcstack[-1]))
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -664,17 +664,18 @@ js::XDRScript(XDRState<mode> *xdr, Handl
             isBlock = obj->isBlock() ? 1 : 0;
         }
         if (!xdr->codeUint32(&isBlock))
             return false;
         if (isBlock == 0) {
             /* Code the nested function's enclosing scope. */
             uint32_t funEnclosingScopeIndex = 0;
             if (mode == XDR_ENCODE) {
-                StaticScopeIter ssi((*objp)->toFunction()->nonLazyScript()->enclosingStaticScope());
+                RootedObject staticScope(cx, (*objp)->toFunction()->nonLazyScript()->enclosingStaticScope());
+                StaticScopeIter ssi(cx, staticScope);
                 if (ssi.done() || ssi.type() == StaticScopeIter::FUNCTION) {
                     JS_ASSERT(ssi.done() == !fun);
                     funEnclosingScopeIndex = UINT32_MAX;
                 } else {
                     funEnclosingScopeIndex = FindBlockIndex(script, ssi.block());
                     JS_ASSERT(funEnclosingScopeIndex < i);
                 }
             }
@@ -2216,18 +2217,18 @@ js::CloneScript(JSContext *cx, HandleObj
                 if (StaticBlockObject *enclosingBlock = innerBlock->enclosingBlock())
                     enclosingScope = objects[FindBlockIndex(src, *enclosingBlock)];
                 else
                     enclosingScope = fun;
 
                 clone = CloneStaticBlockObject(cx, enclosingScope, innerBlock);
             } else if (obj->isFunction()) {
                 RootedFunction innerFun(cx, obj->toFunction());
-
-                StaticScopeIter ssi(innerFun->nonLazyScript()->enclosingStaticScope());
+                RootedObject staticScope(cx, innerFun->nonLazyScript()->enclosingStaticScope());
+                StaticScopeIter ssi(cx, staticScope);
                 RootedObject enclosingScope(cx);
                 if (!ssi.done() && ssi.type() == StaticScopeIter::BLOCK)
                     enclosingScope = objects[FindBlockIndex(src, ssi.block())];
                 else
                     enclosingScope = fun;
 
                 clone = CloneInterpretedFunction(cx, enclosingScope, innerFun);
             } else {
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -6055,17 +6055,17 @@ mjit::Compiler::jsop_aliasedArg(unsigned
 void
 mjit::Compiler::jsop_aliasedVar(ScopeCoordinate sc, bool get, bool poppedAfter)
 {
     RegisterID reg = frame.allocReg(Registers::SavedRegs).reg();
     masm.loadPtr(Address(JSFrameReg, StackFrame::offsetOfScopeChain()), reg);
     for (unsigned i = 0; i < sc.hops; i++)
         masm.loadPayload(Address(reg, ScopeObject::offsetOfEnclosingScope()), reg);
 
-    UnrootedShape shape = ScopeCoordinateToStaticScope(script_, PC).scopeShape();
+    UnrootedShape shape = ScopeCoordinateToStaticScopeShape(cx, script_, PC);
     Address addr;
     if (shape->numFixedSlots() <= sc.slot) {
         masm.loadPtr(Address(reg, JSObject::offsetOfSlots()), reg);
         addr = Address(reg, (sc.slot - shape->numFixedSlots()) * sizeof(Value));
     } else {
         addr = Address(reg, JSObject::getFixedSlotOffset(sc.slot));
     }
 
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -18,26 +18,26 @@
 
 #include "ScopeObject-inl.h"
 
 using namespace js;
 using namespace js::types;
 
 /*****************************************************************************/
 
-StaticScopeIter::StaticScopeIter(JSObject *obj)
-  : obj(obj), onNamedLambda(false)
+StaticScopeIter::StaticScopeIter(JSContext *cx, HandleObject objArg)
+  : obj(cx, objArg), onNamedLambda(false)
 {
     JS_ASSERT_IF(obj, obj->isStaticBlock() || obj->isFunction());
 }
 
 bool
 StaticScopeIter::done() const
 {
-    return obj == NULL;
+    return !obj;
 }
 
 void
 StaticScopeIter::operator++(int)
 {
     if (obj->isStaticBlock()) {
         obj = obj->asStaticBlock().enclosingStaticScope();
     } else if (onNamedLambda || !obj->toFunction()->isNamedLambda()) {
@@ -87,54 +87,54 @@ UnrootedScript
 StaticScopeIter::funScript() const
 {
     JS_ASSERT(type() == FUNCTION);
     return obj->toFunction()->nonLazyScript();
 }
 
 /*****************************************************************************/
 
-StaticScopeIter
-js::ScopeCoordinateToStaticScope(JSScript *script, jsbytecode *pc)
+UnrootedShape
+js::ScopeCoordinateToStaticScopeShape(JSContext *cx, JSScript *script, jsbytecode *pc)
 {
     JS_ASSERT(pc >= script->code && pc < script->code + script->length);
     JS_ASSERT(JOF_OPTYPE(*pc) == JOF_SCOPECOORD);
 
     uint32_t blockIndex = GET_UINT32_INDEX(pc + 2 * sizeof(uint16_t));
-    JSObject *innermostStaticScope;
+    RootedObject innermostStaticScope(cx, NULL);
     if (blockIndex == UINT32_MAX)
         innermostStaticScope = script->function();
     else
         innermostStaticScope = &script->getObject(blockIndex)->asStaticBlock();
 
-    StaticScopeIter ssi(innermostStaticScope);
+    StaticScopeIter ssi(cx, innermostStaticScope);
     ScopeCoordinate sc(pc);
     while (true) {
         if (ssi.hasDynamicScopeObject()) {
             if (!sc.hops)
                 break;
             sc.hops--;
         }
         ssi++;
     }
-    return ssi;
+    return ssi.scopeShape();
 }
 
 PropertyName *
-js::ScopeCoordinateName(JSRuntime *rt, JSScript *script, jsbytecode *pc)
+js::ScopeCoordinateName(JSContext *cx, JSScript *script, jsbytecode *pc)
 {
-    Shape::Range r = ScopeCoordinateToStaticScope(script, pc).scopeShape()->all();
+    Shape::Range r = ScopeCoordinateToStaticScopeShape(cx, script, pc)->all();
     ScopeCoordinate sc(pc);
     while (r.front().slot() != sc.slot)
         r.popFront();
     jsid id = r.front().propid();
 
     /* Beware nameless destructuring formal. */
     if (!JSID_IS_ATOM(id))
-        return rt->atomState.empty;
+        return cx->runtime->atomState.empty;
     return JSID_TO_ATOM(id)->asPropertyName();
 }
 
 /*****************************************************************************/
 
 /*
  * Construct a bare-bones call object given a shape, type, and slots pointer.
  * The call object must be further initialized to be usable.
@@ -422,41 +422,41 @@ with_GetSpecial(JSContext *cx, HandleObj
     Rooted<jsid> id(cx, SPECIALID_TO_JSID(sid));
     return with_GetGeneric(cx, obj, receiver, id, vp);
 }
 
 static JSBool
 with_SetGeneric(JSContext *cx, HandleObject obj, HandleId id,
                 MutableHandleValue vp, JSBool strict)
 {
-    Rooted<JSObject*> actual(cx, &obj->asWith().object());
+    RootedObject actual(cx, &obj->asWith().object());
     return JSObject::setGeneric(cx, actual, actual, id, vp, strict);
 }
 
 static JSBool
 with_SetProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,
                  MutableHandleValue vp, JSBool strict)
 {
-    Rooted<JSObject*> actual(cx, &obj->asWith().object());
+    RootedObject actual(cx, &obj->asWith().object());
     return JSObject::setProperty(cx, actual, actual, name, vp, strict);
 }
 
 static JSBool
 with_SetElement(JSContext *cx, HandleObject obj, uint32_t index,
                 MutableHandleValue vp, JSBool strict)
 {
-    Rooted<JSObject*> actual(cx, &obj->asWith().object());
+    RootedObject actual(cx, &obj->asWith().object());
     return JSObject::setElement(cx, actual, actual, index, vp, strict);
 }
 
 static JSBool
 with_SetSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid,
                 MutableHandleValue vp, JSBool strict)
 {
-    Rooted<JSObject*> actual(cx, &obj->asWith().object());
+    RootedObject actual(cx, &obj->asWith().object());
     return JSObject::setSpecial(cx, actual, actual, sid, vp, strict);
 }
 
 static JSBool
 with_GetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
 {
     RootedObject actual(cx, &obj->asWith().object());
     return JSObject::getGenericAttributes(cx, actual, id, attrsp);
--- a/js/src/vm/ScopeObject.h
+++ b/js/src/vm/ScopeObject.h
@@ -51,21 +51,21 @@ namespace js {
  *      let (x) { eval("function f() {}") }
  *    f does not have an enclosing static scope. This is fine for current uses
  *    for the same reason as 'with'.
  *
  * (See also AssertDynamicScopeMatchesStaticScope.)
  */
 class StaticScopeIter
 {
-    JSObject *obj;
+    RootedObject obj;
     bool onNamedLambda;
 
   public:
-    explicit StaticScopeIter(JSObject *obj);
+    explicit StaticScopeIter(JSContext *cx, HandleObject obj);
 
     bool done() const;
     void operator++(int);
 
     /* Return whether this static scope will be on the dynamic scope chain. */
     bool hasDynamicScopeObject() const;
     UnrootedShape scopeShape() const;
 
@@ -92,25 +92,25 @@ struct ScopeCoordinate
     uint16_t hops;
     uint16_t slot;
 
     inline ScopeCoordinate(jsbytecode *pc);
     inline ScopeCoordinate() {}
 };
 
 /*
- * Return a scope iterator pointing at the static scope containing the variable
+ * Return a shape representing the static scope containing the variable
  * accessed by the ALIASEDVAR op at 'pc'.
  */
-extern StaticScopeIter
-ScopeCoordinateToStaticScope(JSScript *script, jsbytecode *pc);
+extern UnrootedShape
+ScopeCoordinateToStaticScopeShape(JSContext *cx, JSScript *script, jsbytecode *pc);
 
 /* Return the name being accessed by the given ALIASEDVAR op. */
 extern PropertyName *
-ScopeCoordinateName(JSRuntime *rt, JSScript *script, jsbytecode *pc);
+ScopeCoordinateName(JSContext *cx, JSScript *script, jsbytecode *pc);
 
 /*****************************************************************************/
 
 /*
  * Scope objects
  *
  * Scope objects are technically real JSObjects but only belong on the scope
  * chain (that is, fp->scopeChain() or fun->environment()). The hierarchy of
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -228,20 +228,21 @@ StackFrame::copyRawFrameSlots(AutoValueV
     if (!vec->resize(numFormalArgs() + script()->nfixed))
         return false;
     PodCopy(vec->begin(), formals(), numFormalArgs());
     PodCopy(vec->begin() + numFormalArgs(), slots(), script()->nfixed);
     return true;
 }
 
 static inline void
-AssertDynamicScopeMatchesStaticScope(JSScript *script, JSObject *scope)
+AssertDynamicScopeMatchesStaticScope(JSContext *cx, JSScript *script, JSObject *scope)
 {
 #ifdef DEBUG
-    for (StaticScopeIter i(script->enclosingStaticScope()); !i.done(); i++) {
+    RootedObject enclosingScope(cx, script->enclosingStaticScope());
+    for (StaticScopeIter i(cx, enclosingScope); !i.done(); i++) {
         if (i.hasDynamicScopeObject()) {
             /*
              * 'with' does not participate in the static scope of the script,
              * but it does in the dynamic scope, so skip them here.
              */
             while (scope->isWith())
                 scope = &scope->asWith().enclosingScope();
 
@@ -300,17 +301,17 @@ StackFrame::prologue(JSContext *cx, bool
     }
 
     if (isGlobalFrame()) {
         Probes::enterScript(cx, script, NULL, this);
         return true;
     }
 
     JS_ASSERT(isNonEvalFunctionFrame());
-    AssertDynamicScopeMatchesStaticScope(script, scopeChain());
+    AssertDynamicScopeMatchesStaticScope(cx, script, scopeChain());
 
     if (fun()->isHeavyweight() && !initFunctionScopeObjects(cx))
         return false;
 
     if (isConstructing()) {
         RootedObject callee(cx, &this->callee());
         JSObject *obj = js_CreateThisForFunction(cx, callee, newType);
         if (!obj)
@@ -362,17 +363,17 @@ StackFrame::epilogue(JSContext *cx)
         return;
     }
 
     JS_ASSERT(isNonEvalFunctionFrame());
 
     if (fun()->isHeavyweight())
         JS_ASSERT_IF(hasCallObj(), scopeChain()->asCall().callee().nonLazyScript() == script);
     else
-        AssertDynamicScopeMatchesStaticScope(script, scopeChain());
+        AssertDynamicScopeMatchesStaticScope(cx, script, scopeChain());
 
     if (cx->compartment->debugMode())
         DebugScopes::onPopCall(this, cx);
 
 
     if (isConstructing() && returnValue().isPrimitive())
         setReturnValue(ObjectValue(constructorThis()));
 }