diff --git a/js/src/jit/IonFrames.cpp b/js/src/jit/IonFrames.cpp index 7558c4f68339..93d4ddb0f94a 100644 --- a/js/src/jit/IonFrames.cpp +++ b/js/src/jit/IonFrames.cpp @@ -512,7 +512,7 @@ HandleExceptionBaseline(JSContext *cx, const IonFrameIterator &frame, ResumeFrom // Unwind scope chain (pop block objects). if (cx->isExceptionPending()) - UnwindScope(cx, si, tn->stackDepth); + UnwindScope(cx, si, script->main() + tn->start); // Compute base pointer and stack pointer. rfe->framePointer = frame.fp() - BaselineFrame::FramePointerOffset; diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index bc17de52f653..2a6e2221c5a4 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -735,7 +735,7 @@ DebugEpilogue(JSContext *cx, BaselineFrame *frame, jsbytecode *pc, bool ok) { // Unwind scope chain to stack depth 0. ScopeIter si(frame, pc, cx); - UnwindScope(cx, si, 0); + UnwindScope(cx, si, frame->script()->main()); // If ScriptDebugEpilogue returns |true| we have to return the frame's // return value. If it returns |false|, the debugger threw an exception. diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index df764a33ef2c..f3fca4c889bb 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -855,23 +855,25 @@ EnterWith(JSContext *cx, AbstractFramePtr frame, HandleValue val, uint32_t stack return true; } -/* Unwind block and scope chains to match the given depth. */ +// Unwind scope chain and iterator to match the static scope corresponding to +// the given bytecode position. void -js::UnwindScope(JSContext *cx, ScopeIter &si, uint32_t stackDepth) +js::UnwindScope(JSContext *cx, ScopeIter &si, jsbytecode *pc) { - for (; !si.done(); ++si) { + if (si.done()) + return; + + Rooted staticScope(cx, si.frame().script()->getStaticScope(pc)); + + for (; si.staticScope() != staticScope; ++si) { switch (si.type()) { case ScopeIter::Block: - if (si.staticBlock().stackDepth() < stackDepth) - return; if (cx->compartment()->debugMode()) DebugScopes::onPopBlock(cx, si); if (si.staticBlock().needsClone()) si.frame().popBlock(cx); break; case ScopeIter::With: - if (si.scope().as().stackDepth() < stackDepth) - return; si.frame().popWith(cx); break; case ScopeIter::Call: @@ -884,7 +886,7 @@ js::UnwindScope(JSContext *cx, ScopeIter &si, uint32_t stackDepth) static void ForcedReturn(JSContext *cx, ScopeIter &si, FrameRegs ®s) { - UnwindScope(cx, si, 0); + UnwindScope(cx, si, regs.fp()->script()->main()); regs.setToEndOfScript(); } @@ -1009,7 +1011,7 @@ HandleError(JSContext *cx, FrameRegs ®s) for (TryNoteIter tni(cx, regs); !tni.done(); ++tni) { JSTryNote *tn = *tni; - UnwindScope(cx, si, tn->stackDepth); + UnwindScope(cx, si, regs.fp()->script()->main() + tn->start); /* * Set pc to the first bytecode after the the try note to point diff --git a/js/src/vm/Interpreter.h b/js/src/vm/Interpreter.h index f4b237f0ec7e..4a47838e1939 100644 --- a/js/src/vm/Interpreter.h +++ b/js/src/vm/Interpreter.h @@ -318,9 +318,10 @@ TypeOfValue(const Value &v); extern bool HasInstance(JSContext *cx, HandleObject obj, HandleValue v, bool *bp); -/* Unwind block and scope chains to match the given depth. */ +// Unwind scope chain and iterator to match the static scope corresponding to +// the given bytecode position. extern void -UnwindScope(JSContext *cx, ScopeIter &si, uint32_t stackDepth); +UnwindScope(JSContext *cx, ScopeIter &si, jsbytecode *pc); /* * Unwind for an uncatchable exception. This means not running finalizers, etc; diff --git a/js/src/vm/ScopeObject.h b/js/src/vm/ScopeObject.h index ba782924ac4e..275996c2f435 100644 --- a/js/src/vm/ScopeObject.h +++ b/js/src/vm/ScopeObject.h @@ -629,6 +629,7 @@ class ScopeIter Type type() const { JS_ASSERT(!done()); return type_; } bool hasScopeObject() const { JS_ASSERT(!done()); return hasScopeObject_; } ScopeObject &scope() const; + NestedScopeObject* staticScope() const { return staticScope_; } StaticBlockObject &staticBlock() const { JS_ASSERT(type() == Block);