static StackFrame * PushInlinedFrame(JSContext *cx, StackFrame *callerFrame) { // Grab the callee object out of the caller's frame, which has already been restored. // N.B. we currently assume that the caller frame is at a JSOP_CALL pc for the caller frames, // which will not be the case when we inline getters (in which case it would be a // JSOP_GETPROP). That will have to be handled differently. FrameRegs ®s = cx->regs(); JS_ASSERT(JSOp(*regs.pc) == JSOP_CALL || JSOp(*regs.pc) == JSOP_NEW); int callerArgc = GET_ARGC(regs.pc); const Value &calleeVal = regs.sp[-callerArgc - 2]; JSFunction *fun = calleeVal.toObject().toFunction(); JSScript *script = fun->script(); CallArgs inlineArgs = CallArgsFromSp(callerArgc, regs.sp); // Bump the stack pointer to make it look like the inline args have been pushed, but they will // really get filled in by RestoreOneFrame. regs.sp = inlineArgs.end(); InitialFrameFlags flags = INITIAL_NONE; if (JSOp(*regs.pc) == JSOP_NEW) flags = INITIAL_CONSTRUCT; if (!cx->stack.pushInlineFrame(cx, regs, inlineArgs, *fun, script, flags, DONT_REPORT_ERROR)) return NULL; StackFrame *fp = cx->stack.fp(); JS_ASSERT(fp == regs.fp()); JS_ASSERT(fp->prev() == callerFrame); fp->formals()[-2].setObject(*fun); return fp; }
bool ContextStack::pushInvokeFrame(JSContext *cx, const CallArgs &args, InitialFrameFlags initial, InvokeFrameGuard *ifg) { JS_ASSERT(onTop()); JS_ASSERT(space().firstUnused() == args.end()); JSObject &callee = args.callee(); JSFunction *fun = callee.toFunction(); JSScript *script = fun->script(); StackFrame::Flags flags = ToFrameFlags(initial); StackFrame *fp = getCallFrame(cx, REPORT_ERROR, args, fun, script, &flags); if (!fp) return false; fp->initCallFrame(cx, *fun, script, args.length(), flags); ifg->regs_.prepareToRun(*fp, script); ifg->prevRegs_ = seg_->pushRegs(ifg->regs_); JS_ASSERT(space().firstUnused() == ifg->regs_.sp); ifg->setPushed(*this); return true; }