From f05a168466527a4b05c3022828f73c9b907251d1 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Thu, 14 Jan 2016 17:02:43 +0100 Subject: [PATCH] Bug 1234845 part 4 - Eval frame refactoring, remove isFunctionFrame. r=luke --- js/src/builtin/Eval.cpp | 3 +- js/src/builtin/TestingFunctions.cpp | 2 +- js/src/jit/Bailouts.cpp | 5 ++- js/src/jit/BaselineFrame.cpp | 2 +- js/src/jit/BaselineFrame.h | 15 ++++--- js/src/jit/BaselineIC.cpp | 2 +- js/src/jit/BaselineJIT.cpp | 8 +--- js/src/jit/Ion.cpp | 26 +++++------- js/src/jit/SharedIC.cpp | 2 +- js/src/jsfriendapi.cpp | 7 +++- js/src/jsfun.cpp | 12 ++++-- js/src/jsobj.cpp | 4 +- js/src/jsscript.cpp | 2 +- js/src/jsscript.h | 3 ++ js/src/vm/Debugger.cpp | 6 +-- js/src/vm/ScopeObject.cpp | 4 +- js/src/vm/SelfHosting.cpp | 2 +- js/src/vm/Stack-inl.h | 12 +----- js/src/vm/Stack.cpp | 61 ++++++----------------------- js/src/vm/Stack.h | 18 +++------ 20 files changed, 72 insertions(+), 124 deletions(-) diff --git a/js/src/builtin/Eval.cpp b/js/src/builtin/Eval.cpp index b5795e13d82..94ca2b5c831 100644 --- a/js/src/builtin/Eval.cpp +++ b/js/src/builtin/Eval.cpp @@ -435,8 +435,7 @@ js::DirectEval(JSContext* cx, const CallArgs& args) JSOp(*iter.pc()) == JSOP_STRICTEVAL || JSOp(*iter.pc()) == JSOP_SPREADEVAL || JSOp(*iter.pc()) == JSOP_STRICTSPREADEVAL); - MOZ_ASSERT_IF(caller.isFunctionFrame(), - caller.compartment() == caller.callee()->compartment()); + MOZ_ASSERT(caller.compartment() == caller.script()->compartment()); RootedObject scopeChain(cx, caller.scopeChain()); return EvalKernel(cx, args, DIRECT_EVAL, caller, scopeChain, iter.pc()); diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 2b3277bb308..a8c1d707240 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -1579,7 +1579,7 @@ ShellObjectMetadataCallback(JSContext* cx, JSObject*) RootedId id(cx); RootedValue callee(cx); for (NonBuiltinScriptFrameIter iter(cx); !iter.done(); ++iter) { - if (iter.isFunctionFrame() && iter.compartment() == cx->compartment()) { + if (iter.isNonEvalFunctionFrame() && iter.compartment() == cx->compartment()) { id = INT_TO_JSID(stackIndex); RootedObject callee(cx, iter.callee(cx)); if (!JS_DefinePropertyById(cx, stack, id, callee, 0, diff --git a/js/src/jit/Bailouts.cpp b/js/src/jit/Bailouts.cpp index be0532cce04..deb20ca1635 100644 --- a/js/src/jit/Bailouts.cpp +++ b/js/src/jit/Bailouts.cpp @@ -260,7 +260,10 @@ jit::ExceptionHandlerBailout(JSContext* cx, const InlineFrameIterator& frame, bool jit::EnsureHasScopeObjects(JSContext* cx, AbstractFramePtr fp) { - if (fp.isFunctionFrame() && + // Ion does not compile eval scripts. + MOZ_ASSERT(!fp.isEvalFrame()); + + if (fp.isNonEvalFunctionFrame() && fp.callee()->needsCallObject() && !fp.hasCallObj()) { diff --git a/js/src/jit/BaselineFrame.cpp b/js/src/jit/BaselineFrame.cpp index d620f66e08f..3d62d9d51ce 100644 --- a/js/src/jit/BaselineFrame.cpp +++ b/js/src/jit/BaselineFrame.cpp @@ -50,7 +50,7 @@ BaselineFrame::trace(JSTracer* trc, JitFrameIterator& frameIterator) if (isEvalFrame()) { TraceRoot(trc, &evalScript_, "baseline-evalscript"); - if (isFunctionFrame()) + if (script()->isDirectEvalInFunction()) TraceRoot(trc, evalNewTargetAddress(), "baseline-evalNewTarget"); } diff --git a/js/src/jit/BaselineFrame.h b/js/src/jit/BaselineFrame.h index e8b334a9c8c..d3699ed1347 100644 --- a/js/src/jit/BaselineFrame.h +++ b/js/src/jit/BaselineFrame.h @@ -220,7 +220,7 @@ class BaselineFrame private: Value* evalNewTargetAddress() const { MOZ_ASSERT(isEvalFrame()); - MOZ_ASSERT(isFunctionFrame()); + MOZ_ASSERT(script()->isDirectEvalInFunction()); return (Value*)(reinterpret_cast(this) + BaselineFrame::Size() + offsetOfEvalNewTarget()); @@ -228,15 +228,16 @@ class BaselineFrame public: Value newTarget() const { - MOZ_ASSERT(isFunctionFrame()); if (isEvalFrame()) return *evalNewTargetAddress(); + MOZ_ASSERT(isNonEvalFunctionFrame()); if (callee()->isArrow()) return callee()->getExtendedSlot(FunctionExtended::ARROW_NEWTARGET_SLOT); - if (isConstructing()) + if (isConstructing()) { return *(Value*)(reinterpret_cast(this) + BaselineFrame::Size() + offsetOfArg(Max(numFormalArgs(), numActualArgs()))); + } return UndefinedValue(); } @@ -388,11 +389,9 @@ class BaselineFrame void trace(JSTracer* trc, JitFrameIterator& frame); - bool isFunctionFrame() const { - return CalleeTokenIsFunction(calleeToken()); - } bool isGlobalOrModuleFrame() const { - return !isFunctionFrame(); + MOZ_ASSERT(!isEvalFrame()); + return !CalleeTokenIsFunction(calleeToken()); } bool isEvalFrame() const { return flags_ & EVAL; @@ -408,7 +407,7 @@ class BaselineFrame return isNonStrictEvalFrame() && isNonGlobalEvalFrame(); } bool isNonEvalFunctionFrame() const { - return isFunctionFrame() && !isEvalFrame(); + return CalleeTokenIsFunction(calleeToken()) && !isEvalFrame(); } bool isDebuggerEvalFrame() const { return false; diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 922ac367f16..b017c0be14e 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -64,7 +64,7 @@ EnsureCanEnterIon(JSContext* cx, ICWarmUpCounter_Fallback* stub, BaselineFrame* MOZ_ASSERT(LoopEntryCanIonOsr(pc)); JitSpew(JitSpew_BaselineOSR, " Compile at loop entry!"); stat = CanEnterAtBranch(cx, script, frame, pc); - } else if (frame->isFunctionFrame()) { + } else if (frame->isNonEvalFunctionFrame()) { JitSpew(JitSpew_BaselineOSR, " Compile function from top for later entry!"); stat = CompileFunctionForBaseline(cx, script, frame); } else { diff --git a/js/src/jit/BaselineJIT.cpp b/js/src/jit/BaselineJIT.cpp index b2fb0183adb..7b970653c73 100644 --- a/js/src/jit/BaselineJIT.cpp +++ b/js/src/jit/BaselineJIT.cpp @@ -216,11 +216,7 @@ jit::EnterBaselineAtBranch(JSContext* cx, InterpreterFrame* fp, jsbytecode* pc) data.maxArgv = thisv.address(); data.scopeChain = fp->scopeChain(); - // For eval function frames, set the callee token to the enclosing function. - if (fp->isFunctionFrame()) - data.calleeToken = CalleeToToken(&fp->callee(), /* constructing = */ false); - else - data.calleeToken = CalleeToToken(fp->script()); + data.calleeToken = CalleeToToken(fp->script()); if (fp->isEvalFrame()) { if (!vals.reserve(2)) @@ -228,7 +224,7 @@ jit::EnterBaselineAtBranch(JSContext* cx, InterpreterFrame* fp, jsbytecode* pc) vals.infallibleAppend(thisv); - if (fp->isFunctionFrame()) + if (fp->script()->isDirectEvalInFunction()) vals.infallibleAppend(fp->newTarget()); else vals.infallibleAppend(NullValue()); diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index e4fc595652e..b5f27b0ae96 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -2305,9 +2305,10 @@ CheckFrame(JSContext* cx, BaselineFrame* frame) { MOZ_ASSERT(!frame->script()->isGenerator()); MOZ_ASSERT(!frame->isDebuggerEvalFrame()); + MOZ_ASSERT(!frame->isEvalFrame()); // This check is to not overrun the stack. - if (frame->isFunctionFrame()) { + if (frame->isNonEvalFunctionFrame()) { if (TooManyActualArguments(frame->numActualArgs())) { TrackAndSpewIonAbort(cx, frame->script(), "too many actual arguments"); return false; @@ -2633,7 +2634,7 @@ jit::CompileFunctionForBaseline(JSContext* cx, HandleScript script, BaselineFram MOZ_ASSERT(frame->callee()->nonLazyScript()->canIonCompile()); MOZ_ASSERT(!frame->callee()->nonLazyScript()->isIonCompilingOffThread()); MOZ_ASSERT(!frame->callee()->nonLazyScript()->hasIonScript()); - MOZ_ASSERT(frame->isFunctionFrame()); + MOZ_ASSERT(frame->isNonEvalFunctionFrame()); // Mark as forbidden if frame can't be handled. if (!CheckFrame(cx, frame)) { @@ -2782,27 +2783,18 @@ jit::SetEnterJitData(JSContext* cx, EnterJitData& data, RunState& state, AutoVal data.calleeToken = CalleeToToken(state.script()); - if (state.script()->isForEval() && - !(state.asExecute()->type() & InterpreterFrame::GLOBAL_OR_MODULE)) - { - ScriptFrameIter iter(cx); - if (iter.isFunctionFrame()) - data.calleeToken = CalleeToToken(iter.callee(cx), /* constructing = */ false); - + if (state.script()->isForEval() && state.script()->isDirectEvalInFunction()) { // Push newTarget onto the stack. if (!vals.reserve(1)) return false; + ScriptFrameIter iter(cx); data.maxArgc = 1; data.maxArgv = vals.begin(); - if (iter.isFunctionFrame()) { - if (state.asExecute()->newTarget().isNull()) - vals.infallibleAppend(iter.newTarget()); - else - vals.infallibleAppend(state.asExecute()->newTarget()); - } else { - vals.infallibleAppend(NullValue()); - } + if (state.asExecute()->newTarget().isNull()) + vals.infallibleAppend(iter.newTarget()); + else + vals.infallibleAppend(state.asExecute()->newTarget()); } } diff --git a/js/src/jit/SharedIC.cpp b/js/src/jit/SharedIC.cpp index 3cb8e541139..9d9a5d05b7f 100644 --- a/js/src/jit/SharedIC.cpp +++ b/js/src/jit/SharedIC.cpp @@ -4732,7 +4732,7 @@ DoTypeMonitorFallback(JSContext* cx, BaselineFrame* frame, ICTypeMonitor_Fallbac // In derived class constructors (including nested arrows/eval), the // |this| argument or GETALIASEDVAR can return the magic TDZ value. MOZ_ASSERT(value.isMagic(JS_UNINITIALIZED_LEXICAL)); - MOZ_ASSERT(frame->isFunctionFrame()); + MOZ_ASSERT(frame->isNonEvalFunctionFrame() || frame->isEvalFrame()); MOZ_ASSERT(stub->monitorsThis() || *GetNextPc(pc) == JSOP_CHECKTHIS || *GetNextPc(pc) == JSOP_CHECKRETURN); diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 588e9cff1ba..b6307cd0317 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -394,10 +394,15 @@ JS_FRIEND_API(JSFunction*) js::GetOutermostEnclosingFunctionOfScriptedCaller(JSContext* cx) { ScriptFrameIter iter(cx); + + // Skip eval frames. + while (!iter.done() && iter.isEvalFrame()) + ++iter; + if (iter.done()) return nullptr; - if (!iter.isFunctionFrame()) + if (!iter.isNonEvalFunctionFrame()) return nullptr; RootedFunction curr(cx, iter.callee(cx)); diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index 5201ce0c2d4..0c01f207324 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -96,7 +96,7 @@ AdvanceToActiveCallLinear(JSContext* cx, NonBuiltinScriptFrameIter& iter, Handle MOZ_ASSERT(!fun->isBuiltin()); for (; !iter.done(); ++iter) { - if (!iter.isFunctionFrame() || iter.isEvalFrame()) + if (!iter.isNonEvalFunctionFrame()) continue; if (iter.matchCallee(cx, fun)) return true; @@ -252,7 +252,10 @@ CallerGetterImpl(JSContext* cx, const CallArgs& args) } ++iter; - if (iter.done() || !iter.isFunctionFrame()) { + while (!iter.done() && iter.isEvalFrame()) + ++iter; + + if (iter.done() || !iter.isNonEvalFunctionFrame()) { args.rval().setNull(); return true; } @@ -318,7 +321,10 @@ CallerSetterImpl(JSContext* cx, const CallArgs& args) return true; ++iter; - if (iter.done() || !iter.isFunctionFrame()) + while (!iter.done() && iter.isEvalFrame()) + ++iter; + + if (iter.done() || !iter.isNonEvalFunctionFrame()) return true; RootedObject caller(cx, iter.callee(cx)); diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index d60ae23a401..dda4d63cbd4 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -3601,14 +3601,14 @@ js::DumpInterpreterFrame(JSContext* cx, InterpreterFrame* start) else fprintf(stderr, "InterpreterFrame at %p\n", (void*) i.interpFrame()); - if (i.isFunctionFrame()) { + if (i.isNonEvalFunctionFrame()) { fprintf(stderr, "callee fun: "); RootedValue v(cx); JSObject* fun = i.callee(cx); v.setObject(*fun); dumpValue(v); } else { - fprintf(stderr, "global frame, no callee"); + fprintf(stderr, "global or eval frame, no callee"); } fputc('\n', stderr); diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index cc5d12e3c9d..ec5157aa5d0 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -4189,7 +4189,7 @@ JSScript::argumentsOptimizationFailed(JSContext* cx, HandleScript script) if (i.isIon()) continue; AbstractFramePtr frame = i.abstractFramePtr(); - if (frame.isFunctionFrame() && frame.script() == script) { + if (frame.isNonEvalFunctionFrame() && frame.script() == script) { /* We crash on OOM since cleaning up here would be complicated. */ AutoEnterOOMUnsafeRegion oomUnsafe; ArgumentsObject* argsobj = ArgumentsObject::createExpected(cx, frame); diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 9b4f0c89215..bd1c14524be 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -1670,6 +1670,9 @@ class JSScript : public js::gc::TenuredCell /* Return whether this script was compiled for 'eval' */ bool isForEval() const { return isCachedEval() || isActiveEval(); } + /* Return whether this is a 'direct eval' script in a function scope. */ + bool isDirectEvalInFunction() const { return isForEval() && savedCallerFun(); } + /* * Return whether this script is a top-level script. * diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index c37d1c3e3b6..e6e458d221e 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -6292,7 +6292,7 @@ DebuggerFrame_getType(JSContext* cx, unsigned argc, Value* vp) type = cx->names().eval; else if (frame.isGlobalFrame()) type = cx->names().global; - else if (frame.isFunctionFrame()) + else if (frame.isNonEvalFunctionFrame()) type = cx->names().call; else if (frame.isModuleFrame()) type = cx->names().module; @@ -6363,7 +6363,7 @@ static bool DebuggerFrame_getConstructing(JSContext* cx, unsigned argc, Value* vp) { THIS_FRAME_ITER(cx, argc, vp, "get constructing", args, thisobj, _, iter); - args.rval().setBoolean(iter.isFunctionFrame() && iter.isConstructing()); + args.rval().setBoolean(iter.isNonEvalFunctionFrame() && iter.isConstructing()); return true; } @@ -6533,7 +6533,7 @@ DebuggerFrame_getScript(JSContext* cx, unsigned argc, Value* vp) Debugger* debug = Debugger::fromChildJSObject(thisobj); RootedObject scriptObject(cx); - if (frame.isFunctionFrame() && !frame.isEvalFrame()) { + if (frame.isNonEvalFunctionFrame()) { RootedFunction callee(cx, frame.callee()); if (callee->isInterpreted()) { RootedScript script(cx, callee->nonLazyScript()); diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index 95d16f40eb2..204f638cbee 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -2722,7 +2722,7 @@ DebugScopes::updateLiveScopes(JSContext* cx) if (frame.scopeChain()->compartment() != cx->compartment()) continue; - if (frame.isFunctionFrame() && frame.callee()->isGenerator()) + if (frame.isNonEvalFunctionFrame() && frame.callee()->isGenerator()) continue; if (!frame.isDebuggee()) @@ -2907,7 +2907,7 @@ GetDebugScopeForMissing(JSContext* cx, const ScopeIter& si) // For example, |let ({} = "") { yield evalInFrame("foo"); }|. MOZ_ASSERT_IF(si.staticBlock().numVariables() > 0 && si.withinInitialFrame() && - si.initialFrame().isFunctionFrame(), + si.initialFrame().isNonEvalFunctionFrame(), !si.initialFrame().callee()->isGenerator()); Rooted staticBlock(cx, &si.staticBlock()); diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 05d148bbb78..a9a2049ed29 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -635,7 +635,7 @@ intrinsic_ActiveFunction(JSContext* cx, unsigned argc, Value* vp) MOZ_ASSERT(args.length() == 0); ScriptFrameIter iter(cx); - MOZ_ASSERT(iter.isFunctionFrame()); + MOZ_ASSERT(iter.isNonEvalFunctionFrame()); args.rval().setObject(*iter.callee(cx)); return true; } diff --git a/js/src/vm/Stack-inl.h b/js/src/vm/Stack-inl.h index 18500d7c84e..19b2d050786 100644 --- a/js/src/vm/Stack-inl.h +++ b/js/src/vm/Stack-inl.h @@ -44,7 +44,7 @@ IsCacheableNonGlobalScope(JSObject* obj) inline HandleObject InterpreterFrame::scopeChain() const { - MOZ_ASSERT_IF(!(flags_ & HAS_SCOPECHAIN), isFunctionFrame()); + MOZ_ASSERT_IF(!(flags_ & HAS_SCOPECHAIN), isNonEvalFunctionFrame()); if (!(flags_ & HAS_SCOPECHAIN)) { scopeChain_ = callee().environment(); flags_ |= HAS_SCOPECHAIN; @@ -563,16 +563,6 @@ AbstractFramePtr::createSingleton() const return false; } -inline bool -AbstractFramePtr::isFunctionFrame() const -{ - if (isInterpreterFrame()) - return asInterpreterFrame()->isFunctionFrame(); - if (isBaselineFrame()) - return asBaselineFrame()->isFunctionFrame(); - return asRematerializedFrame()->isFunctionFrame(); -} - inline bool AbstractFramePtr::isGlobalOrModuleFrame() const { diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp index 855c5283aa9..8fb7f529d38 100644 --- a/js/src/vm/Stack.cpp +++ b/js/src/vm/Stack.cpp @@ -44,46 +44,24 @@ InterpreterFrame::initExecuteFrame(JSContext* cx, HandleScript script, AbstractF flags_ = type | HAS_SCOPECHAIN; script_ = script; - JSObject* callee = nullptr; - // newTarget = NullValue is an initial sentinel for "please fill me in from the stack". // It should never be passed from Ion code. RootedValue newTarget(cx, newTargetValue); if (!(flags_ & GLOBAL_OR_MODULE)) { if (evalInFramePrev) { - if (evalInFramePrev.isFunctionFrame()) { - callee = evalInFramePrev.callee(); - if (newTarget.isNull()) - newTarget = evalInFramePrev.newTarget(); - flags_ |= FUNCTION; - } else { - MOZ_ASSERT(evalInFramePrev.isGlobalOrModuleFrame()); - flags_ |= GLOBAL_OR_MODULE; - } + if (newTarget.isNull() && evalInFramePrev.script()->functionOrCallerFunction()) + newTarget = evalInFramePrev.newTarget(); } else { FrameIter iter(cx); MOZ_ASSERT(!iter.isWasm()); - if (iter.isFunctionFrame()) { - if (newTarget.isNull()) - newTarget = iter.newTarget(); - callee = iter.callee(cx); - flags_ |= FUNCTION; - } else { - MOZ_ASSERT(iter.isGlobalOrModuleFrame()); - flags_ |= GLOBAL_OR_MODULE; - } + if (newTarget.isNull() && iter.script()->functionOrCallerFunction()) + newTarget = iter.newTarget(); } } Value* dstvp = (Value*)this - 2; - - if (isFunctionFrame()) { - dstvp[1] = ObjectValue(*callee); - } else { - MOZ_ASSERT(isGlobalOrModuleFrame()); - dstvp[1] = NullValue(); - } dstvp[0] = newTarget; + dstvp[1] = NullValue(); //XXX remove, unused callee. scopeChain_ = scopeChain.get(); prev_ = nullptr; @@ -321,7 +299,7 @@ bool InterpreterFrame::checkReturn(JSContext* cx, HandleValue thisv) { MOZ_ASSERT(script()->isDerivedClassConstructor()); - MOZ_ASSERT(isFunctionFrame()); + MOZ_ASSERT(isNonEvalFunctionFrame()); MOZ_ASSERT(callee().isClassConstructor()); HandleValue retVal = returnValue(); @@ -862,25 +840,6 @@ FrameIter::compartment() const MOZ_CRASH("Unexpected state"); } -bool -FrameIter::isFunctionFrame() const -{ - switch (data_.state_) { - case DONE: - break; - case INTERP: - return interpFrame()->isFunctionFrame(); - case JIT: - MOZ_ASSERT(data_.jitFrames_.isScripted()); - if (data_.jitFrames_.isBaselineJS()) - return data_.jitFrames_.isFunctionFrame(); - return ionInlineFrames_.isFunctionFrame(); - case WASM: - return true; - } - MOZ_CRASH("Unexpected state"); -} - bool FrameIter::isGlobalOrModuleFrame() const { @@ -929,7 +888,9 @@ FrameIter::isNonEvalFunctionFrame() const case INTERP: return interpFrame()->isNonEvalFunctionFrame(); case JIT: - return !isEvalFrame() && isFunctionFrame(); + if (data_.jitFrames_.isBaselineJS()) + return data_.jitFrames_.baselineFrame()->isNonEvalFunctionFrame(); + return script()->functionNonDelazifying(); case WASM: return true; } @@ -1145,7 +1106,7 @@ FrameIter::calleeTemplate() const case WASM: break; case INTERP: - MOZ_ASSERT(isFunctionFrame()); + MOZ_ASSERT(isNonEvalFunctionFrame()); return &interpFrame()->callee(); case JIT: if (data_.jitFrames_.isBaselineJS()) @@ -1215,7 +1176,7 @@ FrameIter::numActualArgs() const case WASM: break; case INTERP: - MOZ_ASSERT(isFunctionFrame()); + MOZ_ASSERT(isNonEvalFunctionFrame()); return interpFrame()->numActualArgs(); case JIT: if (data_.jitFrames_.isIonScripted()) diff --git a/js/src/vm/Stack.h b/js/src/vm/Stack.h index da733b701ff..cb561960f48 100644 --- a/js/src/vm/Stack.h +++ b/js/src/vm/Stack.h @@ -202,7 +202,6 @@ class AbstractFramePtr inline JSCompartment* compartment() const; inline bool hasCallObj() const; - inline bool isFunctionFrame() const; inline bool isGlobalOrModuleFrame() const; inline bool isGlobalFrame() const; inline bool isModuleFrame() const; @@ -463,11 +462,8 @@ class InterpreterFrame * module frame: execution of a module */ - bool isFunctionFrame() const { - return !!(flags_ & FUNCTION); - } - bool isGlobalOrModuleFrame() const { + MOZ_ASSERT(!isEvalFrame()); return !!(flags_ & GLOBAL_OR_MODULE); } @@ -677,14 +673,12 @@ class InterpreterFrame */ JSFunction& callee() const { - MOZ_ASSERT(isFunctionFrame()); + MOZ_ASSERT(isNonEvalFunctionFrame()); return calleev().toObject().as(); } const Value& calleev() const { - MOZ_ASSERT(isFunctionFrame()); - if (isEvalFrame()) - return ((const Value*)this)[-1]; + MOZ_ASSERT(isNonEvalFunctionFrame()); return argv()[-2]; } @@ -696,10 +690,11 @@ class InterpreterFrame * frame. */ Value newTarget() const { - MOZ_ASSERT(isFunctionFrame()); if (isEvalFrame()) return ((Value*)this)[-2]; + MOZ_ASSERT(isNonEvalFunctionFrame()); + if (callee().isArrow()) return callee().getExtendedSlot(FunctionExtended::ARROW_NEWTARGET_SLOT); @@ -1846,7 +1841,6 @@ class FrameIter inline bool isBaseline() const; inline bool isPhysicalIonFrame() const; - bool isFunctionFrame() const; bool isGlobalOrModuleFrame() const; bool isEvalFrame() const; bool isNonEvalFunctionFrame() const; @@ -1884,7 +1878,7 @@ class FrameIter JSFunction* callee(JSContext* cx) const; JSFunction* maybeCallee(JSContext* cx) const { - return isFunctionFrame() ? callee(cx) : nullptr; + return isNonEvalFunctionFrame() ? callee(cx) : nullptr; } bool matchCallee(JSContext* cx, HandleFunction fun) const;