void StackIter::popFrame() { StackFrame *oldfp = fp_; JS_ASSERT(seg_->contains(oldfp)); fp_ = fp_->prev(); if (seg_->contains(fp_)) { JSInlinedSite *inline_; pc_ = oldfp->prevpc(&inline_); JS_ASSERT(!inline_); /* * If there is a CallArgsList element between oldfp and fp_, then sp_ * is ignored, so we only consider the case where there is no * intervening CallArgsList. The stack representation is not optimized * for this operation so we need to do a full case analysis of how * frames are pushed by considering each ContextStack::push*Frame. */ if (oldfp->isGeneratorFrame()) { /* Generator's args do not overlap with the caller's expr stack. */ sp_ = (Value *)oldfp->actualArgs() - 2; } else if (oldfp->isNonEvalFunctionFrame()) { /* * When Invoke is called from a native, there will be an enclosing * pushInvokeArgs which pushes a CallArgsList element so we can * ignore that case. The other two cases of function call frames are * Invoke called directly from script and pushInlineFrmae. In both * cases, the actual arguments of the callee should be included in * the caller's expr stack. */ sp_ = oldfp->actualArgsEnd(); } else if (oldfp->isFramePushedByExecute()) { /* pushExecuteFrame pushes exactly (callee, this) before frame. */ sp_ = (Value *)oldfp - 2; } else { /* pushDummyFrame pushes exactly 0 slots before frame. */ JS_ASSERT(oldfp->isDummyFrame()); sp_ = (Value *)oldfp; } script_ = fp_->maybeScript(); } else { poisonRegs(); } }