static void CloseLiveIterators(JSContext *cx, const InlineFrameIterator &frame) { JSScript *script = frame.script(); jsbytecode *pc = frame.pc(); if (!script->hasTrynotes()) return; JSTryNote *tn = script->trynotes()->vector; JSTryNote *tnEnd = tn + script->trynotes()->length; uint32 pcOffset = uint32(pc - script->main()); for (; tn != tnEnd; ++tn) { if (pcOffset < tn->start) continue; if (pcOffset >= tn->start + tn->length) continue; if (tn->kind != JSTRY_ITER) continue; JS_ASSERT(JSOp(*(script->main() + tn->start + tn->length)) == JSOP_ENDITER); JS_ASSERT(tn->stackDepth > 0); uint32 localSlot = tn->stackDepth; CloseLiveIterator(cx, frame, localSlot); } }
static jsbytecode * FindExceptionHandler(JSContext *cx) { StackFrame *fp = cx->fp(); JSScript *script = fp->script(); if (!script->hasTrynotes()) return NULL; error: if (cx->isExceptionPending()) { for (TryNoteIter tni(cx->regs()); !tni.done(); ++tni) { JSTryNote *tn = *tni; UnwindScope(cx, tn->stackDepth); /* * Set pc to the first bytecode after the the try note to point * to the beginning of catch or finally or to [enditer] closing * the for-in loop. */ jsbytecode *pc = script->main() + tn->start + tn->length; cx->regs().pc = pc; cx->regs().sp = fp->base() + tn->stackDepth; switch (tn->kind) { case JSTRY_CATCH: JS_ASSERT(JSOp(*pc) == JSOP_ENTERBLOCK); #if JS_HAS_GENERATORS /* Catch cannot intercept the closing of a generator. */ if (JS_UNLIKELY(cx->getPendingException().isMagic(JS_GENERATOR_CLOSING))) break; #endif /* * Don't clear cx->throwing to save cx->exception from GC * until it is pushed to the stack via [exception] in the * catch block. */ return pc; case JSTRY_FINALLY: /* * Push (true, exception) pair for finally to indicate that * [retsub] should rethrow the exception. */ cx->regs().sp[0].setBoolean(true); cx->regs().sp[1] = cx->getPendingException(); cx->regs().sp += 2; cx->clearPendingException(); return pc; case JSTRY_ITER: { /* * This is similar to JSOP_ENDITER in the interpreter loop, * except the code now uses the stack slot normally used by * JSOP_NEXTITER, namely regs.sp[-1] before the regs.sp -= 2 * adjustment and regs.sp[1] after, to save and restore the * pending exception. */ JS_ASSERT(JSOp(*pc) == JSOP_ENDITER); bool ok = UnwindIteratorForException(cx, &cx->regs().sp[-1].toObject()); cx->regs().sp -= 1; if (!ok) goto error; } } } } else { UnwindForUncatchableException(cx, cx->regs()); } return NULL; }