From 5fabc247065a72df0c0a425e2ef13a9ace5b67e6 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Fri, 29 Jun 2012 11:42:42 -0700 Subject: [PATCH] Bug 769743 - simplify ScopedCoordinate::slot and fix names (r=dvander) --HG-- extra : rebase_source : 5d809f4db11dae7bcaf20591556635b2ae85fe23 --- js/src/frontend/BytecodeEmitter.cpp | 11 +++++---- js/src/frontend/TreeContext-inl.h | 10 -------- js/src/frontend/TreeContext.h | 2 -- js/src/jsanalyze.cpp | 6 ++--- js/src/jsanalyze.h | 2 +- js/src/jsscript.cpp | 38 ++++++++++++----------------- js/src/jsscript.h | 27 +++++++++----------- js/src/jsscriptinlines.h | 24 ++++++++++++++++++ js/src/methodjit/Compiler.cpp | 18 ++++++-------- js/src/vm/ScopeObject-inl.h | 21 +++++++++------- js/src/vm/ScopeObject.cpp | 29 +++++++++++----------- js/src/vm/ScopeObject.h | 16 ++++++------ 12 files changed, 104 insertions(+), 100 deletions(-) diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index c5367bf9518..917f8c8209b 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -847,13 +847,13 @@ EmitAliasedVarOp(JSContext *cx, JSOp op, ParseNode *pn, BytecodeEmitter *bce) ScopeCoordinate sc; if (JOF_OPTYPE(pn->getOp()) == JOF_QARG) { sc.hops = ClonedBlockDepth(bce); - sc.slot = bce->sc->bindings.argToSlot(pn->pn_cookie.slot()); + sc.slot = bce->sc->bindings.formalIndexToSlot(pn->pn_cookie.slot()); } else { JS_ASSERT(JOF_OPTYPE(pn->getOp()) == JOF_LOCAL || pn->isKind(PNK_FUNCTION)); unsigned local = pn->pn_cookie.slot(); if (local < bce->sc->bindings.numVars()) { sc.hops = ClonedBlockDepth(bce); - sc.slot = bce->sc->bindings.localToSlot(local); + sc.slot = bce->sc->bindings.varIndexToSlot(local); } else { unsigned depth = local - bce->sc->bindings.numVars(); unsigned hops = 0; @@ -864,7 +864,7 @@ EmitAliasedVarOp(JSContext *cx, JSOp op, ParseNode *pn, BytecodeEmitter *bce) b = b->enclosingBlock(); } sc.hops = hops; - sc.slot = depth - b->stackDepth(); + sc.slot = b->localIndexToSlot(bce->sc->bindings, local); } } @@ -2521,14 +2521,15 @@ frontend::EmitFunctionScript(JSContext *cx, BytecodeEmitter *bce, ParseNode *bod bce->switchToProlog(); if (Emit1(cx, bce, JSOP_ARGUMENTS) < 0) return false; + unsigned varIndex = bce->sc->bindings.argumentsVarIndex(cx); if (bce->sc->bindingsAccessedDynamically()) { ScopeCoordinate sc; sc.hops = 0; - sc.slot = bce->sc->bindings.localToSlot(bce->sc->argumentsLocal()); + sc.slot = bce->sc->bindings.varIndexToSlot(varIndex); if (!EmitAliasedVarOp(cx, JSOP_SETALIASEDVAR, sc, bce)) return false; } else { - if (!EmitUnaliasedVarOp(cx, JSOP_SETLOCAL, bce->sc->argumentsLocal(), bce)) + if (!EmitUnaliasedVarOp(cx, JSOP_SETLOCAL, varIndex, bce)) return false; } if (Emit1(cx, bce, JSOP_POP) < 0) diff --git a/js/src/frontend/TreeContext-inl.h b/js/src/frontend/TreeContext-inl.h index 22ba408f642..1ef086abc40 100644 --- a/js/src/frontend/TreeContext-inl.h +++ b/js/src/frontend/TreeContext-inl.h @@ -46,16 +46,6 @@ SharedContext::needStrictChecks() { return context->hasStrictOption() || inStrictMode(); } -inline unsigned -SharedContext::argumentsLocal() const -{ - PropertyName *arguments = context->runtime->atomState.argumentsAtom; - unsigned slot; - DebugOnly kind = bindings.lookup(context, arguments, &slot); - JS_ASSERT(kind == VARIABLE || kind == CONSTANT); - return slot; -} - inline TreeContext::TreeContext(Parser *prs, SharedContext *sc, unsigned staticLevel, uint32_t bodyid) : sc(sc), diff --git a/js/src/frontend/TreeContext.h b/js/src/frontend/TreeContext.h index 696fa779f6f..8ce0f89a535 100644 --- a/js/src/frontend/TreeContext.h +++ b/js/src/frontend/TreeContext.h @@ -175,8 +175,6 @@ struct SharedContext { #undef INFUNC - unsigned argumentsLocal() const; - bool inFunction() const { return !!fun_; } JSFunction *fun() const { JS_ASSERT(inFunction()); return fun_; } diff --git a/js/src/jsanalyze.cpp b/js/src/jsanalyze.cpp index 51adff55913..8cfaf066e18 100644 --- a/js/src/jsanalyze.cpp +++ b/js/src/jsanalyze.cpp @@ -123,7 +123,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx) PodZero(escapedSlots, numSlots); if (script->bindingsAccessedDynamically || script->compartment()->debugMode() || - script->argumentsHasLocalBinding()) + script->argumentsHasVarBinding()) { for (unsigned i = 0; i < nargs; i++) escapedSlots[ArgSlot(i)] = true; @@ -159,7 +159,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx) isInlineable = true; if (script->numClosedArgs() || script->numClosedVars() || heavyweight || - script->bindingsAccessedDynamically || script->argumentsHasLocalBinding() || + script->bindingsAccessedDynamically || script->argumentsHasVarBinding() || cx->compartment->debugMode()) { isInlineable = false; @@ -1947,7 +1947,7 @@ ScriptAnalysis::needsArgsObj(JSContext *cx, SeenVector &seen, SSAUseChain *use) bool ScriptAnalysis::needsArgsObj(JSContext *cx) { - JS_ASSERT(script->argumentsHasLocalBinding()); + JS_ASSERT(script->argumentsHasVarBinding()); /* * Since let variables and dynamic name access are not tracked, we cannot diff --git a/js/src/jsanalyze.h b/js/src/jsanalyze.h index a35133b8d08..6ceae36fb2e 100644 --- a/js/src/jsanalyze.h +++ b/js/src/jsanalyze.h @@ -364,7 +364,7 @@ static inline uint32_t GetBytecodeSlot(JSScript *script, jsbytecode *pc) case JSOP_SETALIASEDVAR: { unsigned index; - return ScopeCoordinateToFrameVar(script, pc, &index) == FrameVar_Local + return ScopeCoordinateToFrameIndex(script, pc, &index) == FrameIndex_Local ? LocalSlot(script, index) : ArgSlot(index); } diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 831898e43c3..78f4005a827 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -355,7 +355,7 @@ js::XDRScript(XDRState *xdr, JSScript **scriptp, JSScript *parentScript) StrictModeCode, ContainsDynamicNameAccess, FunHasExtensibleScope, - ArgumentsHasLocalBinding, + ArgumentsHasVarBinding, NeedsArgsObj, OwnFilename, ParentFilename, @@ -373,7 +373,7 @@ js::XDRScript(XDRState *xdr, JSScript **scriptp, JSScript *parentScript) nsrcnotes = ntrynotes = natoms = nobjects = nregexps = nconsts = nClosedArgs = nClosedVars = 0; jssrcnote *notes = NULL; - /* XDR arguments, local vars, and upvars. */ + /* XDR arguments, var vars, and upvars. */ uint16_t nargs, nvars; #if defined(DEBUG) || defined(__GNUC__) /* quell GCC overwarning */ script = NULL; @@ -511,8 +511,8 @@ js::XDRScript(XDRState *xdr, JSScript **scriptp, JSScript *parentScript) scriptBits |= (1 << ContainsDynamicNameAccess); if (script->funHasExtensibleScope) scriptBits |= (1 << FunHasExtensibleScope); - if (script->argumentsHasLocalBinding()) - scriptBits |= (1 << ArgumentsHasLocalBinding); + if (script->argumentsHasVarBinding()) + scriptBits |= (1 << ArgumentsHasVarBinding); if (script->analyzedArgsUsage() && script->needsArgsObj()) scriptBits |= (1 << NeedsArgsObj); if (script->filename) { @@ -593,13 +593,8 @@ js::XDRScript(XDRState *xdr, JSScript **scriptp, JSScript *parentScript) script->bindingsAccessedDynamically = true; if (scriptBits & (1 << FunHasExtensibleScope)) script->funHasExtensibleScope = true; - if (scriptBits & (1 << ArgumentsHasLocalBinding)) { - PropertyName *arguments = cx->runtime->atomState.argumentsAtom; - unsigned local; - DebugOnly kind = script->bindings.lookup(cx, arguments, &local); - JS_ASSERT(kind == VARIABLE || kind == CONSTANT); - script->setArgumentsHasLocalBinding(local); - } + if (scriptBits & (1 << ArgumentsHasVarBinding)) + script->setArgumentsHasVarBinding(); if (scriptBits & (1 << NeedsArgsObj)) script->setNeedsArgsObj(true); if (scriptBits & (1 << IsGenerator)) @@ -1326,7 +1321,7 @@ JSScript::fullyInitFromEmitter(JSContext *cx, BytecodeEmitter *bce) if (bce->sc->inFunction()) { if (bce->sc->funArgumentsHasLocalBinding()) { // This must precede the script->bindings.transfer() call below - script->setArgumentsHasLocalBinding(bce->sc->argumentsLocal()); + script->setArgumentsHasVarBinding(); if (bce->sc->funDefinitelyNeedsArgsObj()) script->setNeedsArgsObj(true); } else { @@ -1795,8 +1790,8 @@ js::CloneScript(JSContext *cx, HandleScript src) dst->nfixed = src->nfixed; dst->nTypeSets = src->nTypeSets; dst->nslots = src->nslots; - if (src->argumentsHasLocalBinding()) { - dst->setArgumentsHasLocalBinding(src->argumentsLocal()); + if (src->argumentsHasVarBinding()) { + dst->setArgumentsHasVarBinding(); if (src->analyzedArgsUsage()) dst->setNeedsArgsObj(src->needsArgsObj()); } @@ -2127,10 +2122,9 @@ JSScript::markChildren(JSTracer *trc) } void -JSScript::setArgumentsHasLocalBinding(uint16_t local) +JSScript::setArgumentsHasVarBinding() { - argsHasLocalBinding_ = true; - argsLocal_ = local; + argsHasVarBinding_ = true; needsArgsAnalysis_ = true; } @@ -2138,7 +2132,7 @@ void JSScript::setNeedsArgsObj(bool needsArgsObj) { JS_ASSERT(!analyzedArgsUsage()); - JS_ASSERT_IF(needsArgsObj, argumentsHasLocalBinding()); + JS_ASSERT_IF(needsArgsObj, argumentsHasVarBinding()); needsArgsAnalysis_ = false; needsArgsObj_ = needsArgsObj; } @@ -2149,7 +2143,7 @@ JSScript::argumentsOptimizationFailed(JSContext *cx, JSScript *script_) Rooted script(cx, script_); JS_ASSERT(script->analyzedArgsUsage()); - JS_ASSERT(script->argumentsHasLocalBinding()); + JS_ASSERT(script->argumentsHasVarBinding()); /* * It is possible that the apply speculation has already failed, everything @@ -2162,7 +2156,7 @@ JSScript::argumentsOptimizationFailed(JSContext *cx, JSScript *script_) script->needsArgsObj_ = true; - const unsigned local = script->argumentsLocal(); + const unsigned var = script->bindings.argumentsVarIndex(cx); /* * By design, the apply-arguments optimization is only made when there @@ -2191,8 +2185,8 @@ JSScript::argumentsOptimizationFailed(JSContext *cx, JSScript *script_) } /* Note: 'arguments' may have already been overwritten. */ - if (fp->unaliasedLocal(local).isMagic(JS_OPTIMIZED_ARGUMENTS)) - fp->unaliasedLocal(local) = ObjectValue(*argsobj); + if (fp->unaliasedLocal(var).isMagic(JS_OPTIMIZED_ARGUMENTS)) + fp->unaliasedLocal(var) = ObjectValue(*argsobj); } } diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 16d61ceb9bb..32d6c120bfb 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -104,15 +104,13 @@ class Bindings unsigned count() const { return nargs + nvars; } /* - * These functions map between argument/var indices [0, nargs/nvars) and - * and Bindings indices [0, nargs + nvars). + * The VM's StackFrame allocates a Value for each formal and variable. + * A (formal|var)Index is the index passed to fp->unaliasedFormal/Var to + * access this variable. These two functions convert between formal/var + * indices and the corresponding slot in the CallObject. */ - bool slotIsArg(uint16_t i) const { return i < nargs; } - bool slotIsLocal(uint16_t i) const { return i >= nargs; } - uint16_t argToSlot(uint16_t i) { JS_ASSERT(i < nargs); return i; } - uint16_t localToSlot(uint16_t i) { return i + nargs; } - uint16_t slotToArg(uint16_t i) { JS_ASSERT(slotIsArg(i)); return i; } - uint16_t slotToLocal(uint16_t i) { JS_ASSERT(slotIsLocal(i)); return i - nargs; } + inline uint16_t formalIndexToSlot(uint16_t i); + inline uint16_t varIndexToSlot(uint16_t i); /* Ensure these bindings have a shape lineage. */ inline bool ensureShape(JSContext *cx); @@ -188,6 +186,9 @@ class Bindings return lookup(cx, name, NULL) != NONE; } + /* Convenience method to get the var index of 'arguments'. */ + inline unsigned argumentsVarIndex(JSContext *cx) const; + /* * This method returns the local variable, argument, etc. names used by a * script. This function must be called only when count() > 0. @@ -478,9 +479,6 @@ struct JSScript : public js::gc::Cell uint16_t nslots; /* vars plus maximum stack depth */ uint16_t staticLevel;/* static level for display maintenance */ - private: - uint16_t argsLocal_; /* local holding 'arguments' (if argumentsHasLocalBindings) */ - // 8-bit fields. public: @@ -542,7 +540,7 @@ struct JSScript : public js::gc::Cell private: /* See comments below. */ - bool argsHasLocalBinding_:1; + bool argsHasVarBinding_:1; bool needsArgsAnalysis_:1; bool needsArgsObj_:1; @@ -570,10 +568,9 @@ struct JSScript : public js::gc::Cell void setVersion(JSVersion v) { version = v; } /* See ContextFlags::funArgumentsHasLocalBinding comment. */ - bool argumentsHasLocalBinding() const { return argsHasLocalBinding_; } + bool argumentsHasVarBinding() const { return argsHasVarBinding_; } jsbytecode *argumentsBytecode() const { JS_ASSERT(code[0] == JSOP_ARGUMENTS); return code; } - unsigned argumentsLocal() const { JS_ASSERT(argsHasLocalBinding_); return argsLocal_; } - void setArgumentsHasLocalBinding(uint16_t local); + void setArgumentsHasVarBinding(); /* * As an optimization, even when argsHasLocalBinding, the function prologue diff --git a/js/src/jsscriptinlines.h b/js/src/jsscriptinlines.h index c239b3a0691..0225b4af56f 100644 --- a/js/src/jsscriptinlines.h +++ b/js/src/jsscriptinlines.h @@ -76,6 +76,30 @@ Bindings::extensibleParents() return lastBinding && lastBinding->extensibleParents(); } +uint16_t +Bindings::formalIndexToSlot(uint16_t i) +{ + JS_ASSERT(i < nargs); + return CallObject::RESERVED_SLOTS + i; +} + +uint16_t +Bindings::varIndexToSlot(uint16_t i) +{ + JS_ASSERT(i < nvars); + return CallObject::RESERVED_SLOTS + i + nargs; +} + +unsigned +Bindings::argumentsVarIndex(JSContext *cx) const +{ + PropertyName *arguments = cx->runtime->atomState.argumentsAtom; + unsigned i; + DebugOnly kind = lookup(cx, arguments, &i); + JS_ASSERT(kind == VARIABLE || kind == CONSTANT); + return i; +} + extern void CurrentScriptFileLineOriginSlow(JSContext *cx, const char **file, unsigned *linenop, JSPrincipals **origin); diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index 7bf19ab07e5..0963fac500a 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -1106,7 +1106,7 @@ mjit::Compiler::generatePrologue() * fp->u.nactual. fp->u.nactual is only set when numActual != numFormal, * so store 'fp->u.nactual = numFormal' when there is no over/underflow. */ - if (script->argumentsHasLocalBinding()) { + if (script->argumentsHasVarBinding()) { Jump hasArgs = masm.branchTest32(Assembler::NonZero, FrameFlagsAddress(), Imm32(StackFrame::UNDERFLOW_ARGS | StackFrame::OVERFLOW_ARGS)); @@ -5846,8 +5846,6 @@ mjit::Compiler::jsop_aliasedVar(ScopeCoordinate sc, bool get, bool poppedAfter) for (unsigned i = 0; i < sc.hops; i++) masm.loadPayload(Address(reg, ScopeObject::offsetOfEnclosingScope()), reg); - unsigned slot = ScopeObject::CALL_BLOCK_RESERVED_SLOTS + sc.slot; - /* * TODO bug 753158: Call and Block objects should use the same layout * strategy: up to the maximum numFixedSlots and overflow (if any) in @@ -5862,11 +5860,11 @@ mjit::Compiler::jsop_aliasedVar(ScopeCoordinate sc, bool get, bool poppedAfter) * slot over is in the dynamic slots. */ uint32_t nfixed = gc::GetGCKindSlots(BlockObject::FINALIZE_KIND); - if (nfixed <= slot) { + if (nfixed <= sc.slot) { masm.loadPtr(Address(reg, JSObject::offsetOfSlots()), reg); - addr = Address(reg, (slot - nfixed) * sizeof(Value)); + addr = Address(reg, (sc.slot - nfixed) * sizeof(Value)); } else { - addr = Address(reg, JSObject::getFixedSlotOffset(slot)); + addr = Address(reg, JSObject::getFixedSlotOffset(sc.slot)); } } else { /* @@ -5874,17 +5872,17 @@ mjit::Compiler::jsop_aliasedVar(ScopeCoordinate sc, bool get, bool poppedAfter) * slots are either altogether in fixed slots or altogether in dynamic * slots (by having numFixed == RESERVED_SLOTS). */ - if (script->bindings.lastShape()->numFixedSlots() <= slot) { + if (script->bindings.lastShape()->numFixedSlots() <= sc.slot) { masm.loadPtr(Address(reg, JSObject::offsetOfSlots()), reg); - addr = Address(reg, sc.slot * sizeof(Value)); + addr = Address(reg, (sc.slot - CallObject::RESERVED_SLOTS) * sizeof(Value)); } else { - addr = Address(reg, JSObject::getFixedSlotOffset(slot)); + addr = Address(reg, JSObject::getFixedSlotOffset(sc.slot)); } } if (get) { unsigned index; - FrameEntry *fe = ScopeCoordinateToFrameVar(script, PC, &index) == FrameVar_Local + FrameEntry *fe = ScopeCoordinateToFrameIndex(script, PC, &index) == FrameIndex_Local ? frame.getLocal(index) : frame.getArg(index); JSValueType type = fe->isTypeKnown() ? fe->getKnownType() : JSVAL_TYPE_UNKNOWN; diff --git a/js/src/vm/ScopeObject-inl.h b/js/src/vm/ScopeObject-inl.h index 48d923b93b2..d726c5e384f 100644 --- a/js/src/vm/ScopeObject-inl.h +++ b/js/src/vm/ScopeObject-inl.h @@ -39,18 +39,15 @@ inline const Value & ScopeObject::aliasedVar(ScopeCoordinate sc) { JS_ASSERT(isCall() || isClonedBlock()); - JS_STATIC_ASSERT(CALL_BLOCK_RESERVED_SLOTS == CallObject::RESERVED_SLOTS); - JS_STATIC_ASSERT(CALL_BLOCK_RESERVED_SLOTS == BlockObject::RESERVED_SLOTS); - return getSlot(CALL_BLOCK_RESERVED_SLOTS + sc.slot); + return getSlot(sc.slot); } inline void ScopeObject::setAliasedVar(ScopeCoordinate sc, const Value &v) { JS_ASSERT(isCall() || isClonedBlock()); - JS_STATIC_ASSERT(CALL_BLOCK_RESERVED_SLOTS == CallObject::RESERVED_SLOTS); - JS_STATIC_ASSERT(CALL_BLOCK_RESERVED_SLOTS == BlockObject::RESERVED_SLOTS); - setSlot(CALL_BLOCK_RESERVED_SLOTS + sc.slot, v); + JS_STATIC_ASSERT(CallObject::RESERVED_SLOTS == BlockObject::RESERVED_SLOTS); + setSlot(sc.slot, v); } /*static*/ inline size_t @@ -159,10 +156,16 @@ BlockObject::slotCount() const } inline unsigned -BlockObject::slotToFrameLocal(JSScript *script, unsigned i) +BlockObject::slotToLocalIndex(const Bindings &bindings, unsigned slot) { - JS_ASSERT(i < slotCount()); - return script->nfixed + stackDepth() + i; + JS_ASSERT(slot < RESERVED_SLOTS + slotCount()); + return bindings.numVars() + stackDepth() + (slot - RESERVED_SLOTS); +} + +inline unsigned +BlockObject::localIndexToSlot(const Bindings &bindings, unsigned i) +{ + return RESERVED_SLOTS + (i - (bindings.numVars() + stackDepth())); } inline const Value & diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index c5c4414a688..ccedbd93b24 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -49,10 +49,9 @@ js::ScopeCoordinateName(JSRuntime *rt, JSScript *script, jsbytecode *pc) { StaticBlockObject *maybeBlock = ScopeCoordinateBlockChain(script, pc); ScopeCoordinate sc(pc); - uint32_t targetSlot = ScopeObject::CALL_BLOCK_RESERVED_SLOTS + sc.slot; Shape *shape = maybeBlock ? maybeBlock->lastProperty() : script->bindings.lastShape(); Shape::Range r = shape->all(); - while (r.front().slot() != targetSlot) + while (r.front().slot() != sc.slot) r.popFront(); jsid id = r.front().propid(); /* Beware nameless destructuring formal. */ @@ -61,22 +60,24 @@ js::ScopeCoordinateName(JSRuntime *rt, JSScript *script, jsbytecode *pc) return JSID_TO_ATOM(id)->asPropertyName(); } -FrameVarType -js::ScopeCoordinateToFrameVar(JSScript *script, jsbytecode *pc, unsigned *index) +FrameIndexType +js::ScopeCoordinateToFrameIndex(JSScript *script, jsbytecode *pc, unsigned *index) { ScopeCoordinate sc(pc); if (StaticBlockObject *block = ScopeCoordinateBlockChain(script, pc)) { - *index = block->slotToFrameLocal(script, sc.slot); - return FrameVar_Local; + *index = block->slotToLocalIndex(script->bindings, sc.slot); + return FrameIndex_Local; } - if (script->bindings.slotIsLocal(sc.slot)) { - *index = script->bindings.slotToLocal(sc.slot); - return FrameVar_Local; + unsigned i = sc.slot - CallObject::RESERVED_SLOTS; + if (i < script->bindings.numArgs()) { + *index = i; + return FrameIndex_Arg; } - *index = script->bindings.slotToArg(sc.slot); - return FrameVar_Arg; + *index = i - script->bindings.numArgs(); + JS_ASSERT(*index < script->bindings.numVars()); + return FrameIndex_Local; } /*****************************************************************************/ @@ -626,7 +627,7 @@ void ClonedBlockObject::copyUnaliasedValues(StackFrame *fp) { StaticBlockObject &block = staticBlock(); - unsigned base = block.slotToFrameLocal(fp->script(), 0); + unsigned base = fp->script()->nfixed + block.stackDepth(); for (unsigned i = 0; i < slotCount(); ++i) { if (!block.isAliased(i)) setVar(i, fp->unaliasedLocal(base + i), DONT_CHECK_ALIASING); @@ -1205,7 +1206,7 @@ class DebugScopeProxy : public BaseProxyHandler if (maybefp) { JSScript *script = maybefp->script(); - unsigned local = block.slotToFrameLocal(script, i); + unsigned local = block.slotToLocalIndex(script->bindings, shape->slot()); if (action == GET) *vp = maybefp->unaliasedLocal(local); else @@ -1244,7 +1245,7 @@ class DebugScopeProxy : public BaseProxyHandler static bool isMissingArgumentsBinding(ScopeObject &scope) { return isFunctionScope(scope) && - !scope.asCall().getCalleeFunction()->script()->argumentsHasLocalBinding(); + !scope.asCall().getCalleeFunction()->script()->argumentsHasVarBinding(); } /* diff --git a/js/src/vm/ScopeObject.h b/js/src/vm/ScopeObject.h index 3ce652619cb..bf7a3941ecb 100644 --- a/js/src/vm/ScopeObject.h +++ b/js/src/vm/ScopeObject.h @@ -51,9 +51,9 @@ ScopeCoordinateName(JSRuntime *rt, JSScript *script, jsbytecode *pc); * variable is used to refer to the jit/inference information). This function * maps from the ScopeCoordinate space to the StackFrame variable space. */ -enum FrameVarType { FrameVar_Local, FrameVar_Arg }; -extern FrameVarType -ScopeCoordinateToFrameVar(JSScript *script, jsbytecode *pc, unsigned *index); +enum FrameIndexType { FrameIndex_Local, FrameIndex_Arg }; +extern FrameIndexType +ScopeCoordinateToFrameIndex(JSScript *script, jsbytecode *pc, unsigned *index); /*****************************************************************************/ @@ -101,9 +101,6 @@ class ScopeObject : public JSObject static const uint32_t SCOPE_CHAIN_SLOT = 0; public: - /* Number of reserved slots for both CallObject and BlockObject. */ - static const uint32_t CALL_BLOCK_RESERVED_SLOTS = 2; - /* * Since every scope chain terminates with a global object and GlobalObject * does not derive ScopeObject (it has a completely different layout), the @@ -133,7 +130,7 @@ class CallObject : public ScopeObject create(JSContext *cx, JSScript *script, HandleObject enclosing, HandleFunction callee); public: - static const uint32_t RESERVED_SLOTS = CALL_BLOCK_RESERVED_SLOTS; + static const uint32_t RESERVED_SLOTS = 2; static CallObject *createForFunction(JSContext *cx, StackFrame *fp); static CallObject *createForStrictEval(JSContext *cx, StackFrame *fp); @@ -216,7 +213,7 @@ class WithObject : public NestedScopeObject class BlockObject : public NestedScopeObject { public: - static const unsigned RESERVED_SLOTS = CALL_BLOCK_RESERVED_SLOTS; + static const unsigned RESERVED_SLOTS = 2; static const gc::AllocKind FINALIZE_KIND = gc::FINALIZE_OBJECT4_BACKGROUND; /* Return the number of variables associated with this block. */ @@ -227,7 +224,8 @@ class BlockObject : public NestedScopeObject * range [0, slotCount()) and the return local index is in the range * [script->nfixed, script->nfixed + script->nslots). */ - unsigned slotToFrameLocal(JSScript *script, unsigned i); + unsigned slotToLocalIndex(const Bindings &bindings, unsigned slot); + unsigned localIndexToSlot(const Bindings &bindings, uint32_t i); protected: /* Blocks contain an object slot for each slot i: 0 <= i < slotCount. */