bool GeneratorObject::suspend(JSContext *cx, HandleObject obj, AbstractFramePtr frame, jsbytecode *pc, Value *vp, unsigned nvalues) { MOZ_ASSERT(*pc == JSOP_INITIALYIELD || *pc == JSOP_YIELD); Rooted<GeneratorObject*> genObj(cx, &obj->as<GeneratorObject>()); MOZ_ASSERT(!genObj->hasExpressionStack()); if (*pc == JSOP_YIELD && genObj->isClosing() && genObj->is<LegacyGeneratorObject>()) { RootedValue val(cx, ObjectValue(*frame.callee())); js_ReportValueError(cx, JSMSG_BAD_GENERATOR_YIELD, JSDVG_IGNORE_STACK, val, NullPtr()); return false; } uint32_t yieldIndex = GET_UINT24(pc); genObj->setYieldIndex(yieldIndex); genObj->setScopeChain(*frame.scopeChain()); if (nvalues) { ArrayObject *stack = NewDenseCopiedArray(cx, nvalues, vp); if (!stack) return false; genObj->setExpressionStack(*stack); } return true; }
static void CopyStackFrameArguments(const AbstractFramePtr frame, HeapValue *dst, unsigned totalArgs) { JS_ASSERT_IF(frame.isStackFrame(), !frame.asStackFrame()->runningInIon()); unsigned numActuals = frame.numActualArgs(); unsigned numFormals = frame.callee()->nargs; JS_ASSERT(numActuals <= totalArgs); JS_ASSERT(numFormals <= totalArgs); JS_ASSERT(Max(numActuals, numFormals) == totalArgs); /* Copy formal arguments. */ Value *src = frame.formals(); Value *end = src + numFormals; while (src != end) (dst++)->init(*src++); /* Copy actual argument which are not contignous. */ if (numFormals < numActuals) { src = frame.actuals() + numFormals; end = src + (numActuals - numFormals); while (src != end) (dst++)->init(*src++); } }
// Initialize the decl env Object, call object, and any arguments obj of the // current frame. bool jit::EnsureHasEnvironmentObjects(JSContext* cx, AbstractFramePtr fp) { // Ion does not compile eval scripts. MOZ_ASSERT(!fp.isEvalFrame()); if (fp.isFunctionFrame()) { // Ion does not handle extra var environments due to parameter // expressions yet. MOZ_ASSERT(!fp.callee()->needsExtraBodyVarEnvironment()); if (!fp.hasInitialEnvironment() && fp.callee()->needsFunctionEnvironmentObjects()) { if (!fp.initFunctionEnvironmentObjects(cx)) return false; } } return true; }
/* static */ void ArgumentsObject::MaybeForwardToCallObject(AbstractFramePtr frame, ArgumentsObject* obj, ArgumentsData* data) { JSScript* script = frame.script(); if (frame.callee()->needsCallObject() && script->argumentsAliasesFormals()) { obj->initFixedSlot(MAYBE_CALL_SLOT, ObjectValue(frame.callObj())); for (PositionalFormalParameterIter fi(script); fi; fi++) { if (fi.closedOver()) data->args[fi.argumentSlot()] = MagicEnvSlotValue(fi.location().slot()); } } }
// Initialize the decl env Object, call object, and any arguments obj of the current frame. bool jit::EnsureHasScopeObjects(JSContext* cx, AbstractFramePtr fp) { // Ion does not compile eval scripts. MOZ_ASSERT(!fp.isEvalFrame()); if (fp.isFunctionFrame() && fp.callee()->needsCallObject() && !fp.hasCallObj()) { return fp.initFunctionScopeObjects(cx); } return true; }
bool js::DirectEval(JSContext *cx, const CallArgs &args) { // Direct eval can assume it was called from an interpreted or baseline frame. ScriptFrameIter iter(cx); AbstractFramePtr caller = iter.abstractFramePtr(); JS_ASSERT(caller.scopeChain()->global().valueIsEval(args.calleev())); JS_ASSERT(JSOp(*iter.pc()) == JSOP_EVAL || JSOp(*iter.pc()) == JSOP_SPREADEVAL); JS_ASSERT_IF(caller.isFunctionFrame(), caller.compartment() == caller.callee()->compartment()); RootedObject scopeChain(cx, caller.scopeChain()); return EvalKernel(cx, args, DIRECT_EVAL, caller, scopeChain, iter.pc()); }
bool js::DirectEval(JSContext *cx, const CallArgs &args) { // Direct eval can assume it was called from an interpreted or baseline frame. ScriptFrameIter iter(cx); AbstractFramePtr caller = iter.abstractFramePtr(); JS_ASSERT(IsBuiltinEvalForScope(caller.scopeChain(), args.calleev())); JS_ASSERT(JSOp(*iter.pc()) == JSOP_EVAL); JS_ASSERT_IF(caller.isFunctionFrame(), caller.compartment() == caller.callee()->compartment()); if (!WarnOnTooManyArgs(cx, args)) return false; RootedObject scopeChain(cx, caller.scopeChain()); return EvalKernel(cx, args, DIRECT_EVAL, caller, scopeChain, iter.pc()); }
void StackFrame::initExecuteFrame(JSContext *cx, JSScript *script, AbstractFramePtr evalInFramePrev, const Value &thisv, JSObject &scopeChain, ExecuteType type) { /* * See encoding of ExecuteType. When GLOBAL isn't set, we are executing a * script in the context of another frame and the frame type is determined * by the context. */ flags_ = type | HAS_SCOPECHAIN; JSObject *callee = nullptr; if (!(flags_ & (GLOBAL))) { if (evalInFramePrev) { JS_ASSERT(evalInFramePrev.isFunctionFrame() || evalInFramePrev.isGlobalFrame()); if (evalInFramePrev.isFunctionFrame()) { callee = evalInFramePrev.callee(); flags_ |= FUNCTION; } else { flags_ |= GLOBAL; } } else { ScriptFrameIter iter(cx); JS_ASSERT(iter.isFunctionFrame() || iter.isGlobalFrame()); if (iter.isFunctionFrame()) { callee = iter.callee(); flags_ |= FUNCTION; } else { flags_ |= GLOBAL; } } } Value *dstvp = (Value *)this - 2; dstvp[1] = thisv; if (isFunctionFrame()) { dstvp[0] = ObjectValue(*callee); exec.fun = &callee->as<JSFunction>(); u.evalScript = script; } else { JS_ASSERT(isGlobalFrame()); dstvp[0] = NullValue(); exec.script = script; #ifdef DEBUG u.evalScript = (JSScript *)0xbad; #endif } scopeChain_ = &scopeChain; prev_ = nullptr; prevpc_ = nullptr; prevsp_ = nullptr; JS_ASSERT_IF(evalInFramePrev, isDebuggerFrame()); evalInFramePrev_ = evalInFramePrev; #ifdef DEBUG Debug_SetValueRangeToCrashOnTouch(&rval_, 1); hookData_ = (void *)0xbad; #endif }