mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 829554 - Abstract ScopeIter/DebugScopeProxy frame access. r=luke
--HG-- extra : rebase_source : 18cc0baea68fb9b91b32c54bedcac6eb805449e3
This commit is contained in:
parent
cf1257b075
commit
3f4c90b945
@ -282,6 +282,11 @@ class CompartmentChecker
|
||||
if (fp)
|
||||
check(fp->scopeChain());
|
||||
}
|
||||
|
||||
void check(TaggedFramePtr frame) {
|
||||
if (frame)
|
||||
check(frame.scopeChain());
|
||||
}
|
||||
};
|
||||
#endif /* JS_CRASH_DIAGNOSTICS */
|
||||
|
||||
|
@ -2714,9 +2714,9 @@ JSScript::argumentsOptimizationFailed(JSContext *cx, HandleScript script)
|
||||
*/
|
||||
if (i.isIon())
|
||||
continue;
|
||||
StackFrame *fp = i.interpFrame();
|
||||
if (fp->isFunctionFrame() && fp->script() == script) {
|
||||
ArgumentsObject *argsobj = ArgumentsObject::createExpected(cx, fp);
|
||||
TaggedFramePtr frame = i.taggedFramePtr();
|
||||
if (frame.isFunctionFrame() && frame.script() == script) {
|
||||
ArgumentsObject *argsobj = ArgumentsObject::createExpected(cx, frame);
|
||||
if (!argsobj) {
|
||||
/*
|
||||
* We can't leave stack frames with script->needsArgsObj but no
|
||||
@ -2728,8 +2728,8 @@ JSScript::argumentsOptimizationFailed(JSContext *cx, HandleScript script)
|
||||
}
|
||||
|
||||
/* Note: 'arguments' may have already been overwritten. */
|
||||
if (fp->unaliasedLocal(var).isMagic(JS_OPTIMIZED_ARGUMENTS))
|
||||
fp->unaliasedLocal(var) = ObjectValue(*argsobj);
|
||||
if (frame.unaliasedLocal(var).isMagic(JS_OPTIMIZED_ARGUMENTS))
|
||||
frame.unaliasedLocal(var) = ObjectValue(*argsobj);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,22 +23,22 @@ using namespace js;
|
||||
using namespace js::gc;
|
||||
|
||||
static void
|
||||
CopyStackFrameArguments(const StackFrame *fp, HeapValue *dst)
|
||||
CopyStackFrameArguments(const TaggedFramePtr frame, HeapValue *dst)
|
||||
{
|
||||
JS_ASSERT(!fp->runningInIon());
|
||||
JS_ASSERT_IF(frame.isStackFrame(), !frame.asStackFrame()->runningInIon());
|
||||
|
||||
unsigned numActuals = fp->numActualArgs();
|
||||
unsigned numFormals = fp->callee().nargs;
|
||||
unsigned numActuals = frame.numActualArgs();
|
||||
unsigned numFormals = frame.callee().nargs;
|
||||
|
||||
/* Copy formal arguments. */
|
||||
Value *src = fp->formals();
|
||||
Value *src = frame.formals();
|
||||
Value *end = src + numFormals;
|
||||
while (src != end)
|
||||
(dst++)->init(*src++);
|
||||
|
||||
/* Copy actual argument which are not contignous. */
|
||||
if (numFormals < numActuals) {
|
||||
src = fp->actuals() + numFormals;
|
||||
src = frame.actuals() + numFormals;
|
||||
end = src + (numActuals - numFormals);
|
||||
while (src != end)
|
||||
(dst++)->init(*src++);
|
||||
@ -46,26 +46,26 @@ CopyStackFrameArguments(const StackFrame *fp, HeapValue *dst)
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
ArgumentsObject::MaybeForwardToCallObject(StackFrame *fp, JSObject *obj, ArgumentsData *data)
|
||||
ArgumentsObject::MaybeForwardToCallObject(TaggedFramePtr frame, JSObject *obj, ArgumentsData *data)
|
||||
{
|
||||
UnrootedScript script = fp->script();
|
||||
if (fp->fun()->isHeavyweight() && script->argsObjAliasesFormals()) {
|
||||
obj->initFixedSlot(MAYBE_CALL_SLOT, ObjectValue(fp->callObj()));
|
||||
UnrootedScript script = frame.script();
|
||||
if (frame.fun()->isHeavyweight() && script->argsObjAliasesFormals()) {
|
||||
obj->initFixedSlot(MAYBE_CALL_SLOT, ObjectValue(frame.callObj()));
|
||||
for (AliasedFormalIter fi(script); fi; fi++)
|
||||
data->args[fi.frameIndex()] = MagicValue(JS_FORWARD_TO_CALL_OBJECT);
|
||||
}
|
||||
}
|
||||
|
||||
struct CopyStackFrameArgs
|
||||
struct CopyFrameArgs
|
||||
{
|
||||
StackFrame *fp_;
|
||||
TaggedFramePtr frame_;
|
||||
|
||||
CopyStackFrameArgs(StackFrame *fp)
|
||||
: fp_(fp)
|
||||
CopyFrameArgs(TaggedFramePtr frame)
|
||||
: frame_(frame)
|
||||
{ }
|
||||
|
||||
void copyArgs(HeapValue *dst) const {
|
||||
CopyStackFrameArguments(fp_, dst);
|
||||
CopyStackFrameArguments(frame_, dst);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -73,7 +73,7 @@ struct CopyStackFrameArgs
|
||||
* call object is the canonical location for formals.
|
||||
*/
|
||||
void maybeForwardToCallObject(JSObject *obj, ArgumentsData *data) {
|
||||
ArgumentsObject::MaybeForwardToCallObject(fp_, obj, data);
|
||||
ArgumentsObject::MaybeForwardToCallObject(frame_, obj, data);
|
||||
}
|
||||
};
|
||||
|
||||
@ -87,7 +87,7 @@ struct CopyStackIterArgs
|
||||
|
||||
void copyArgs(HeapValue *dstBase) const {
|
||||
if (!iter_.isIon()) {
|
||||
CopyStackFrameArguments(iter_.interpFrame(), dstBase);
|
||||
CopyStackFrameArguments(iter_.taggedFramePtr(), dstBase);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ struct CopyStackIterArgs
|
||||
*/
|
||||
void maybeForwardToCallObject(JSObject *obj, ArgumentsData *data) {
|
||||
if (!iter_.isIon())
|
||||
ArgumentsObject::MaybeForwardToCallObject(iter_.interpFrame(), obj, data);
|
||||
ArgumentsObject::MaybeForwardToCallObject(iter_.taggedFramePtr(), obj, data);
|
||||
}
|
||||
};
|
||||
|
||||
@ -176,17 +176,17 @@ ArgumentsObject::create(JSContext *cx, HandleScript script, HandleFunction calle
|
||||
}
|
||||
|
||||
ArgumentsObject *
|
||||
ArgumentsObject::createExpected(JSContext *cx, StackFrame *fp)
|
||||
ArgumentsObject::createExpected(JSContext *cx, TaggedFramePtr frame)
|
||||
{
|
||||
JS_ASSERT(fp->script()->needsArgsObj());
|
||||
RootedScript script(cx, fp->script());
|
||||
RootedFunction callee(cx, &fp->callee());
|
||||
CopyStackFrameArgs copy(fp);
|
||||
ArgumentsObject *argsobj = create(cx, script, callee, fp->numActualArgs(), copy);
|
||||
JS_ASSERT(frame.script()->needsArgsObj());
|
||||
RootedScript script(cx, frame.script());
|
||||
RootedFunction callee(cx, &frame.callee());
|
||||
CopyFrameArgs copy(frame);
|
||||
ArgumentsObject *argsobj = create(cx, script, callee, frame.numActualArgs(), copy);
|
||||
if (!argsobj)
|
||||
return NULL;
|
||||
|
||||
fp->initArgsObj(*argsobj);
|
||||
frame.initArgsObj(*argsobj);
|
||||
return argsobj;
|
||||
}
|
||||
|
||||
@ -200,12 +200,12 @@ ArgumentsObject::createUnexpected(JSContext *cx, StackIter &iter)
|
||||
}
|
||||
|
||||
ArgumentsObject *
|
||||
ArgumentsObject::createUnexpected(JSContext *cx, StackFrame *fp)
|
||||
ArgumentsObject::createUnexpected(JSContext *cx, TaggedFramePtr frame)
|
||||
{
|
||||
RootedScript script(cx, fp->script());
|
||||
RootedFunction callee(cx, &fp->callee());
|
||||
CopyStackFrameArgs copy(fp);
|
||||
return create(cx, script, callee, fp->numActualArgs(), copy);
|
||||
RootedScript script(cx, frame.script());
|
||||
RootedFunction callee(cx, &frame.callee());
|
||||
CopyFrameArgs copy(frame);
|
||||
return create(cx, script, callee, frame.numActualArgs(), copy);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -114,7 +114,7 @@ class ArgumentsObject : public JSObject
|
||||
static const gc::AllocKind FINALIZE_KIND = gc::FINALIZE_OBJECT4;
|
||||
|
||||
/* Create an arguments object for a frame that is expecting them. */
|
||||
static ArgumentsObject *createExpected(JSContext *cx, StackFrame *fp);
|
||||
static ArgumentsObject *createExpected(JSContext *cx, TaggedFramePtr frame);
|
||||
|
||||
/*
|
||||
* Purposefully disconnect the returned arguments object from the frame
|
||||
@ -123,7 +123,7 @@ class ArgumentsObject : public JSObject
|
||||
* not aliased and generally simplifies arguments objects.
|
||||
*/
|
||||
static ArgumentsObject *createUnexpected(JSContext *cx, StackIter &iter);
|
||||
static ArgumentsObject *createUnexpected(JSContext *cx, StackFrame *fp);
|
||||
static ArgumentsObject *createUnexpected(JSContext *cx, TaggedFramePtr frame);
|
||||
|
||||
/*
|
||||
* Return the initial length of the arguments. This may differ from the
|
||||
@ -202,7 +202,7 @@ class ArgumentsObject : public JSObject
|
||||
return getFixedSlotOffset(DATA_SLOT);
|
||||
}
|
||||
|
||||
static void MaybeForwardToCallObject(StackFrame *fp, JSObject *obj, ArgumentsData *data);
|
||||
static void MaybeForwardToCallObject(TaggedFramePtr frame, JSObject *obj, ArgumentsData *data);
|
||||
};
|
||||
|
||||
class NormalArgumentsObject : public ArgumentsObject
|
||||
|
@ -3360,7 +3360,7 @@ DebuggerFrame_getEnvironment(JSContext *cx, unsigned argc, Value *vp)
|
||||
Rooted<Env*> env(cx);
|
||||
{
|
||||
AutoCompartment ac(cx, iter.scopeChain());
|
||||
env = GetDebugScopeForFrame(cx, iter.interpFrame());
|
||||
env = GetDebugScopeForFrame(cx, iter.taggedFramePtr());
|
||||
if (!env)
|
||||
return false;
|
||||
}
|
||||
@ -3777,7 +3777,7 @@ DebuggerGenericEval(JSContext *cx, const char *fullMethodName,
|
||||
if (!iter->computeThis())
|
||||
return false;
|
||||
thisv = iter->thisv();
|
||||
env = GetDebugScopeForFrame(cx, iter->interpFrame());
|
||||
env = GetDebugScopeForFrame(cx, iter->taggedFramePtr());
|
||||
if (!env)
|
||||
return false;
|
||||
} else {
|
||||
|
@ -220,22 +220,22 @@ CallObject::createForFunction(JSContext *cx, HandleObject enclosing, HandleFunct
|
||||
}
|
||||
|
||||
CallObject *
|
||||
CallObject::createForFunction(JSContext *cx, StackFrame *fp)
|
||||
CallObject::createForFunction(JSContext *cx, TaggedFramePtr frame)
|
||||
{
|
||||
AssertCanGC();
|
||||
JS_ASSERT(fp->isNonEvalFunctionFrame());
|
||||
assertSameCompartment(cx, fp);
|
||||
JS_ASSERT(frame.isNonEvalFunctionFrame());
|
||||
assertSameCompartment(cx, frame);
|
||||
|
||||
RootedObject scopeChain(cx, fp->scopeChain());
|
||||
RootedFunction callee(cx, &fp->callee());
|
||||
RootedObject scopeChain(cx, frame.scopeChain());
|
||||
RootedFunction callee(cx, &frame.callee());
|
||||
|
||||
CallObject *callobj = createForFunction(cx, scopeChain, callee);
|
||||
if (!callobj)
|
||||
return NULL;
|
||||
|
||||
/* Copy in the closed-over formal arguments. */
|
||||
for (AliasedFormalIter i(fp->script()); i; i++)
|
||||
callobj->setAliasedVar(i, fp->unaliasedFormal(i.frameIndex(), DONT_CHECK_ALIASING));
|
||||
for (AliasedFormalIter i(frame.script()); i; i++)
|
||||
callobj->setAliasedVar(i, frame.unaliasedFormal(i.frameIndex(), DONT_CHECK_ALIASING));
|
||||
|
||||
return callobj;
|
||||
}
|
||||
@ -611,9 +611,9 @@ Class js::WithClass = {
|
||||
/*****************************************************************************/
|
||||
|
||||
ClonedBlockObject *
|
||||
ClonedBlockObject::create(JSContext *cx, Handle<StaticBlockObject *> block, StackFrame *fp)
|
||||
ClonedBlockObject::create(JSContext *cx, Handle<StaticBlockObject *> block, TaggedFramePtr frame)
|
||||
{
|
||||
assertSameCompartment(cx, fp);
|
||||
assertSameCompartment(cx, frame);
|
||||
|
||||
RootedTypeObject type(cx, block->getNewType(cx));
|
||||
if (!type)
|
||||
@ -630,9 +630,9 @@ ClonedBlockObject::create(JSContext *cx, Handle<StaticBlockObject *> block, Stac
|
||||
return NULL;
|
||||
|
||||
/* Set the parent if necessary, as for call objects. */
|
||||
if (&fp->global() != obj->getParent()) {
|
||||
if (&frame.scopeChain()->global() != obj->getParent()) {
|
||||
JS_ASSERT(obj->getParent() == NULL);
|
||||
Rooted<GlobalObject*> global(cx, &fp->global());
|
||||
Rooted<GlobalObject*> global(cx, &frame.scopeChain()->global());
|
||||
if (!JSObject::setParent(cx, obj, global))
|
||||
return NULL;
|
||||
}
|
||||
@ -640,18 +640,18 @@ ClonedBlockObject::create(JSContext *cx, Handle<StaticBlockObject *> block, Stac
|
||||
JS_ASSERT(!obj->inDictionaryMode());
|
||||
JS_ASSERT(obj->slotSpan() >= block->slotCount() + RESERVED_SLOTS);
|
||||
|
||||
obj->setReservedSlot(SCOPE_CHAIN_SLOT, ObjectValue(*fp->scopeChain()));
|
||||
obj->setReservedSlot(SCOPE_CHAIN_SLOT, ObjectValue(*frame.scopeChain()));
|
||||
obj->setReservedSlot(DEPTH_SLOT, PrivateUint32Value(block->stackDepth()));
|
||||
|
||||
/*
|
||||
* Copy in the closed-over locals. Closed-over locals don't need
|
||||
* any fixup since the initial value is 'undefined'.
|
||||
*/
|
||||
Value *src = fp->base() + block->stackDepth();
|
||||
unsigned nslots = block->slotCount();
|
||||
for (unsigned i = 0; i < nslots; ++i, ++src) {
|
||||
unsigned base = frame.script()->nfixed + block->stackDepth();
|
||||
for (unsigned i = 0; i < nslots; ++i) {
|
||||
if (block->isAliased(i))
|
||||
obj->asClonedBlock().setVar(i, *src);
|
||||
obj->asClonedBlock().setVar(i, frame.unaliasedLocal(base + i));
|
||||
}
|
||||
|
||||
JS_ASSERT(obj->isDelegate());
|
||||
@ -660,14 +660,14 @@ ClonedBlockObject::create(JSContext *cx, Handle<StaticBlockObject *> block, Stac
|
||||
}
|
||||
|
||||
void
|
||||
ClonedBlockObject::copyUnaliasedValues(StackFrame *fp)
|
||||
ClonedBlockObject::copyUnaliasedValues(TaggedFramePtr frame)
|
||||
{
|
||||
AutoAssertNoGC nogc;
|
||||
StaticBlockObject &block = staticBlock();
|
||||
unsigned base = fp->script()->nfixed + block.stackDepth();
|
||||
unsigned base = frame.script()->nfixed + block.stackDepth();
|
||||
for (unsigned i = 0; i < slotCount(); ++i) {
|
||||
if (!block.isAliased(i))
|
||||
setVar(i, fp->unaliasedLocal(base + i), DONT_CHECK_ALIASING);
|
||||
setVar(i, frame.unaliasedLocal(base + i), DONT_CHECK_ALIASING);
|
||||
}
|
||||
}
|
||||
|
||||
@ -881,7 +881,7 @@ js::CloneStaticBlockObject(JSContext *cx, HandleObject enclosingScope, Handle<St
|
||||
|
||||
ScopeIter::ScopeIter(JSContext *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
: fp_(NULL),
|
||||
: frame_(),
|
||||
cur_(cx, reinterpret_cast<JSObject *>(-1)),
|
||||
block_(cx, reinterpret_cast<StaticBlockObject *>(-1)),
|
||||
type_(Type(-1))
|
||||
@ -891,7 +891,7 @@ ScopeIter::ScopeIter(JSContext *cx
|
||||
|
||||
ScopeIter::ScopeIter(const ScopeIter &si, JSContext *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
: fp_(si.fp_),
|
||||
: frame_(si.frame_),
|
||||
cur_(cx, si.cur_),
|
||||
block_(cx, si.block_),
|
||||
type_(si.type_),
|
||||
@ -902,7 +902,7 @@ ScopeIter::ScopeIter(const ScopeIter &si, JSContext *cx
|
||||
|
||||
ScopeIter::ScopeIter(JSObject &enclosingScope, JSContext *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
: fp_(NULL),
|
||||
: frame_(),
|
||||
cur_(cx, &enclosingScope),
|
||||
block_(cx, reinterpret_cast<StaticBlockObject *>(-1)),
|
||||
type_(Type(-1))
|
||||
@ -910,20 +910,20 @@ ScopeIter::ScopeIter(JSObject &enclosingScope, JSContext *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
ScopeIter::ScopeIter(StackFrame *fp, JSContext *cx
|
||||
ScopeIter::ScopeIter(TaggedFramePtr frame, JSContext *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
: fp_(fp),
|
||||
cur_(cx, fp->scopeChain()),
|
||||
block_(cx, fp->maybeBlockChain())
|
||||
: frame_(frame),
|
||||
cur_(cx, frame.scopeChain()),
|
||||
block_(cx, frame.maybeBlockChain())
|
||||
{
|
||||
assertSameCompartment(cx, fp);
|
||||
assertSameCompartment(cx, frame);
|
||||
settle();
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
ScopeIter::ScopeIter(const ScopeIter &si, StackFrame *fp, JSContext *cx
|
||||
ScopeIter::ScopeIter(const ScopeIter &si, TaggedFramePtr frame, JSContext *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
: fp_(fp),
|
||||
: frame_(frame),
|
||||
cur_(cx, si.cur_),
|
||||
block_(cx, si.block_),
|
||||
type_(si.type_),
|
||||
@ -932,9 +932,9 @@ ScopeIter::ScopeIter(const ScopeIter &si, StackFrame *fp, JSContext *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
ScopeIter::ScopeIter(StackFrame *fp, ScopeObject &scope, JSContext *cx
|
||||
ScopeIter::ScopeIter(TaggedFramePtr frame, ScopeObject &scope, JSContext *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
: fp_(fp),
|
||||
: frame_(frame),
|
||||
cur_(cx, &scope),
|
||||
block_(cx)
|
||||
{
|
||||
@ -954,7 +954,7 @@ ScopeIter::ScopeIter(StackFrame *fp, ScopeObject &scope, JSContext *cx
|
||||
* determine the block (if any) that encloses 'scope'.
|
||||
*/
|
||||
if (cur_->isNestedScope()) {
|
||||
block_ = fp->maybeBlockChain();
|
||||
block_ = frame.maybeBlockChain();
|
||||
while (block_) {
|
||||
if (block_->stackDepth() <= cur_->asNestedScope().stackDepth())
|
||||
break;
|
||||
@ -983,10 +983,10 @@ ScopeIter::operator++()
|
||||
case Call:
|
||||
if (hasScopeObject_) {
|
||||
cur_ = &cur_->asCall().enclosingScope();
|
||||
if (CallObjectLambdaName(*fp_->fun()))
|
||||
if (CallObjectLambdaName(*frame_.fun()))
|
||||
cur_ = &cur_->asDeclEnv().enclosingScope();
|
||||
}
|
||||
fp_ = NULL;
|
||||
frame_ = TaggedFramePtr();
|
||||
break;
|
||||
case Block:
|
||||
block_ = block_->enclosingBlock();
|
||||
@ -1002,7 +1002,7 @@ ScopeIter::operator++()
|
||||
case StrictEvalScope:
|
||||
if (hasScopeObject_)
|
||||
cur_ = &cur_->asCall().enclosingScope();
|
||||
fp_ = NULL;
|
||||
frame_ = TaggedFramePtr();
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
@ -1035,7 +1035,7 @@ ScopeIter::settle()
|
||||
* ever introduced as the *enclosing* scope of a frame, they should never
|
||||
* show up in scope iteration and fall into the final non-scope case.
|
||||
*/
|
||||
if (fp_->isNonEvalFunctionFrame() && !fp_->fun()->isHeavyweight()) {
|
||||
if (frame_.isNonEvalFunctionFrame() && !frame_.fun()->isHeavyweight()) {
|
||||
if (block_) {
|
||||
type_ = Block;
|
||||
hasScopeObject_ = block_->needsClone();
|
||||
@ -1043,22 +1043,22 @@ ScopeIter::settle()
|
||||
type_ = Call;
|
||||
hasScopeObject_ = false;
|
||||
}
|
||||
} else if (fp_->isNonStrictDirectEvalFrame() && cur_ == fp_->prev()->scopeChain()) {
|
||||
} else if (frame_.isNonStrictDirectEvalFrame() && cur_ == frame_.evalPrev().scopeChain()) {
|
||||
if (block_) {
|
||||
JS_ASSERT(!block_->needsClone());
|
||||
type_ = Block;
|
||||
hasScopeObject_ = false;
|
||||
} else {
|
||||
fp_ = NULL;
|
||||
frame_ = TaggedFramePtr();
|
||||
}
|
||||
} else if (fp_->isNonEvalFunctionFrame() && !fp_->hasCallObj()) {
|
||||
JS_ASSERT(cur_ == fp_->fun()->environment());
|
||||
fp_ = NULL;
|
||||
} else if (fp_->isStrictEvalFrame() && !fp_->hasCallObj()) {
|
||||
JS_ASSERT(cur_ == fp_->prev()->scopeChain());
|
||||
fp_ = NULL;
|
||||
} else if (frame_.isNonEvalFunctionFrame() && !frame_.hasCallObj()) {
|
||||
JS_ASSERT(cur_ == frame_.fun()->environment());
|
||||
frame_ = TaggedFramePtr();
|
||||
} else if (frame_.isStrictEvalFrame() && !frame_.hasCallObj()) {
|
||||
JS_ASSERT(cur_ == frame_.evalPrev().scopeChain());
|
||||
frame_ = TaggedFramePtr();
|
||||
} else if (cur_->isWith()) {
|
||||
JS_ASSERT_IF(fp_->isFunctionFrame(), fp_->fun()->isHeavyweight());
|
||||
JS_ASSERT_IF(frame_.isFunctionFrame(), frame_.fun()->isHeavyweight());
|
||||
JS_ASSERT_IF(block_, block_->needsClone());
|
||||
JS_ASSERT_IF(block_, block_->stackDepth() < cur_->asWith().stackDepth());
|
||||
type_ = With;
|
||||
@ -1071,11 +1071,11 @@ ScopeIter::settle()
|
||||
CallObject &callobj = cur_->asCall();
|
||||
type_ = callobj.isForEval() ? StrictEvalScope : Call;
|
||||
hasScopeObject_ = true;
|
||||
JS_ASSERT_IF(type_ == Call, callobj.callee().nonLazyScript() == fp_->script());
|
||||
JS_ASSERT_IF(type_ == Call, callobj.callee().nonLazyScript() == frame_.script());
|
||||
} else {
|
||||
JS_ASSERT(!cur_->isScope());
|
||||
JS_ASSERT(fp_->isGlobalFrame() || fp_->isDebuggerFrame());
|
||||
fp_ = NULL;
|
||||
JS_ASSERT(frame_.isGlobalFrame() || frame_.isDebuggerFrame());
|
||||
frame_ = TaggedFramePtr();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1083,15 +1083,15 @@ ScopeIter::settle()
|
||||
ScopeIterKey::hash(ScopeIterKey si)
|
||||
{
|
||||
/* hasScopeObject_ is determined by the other fields. */
|
||||
return size_t(si.fp_) ^ size_t(si.cur_) ^ size_t(si.block_) ^ si.type_;
|
||||
return size_t(si.frame_.raw()) ^ size_t(si.cur_) ^ size_t(si.block_) ^ si.type_;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
ScopeIterKey::match(ScopeIterKey si1, ScopeIterKey si2)
|
||||
{
|
||||
/* hasScopeObject_ is determined by the other fields. */
|
||||
return si1.fp_ == si2.fp_ &&
|
||||
(!si1.fp_ ||
|
||||
return si1.frame_ == si2.frame_ &&
|
||||
(!si1.frame_ ||
|
||||
(si1.cur_ == si2.cur_ &&
|
||||
si1.block_ == si2.block_ &&
|
||||
si1.type_ == si2.type_));
|
||||
@ -1148,7 +1148,7 @@ class DebugScopeProxy : public BaseProxyHandler
|
||||
jsid id, Action action, Value *vp)
|
||||
{
|
||||
JS_ASSERT(&debugScope->scope() == scope);
|
||||
StackFrame *maybefp = DebugScopes::hasLiveFrame(*scope);
|
||||
TaggedFramePtr maybeframe = DebugScopes::hasLiveFrame(*scope);
|
||||
|
||||
/* Handle unaliased formals, vars, and consts at function scope. */
|
||||
if (scope->isCall() && !scope->asCall().isForEval()) {
|
||||
@ -1169,11 +1169,11 @@ class DebugScopeProxy : public BaseProxyHandler
|
||||
if (script->varIsAliased(i))
|
||||
return false;
|
||||
|
||||
if (maybefp) {
|
||||
if (maybeframe) {
|
||||
if (action == GET)
|
||||
*vp = maybefp->unaliasedVar(i);
|
||||
*vp = maybeframe.unaliasedVar(i);
|
||||
else
|
||||
maybefp->unaliasedVar(i) = *vp;
|
||||
maybeframe.unaliasedVar(i) = *vp;
|
||||
} else if (JSObject *snapshot = debugScope->maybeSnapshot()) {
|
||||
if (action == GET)
|
||||
*vp = snapshot->getDenseElement(bindings.numArgs() + i);
|
||||
@ -1194,17 +1194,17 @@ class DebugScopeProxy : public BaseProxyHandler
|
||||
if (script->formalIsAliased(i))
|
||||
return false;
|
||||
|
||||
if (maybefp) {
|
||||
if (script->argsObjAliasesFormals() && maybefp->hasArgsObj()) {
|
||||
if (maybeframe) {
|
||||
if (script->argsObjAliasesFormals() && maybeframe.hasArgsObj()) {
|
||||
if (action == GET)
|
||||
*vp = maybefp->argsObj().arg(i);
|
||||
*vp = maybeframe.argsObj().arg(i);
|
||||
else
|
||||
maybefp->argsObj().setArg(i, *vp);
|
||||
maybeframe.argsObj().setArg(i, *vp);
|
||||
} else {
|
||||
if (action == GET)
|
||||
*vp = maybefp->unaliasedFormal(i, DONT_CHECK_ALIASING);
|
||||
*vp = maybeframe.unaliasedFormal(i, DONT_CHECK_ALIASING);
|
||||
else
|
||||
maybefp->unaliasedFormal(i, DONT_CHECK_ALIASING) = *vp;
|
||||
maybeframe.unaliasedFormal(i, DONT_CHECK_ALIASING) = *vp;
|
||||
}
|
||||
} else if (JSObject *snapshot = debugScope->maybeSnapshot()) {
|
||||
if (action == GET)
|
||||
@ -1236,13 +1236,13 @@ class DebugScopeProxy : public BaseProxyHandler
|
||||
if (block->staticBlock().isAliased(i))
|
||||
return false;
|
||||
|
||||
if (maybefp) {
|
||||
UnrootedScript script = maybefp->script();
|
||||
if (maybeframe) {
|
||||
UnrootedScript script = maybeframe.script();
|
||||
unsigned local = block->slotToLocalIndex(script->bindings, shape->slot());
|
||||
if (action == GET)
|
||||
*vp = maybefp->unaliasedLocal(local);
|
||||
*vp = maybeframe.unaliasedLocal(local);
|
||||
else
|
||||
maybefp->unaliasedLocal(local) = *vp;
|
||||
maybeframe.unaliasedLocal(local) = *vp;
|
||||
JS_ASSERT(analyze::LocalSlot(script, local) >= analyze::TotalSlots(script));
|
||||
} else {
|
||||
if (action == GET)
|
||||
@ -1299,14 +1299,14 @@ class DebugScopeProxy : public BaseProxyHandler
|
||||
if (scope.asCall().callee().nonLazyScript()->needsArgsObj())
|
||||
return true;
|
||||
|
||||
StackFrame *maybefp = DebugScopes::hasLiveFrame(scope);
|
||||
if (!maybefp) {
|
||||
TaggedFramePtr maybeframe = DebugScopes::hasLiveFrame(scope);
|
||||
if (!maybeframe) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_DEBUG_NOT_LIVE,
|
||||
"Debugger scope");
|
||||
return false;
|
||||
}
|
||||
|
||||
*maybeArgsObj = ArgumentsObject::createUnexpected(cx, maybefp);
|
||||
*maybeArgsObj = ArgumentsObject::createUnexpected(cx, maybeframe);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1597,7 +1597,7 @@ DebugScopes::sweep(JSRuntime *rt)
|
||||
|
||||
for (LiveScopeMap::Enum e(liveScopes); !e.empty(); e.popFront()) {
|
||||
ScopeObject *scope = e.front().key;
|
||||
StackFrame *fp = e.front().value;
|
||||
TaggedFramePtr frame = e.front().value;
|
||||
|
||||
/*
|
||||
* Scopes can be finalized when a debugger-synthesized ScopeObject is
|
||||
@ -1613,7 +1613,7 @@ DebugScopes::sweep(JSRuntime *rt)
|
||||
* suspended generator frames. Since a generator can be finalized while
|
||||
* its scope is live, we must explicitly detect finalized generators.
|
||||
*/
|
||||
if (JSGenerator *gen = fp->maybeSuspendedGenerator(rt)) {
|
||||
if (JSGenerator *gen = frame.maybeSuspendedGenerator(rt)) {
|
||||
JS_ASSERT(gen->state == JSGEN_NEWBORN || gen->state == JSGEN_OPEN);
|
||||
if (IsObjectAboutToBeFinalized(&gen->obj)) {
|
||||
e.removeFront();
|
||||
@ -1725,7 +1725,7 @@ DebugScopes::addDebugScope(JSContext *cx, const ScopeIter &si, DebugScopeObject
|
||||
}
|
||||
|
||||
JS_ASSERT(!scopes->liveScopes.has(&debugScope.scope()));
|
||||
if (!scopes->liveScopes.put(&debugScope.scope(), si.fp())) {
|
||||
if (!scopes->liveScopes.put(&debugScope.scope(), si.frame())) {
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
@ -1734,10 +1734,10 @@ DebugScopes::addDebugScope(JSContext *cx, const ScopeIter &si, DebugScopeObject
|
||||
}
|
||||
|
||||
void
|
||||
DebugScopes::onPopCall(StackFrame *fp, JSContext *cx)
|
||||
DebugScopes::onPopCall(TaggedFramePtr frame, JSContext *cx)
|
||||
{
|
||||
JS_ASSERT(!fp->isYielding());
|
||||
assertSameCompartment(cx, fp);
|
||||
JS_ASSERT(!frame.isYielding());
|
||||
assertSameCompartment(cx, frame);
|
||||
|
||||
DebugScopes *scopes = cx->compartment->debugScopes;
|
||||
if (!scopes)
|
||||
@ -1745,20 +1745,20 @@ DebugScopes::onPopCall(StackFrame *fp, JSContext *cx)
|
||||
|
||||
Rooted<DebugScopeObject*> debugScope(cx, NULL);
|
||||
|
||||
if (fp->fun()->isHeavyweight()) {
|
||||
if (frame.fun()->isHeavyweight()) {
|
||||
/*
|
||||
* The StackFrame may be observed before the prologue has created the
|
||||
* CallObject. See ScopeIter::settle.
|
||||
*/
|
||||
if (!fp->hasCallObj())
|
||||
if (!frame.hasCallObj())
|
||||
return;
|
||||
|
||||
CallObject &callobj = fp->scopeChain()->asCall();
|
||||
CallObject &callobj = frame.scopeChain()->asCall();
|
||||
scopes->liveScopes.remove(&callobj);
|
||||
if (ObjectWeakMap::Ptr p = scopes->proxiedScopes.lookup(&callobj))
|
||||
debugScope = &p->value->asDebugScope();
|
||||
} else {
|
||||
ScopeIter si(fp, cx);
|
||||
ScopeIter si(frame, cx);
|
||||
if (MissingScopeMap::Ptr p = scopes->missingScopes.lookup(si)) {
|
||||
debugScope = p->value;
|
||||
scopes->liveScopes.remove(&debugScope->scope().asCall());
|
||||
@ -1783,18 +1783,18 @@ DebugScopes::onPopCall(StackFrame *fp, JSContext *cx)
|
||||
* but it simplifies later indexing logic.
|
||||
*/
|
||||
AutoValueVector vec(cx);
|
||||
if (!fp->copyRawFrameSlots(&vec) || vec.length() == 0)
|
||||
if (!frame.copyRawFrameSlots(&vec) || vec.length() == 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Copy in formals that are not aliased via the scope chain
|
||||
* but are aliased via the arguments object.
|
||||
*/
|
||||
RootedScript script(cx, fp->script());
|
||||
if (script->needsArgsObj() && fp->hasArgsObj()) {
|
||||
for (unsigned i = 0; i < fp->numFormalArgs(); ++i) {
|
||||
RootedScript script(cx, frame.script());
|
||||
if (script->needsArgsObj() && frame.hasArgsObj()) {
|
||||
for (unsigned i = 0; i < frame.numFormalArgs(); ++i) {
|
||||
if (script->formalLivesInArgumentsObject(i))
|
||||
vec[i] = fp->argsObj().arg(i);
|
||||
vec[i] = frame.argsObj().arg(i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1813,24 +1813,24 @@ DebugScopes::onPopCall(StackFrame *fp, JSContext *cx)
|
||||
}
|
||||
|
||||
void
|
||||
DebugScopes::onPopBlock(JSContext *cx, StackFrame *fp)
|
||||
DebugScopes::onPopBlock(JSContext *cx, TaggedFramePtr frame)
|
||||
{
|
||||
assertSameCompartment(cx, fp);
|
||||
assertSameCompartment(cx, frame);
|
||||
|
||||
DebugScopes *scopes = cx->compartment->debugScopes;
|
||||
if (!scopes)
|
||||
return;
|
||||
|
||||
StaticBlockObject &staticBlock = *fp->maybeBlockChain();
|
||||
StaticBlockObject &staticBlock = *frame.maybeBlockChain();
|
||||
if (staticBlock.needsClone()) {
|
||||
ClonedBlockObject &clone = fp->scopeChain()->asClonedBlock();
|
||||
clone.copyUnaliasedValues(fp);
|
||||
ClonedBlockObject &clone = frame.scopeChain()->asClonedBlock();
|
||||
clone.copyUnaliasedValues(frame);
|
||||
scopes->liveScopes.remove(&clone);
|
||||
} else {
|
||||
ScopeIter si(fp, cx);
|
||||
ScopeIter si(frame, cx);
|
||||
if (MissingScopeMap::Ptr p = scopes->missingScopes.lookup(si)) {
|
||||
ClonedBlockObject &clone = p->value->scope().asClonedBlock();
|
||||
clone.copyUnaliasedValues(fp);
|
||||
clone.copyUnaliasedValues(frame);
|
||||
scopes->liveScopes.remove(&clone);
|
||||
scopes->missingScopes.remove(p);
|
||||
}
|
||||
@ -1838,17 +1838,17 @@ DebugScopes::onPopBlock(JSContext *cx, StackFrame *fp)
|
||||
}
|
||||
|
||||
void
|
||||
DebugScopes::onPopWith(StackFrame *fp)
|
||||
DebugScopes::onPopWith(TaggedFramePtr frame)
|
||||
{
|
||||
DebugScopes *scopes = fp->compartment()->debugScopes;
|
||||
DebugScopes *scopes = frame.compartment()->debugScopes;
|
||||
if (scopes)
|
||||
scopes->liveScopes.remove(&fp->scopeChain()->asWith());
|
||||
scopes->liveScopes.remove(&frame.scopeChain()->asWith());
|
||||
}
|
||||
|
||||
void
|
||||
DebugScopes::onPopStrictEvalScope(StackFrame *fp)
|
||||
DebugScopes::onPopStrictEvalScope(TaggedFramePtr frame)
|
||||
{
|
||||
DebugScopes *scopes = fp->compartment()->debugScopes;
|
||||
DebugScopes *scopes = frame.compartment()->debugScopes;
|
||||
if (!scopes)
|
||||
return;
|
||||
|
||||
@ -1856,12 +1856,12 @@ DebugScopes::onPopStrictEvalScope(StackFrame *fp)
|
||||
* The StackFrame may be observed before the prologue has created the
|
||||
* CallObject. See ScopeIter::settle.
|
||||
*/
|
||||
if (fp->hasCallObj())
|
||||
scopes->liveScopes.remove(&fp->scopeChain()->asCall());
|
||||
if (frame.hasCallObj())
|
||||
scopes->liveScopes.remove(&frame.scopeChain()->asCall());
|
||||
}
|
||||
|
||||
void
|
||||
DebugScopes::onGeneratorFrameChange(StackFrame *from, StackFrame *to, JSContext *cx)
|
||||
DebugScopes::onGeneratorFrameChange(TaggedFramePtr from, TaggedFramePtr to, JSContext *cx)
|
||||
{
|
||||
for (ScopeIter toIter(to, cx); !toIter.done(); ++toIter) {
|
||||
DebugScopes *scopes = ensureCompartmentData(cx);
|
||||
@ -1884,7 +1884,7 @@ DebugScopes::onGeneratorFrameChange(StackFrame *from, StackFrame *to, JSContext
|
||||
scopes->liveScopes.add(livePtr, &toIter.scope(), to); // OOM here?
|
||||
} else {
|
||||
ScopeIter si(toIter, from, cx);
|
||||
JS_ASSERT(si.fp()->compartment() == cx->compartment);
|
||||
JS_ASSERT(si.frame().scopeChain()->compartment() == cx->compartment);
|
||||
if (MissingScopeMap::Ptr p = scopes->missingScopes.lookup(si)) {
|
||||
DebugScopeObject &debugScope = *p->value;
|
||||
scopes->liveScopes.lookup(&debugScope.scope())->value = to;
|
||||
@ -1930,39 +1930,39 @@ DebugScopes::updateLiveScopes(JSContext *cx)
|
||||
if (i.isIon())
|
||||
continue;
|
||||
|
||||
StackFrame *fp = i.interpFrame();
|
||||
if (fp->scopeChain()->compartment() != cx->compartment)
|
||||
TaggedFramePtr frame = i.taggedFramePtr();
|
||||
if (frame.scopeChain()->compartment() != cx->compartment)
|
||||
continue;
|
||||
|
||||
for (ScopeIter si(fp, cx); !si.done(); ++si) {
|
||||
for (ScopeIter si(frame, cx); !si.done(); ++si) {
|
||||
if (si.hasScopeObject()) {
|
||||
JS_ASSERT(si.scope().compartment() == cx->compartment);
|
||||
DebugScopes *scopes = ensureCompartmentData(cx);
|
||||
if (!scopes)
|
||||
return false;
|
||||
if (!scopes->liveScopes.put(&si.scope(), fp))
|
||||
if (!scopes->liveScopes.put(&si.scope(), frame))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (fp->prevUpToDate())
|
||||
if (frame.prevUpToDate())
|
||||
return true;
|
||||
JS_ASSERT(fp->compartment()->debugMode());
|
||||
fp->setPrevUpToDate();
|
||||
JS_ASSERT(frame.scopeChain()->compartment()->debugMode());
|
||||
frame.setPrevUpToDate();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
StackFrame *
|
||||
TaggedFramePtr
|
||||
DebugScopes::hasLiveFrame(ScopeObject &scope)
|
||||
{
|
||||
DebugScopes *scopes = scope.compartment()->debugScopes;
|
||||
if (!scopes)
|
||||
return NULL;
|
||||
return TaggedFramePtr();
|
||||
|
||||
if (LiveScopeMap::Ptr p = scopes->liveScopes.lookup(&scope)) {
|
||||
StackFrame *fp = p->value;
|
||||
TaggedFramePtr frame = p->value;
|
||||
|
||||
/*
|
||||
* Since liveScopes is effectively a weak pointer, we need a read
|
||||
@ -1975,12 +1975,12 @@ DebugScopes::hasLiveFrame(ScopeObject &scope)
|
||||
* 4. GC completes, live objects may now point to values that weren't
|
||||
* marked and thus may point to swept GC things
|
||||
*/
|
||||
if (JSGenerator *gen = fp->maybeSuspendedGenerator(scope.compartment()->rt))
|
||||
if (JSGenerator *gen = frame.maybeSuspendedGenerator(scope.compartment()->rt))
|
||||
JSObject::readBarrier(gen->obj);
|
||||
|
||||
return fp;
|
||||
return frame;
|
||||
}
|
||||
return NULL;
|
||||
return TaggedFramePtr();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -2041,7 +2041,7 @@ GetDebugScopeForMissing(JSContext *cx, const ScopeIter &si)
|
||||
DebugScopeObject *debugScope = NULL;
|
||||
switch (si.type()) {
|
||||
case ScopeIter::Call: {
|
||||
Rooted<CallObject*> callobj(cx, CallObject::createForFunction(cx, si.fp()));
|
||||
Rooted<CallObject*> callobj(cx, CallObject::createForFunction(cx, si.frame()));
|
||||
if (!callobj)
|
||||
return NULL;
|
||||
|
||||
@ -2058,7 +2058,7 @@ GetDebugScopeForMissing(JSContext *cx, const ScopeIter &si)
|
||||
}
|
||||
case ScopeIter::Block: {
|
||||
Rooted<StaticBlockObject *> staticBlock(cx, &si.staticBlock());
|
||||
ClonedBlockObject *block = ClonedBlockObject::create(cx, staticBlock, si.fp());
|
||||
ClonedBlockObject *block = ClonedBlockObject::create(cx, staticBlock, si.frame());
|
||||
if (!block)
|
||||
return NULL;
|
||||
|
||||
@ -2097,8 +2097,8 @@ GetDebugScope(JSContext *cx, JSObject &obj)
|
||||
}
|
||||
|
||||
Rooted<ScopeObject*> scope(cx, &obj.asScope());
|
||||
if (StackFrame *fp = DebugScopes::hasLiveFrame(*scope)) {
|
||||
ScopeIter si(fp, *scope, cx);
|
||||
if (TaggedFramePtr frame = DebugScopes::hasLiveFrame(*scope)) {
|
||||
ScopeIter si(frame, *scope, cx);
|
||||
return GetDebugScope(cx, si);
|
||||
}
|
||||
ScopeIter si(scope->enclosingScope(), cx);
|
||||
@ -2133,11 +2133,11 @@ js::GetDebugScopeForFunction(JSContext *cx, JSFunction *fun)
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js::GetDebugScopeForFrame(JSContext *cx, StackFrame *fp)
|
||||
js::GetDebugScopeForFrame(JSContext *cx, TaggedFramePtr frame)
|
||||
{
|
||||
assertSameCompartment(cx, fp);
|
||||
assertSameCompartment(cx, frame);
|
||||
if (CanUseDebugScopeMaps(cx) && !DebugScopes::updateLiveScopes(cx))
|
||||
return NULL;
|
||||
ScopeIter si(fp, cx);
|
||||
ScopeIter si(frame, cx);
|
||||
return GetDebugScope(cx, si);
|
||||
}
|
||||
|
@ -197,7 +197,7 @@ class CallObject : public ScopeObject
|
||||
|
||||
static CallObject *createForFunction(JSContext *cx, HandleObject enclosing, HandleFunction callee);
|
||||
|
||||
static CallObject *createForFunction(JSContext *cx, StackFrame *fp);
|
||||
static CallObject *createForFunction(JSContext *cx, TaggedFramePtr frame);
|
||||
static CallObject *createForStrictEval(JSContext *cx, StackFrame *fp);
|
||||
|
||||
/* True if this is for a strict mode eval frame. */
|
||||
@ -356,7 +356,7 @@ class ClonedBlockObject : public BlockObject
|
||||
{
|
||||
public:
|
||||
static ClonedBlockObject *create(JSContext *cx, Handle<StaticBlockObject *> block,
|
||||
StackFrame *fp);
|
||||
TaggedFramePtr frame);
|
||||
|
||||
/* The static block from which this block was cloned. */
|
||||
StaticBlockObject &staticBlock() const;
|
||||
@ -366,7 +366,7 @@ class ClonedBlockObject : public BlockObject
|
||||
void setVar(unsigned i, const Value &v, MaybeCheckAliasing = CHECK_ALIASING);
|
||||
|
||||
/* Copy in all the unaliased formals and locals. */
|
||||
void copyUnaliasedValues(StackFrame *fp);
|
||||
void copyUnaliasedValues(TaggedFramePtr frame);
|
||||
};
|
||||
|
||||
template<XDRMode mode>
|
||||
@ -402,7 +402,7 @@ class ScopeIter
|
||||
enum Type { Call, Block, With, StrictEvalScope };
|
||||
|
||||
private:
|
||||
StackFrame *fp_;
|
||||
TaggedFramePtr frame_;
|
||||
RootedObject cur_;
|
||||
Rooted<StaticBlockObject *> block_;
|
||||
Type type_;
|
||||
@ -423,7 +423,7 @@ class ScopeIter
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||
|
||||
/* Constructing from StackFrame places ScopeIter on the innermost scope. */
|
||||
explicit ScopeIter(StackFrame *fp, JSContext *cx
|
||||
explicit ScopeIter(TaggedFramePtr frame, JSContext *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||
|
||||
/*
|
||||
@ -437,14 +437,14 @@ class ScopeIter
|
||||
* For the special case of generators, copy the given ScopeIter, with 'fp'
|
||||
* as the StackFrame instead of si.fp(). Not for general use.
|
||||
*/
|
||||
ScopeIter(const ScopeIter &si, StackFrame *fp, JSContext *cx
|
||||
ScopeIter(const ScopeIter &si, TaggedFramePtr frame, JSContext *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||
|
||||
/* Like ScopeIter(StackFrame *) except start at 'scope'. */
|
||||
ScopeIter(StackFrame *fp, ScopeObject &scope, JSContext *cx
|
||||
ScopeIter(TaggedFramePtr frame, ScopeObject &scope, JSContext *cx
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||
|
||||
bool done() const { return !fp_; }
|
||||
bool done() const { return !frame_; }
|
||||
|
||||
/* If done(): */
|
||||
|
||||
@ -454,7 +454,7 @@ class ScopeIter
|
||||
|
||||
ScopeIter &operator++();
|
||||
|
||||
StackFrame *fp() const { JS_ASSERT(!done()); return fp_; }
|
||||
TaggedFramePtr frame() const { JS_ASSERT(!done()); return frame_; }
|
||||
Type type() const { JS_ASSERT(!done()); return type_; }
|
||||
bool hasScopeObject() const { JS_ASSERT(!done()); return hasScopeObject_; }
|
||||
ScopeObject &scope() const;
|
||||
@ -466,18 +466,18 @@ class ScopeIter
|
||||
|
||||
class ScopeIterKey
|
||||
{
|
||||
StackFrame *fp_;
|
||||
TaggedFramePtr frame_;
|
||||
JSObject *cur_;
|
||||
StaticBlockObject *block_;
|
||||
ScopeIter::Type type_;
|
||||
|
||||
public:
|
||||
ScopeIterKey() : fp_(NULL), cur_(NULL), block_(NULL), type_() {}
|
||||
ScopeIterKey() : frame_(), cur_(NULL), block_(NULL), type_() {}
|
||||
ScopeIterKey(const ScopeIter &si)
|
||||
: fp_(si.fp_), cur_(si.cur_), block_(si.block_), type_(si.type_)
|
||||
: frame_(si.frame_), cur_(si.cur_), block_(si.block_), type_(si.type_)
|
||||
{}
|
||||
|
||||
StackFrame *fp() const { return fp_; }
|
||||
TaggedFramePtr frame() const { return frame_; }
|
||||
ScopeIter::Type type() const { return type_; }
|
||||
|
||||
/* For use as hash policy */
|
||||
@ -517,7 +517,7 @@ extern JSObject *
|
||||
GetDebugScopeForFunction(JSContext *cx, JSFunction *fun);
|
||||
|
||||
extern JSObject *
|
||||
GetDebugScopeForFrame(JSContext *cx, StackFrame *fp);
|
||||
GetDebugScopeForFrame(JSContext *cx, TaggedFramePtr frame);
|
||||
|
||||
/* Provides debugger access to a scope. */
|
||||
class DebugScopeObject : public JSObject
|
||||
@ -573,7 +573,7 @@ class DebugScopes
|
||||
* updates of liveScopes need only fill in the new scopes.
|
||||
*/
|
||||
typedef HashMap<ScopeObject *,
|
||||
StackFrame *,
|
||||
TaggedFramePtr,
|
||||
DefaultHasher<ScopeObject *>,
|
||||
RuntimeAllocPolicy> LiveScopeMap;
|
||||
LiveScopeMap liveScopes;
|
||||
@ -598,17 +598,17 @@ class DebugScopes
|
||||
static bool addDebugScope(JSContext *cx, const ScopeIter &si, DebugScopeObject &debugScope);
|
||||
|
||||
static bool updateLiveScopes(JSContext *cx);
|
||||
static StackFrame *hasLiveFrame(ScopeObject &scope);
|
||||
static TaggedFramePtr hasLiveFrame(ScopeObject &scope);
|
||||
|
||||
/*
|
||||
* In debug-mode, these must be called whenever exiting a call/block or
|
||||
* when activating/yielding a generator.
|
||||
*/
|
||||
static void onPopCall(StackFrame *fp, JSContext *cx);
|
||||
static void onPopBlock(JSContext *cx, StackFrame *fp);
|
||||
static void onPopWith(StackFrame *fp);
|
||||
static void onPopStrictEvalScope(StackFrame *fp);
|
||||
static void onGeneratorFrameChange(StackFrame *from, StackFrame *to, JSContext *cx);
|
||||
static void onPopCall(TaggedFramePtr frame, JSContext *cx);
|
||||
static void onPopBlock(JSContext *cx, TaggedFramePtr frame);
|
||||
static void onPopWith(TaggedFramePtr frame);
|
||||
static void onPopStrictEvalScope(TaggedFramePtr frame);
|
||||
static void onGeneratorFrameChange(TaggedFramePtr from, TaggedFramePtr to, JSContext *cx);
|
||||
static void onCompartmentLeaveDebugMode(JSCompartment *c);
|
||||
};
|
||||
|
||||
|
@ -1712,6 +1712,17 @@ class TaggedFramePtr
|
||||
{
|
||||
uintptr_t ptr_;
|
||||
|
||||
public:
|
||||
TaggedFramePtr()
|
||||
: ptr_(0)
|
||||
{}
|
||||
|
||||
TaggedFramePtr(StackFrame *fp)
|
||||
: ptr_(uintptr_t(fp) | 0x1)
|
||||
{
|
||||
JS_ASSERT(fp);
|
||||
}
|
||||
|
||||
bool isStackFrame() const {
|
||||
return ptr_ & 0x1;
|
||||
}
|
||||
@ -1723,28 +1734,200 @@ class TaggedFramePtr
|
||||
return res;
|
||||
}
|
||||
|
||||
public:
|
||||
TaggedFramePtr()
|
||||
: ptr_(0)
|
||||
{}
|
||||
|
||||
explicit TaggedFramePtr(StackFrame *fp)
|
||||
: ptr_(uintptr_t(fp) | 0x1)
|
||||
{
|
||||
JS_ASSERT(fp);
|
||||
}
|
||||
|
||||
void *raw() const { return reinterpret_cast<void *>(ptr_); }
|
||||
|
||||
bool operator ==(const TaggedFramePtr &other) const { return ptr_ == other.ptr_; }
|
||||
bool operator !=(const TaggedFramePtr &other) const { return ptr_ != other.ptr_; }
|
||||
|
||||
operator bool() const { return !!ptr_; }
|
||||
|
||||
JSGenerator *maybeSuspendedGenerator(JSRuntime *rt) const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->maybeSuspendedGenerator(rt);
|
||||
return NULL;
|
||||
}
|
||||
JSObject *scopeChain() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->scopeChain();
|
||||
return NULL;
|
||||
}
|
||||
JSCompartment *compartment() const {
|
||||
return scopeChain()->compartment();
|
||||
}
|
||||
StaticBlockObject *maybeBlockChain() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->maybeBlockChain();
|
||||
return NULL;
|
||||
}
|
||||
bool hasCallObj() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->hasCallObj();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return false;
|
||||
}
|
||||
CallObject &callObj() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->callObj();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return asStackFrame()->callObj();
|
||||
}
|
||||
bool isGeneratorFrame() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->isGeneratorFrame();
|
||||
return false;
|
||||
}
|
||||
bool isYielding() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->isYielding();
|
||||
return false;
|
||||
}
|
||||
bool isFunctionFrame() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->isFunctionFrame();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return false;
|
||||
}
|
||||
bool isGlobalFrame() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->isGlobalFrame();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return false;
|
||||
}
|
||||
bool isEvalFrame() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->isEvalFrame();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return false;
|
||||
}
|
||||
bool isDebuggerFrame() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->isDebuggerFrame();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return false;
|
||||
}
|
||||
JSScript *script() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->script();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return NULL;
|
||||
}
|
||||
UnrootedFunction fun() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->fun();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return NULL;
|
||||
}
|
||||
JSFunction &callee() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->callee();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return asStackFrame()->callee();
|
||||
}
|
||||
bool isNonEvalFunctionFrame() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->isNonEvalFunctionFrame();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return false;
|
||||
}
|
||||
bool isNonStrictDirectEvalFrame() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->isNonStrictDirectEvalFrame();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return false;
|
||||
}
|
||||
bool isStrictEvalFrame() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->isStrictEvalFrame();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return false;
|
||||
}
|
||||
unsigned numActualArgs() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->numActualArgs();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return 0;
|
||||
}
|
||||
unsigned numFormalArgs() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->numFormalArgs();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return 0;
|
||||
}
|
||||
Value *formals() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->formals();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return NULL;
|
||||
}
|
||||
Value *actuals() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->actuals();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return NULL;
|
||||
}
|
||||
bool hasArgsObj() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->hasArgsObj();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return false;
|
||||
}
|
||||
ArgumentsObject &argsObj() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->argsObj();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return asStackFrame()->argsObj();
|
||||
}
|
||||
void initArgsObj(ArgumentsObject &argsobj) const {
|
||||
if (isStackFrame()) {
|
||||
asStackFrame()->initArgsObj(argsobj);
|
||||
return;
|
||||
}
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
}
|
||||
bool copyRawFrameSlots(AutoValueVector *vec) const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->copyRawFrameSlots(vec);
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return false;
|
||||
}
|
||||
Value &unaliasedVar(unsigned i, MaybeCheckAliasing checkAliasing = CHECK_ALIASING) {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->unaliasedVar(i, checkAliasing);
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return asStackFrame()->unaliasedVar(i);
|
||||
}
|
||||
Value &unaliasedLocal(unsigned i, MaybeCheckAliasing checkAliasing = CHECK_ALIASING) {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->unaliasedLocal(i, checkAliasing);
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return asStackFrame()->unaliasedLocal(i);
|
||||
}
|
||||
Value &unaliasedFormal(unsigned i, MaybeCheckAliasing checkAliasing = CHECK_ALIASING) {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->unaliasedFormal(i, checkAliasing);
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return asStackFrame()->unaliasedFormal(i);
|
||||
}
|
||||
bool prevUpToDate() const {
|
||||
if (isStackFrame())
|
||||
return asStackFrame()->prevUpToDate();
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return false;
|
||||
}
|
||||
void setPrevUpToDate() const {
|
||||
if (isStackFrame()) {
|
||||
asStackFrame()->setPrevUpToDate();
|
||||
return;
|
||||
}
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
}
|
||||
TaggedFramePtr evalPrev() const {
|
||||
JS_ASSERT(isEvalFrame());
|
||||
if (isStackFrame())
|
||||
return TaggedFramePtr(asStackFrame()->prev());
|
||||
JS_NOT_REACHED("Invalid frame");
|
||||
return TaggedFramePtr();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
|
Loading…
Reference in New Issue
Block a user