Backed out changeset 24403e652d6d (bug 1141865)

This commit is contained in:
Carsten "Tomcat" Book 2015-06-03 12:42:03 +02:00
Родитель 3a80a55abd
Коммит 2eae096d54
32 изменённых файлов: 84 добавлений и 384 удалений

Просмотреть файл

@ -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);