зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 24403e652d6d (bug 1141865)
This commit is contained in:
Родитель
3a80a55abd
Коммит
2eae096d54
|
@ -361,17 +361,15 @@ EvalKernel(JSContext* cx, const CallArgs& args, EvalType evalType, AbstractFrame
|
|||
esg.setNewScript(compiled);
|
||||
}
|
||||
|
||||
// Look up the newTarget from the frame iterator.
|
||||
Value newTargetVal = NullValue();
|
||||
return ExecuteKernel(cx, esg.script(), *scopeobj, thisv, newTargetVal, ExecuteType(evalType),
|
||||
return ExecuteKernel(cx, esg.script(), *scopeobj, thisv, ExecuteType(evalType),
|
||||
NullFramePtr() /* evalInFrame */, args.rval().address());
|
||||
}
|
||||
|
||||
bool
|
||||
js::DirectEvalStringFromIon(JSContext* cx,
|
||||
HandleObject scopeobj, HandleScript callerScript,
|
||||
HandleValue thisValue, HandleValue newTargetValue,
|
||||
HandleString str, jsbytecode* pc, MutableHandleValue vp)
|
||||
HandleValue thisValue, HandleString str,
|
||||
jsbytecode* pc, MutableHandleValue vp)
|
||||
{
|
||||
AssertInnerizedScopeChain(cx, *scopeobj);
|
||||
|
||||
|
@ -463,8 +461,8 @@ js::DirectEvalStringFromIon(JSContext* cx,
|
|||
nthisValue = ObjectValue(*obj);
|
||||
}
|
||||
|
||||
return ExecuteKernel(cx, esg.script(), *scopeobj, nthisValue, newTargetValue,
|
||||
ExecuteType(DIRECT_EVAL), NullFramePtr() /* evalInFrame */, vp.address());
|
||||
return ExecuteKernel(cx, esg.script(), *scopeobj, nthisValue, ExecuteType(DIRECT_EVAL),
|
||||
NullFramePtr() /* evalInFrame */, vp.address());
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -536,7 +534,7 @@ js::ExecuteInGlobalAndReturnScope(JSContext* cx, HandleObject global, HandleScri
|
|||
RootedValue rval(cx);
|
||||
// XXXbz when this is fixed to pass in an actual ScopeObject, fix
|
||||
// up the assert in js::CloneFunctionObject accordingly.
|
||||
if (!ExecuteKernel(cx, script, *scope, thisv, UndefinedValue(), EXECUTE_GLOBAL,
|
||||
if (!ExecuteKernel(cx, script, *scope, thisv, EXECUTE_GLOBAL,
|
||||
NullFramePtr() /* evalInFrame */, rval.address()))
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -30,8 +30,8 @@ DirectEval(JSContext* cx, const CallArgs& args);
|
|||
extern bool
|
||||
DirectEvalStringFromIon(JSContext* cx,
|
||||
HandleObject scopeObj, HandleScript callerScript,
|
||||
HandleValue thisValue, HandleValue newTargetValue,
|
||||
HandleString str, jsbytecode * pc, MutableHandleValue vp);
|
||||
HandleValue thisValue, HandleString str,
|
||||
jsbytecode * pc, MutableHandleValue vp);
|
||||
|
||||
// True iff fun is a built-in eval function.
|
||||
extern bool
|
||||
|
|
|
@ -7836,40 +7836,18 @@ Parser<ParseHandler>::argumentList(YieldHandling yieldHandling, Node listNode, b
|
|||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::checkAllowedNestedSyntax(SharedContext::AllowedSyntax allowed,
|
||||
SharedContext** allowingContext)
|
||||
Parser<ParseHandler>::checkAndMarkSuperScope()
|
||||
{
|
||||
for (GenericParseContext* gpc = pc; gpc; gpc = gpc->parent) {
|
||||
SharedContext* sc = gpc->sc;
|
||||
|
||||
// Arrow functions don't help decide whether we should allow nested
|
||||
// syntax, as they don't store any of the necessary state for themselves.
|
||||
if (sc->isFunctionBox() && sc->asFunctionBox()->function()->isArrow()) {
|
||||
// For now (!), disallow new.target in arrow functions. This will
|
||||
// change later in this bug!
|
||||
if (allowed == SharedContext::AllowedSyntax::NewTarget)
|
||||
return false;
|
||||
continue;
|
||||
if (sc->allowSuperProperty()) {
|
||||
if (sc->isFunctionBox())
|
||||
sc->asFunctionBox()->setNeedsHomeObject();
|
||||
return true;
|
||||
} else if (sc->isFunctionBox() && !sc->asFunctionBox()->function()->isArrow()) {
|
||||
// super is not legal in normal functions.
|
||||
break;
|
||||
}
|
||||
|
||||
if (!sc->allowSyntax(allowed))
|
||||
return false;
|
||||
if (allowingContext)
|
||||
*allowingContext = sc;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::checkAndMarkSuperScope()
|
||||
{
|
||||
SharedContext* foundContext = nullptr;
|
||||
if (checkAllowedNestedSyntax(SharedContext::AllowedSyntax::SuperProperty, &foundContext)) {
|
||||
if (foundContext->isFunctionBox())
|
||||
foundContext->asFunctionBox()->setNeedsHomeObject();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -8666,7 +8644,9 @@ Parser<ParseHandler>::tryNewTarget(Node &newTarget)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!checkAllowedNestedSyntax(SharedContext::AllowedSyntax::NewTarget)) {
|
||||
if (!pc->sc->isFunctionBox() || pc->sc->asFunctionBox()->isGenerator() ||
|
||||
pc->sc->asFunctionBox()->function()->isArrow())
|
||||
{
|
||||
reportWithOffset(ParseError, false, begin, JSMSG_BAD_NEWTARGET);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -589,8 +589,6 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
|||
Node parenExprOrGeneratorComprehension(YieldHandling yieldHandling);
|
||||
Node exprInParens(InHandling inHandling, YieldHandling yieldHandling);
|
||||
|
||||
bool checkAllowedNestedSyntax(SharedContext::AllowedSyntax allowed,
|
||||
SharedContext** allowingContext = nullptr);
|
||||
bool tryNewTarget(Node& newTarget);
|
||||
bool checkAndMarkSuperScope();
|
||||
|
||||
|
|
|
@ -230,27 +230,7 @@ class SharedContext
|
|||
return atom == context->names().dotGenerator || atom == context->names().dotGenRVal;
|
||||
}
|
||||
|
||||
enum class AllowedSyntax {
|
||||
NewTarget,
|
||||
SuperProperty
|
||||
};
|
||||
virtual bool allowSyntax(AllowedSyntax allowed) const = 0;
|
||||
|
||||
protected:
|
||||
static bool FunctionAllowsSyntax(JSFunction* func, AllowedSyntax allowed)
|
||||
{
|
||||
MOZ_ASSERT(!func->isArrow());
|
||||
|
||||
switch (allowed) {
|
||||
case AllowedSyntax::NewTarget:
|
||||
// For now, disallow new.target inside generators
|
||||
return !func->isGenerator();
|
||||
case AllowedSyntax::SuperProperty:
|
||||
return func->allowSuperProperty();
|
||||
default:;
|
||||
}
|
||||
MOZ_CRASH("Unknown AllowedSyntax query");
|
||||
}
|
||||
virtual bool allowSuperProperty() const = 0;
|
||||
};
|
||||
|
||||
class GlobalSharedContext : public SharedContext
|
||||
|
@ -269,17 +249,13 @@ class GlobalSharedContext : public SharedContext
|
|||
ObjectBox* toObjectBox() { return nullptr; }
|
||||
HandleObject evalStaticScope() const { return staticEvalScope_; }
|
||||
|
||||
bool allowSyntax(AllowedSyntax allowed) const {
|
||||
bool allowSuperProperty() const {
|
||||
StaticScopeIter<CanGC> it(context, staticEvalScope_);
|
||||
for (; !it.done(); it++) {
|
||||
if (it.type() == StaticScopeIter<CanGC>::Function) {
|
||||
if (it.fun().isArrow()) {
|
||||
// For the moment, disallow new.target inside arrow functions
|
||||
if (allowed == AllowedSyntax::NewTarget)
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
return FunctionAllowsSyntax(&it.fun(), allowed);
|
||||
if (it.type() == StaticScopeIter<CanGC>::Function &&
|
||||
!it.fun().isArrow())
|
||||
{
|
||||
return it.fun().allowSuperProperty();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -344,7 +320,7 @@ class FunctionBox : public ObjectBox, public SharedContext
|
|||
void setArgumentsHasLocalBinding() { funCxFlags.argumentsHasLocalBinding = true; }
|
||||
void setDefinitelyNeedsArgsObj() { MOZ_ASSERT(funCxFlags.argumentsHasLocalBinding);
|
||||
funCxFlags.definitelyNeedsArgsObj = true; }
|
||||
void setNeedsHomeObject() { MOZ_ASSERT(function()->allowSuperProperty());
|
||||
void setNeedsHomeObject() { MOZ_ASSERT(allowSuperProperty());
|
||||
funCxFlags.needsHomeObject = true; }
|
||||
|
||||
bool hasDefaults() const {
|
||||
|
@ -376,13 +352,8 @@ class FunctionBox : public ObjectBox, public SharedContext
|
|||
isGenerator();
|
||||
}
|
||||
|
||||
bool allowSyntax(AllowedSyntax allowed) const {
|
||||
// For now (!) we don't allow new.target in generators, and can't
|
||||
// check that for functions we haven't finished parsing, as they
|
||||
// don't have initialized scripts. Check from our stashed bits instead.
|
||||
if (allowed == AllowedSyntax::NewTarget)
|
||||
return !isGenerator();
|
||||
return FunctionAllowsSyntax(function(), allowed);
|
||||
bool allowSuperProperty() const {
|
||||
return function()->allowSuperProperty();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -400,7 +371,6 @@ SharedContext::asGlobalSharedContext()
|
|||
return static_cast<GlobalSharedContext*>(this);
|
||||
}
|
||||
|
||||
|
||||
// In generators, we treat all locals as aliased so that they get stored on the
|
||||
// heap. This way there is less information to copy off the stack when
|
||||
// suspending, and back on when resuming. It also avoids the need to create and
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
// Test that new.target is acceptably usable in RematerializedFrames.
|
||||
|
||||
load(libdir + "jitopts.js");
|
||||
|
||||
if (!jitTogglesMatch(Opts_Ion2NoOffthreadCompilation))
|
||||
quit();
|
||||
|
||||
withJitOptions(Opts_Ion2NoOffthreadCompilation, function () {
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger;
|
||||
|
||||
g.toggle = function toggle(d, expected) {
|
||||
if (d) {
|
||||
dbg.addDebuggee(g);
|
||||
|
||||
var frame = dbg.getNewestFrame();
|
||||
assertEq(frame.implementation, "ion");
|
||||
assertEq(frame.constructing, true);
|
||||
|
||||
// CONGRATS IF THIS FAILS! You, proud saviour, have made new.target parse
|
||||
// in debug frame evals (presumably by hooking up static scope walks).
|
||||
// Uncomment the assert below for efaust's undying gratitude.
|
||||
// Note that we use .name here because of CCW nonsense.
|
||||
assertEq(frame.eval('new.target').throw.unsafeDereference().name, "SyntaxError");
|
||||
// assertEq(frame.eval('new.target').value.unsafeDereference(), expected);
|
||||
}
|
||||
};
|
||||
|
||||
g.eval("" + function f(d) { new g(d, g, 15); });
|
||||
|
||||
g.eval("" + function g(d, expected) { toggle(d, expected); });
|
||||
|
||||
g.eval("(" + function test() {
|
||||
for (var i = 0; i < 5; i++)
|
||||
f(false);
|
||||
f(true);
|
||||
} + ")();");
|
||||
});
|
|
@ -1513,11 +1513,6 @@ BaselineCompiler::storeValue(const StackValue* source, const Address& dest,
|
|||
masm.loadValue(frame.addressOfThis(), scratch);
|
||||
masm.storeValue(scratch, dest);
|
||||
break;
|
||||
case StackValue::EvalNewTargetSlot:
|
||||
MOZ_ASSERT(script->isForEval());
|
||||
masm.loadValue(frame.addressOfEvalNewTarget(), scratch);
|
||||
masm.storeValue(scratch, dest);
|
||||
break;
|
||||
case StackValue::Stack:
|
||||
masm.loadValue(frame.addressOfStackValue(source), scratch);
|
||||
masm.storeValue(scratch, dest);
|
||||
|
@ -2686,11 +2681,6 @@ BaselineCompiler::emit_JSOP_SETARG()
|
|||
bool
|
||||
BaselineCompiler::emit_JSOP_NEWTARGET()
|
||||
{
|
||||
if (script->isForEval()) {
|
||||
frame.pushEvalNewTarget();
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(function());
|
||||
frame.syncStack(0);
|
||||
|
||||
|
|
|
@ -48,10 +48,8 @@ BaselineFrame::trace(JSTracer* trc, JitFrameIterator& frameIterator)
|
|||
if (hasReturnValue())
|
||||
TraceRoot(trc, returnValue().address(), "baseline-rval");
|
||||
|
||||
if (isEvalFrame()) {
|
||||
if (isEvalFrame())
|
||||
TraceRoot(trc, &evalScript_, "baseline-evalscript");
|
||||
TraceRoot(trc, evalNewTargetAddress(), "baseline-evalNewTarget");
|
||||
}
|
||||
|
||||
if (hasArgsObj())
|
||||
TraceRoot(trc, &argsObj_, "baseline-args-obj");
|
||||
|
|
|
@ -217,25 +217,6 @@ class BaselineFrame
|
|||
offsetOfArg(0));
|
||||
}
|
||||
|
||||
private:
|
||||
Value* evalNewTargetAddress() const {
|
||||
MOZ_ASSERT(isEvalFrame());
|
||||
return (Value*)(reinterpret_cast<const uint8_t*>(this) +
|
||||
BaselineFrame::Size() +
|
||||
offsetOfEvalNewTarget());
|
||||
}
|
||||
|
||||
public:
|
||||
Value newTarget() const {
|
||||
if (isEvalFrame())
|
||||
return *evalNewTargetAddress();
|
||||
if (isConstructing())
|
||||
return *(Value*)(reinterpret_cast<const uint8_t*>(this) +
|
||||
BaselineFrame::Size() +
|
||||
offsetOfArg(Max(numFormalArgs(), numActualArgs())));
|
||||
return UndefinedValue();
|
||||
}
|
||||
|
||||
bool copyRawFrameSlots(AutoValueVector* vec) const;
|
||||
|
||||
bool hasReturnValue() const {
|
||||
|
@ -418,9 +399,6 @@ class BaselineFrame
|
|||
static size_t offsetOfThis() {
|
||||
return FramePointerOffset + js::jit::JitFrameLayout::offsetOfThis();
|
||||
}
|
||||
static size_t offsetOfEvalNewTarget() {
|
||||
return offsetOfArg(0);
|
||||
}
|
||||
static size_t offsetOfArg(size_t index) {
|
||||
return FramePointerOffset + js::jit::JitFrameLayout::offsetOfActualArg(index);
|
||||
}
|
||||
|
|
|
@ -39,10 +39,6 @@ FrameInfo::sync(StackValue* val)
|
|||
case StackValue::ThisSlot:
|
||||
masm.pushValue(addressOfThis());
|
||||
break;
|
||||
case StackValue::EvalNewTargetSlot:
|
||||
MOZ_ASSERT(script->isForEval());
|
||||
masm.pushValue(addressOfEvalNewTarget());
|
||||
break;
|
||||
case StackValue::Register:
|
||||
masm.pushValue(val->reg());
|
||||
break;
|
||||
|
@ -99,9 +95,6 @@ FrameInfo::popValue(ValueOperand dest)
|
|||
case StackValue::ThisSlot:
|
||||
masm.loadValue(addressOfThis(), dest);
|
||||
break;
|
||||
case StackValue::EvalNewTargetSlot:
|
||||
masm.loadValue(addressOfEvalNewTarget(), dest);
|
||||
break;
|
||||
case StackValue::Stack:
|
||||
masm.popValue(dest);
|
||||
break;
|
||||
|
|
|
@ -54,8 +54,7 @@ class StackValue
|
|||
Stack,
|
||||
LocalSlot,
|
||||
ArgSlot,
|
||||
ThisSlot,
|
||||
EvalNewTargetSlot
|
||||
ThisSlot
|
||||
#ifdef DEBUG
|
||||
// In debug builds, assert Kind is initialized.
|
||||
, Uninitialized
|
||||
|
@ -151,10 +150,6 @@ class StackValue
|
|||
kind_ = ThisSlot;
|
||||
knownType_ = JSVAL_TYPE_UNKNOWN;
|
||||
}
|
||||
void setEvalNewTarget() {
|
||||
kind_ = EvalNewTargetSlot;
|
||||
knownType_ = JSVAL_TYPE_UNKNOWN;
|
||||
}
|
||||
void setStack() {
|
||||
kind_ = Stack;
|
||||
knownType_ = JSVAL_TYPE_UNKNOWN;
|
||||
|
@ -264,12 +259,6 @@ class FrameInfo
|
|||
StackValue* sv = rawPush();
|
||||
sv->setThis();
|
||||
}
|
||||
inline void pushEvalNewTarget() {
|
||||
MOZ_ASSERT(script->isForEval());
|
||||
StackValue* sv = rawPush();
|
||||
sv->setEvalNewTarget();
|
||||
}
|
||||
|
||||
inline void pushScratchValue() {
|
||||
masm.pushValue(addressOfScratchValue());
|
||||
StackValue* sv = rawPush();
|
||||
|
@ -286,9 +275,6 @@ class FrameInfo
|
|||
Address addressOfThis() const {
|
||||
return Address(BaselineFrameReg, BaselineFrame::offsetOfThis());
|
||||
}
|
||||
Address addressOfEvalNewTarget() const {
|
||||
return Address(BaselineFrameReg, BaselineFrame::offsetOfEvalNewTarget());
|
||||
}
|
||||
Address addressOfCalleeToken() const {
|
||||
return Address(BaselineFrameReg, BaselineFrame::offsetOfCalleeToken());
|
||||
}
|
||||
|
|
|
@ -181,7 +181,6 @@ jit::EnterBaselineAtBranch(JSContext* cx, InterpreterFrame* fp, jsbytecode* pc)
|
|||
data.osrFrame = fp;
|
||||
data.osrNumStackValues = fp->script()->nfixed() + cx->interpreterRegs().stackDepth();
|
||||
|
||||
AutoValueVector vals(cx);
|
||||
RootedValue thisv(cx);
|
||||
|
||||
if (fp->isNonEvalFunctionFrame()) {
|
||||
|
@ -204,21 +203,6 @@ jit::EnterBaselineAtBranch(JSContext* cx, InterpreterFrame* fp, jsbytecode* pc)
|
|||
data.calleeToken = CalleeToToken(&fp->callee(), /* constructing = */ false);
|
||||
else
|
||||
data.calleeToken = CalleeToToken(fp->script());
|
||||
|
||||
if (fp->isEvalFrame()) {
|
||||
if (!vals.reserve(2))
|
||||
return JitExec_Aborted;
|
||||
|
||||
vals.infallibleAppend(thisv);
|
||||
|
||||
if (fp->isFunctionFrame())
|
||||
vals.infallibleAppend(fp->newTarget());
|
||||
else
|
||||
vals.infallibleAppend(NullValue());
|
||||
|
||||
data.maxArgc = 2;
|
||||
data.maxArgv = vals.begin();
|
||||
}
|
||||
}
|
||||
|
||||
TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime());
|
||||
|
|
|
@ -3485,8 +3485,8 @@ CodeGenerator::visitFilterArgumentsOrEvalV(LFilterArgumentsOrEvalV* lir)
|
|||
masm.bind(&done);
|
||||
}
|
||||
|
||||
typedef bool (*DirectEvalSFn)(JSContext*, HandleObject, HandleScript, HandleValue, HandleValue,
|
||||
HandleString, jsbytecode*, MutableHandleValue);
|
||||
typedef bool (*DirectEvalSFn)(JSContext*, HandleObject, HandleScript, HandleValue, HandleString,
|
||||
jsbytecode*, MutableHandleValue);
|
||||
static const VMFunction DirectEvalStringInfo = FunctionInfo<DirectEvalSFn>(DirectEvalStringFromIon);
|
||||
|
||||
void
|
||||
|
@ -3497,7 +3497,6 @@ CodeGenerator::visitCallDirectEval(LCallDirectEval* lir)
|
|||
|
||||
pushArg(ImmPtr(lir->mir()->pc()));
|
||||
pushArg(string);
|
||||
pushArg(ToValue(lir, LCallDirectEval::NewTarget));
|
||||
pushArg(ToValue(lir, LCallDirectEval::ThisValue));
|
||||
pushArg(ImmGCPtr(gen->info().script()));
|
||||
pushArg(scopeChain);
|
||||
|
|
|
@ -2595,22 +2595,6 @@ jit::SetEnterJitData(JSContext* cx, EnterJitData& data, RunState& state, AutoVal
|
|||
ScriptFrameIter iter(cx);
|
||||
if (iter.isFunctionFrame())
|
||||
data.calleeToken = CalleeToToken(iter.callee(cx), /* constructing = */ false);
|
||||
|
||||
// Push newTarget onto the stack, as well as Argv.
|
||||
if (!vals.reserve(2))
|
||||
return false;
|
||||
|
||||
data.maxArgc = 2;
|
||||
data.maxArgv = vals.begin();
|
||||
vals.infallibleAppend(state.asExecute()->thisv());
|
||||
if (iter.isFunctionFrame()) {
|
||||
if (state.asExecute()->newTarget().isNull())
|
||||
vals.infallibleAppend(iter.newTarget());
|
||||
else
|
||||
vals.infallibleAppend(state.asExecute()->newTarget());
|
||||
} else {
|
||||
vals.infallibleAppend(NullValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6427,10 +6427,6 @@ IonBuilder::jsop_eval(uint32_t argc)
|
|||
current->pushSlot(info().thisSlot());
|
||||
MDefinition* thisValue = current->pop();
|
||||
|
||||
if (!jsop_newtarget())
|
||||
return false;
|
||||
MDefinition* newTargetValue = current->pop();
|
||||
|
||||
// Try to pattern match 'eval(v + "()")'. In this case v is likely a
|
||||
// name on the scope chain and the eval is performing a call on that
|
||||
// value. Use a dynamic scope chain lookup rather than a full eval.
|
||||
|
@ -6459,8 +6455,7 @@ IonBuilder::jsop_eval(uint32_t argc)
|
|||
MInstruction* filterArguments = MFilterArgumentsOrEval::New(alloc(), string);
|
||||
current->add(filterArguments);
|
||||
|
||||
MInstruction* ins = MCallDirectEval::New(alloc(), scopeChain, string,
|
||||
thisValue, newTargetValue, pc);
|
||||
MInstruction* ins = MCallDirectEval::New(alloc(), scopeChain, string, thisValue, pc);
|
||||
current->add(ins);
|
||||
current->push(ins);
|
||||
|
||||
|
@ -9436,12 +9431,6 @@ IonBuilder::jsop_arguments()
|
|||
bool
|
||||
IonBuilder::jsop_newtarget()
|
||||
{
|
||||
if (!info().funMaybeLazy()) {
|
||||
MOZ_ASSERT(!info().script()->isForEval());
|
||||
pushConstant(NullValue());
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(info().funMaybeLazy());
|
||||
if (inliningDepth_ == 0) {
|
||||
MNewTarget* newTarget = MNewTarget::New(alloc());
|
||||
|
|
|
@ -701,8 +701,8 @@ class InlineFrameIterator
|
|||
|
||||
template <class ArgOp, class LocalOp>
|
||||
void readFrameArgsAndLocals(JSContext* cx, ArgOp& argOp, LocalOp& localOp,
|
||||
JSObject** scopeChain, bool* hasCallObj,
|
||||
Value* rval, ArgumentsObject** argsObj, Value* thisv,
|
||||
JSObject** scopeChain, bool* hasCallObj, Value* rval,
|
||||
ArgumentsObject** argsObj, Value* thisv,
|
||||
ReadFrameArgsBehavior behavior,
|
||||
MaybeReadFallback& fallback) const
|
||||
{
|
||||
|
@ -762,13 +762,13 @@ class InlineFrameIterator
|
|||
parent_s.skip(); // scope chain
|
||||
parent_s.skip(); // return value
|
||||
parent_s.readFunctionFrameArgs(argOp, nullptr, nullptr,
|
||||
nformal, nactual + isConstructing(), it.script(),
|
||||
nformal, nactual, it.script(),
|
||||
fallback);
|
||||
} else {
|
||||
// There is no parent frame to this inlined frame, we can read
|
||||
// from the frame's Value vector directly.
|
||||
Value* argv = frame_->actualArgs();
|
||||
for (unsigned i = nformal; i < nactual + isConstructing(); i++)
|
||||
for (unsigned i = nformal; i < nactual; i++)
|
||||
argOp(argv[i]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1927,7 +1927,7 @@ class LFilterArgumentsOrEvalV : public LCallInstructionHelper<0, BOX_PIECES, 3>
|
|||
}
|
||||
};
|
||||
|
||||
class LCallDirectEval : public LCallInstructionHelper<BOX_PIECES, 2 + (2 * BOX_PIECES), 0>
|
||||
class LCallDirectEval : public LCallInstructionHelper<BOX_PIECES, 2 + BOX_PIECES, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(CallDirectEval)
|
||||
|
@ -1939,7 +1939,6 @@ class LCallDirectEval : public LCallInstructionHelper<BOX_PIECES, 2 + (2 * BOX_P
|
|||
}
|
||||
|
||||
static const size_t ThisValue = 2;
|
||||
static const size_t NewTarget = 2 + BOX_PIECES;
|
||||
|
||||
MCallDirectEval* mir() const {
|
||||
return mir_->toCallDirectEval();
|
||||
|
|
|
@ -609,12 +609,10 @@ LIRGenerator::visitCallDirectEval(MCallDirectEval* ins)
|
|||
MOZ_ASSERT(string->type() == MIRType_String);
|
||||
|
||||
MDefinition* thisValue = ins->getThisValue();
|
||||
MDefinition* newTargetValue = ins->getNewTargetValue();
|
||||
|
||||
LInstruction* lir = new(alloc()) LCallDirectEval(useRegisterAtStart(scopeChain),
|
||||
useRegisterAtStart(string));
|
||||
useBoxAtStart(lir, LCallDirectEval::ThisValue, thisValue);
|
||||
useBoxAtStart(lir, LCallDirectEval::NewTarget, newTargetValue);
|
||||
|
||||
defineReturn(lir, ins);
|
||||
assignSafepoint(lir, ins);
|
||||
|
|
|
@ -4069,21 +4069,19 @@ class MFilterArgumentsOrEval
|
|||
};
|
||||
|
||||
class MCallDirectEval
|
||||
: public MAryInstruction<4>,
|
||||
public Mix4Policy<ObjectPolicy<0>,
|
||||
: public MAryInstruction<3>,
|
||||
public Mix3Policy<ObjectPolicy<0>,
|
||||
StringPolicy<1>,
|
||||
BoxPolicy<2>,
|
||||
BoxPolicy<3> >::Data
|
||||
BoxPolicy<2> >::Data
|
||||
{
|
||||
protected:
|
||||
MCallDirectEval(MDefinition* scopeChain, MDefinition* string, MDefinition* thisValue,
|
||||
MDefinition* newTargetValue, jsbytecode* pc)
|
||||
jsbytecode* pc)
|
||||
: pc_(pc)
|
||||
{
|
||||
initOperand(0, scopeChain);
|
||||
initOperand(1, string);
|
||||
initOperand(2, thisValue);
|
||||
initOperand(3, newTargetValue);
|
||||
setResultType(MIRType_Value);
|
||||
}
|
||||
|
||||
|
@ -4092,9 +4090,9 @@ class MCallDirectEval
|
|||
|
||||
static MCallDirectEval*
|
||||
New(TempAllocator& alloc, MDefinition* scopeChain, MDefinition* string, MDefinition* thisValue,
|
||||
MDefinition* newTargetValue, jsbytecode* pc)
|
||||
jsbytecode* pc)
|
||||
{
|
||||
return new(alloc) MCallDirectEval(scopeChain, string, thisValue, newTargetValue, pc);
|
||||
return new(alloc) MCallDirectEval(scopeChain, string, thisValue, pc);
|
||||
}
|
||||
|
||||
MDefinition* getScopeChain() const {
|
||||
|
@ -4106,9 +4104,6 @@ class MCallDirectEval
|
|||
MDefinition* getThisValue() const {
|
||||
return getOperand(2);
|
||||
}
|
||||
MDefinition* getNewTargetValue() const {
|
||||
return getOperand(3);
|
||||
}
|
||||
|
||||
jsbytecode* pc() const {
|
||||
return pc_;
|
||||
|
|
|
@ -35,7 +35,6 @@ RematerializedFrame::RematerializedFrame(JSContext* cx, uint8_t* top, unsigned n
|
|||
InlineFrameIterator& iter, MaybeReadFallback& fallback)
|
||||
: prevUpToDate_(false),
|
||||
isDebuggee_(iter.script()->isDebuggee()),
|
||||
isConstructing_(iter.isConstructing()),
|
||||
top_(top),
|
||||
pc_(iter.pc()),
|
||||
frameNo_(iter.frameNo()),
|
||||
|
@ -58,7 +57,7 @@ RematerializedFrame::New(JSContext* cx, uint8_t* top, InlineFrameIterator& iter,
|
|||
MaybeReadFallback& fallback)
|
||||
{
|
||||
unsigned numFormals = iter.isFunctionFrame() ? iter.calleeTemplate()->nargs() : 0;
|
||||
unsigned argSlots = Max(numFormals, iter.numActualArgs()) + iter.isConstructing();
|
||||
unsigned argSlots = Max(numFormals, iter.numActualArgs());
|
||||
size_t numBytes = sizeof(RematerializedFrame) +
|
||||
(argSlots + iter.script()->nfixed()) * sizeof(Value) -
|
||||
sizeof(Value); // 1 Value included in sizeof(RematerializedFrame)
|
||||
|
@ -159,8 +158,7 @@ RematerializedFrame::mark(JSTracer* trc)
|
|||
TraceRoot(trc, &callee_, "remat ion frame callee");
|
||||
TraceRoot(trc, &returnValue_, "remat ion frame return value");
|
||||
TraceRoot(trc, &thisValue_, "remat ion frame this");
|
||||
TraceRootRange(trc, numActualArgs_ + isConstructing_ + script_->nfixed(),
|
||||
slots_, "remat ion frame stack");
|
||||
TraceRootRange(trc, numActualArgs_ + script_->nfixed(), slots_, "remat ion frame stack");
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -32,9 +32,6 @@ class RematerializedFrame
|
|||
// Has a call object been pushed?
|
||||
bool hasCallObj_;
|
||||
|
||||
// Is this frame constructing?
|
||||
bool isConstructing_;
|
||||
|
||||
// The fp of the top frame associated with this possibly inlined frame.
|
||||
uint8_t* top_;
|
||||
|
||||
|
@ -165,10 +162,6 @@ class RematerializedFrame
|
|||
return thisValue_;
|
||||
}
|
||||
|
||||
bool isConstructing() const {
|
||||
return isConstructing_;
|
||||
}
|
||||
|
||||
unsigned numFormalArgs() const {
|
||||
return maybeFun() ? fun()->nargs() : 0;
|
||||
}
|
||||
|
@ -180,7 +173,7 @@ class RematerializedFrame
|
|||
return slots_;
|
||||
}
|
||||
Value* locals() {
|
||||
return slots_ + numActualArgs_ + isConstructing_;
|
||||
return slots_ + numActualArgs_;
|
||||
}
|
||||
|
||||
Value& unaliasedLocal(unsigned i) {
|
||||
|
@ -200,13 +193,6 @@ class RematerializedFrame
|
|||
return argv()[i];
|
||||
}
|
||||
|
||||
Value newTarget() {
|
||||
MOZ_ASSERT(isFunctionFrame());
|
||||
if (isConstructing())
|
||||
return argv()[numActualArgs()];
|
||||
return UndefinedValue();
|
||||
}
|
||||
|
||||
Value returnValue() const {
|
||||
return returnValue_;
|
||||
}
|
||||
|
|
|
@ -1152,7 +1152,6 @@ FilterTypeSetPolicy::adjustInputs(TempAllocator& alloc, MInstruction* ins)
|
|||
_(Mix3Policy<StringPolicy<0>, IntPolicy<1>, IntPolicy<2>>) \
|
||||
_(Mix3Policy<StringPolicy<0>, ObjectPolicy<1>, StringPolicy<2> >) \
|
||||
_(Mix3Policy<StringPolicy<0>, StringPolicy<1>, StringPolicy<2> >) \
|
||||
_(Mix4Policy<ObjectPolicy<0>, StringPolicy<1>, BoxPolicy<2>, BoxPolicy<3>>) \
|
||||
_(Mix4Policy<ObjectPolicy<0>, IntPolicy<1>, IntPolicy<2>, IntPolicy<3>>) \
|
||||
_(Mix4Policy<SimdScalarPolicy<0>, SimdScalarPolicy<1>, SimdScalarPolicy<2>, SimdScalarPolicy<3> >) \
|
||||
_(MixPolicy<BoxPolicy<0>, ObjectPolicy<1> >) \
|
||||
|
|
|
@ -446,7 +446,6 @@ template <> struct MatchContext<ExclusiveContext*> {
|
|||
#define FOR_EACH_ARGS_4(Macro, Sep, Last) FOR_EACH_ARGS_3(Macro, Sep, Sep) Macro(4) Last(4)
|
||||
#define FOR_EACH_ARGS_5(Macro, Sep, Last) FOR_EACH_ARGS_4(Macro, Sep, Sep) Macro(5) Last(5)
|
||||
#define FOR_EACH_ARGS_6(Macro, Sep, Last) FOR_EACH_ARGS_5(Macro, Sep, Sep) Macro(6) Last(6)
|
||||
#define FOR_EACH_ARGS_7(Macro, Sep, Last) FOR_EACH_ARGS_6(Macro, Sep, Sep) Macro(7) Last(7)
|
||||
|
||||
#define COMPUTE_INDEX(NbArg) NbArg
|
||||
#define COMPUTE_OUTPARAM_RESULT(NbArg) OutParamToDataType<A ## NbArg>::result
|
||||
|
@ -586,15 +585,8 @@ template <class R, class Context, class A1, class A2, class A3, class A4, class
|
|||
FUNCTION_INFO_STRUCT_BODY(FOR_EACH_ARGS_6)
|
||||
};
|
||||
|
||||
template <class R, class Context, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
|
||||
struct FunctionInfo<R (*)(Context, A1, A2, A3, A4, A5, A6, A7)> : public VMFunction {
|
||||
typedef R (*pf)(Context, A1, A2, A3, A4, A5, A6, A7);
|
||||
FUNCTION_INFO_STRUCT_BODY(FOR_EACH_ARGS_7)
|
||||
};
|
||||
|
||||
#undef FUNCTION_INFO_STRUCT_BODY
|
||||
|
||||
#undef FOR_EACH_ARGS_7
|
||||
#undef FOR_EACH_ARGS_6
|
||||
#undef FOR_EACH_ARGS_5
|
||||
#undef FOR_EACH_ARGS_4
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
// new.target is valid inside Function() invocations
|
||||
var func = new Function("new.target");
|
||||
|
||||
// new.target is invalid inside eval, even (for now!) eval inside a function.
|
||||
assertThrowsInstanceOf(() => eval('new.target'), SyntaxError);
|
||||
|
||||
function evalInFunction() { eval('new.target'); }
|
||||
assertThrowsInstanceOf(() => evalInFunction(), SyntaxError);
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(0,0,"OK");
|
|
@ -1,6 +1,3 @@
|
|||
// new.target is valid inside Function() invocations
|
||||
var func = new Function("new.target");
|
||||
|
||||
// Note that this will also test new.target in ion inlines. When the toplevel
|
||||
// script is compiled, assertNewTarget will be inlined.
|
||||
function assertNewTarget(expected, unused) { assertEq(new.target, expected); }
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
// Eval of new.target is invalid outside functions.
|
||||
try {
|
||||
eval('new.target');
|
||||
assertEq(false, true);
|
||||
} catch (e if e instanceof SyntaxError) { }
|
||||
|
||||
// new.target is (for now!) invalid inside arrow functions, or eval inside arrow
|
||||
// functions.
|
||||
assertThrowsInstanceOf(() => eval('new.target'), SyntaxError);
|
||||
|
||||
// new.target is invalid inside indirect eval.
|
||||
let ieval = eval;
|
||||
try {
|
||||
(function () ieval('new.target'))();
|
||||
assertEq(false, true);
|
||||
} catch (e if e instanceof SyntaxError) { }
|
||||
|
||||
function assertNewTarget(expected) {
|
||||
assertEq(eval('new.target'), expected);
|
||||
|
||||
// Also test nestings "by induction"
|
||||
assertEq(eval('eval("new.target")'), expected);
|
||||
assertEq(eval("eval('eval(`new.target`)')"), expected);
|
||||
}
|
||||
|
||||
const ITERATIONS = 550;
|
||||
for (let i = 0; i < ITERATIONS; i++)
|
||||
assertNewTarget(undefined);
|
||||
|
||||
for (let i = 0; i < ITERATIONS; i++)
|
||||
new assertNewTarget(assertNewTarget);
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(0,0,"OK");
|
|
@ -6287,7 +6287,7 @@ EvaluateInEnv(JSContext* cx, Handle<Env*> env, HandleValue thisv, AbstractFrameP
|
|||
|
||||
script->setActiveEval();
|
||||
ExecuteType type = !frame ? EXECUTE_DEBUG_GLOBAL : EXECUTE_DEBUG;
|
||||
return ExecuteKernel(cx, script, *env, thisv, NullValue(), type, frame, rval.address());
|
||||
return ExecuteKernel(cx, script, *env, thisv, type, frame, rval.address());
|
||||
}
|
||||
|
||||
enum EvalBindings { EvalHasExtraBindings = true, EvalWithDefaultBindings = false };
|
||||
|
|
|
@ -366,8 +366,8 @@ InvokeState::pushInterpreterFrame(JSContext* cx)
|
|||
InterpreterFrame*
|
||||
ExecuteState::pushInterpreterFrame(JSContext* cx)
|
||||
{
|
||||
return cx->runtime()->interpreterStack().pushExecuteFrame(cx, script_, thisv_, newTargetValue_,
|
||||
scopeChain_, type_, evalInFrame_);
|
||||
return cx->runtime()->interpreterStack().pushExecuteFrame(cx, script_, thisv_, scopeChain_,
|
||||
type_, evalInFrame_);
|
||||
}
|
||||
namespace js {
|
||||
|
||||
|
@ -847,8 +847,7 @@ js::InvokeSetter(JSContext* cx, const Value& thisv, Value fval, HandleValue v)
|
|||
|
||||
bool
|
||||
js::ExecuteKernel(JSContext* cx, HandleScript script, JSObject& scopeChainArg, const Value& thisv,
|
||||
const Value& newTargetValue, ExecuteType type, AbstractFramePtr evalInFrame,
|
||||
Value* result)
|
||||
ExecuteType type, AbstractFramePtr evalInFrame, Value* result)
|
||||
{
|
||||
MOZ_ASSERT_IF(evalInFrame, type == EXECUTE_DEBUG);
|
||||
MOZ_ASSERT_IF(type == EXECUTE_GLOBAL, !IsSyntacticScope(&scopeChainArg));
|
||||
|
@ -883,7 +882,7 @@ js::ExecuteKernel(JSContext* cx, HandleScript script, JSObject& scopeChainArg, c
|
|||
TypeScript::SetThis(cx, script, thisv);
|
||||
|
||||
probes::StartExecution(script);
|
||||
ExecuteState state(cx, script, thisv, newTargetValue, scopeChainArg, type, evalInFrame, result);
|
||||
ExecuteState state(cx, script, thisv, scopeChainArg, type, evalInFrame, result);
|
||||
bool ok = RunScript(cx, state);
|
||||
probes::StopExecution(script);
|
||||
|
||||
|
@ -923,7 +922,7 @@ js::Execute(JSContext* cx, HandleScript script, JSObject& scopeChainArg, Value*
|
|||
return false;
|
||||
Value thisv = ObjectValue(*thisObj);
|
||||
|
||||
return ExecuteKernel(cx, script, *scopeChain, thisv, NullValue(), EXECUTE_GLOBAL,
|
||||
return ExecuteKernel(cx, script, *scopeChain, thisv, EXECUTE_GLOBAL,
|
||||
NullFramePtr() /* evalInFrame */, rval);
|
||||
}
|
||||
|
||||
|
|
|
@ -105,8 +105,7 @@ InvokeConstructor(JSContext* cx, Value fval, unsigned argc, const Value* argv,
|
|||
*/
|
||||
extern bool
|
||||
ExecuteKernel(JSContext* cx, HandleScript script, JSObject& scopeChain, const Value& thisv,
|
||||
const Value& newTargetVal, ExecuteType type, AbstractFramePtr evalInFrame,
|
||||
Value* result);
|
||||
ExecuteType type, AbstractFramePtr evalInFrame, Value* result);
|
||||
|
||||
/* Execute a script with the given scopeChain as global code. */
|
||||
extern bool
|
||||
|
@ -164,28 +163,23 @@ class ExecuteState : public RunState
|
|||
ExecuteType type_;
|
||||
|
||||
RootedValue thisv_;
|
||||
RootedValue newTargetValue_;
|
||||
RootedObject scopeChain_;
|
||||
|
||||
AbstractFramePtr evalInFrame_;
|
||||
Value* result_;
|
||||
|
||||
public:
|
||||
ExecuteState(JSContext* cx, JSScript* script, const Value& thisv, const Value& newTargetValue,
|
||||
JSObject& scopeChain, ExecuteType type, AbstractFramePtr evalInFrame,
|
||||
Value* result)
|
||||
ExecuteState(JSContext* cx, JSScript* script, const Value& thisv, JSObject& scopeChain,
|
||||
ExecuteType type, AbstractFramePtr evalInFrame, Value* result)
|
||||
: RunState(cx, Execute, script),
|
||||
type_(type),
|
||||
thisv_(cx, thisv),
|
||||
newTargetValue_(cx, newTargetValue),
|
||||
scopeChain_(cx, &scopeChain),
|
||||
evalInFrame_(evalInFrame),
|
||||
result_(result)
|
||||
{ }
|
||||
|
||||
Value* addressOfThisv() { return thisv_.address(); }
|
||||
Value thisv() { return thisv_; }
|
||||
Value newTarget() { return newTargetValue_; }
|
||||
JSObject* scopeChain() const { return scopeChain_; }
|
||||
ExecuteType type() const { return type_; }
|
||||
|
||||
|
|
|
@ -816,16 +816,6 @@ AbstractFramePtr::thisValue() const
|
|||
return asRematerializedFrame()->thisValue();
|
||||
}
|
||||
|
||||
inline Value
|
||||
AbstractFramePtr::newTarget() const
|
||||
{
|
||||
if (isInterpreterFrame())
|
||||
return asInterpreterFrame()->newTarget();
|
||||
if (isBaselineFrame())
|
||||
return asBaselineFrame()->newTarget();
|
||||
return asRematerializedFrame()->newTarget();
|
||||
}
|
||||
|
||||
inline bool
|
||||
AbstractFramePtr::freshenBlock(JSContext* cx) const
|
||||
{
|
||||
|
|
|
@ -33,8 +33,7 @@ using mozilla::PodCopy;
|
|||
|
||||
void
|
||||
InterpreterFrame::initExecuteFrame(JSContext* cx, HandleScript script, AbstractFramePtr evalInFramePrev,
|
||||
const Value& thisv, const Value& newTargetValue, HandleObject scopeChain,
|
||||
ExecuteType type)
|
||||
const Value& thisv, HandleObject scopeChain, ExecuteType type)
|
||||
{
|
||||
/*
|
||||
* See encoding of ExecuteType. When GLOBAL isn't set, we are executing a
|
||||
|
@ -44,14 +43,11 @@ InterpreterFrame::initExecuteFrame(JSContext* cx, HandleScript script, AbstractF
|
|||
flags_ = type | HAS_SCOPECHAIN;
|
||||
|
||||
JSObject* callee = nullptr;
|
||||
RootedValue newTarget(cx, newTargetValue);
|
||||
if (!(flags_ & (GLOBAL))) {
|
||||
if (evalInFramePrev) {
|
||||
MOZ_ASSERT(evalInFramePrev.isFunctionFrame() || evalInFramePrev.isGlobalFrame());
|
||||
if (evalInFramePrev.isFunctionFrame()) {
|
||||
callee = evalInFramePrev.callee();
|
||||
if (newTarget.isNull())
|
||||
newTarget = evalInFramePrev.newTarget();
|
||||
flags_ |= FUNCTION;
|
||||
} else {
|
||||
flags_ |= GLOBAL;
|
||||
|
@ -61,8 +57,6 @@ InterpreterFrame::initExecuteFrame(JSContext* cx, HandleScript script, AbstractF
|
|||
MOZ_ASSERT(iter.isFunctionFrame() || iter.isGlobalFrame());
|
||||
MOZ_ASSERT(!iter.isAsmJS());
|
||||
if (iter.isFunctionFrame()) {
|
||||
if (newTarget.isNull())
|
||||
newTarget = iter.newTarget();
|
||||
callee = iter.callee(cx);
|
||||
flags_ |= FUNCTION;
|
||||
} else {
|
||||
|
@ -70,26 +64,22 @@ InterpreterFrame::initExecuteFrame(JSContext* cx, HandleScript script, AbstractF
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Null is just a sentinel value. We should have figured it out by now.
|
||||
MOZ_ASSERT_IF(isFunctionFrame(), newTarget.isObject() || newTarget.isUndefined());
|
||||
|
||||
Value* dstvp = (Value*)this - 3;
|
||||
dstvp[2] = thisv;
|
||||
Value* dstvp = (Value*)this - 2;
|
||||
dstvp[1] = thisv;
|
||||
|
||||
if (isFunctionFrame()) {
|
||||
dstvp[1] = ObjectValue(*callee);
|
||||
dstvp[0] = ObjectValue(*callee);
|
||||
exec.fun = &callee->as<JSFunction>();
|
||||
u.evalScript = script;
|
||||
} else {
|
||||
MOZ_ASSERT(isGlobalFrame());
|
||||
dstvp[1] = NullValue();
|
||||
dstvp[0] = NullValue();
|
||||
exec.script = script;
|
||||
#ifdef DEBUG
|
||||
u.evalScript = (JSScript*)0xbad;
|
||||
#endif
|
||||
}
|
||||
dstvp[0] = newTarget;
|
||||
|
||||
scopeChain_ = scopeChain.get();
|
||||
prev_ = nullptr;
|
||||
|
@ -409,8 +399,8 @@ InterpreterFrame::markValues(JSTracer* trc, Value* sp, jsbytecode* pc)
|
|||
unsigned argc = Max(numActualArgs(), numFormalArgs());
|
||||
TraceRootRange(trc, argc + 2 + isConstructing(), argv_ - 2, "fp argv");
|
||||
} else {
|
||||
// Mark callee, |this|, and newTarget
|
||||
TraceRootRange(trc, 3, ((Value*)this) - 3, "stack callee, this, newTarget");
|
||||
// Mark callee and |this|
|
||||
TraceRootRange(trc, 2, ((Value*)this) - 2, "stack callee and this");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -468,19 +458,19 @@ InterpreterStack::pushInvokeFrame(JSContext* cx, const CallArgs& args, InitialFr
|
|||
|
||||
InterpreterFrame*
|
||||
InterpreterStack::pushExecuteFrame(JSContext* cx, HandleScript script, const Value& thisv,
|
||||
const Value& newTargetValue, HandleObject scopeChain,
|
||||
ExecuteType type, AbstractFramePtr evalInFrame)
|
||||
HandleObject scopeChain, ExecuteType type,
|
||||
AbstractFramePtr evalInFrame)
|
||||
{
|
||||
LifoAlloc::Mark mark = allocator_.mark();
|
||||
|
||||
unsigned nvars = 3 /* callee, this, newTarget */ + script->nslots();
|
||||
unsigned nvars = 2 /* callee, this */ + script->nslots();
|
||||
uint8_t* buffer = allocateFrame(cx, sizeof(InterpreterFrame) + nvars * sizeof(Value));
|
||||
if (!buffer)
|
||||
return nullptr;
|
||||
|
||||
InterpreterFrame* fp = reinterpret_cast<InterpreterFrame*>(buffer + 3 * sizeof(Value));
|
||||
InterpreterFrame* fp = reinterpret_cast<InterpreterFrame*>(buffer + 2 * sizeof(Value));
|
||||
fp->mark_ = mark;
|
||||
fp->initExecuteFrame(cx, script, evalInFrame, thisv, newTargetValue, scopeChain, type);
|
||||
fp->initExecuteFrame(cx, script, evalInFrame, thisv, scopeChain, type);
|
||||
fp->initLocals();
|
||||
|
||||
return fp;
|
||||
|
@ -1262,22 +1252,6 @@ FrameIter::thisv(JSContext* cx) const
|
|||
MOZ_CRASH("Unexpected state");
|
||||
}
|
||||
|
||||
Value
|
||||
FrameIter::newTarget() const
|
||||
{
|
||||
switch (data_.state_) {
|
||||
case DONE:
|
||||
case ASMJS:
|
||||
break;
|
||||
case INTERP:
|
||||
return interpFrame()->newTarget();
|
||||
case JIT:
|
||||
MOZ_ASSERT(data_.jitFrames_.isBaselineJS());
|
||||
return data_.jitFrames_.baselineFrame()->newTarget();
|
||||
}
|
||||
MOZ_CRASH("Unexpected state");
|
||||
}
|
||||
|
||||
Value
|
||||
FrameIter::returnValue() const
|
||||
{
|
||||
|
|
|
@ -204,8 +204,6 @@ class AbstractFramePtr
|
|||
inline Value calleev() const;
|
||||
inline Value& thisValue() const;
|
||||
|
||||
inline Value newTarget() const;
|
||||
|
||||
inline bool isNonEvalFunctionFrame() const;
|
||||
inline bool isNonStrictDirectEvalFrame() const;
|
||||
inline bool isStrictEvalFrame() const;
|
||||
|
@ -407,8 +405,7 @@ class InterpreterFrame
|
|||
|
||||
/* Used for global and eval frames. */
|
||||
void initExecuteFrame(JSContext* cx, HandleScript script, AbstractFramePtr prev,
|
||||
const Value& thisv, const Value& newTargetValue,
|
||||
HandleObject scopeChain, ExecuteType type);
|
||||
const Value& thisv, HandleObject scopeChain, ExecuteType type);
|
||||
|
||||
public:
|
||||
/*
|
||||
|
@ -751,10 +748,8 @@ class InterpreterFrame
|
|||
* frame.
|
||||
*/
|
||||
Value newTarget() const {
|
||||
MOZ_ASSERT(isFunctionFrame());
|
||||
if (isEvalFrame())
|
||||
return ((Value*)this)[-3];
|
||||
|
||||
// new.target in eval() NYI.
|
||||
MOZ_ASSERT(isNonEvalFunctionFrame());
|
||||
if (isConstructing()) {
|
||||
unsigned pushedArgs = Max(numFormalArgs(), numActualArgs());
|
||||
return argv()[pushedArgs];
|
||||
|
@ -1022,8 +1017,8 @@ class InterpreterStack
|
|||
|
||||
// For execution of eval or global code.
|
||||
InterpreterFrame* pushExecuteFrame(JSContext* cx, HandleScript script, const Value& thisv,
|
||||
const Value& newTargetValue, HandleObject scopeChain,
|
||||
ExecuteType type, AbstractFramePtr evalInFrame);
|
||||
HandleObject scopeChain, ExecuteType type,
|
||||
AbstractFramePtr evalInFrame);
|
||||
|
||||
// Called to invoke a function.
|
||||
InterpreterFrame* pushInvokeFrame(JSContext* cx, const CallArgs& args,
|
||||
|
@ -1761,8 +1756,6 @@ class FrameIter
|
|||
Value computedThisValue() const;
|
||||
Value thisv(JSContext* cx) const;
|
||||
|
||||
Value newTarget() const;
|
||||
|
||||
Value returnValue() const;
|
||||
void setReturnValue(const Value& v);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче