mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 769743 - simplify ScopedCoordinate::slot and fix names (r=dvander)
This commit is contained in:
parent
377048539c
commit
f3d3d4c0f8
@ -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)
|
||||
|
@ -46,16 +46,6 @@ SharedContext::needStrictChecks() {
|
||||
return context->hasStrictOption() || inStrictMode();
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
SharedContext::argumentsLocal() const
|
||||
{
|
||||
PropertyName *arguments = context->runtime->atomState.argumentsAtom;
|
||||
unsigned slot;
|
||||
DebugOnly<BindingKind> 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),
|
||||
|
@ -175,8 +175,6 @@ struct SharedContext {
|
||||
|
||||
#undef INFUNC
|
||||
|
||||
unsigned argumentsLocal() const;
|
||||
|
||||
bool inFunction() const { return !!fun_; }
|
||||
|
||||
JSFunction *fun() const { JS_ASSERT(inFunction()); return fun_; }
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -355,7 +355,7 @@ js::XDRScript(XDRState<mode> *xdr, JSScript **scriptp, JSScript *parentScript)
|
||||
StrictModeCode,
|
||||
ContainsDynamicNameAccess,
|
||||
FunHasExtensibleScope,
|
||||
ArgumentsHasLocalBinding,
|
||||
ArgumentsHasVarBinding,
|
||||
NeedsArgsObj,
|
||||
OwnFilename,
|
||||
ParentFilename,
|
||||
@ -373,7 +373,7 @@ js::XDRScript(XDRState<mode> *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<mode> *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<mode> *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<BindingKind> 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<JSScript*> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
@ -451,10 +452,6 @@ struct JSScript : public js::gc::Cell
|
||||
* or has had backedges taken. Reset if the
|
||||
* script's JIT code is forcibly discarded. */
|
||||
|
||||
#if JS_BITS_PER_WORD == 32
|
||||
uint32_t pad32;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
// Unique identifier within the compartment for this script, used for
|
||||
// printing analysis information.
|
||||
@ -478,9 +475,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 +536,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 +564,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
|
||||
|
@ -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<BindingKind> 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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 &
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user