Bug 1143679 - Make TryNoteIterIon behave more like Baseline/interpreter iterators. r=shu, a=lizzard
--- a/js/src/jit/IonFrames.cpp
+++ b/js/src/jit/IonFrames.cpp
@@ -351,24 +351,30 @@ JitFrameIterator::machineState() const
double* floatSpill = reinterpret_cast<double*>(spill);
for (FloatRegisterBackwardIterator iter(reader.allFloatSpills()); iter.more(); iter++)
machine.setRegisterLocation(*iter, --floatSpill);
return machine;
}
+static uint32_t
+NumArgAndLocalSlots(const InlineFrameIterator& frame)
+{
+ JSScript* script = frame.script();
+ return CountArgSlots(script, frame.maybeCallee()) + script->nfixed();
+}
+
static void
-CloseLiveIterator(JSContext* cx, const InlineFrameIterator& frame, uint32_t localSlot)
+CloseLiveIterator(JSContext* cx, const InlineFrameIterator& frame, uint32_t stackSlot)
{
SnapshotIterator si = frame.snapshotIterator();
// Skip stack slots until we reach the iterator object.
- uint32_t base = CountArgSlots(frame.script(), frame.maybeCallee()) + frame.script()->nfixed();
- uint32_t skipSlots = base + localSlot - 1;
+ uint32_t skipSlots = NumArgAndLocalSlots(frame) + stackSlot - 1;
for (unsigned i = 0; i < skipSlots; i++)
si.skip();
Value v = si.read();
RootedObject obj(cx, &v.toObject());
if (cx->isExceptionPending())
@@ -402,26 +408,34 @@ HandleExceptionIon(JSContext* cx, const
ExceptionBailoutInfo propagateInfo;
uint32_t retval = ExceptionHandlerBailout(cx, frame, rfe, propagateInfo, overrecursed);
bailedOutForDebugMode = retval == BAILOUT_RETURN_OK;
}
if (!script->hasTrynotes())
return;
+ uint32_t base = NumArgAndLocalSlots(frame);
+ SnapshotIterator si = frame.snapshotIterator();
+ JS_ASSERT(si.numAllocations() >= base);
+ const uint32_t stackDepth = si.numAllocations() - base;
+
JSTryNote* tn = script->trynotes()->vector;
JSTryNote* tnEnd = tn + script->trynotes()->length;
uint32_t pcOffset = uint32_t(pc - script->main());
for (; tn != tnEnd; ++tn) {
if (pcOffset < tn->start)
continue;
if (pcOffset >= tn->start + tn->length)
continue;
+ if (tn->stackDepth > stackDepth)
+ continue;
+
switch (tn->kind) {
case JSTRY_ITER: {
JS_ASSERT(JSOp(*(script->main() + tn->start + tn->length)) == JSOP_ENDITER);
JS_ASSERT(tn->stackDepth > 0);
uint32_t localSlot = tn->stackDepth;
CloseLiveIterator(cx, frame, localSlot);
break;