Backed out changeset 0f963fbdc918 (bug 1141865)

This commit is contained in:
Carsten "Tomcat" Book 2015-06-03 12:41:48 +02:00
Родитель e1180d592e
Коммит 3a80a55abd
27 изменённых файлов: 58 добавлений и 307 удалений

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

@ -5452,19 +5452,6 @@ BytecodeEmitter::emitFor(ParseNode* pn, ptrdiff_t top)
return emitNormalFor(pn, top);
}
bool
BytecodeEmitter::arrowNeedsNewTarget()
{
for (BytecodeEmitter* bce = this; bce; bce = bce->parent) {
SharedContext *sc = bce->sc;
if (sc->isFunctionBox() && sc->asFunctionBox()->function()->isArrow())
continue;
return sc->allowSyntax(SharedContext::AllowedSyntax::NewTarget);
}
MOZ_CRASH("impossible parent chain");
}
MOZ_NEVER_INLINE bool
BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
{
@ -5556,21 +5543,10 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
/* Non-hoisted functions simply emit their respective op. */
if (!pn->functionIsHoisted()) {
/* JSOP_LAMBDA_ARROW is always preceded by JSOP_THIS and a new.target */
/* JSOP_LAMBDA_ARROW is always preceded by JSOP_THIS. */
MOZ_ASSERT(fun->isArrow() == (pn->getOp() == JSOP_LAMBDA_ARROW));
if (fun->isArrow()) {
if (!emit1(JSOP_THIS))
return false;
if (arrowNeedsNewTarget()) {
if (!emit1(JSOP_NEWTARGET))
return false;
} else {
if (!emit1(JSOP_NULL))
return false;
}
}
if (fun->isArrow() && !emit1(JSOP_THIS))
return false;
if (needsProto) {
MOZ_ASSERT(pn->getOp() == JSOP_LAMBDA);
pn->setOp(JSOP_FUNWITHPROTO);

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

@ -432,7 +432,6 @@ struct BytecodeEmitter
bool emitObjectPairOp(ObjectBox* objbox1, ObjectBox* objbox2, JSOp op);
bool emitRegExp(uint32_t index);
bool arrowNeedsNewTarget();
MOZ_NEVER_INLINE bool emitFunction(ParseNode* pn, bool needsProto = false);
MOZ_NEVER_INLINE bool emitObject(ParseNode* pn);

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

@ -7844,8 +7844,13 @@ Parser<ParseHandler>::checkAllowedNestedSyntax(SharedContext::AllowedSyntax allo
// 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())
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->allowSyntax(allowed))
return false;

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

@ -272,9 +272,13 @@ class GlobalSharedContext : public SharedContext
bool allowSyntax(AllowedSyntax allowed) const {
StaticScopeIter<CanGC> it(context, staticEvalScope_);
for (; !it.done(); it++) {
if (it.type() == StaticScopeIter<CanGC>::Function &&
!it.fun().isArrow())
{
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);
}
}

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

@ -1,41 +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");
// the arrow function will not be constructing, even though it has a
// new.target value.
assertEq(frame.constructing, false);
// 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').return.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);
} + ")();");
});

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

@ -1463,24 +1463,22 @@ BaselineCompiler::emit_JSOP_LAMBDA()
return true;
}
typedef JSObject* (*LambdaArrowFn)(JSContext*, HandleFunction, HandleObject,
HandleValue, HandleValue);
typedef JSObject* (*LambdaArrowFn)(JSContext*, HandleFunction, HandleObject, HandleValue);
static const VMFunction LambdaArrowInfo = FunctionInfo<LambdaArrowFn>(js::LambdaArrow);
bool
BaselineCompiler::emit_JSOP_LAMBDA_ARROW()
{
// Keep pushed |this| in R0, and newTarget in R1.
frame.popRegsAndSync(2);
// Keep pushed |this| in R0.
frame.popRegsAndSync(1);
RootedFunction fun(cx, script->getFunction(GET_UINT32_INDEX(pc)));
prepareVMCall();
masm.loadPtr(frame.addressOfScopeChain(), R2.scratchReg());
masm.loadPtr(frame.addressOfScopeChain(), R1.scratchReg());
pushArg(R1);
pushArg(R0);
pushArg(R2.scratchReg());
pushArg(R1.scratchReg());
pushArg(ImmGCPtr(fun));
if (!callVM(LambdaArrowInfo))
@ -2696,16 +2694,6 @@ BaselineCompiler::emit_JSOP_NEWTARGET()
MOZ_ASSERT(function());
frame.syncStack(0);
if (function()->isArrow()) {
// Arrow functions store their |new.target| value in an
// extended slot.
Register scratch = R0.scratchReg();
masm.loadFunctionFromCalleeToken(frame.addressOfCalleeToken(), scratch);
masm.loadValue(Address(scratch, FunctionExtended::offsetOfArrowNewTargetSlot()), R0);
frame.push(R0);
return true;
}
// if (!isConstructing()) push(undefined)
Label constructing, done;
masm.branchTestPtr(Assembler::NonZero, frame.addressOfCalleeToken(),

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

@ -227,11 +227,8 @@ class BaselineFrame
public:
Value newTarget() const {
MOZ_ASSERT(isFunctionFrame());
if (isEvalFrame())
return *evalNewTargetAddress();
if (fun()->isArrow())
return fun()->getExtendedSlot(FunctionExtended::ARROW_NEWTARGET_SLOT);
if (isConstructing())
return *(Value*)(reinterpret_cast<const uint8_t*>(this) +
BaselineFrame::Size() +

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

@ -1720,100 +1720,42 @@ CodeGenerator::visitLambda(LLambda* lir)
masm.bind(ool->rejoin());
}
class OutOfLineLambdaArrow : public OutOfLineCodeBase<CodeGenerator>
{
public:
LLambdaArrow* lir;
Label entryNoPop_;
explicit OutOfLineLambdaArrow(LLambdaArrow* lir)
: lir(lir)
{ }
void accept(CodeGenerator* codegen) {
codegen->visitOutOfLineLambdaArrow(this);
}
Label* entryNoPop() {
return &entryNoPop_;
}
};
typedef JSObject* (*LambdaArrowFn)(JSContext*, HandleFunction, HandleObject, HandleValue, HandleValue);
typedef JSObject* (*LambdaArrowFn)(JSContext*, HandleFunction, HandleObject, HandleValue);
static const VMFunction LambdaArrowInfo = FunctionInfo<LambdaArrowFn>(js::LambdaArrow);
void
CodeGenerator::visitOutOfLineLambdaArrow(OutOfLineLambdaArrow* ool)
{
Register scopeChain = ToRegister(ool->lir->scopeChain());
ValueOperand thisv = ToValue(ool->lir, LLambdaArrow::ThisValue);
ValueOperand newTarget = ToValue(ool->lir, LLambdaArrow::NewTargetValue);
Register output = ToRegister(ool->lir->output());
const LambdaFunctionInfo& info = ool->lir->mir()->info();
// When we get here, we may need to restore part of the newTarget,
// which has been conscripted into service as a temp register.
masm.pop(newTarget.scratchReg());
masm.bind(ool->entryNoPop());
saveLive(ool->lir);
pushArg(newTarget);
pushArg(thisv);
pushArg(scopeChain);
pushArg(ImmGCPtr(info.fun));
callVM(LambdaArrowInfo, ool->lir);
StoreRegisterTo(output).generate(this);
restoreLiveIgnore(ool->lir, StoreRegisterTo(output).clobbered());
masm.jump(ool->rejoin());
}
void
CodeGenerator::visitLambdaArrow(LLambdaArrow* lir)
{
Register scopeChain = ToRegister(lir->scopeChain());
ValueOperand thisv = ToValue(lir, LLambdaArrow::ThisValue);
ValueOperand newTarget = ToValue(lir, LLambdaArrow::NewTargetValue);
Register output = ToRegister(lir->output());
Register tempReg = ToRegister(lir->temp());
const LambdaFunctionInfo& info = lir->mir()->info();
OutOfLineLambdaArrow* ool = new (alloc()) OutOfLineLambdaArrow(lir);
addOutOfLineCode(ool, lir->mir());
OutOfLineCode* ool = oolCallVM(LambdaArrowInfo, lir,
(ArgList(), ImmGCPtr(info.fun), scopeChain, thisv),
StoreRegisterTo(output));
MOZ_ASSERT(!info.useSingletonForClone);
if (info.singletonType) {
// If the function has a singleton type, this instruction will only be
// executed once so we don't bother inlining it.
masm.jump(ool->entryNoPop());
masm.jump(ool->entry());
masm.bind(ool->rejoin());
return;
}
// There's not enough registers on x86 with the profiler enabled to request
// a temp. Instead, spill part of one of the values, being prepared to
// restore it if necessary on the out of line path.
Register tempReg = newTarget.scratchReg();
masm.push(newTarget.scratchReg());
masm.createGCObject(output, tempReg, info.fun, gc::DefaultHeap, ool->entry());
masm.pop(newTarget.scratchReg());
emitLambdaInit(output, scopeChain, info);
// Initialize extended slots. Lexical |this| is stored in the first one.
MOZ_ASSERT(info.flags & JSFunction::EXTENDED);
static_assert(FunctionExtended::NUM_EXTENDED_SLOTS == 2, "All slots must be initialized");
static_assert(FunctionExtended::ARROW_THIS_SLOT == 0, "|this| must be stored in first slot");
static_assert(FunctionExtended::ARROW_NEWTARGET_SLOT == 1,
"|new.target| must be stored in second slot");
masm.storeValue(thisv, Address(output, FunctionExtended::offsetOfExtendedSlot(0)));
masm.storeValue(newTarget, Address(output, FunctionExtended::offsetOfExtendedSlot(1)));
masm.storeValue(UndefinedValue(), Address(output, FunctionExtended::offsetOfExtendedSlot(1)));
masm.bind(ool->rejoin());
}
@ -5023,14 +4965,6 @@ CodeGenerator::visitLoadArrowThis(LLoadArrowThis* lir)
masm.loadValue(Address(callee, FunctionExtended::offsetOfArrowThisSlot()), output);
}
void
CodeGenerator::visitArrowNewTarget(LArrowNewTarget* lir)
{
Register callee = ToRegister(lir->callee());
ValueOperand output = ToOutValue(lir);
masm.loadValue(Address(callee, FunctionExtended::offsetOfArrowNewTargetSlot()), output);
}
void
CodeGenerator::visitArrayLength(LArrayLength* lir)
{

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

@ -42,7 +42,6 @@ class OutOfLineCallPostWriteBarrier;
class OutOfLineIsCallable;
class OutOfLineRegExpExec;
class OutOfLineRegExpTest;
class OutOfLineLambdaArrow;
class CodeGenerator : public CodeGeneratorSpecific
{
@ -105,7 +104,6 @@ class CodeGenerator : public CodeGeneratorSpecific
void visitRegExpReplace(LRegExpReplace* lir);
void visitStringReplace(LStringReplace* lir);
void visitLambda(LLambda* lir);
void visitOutOfLineLambdaArrow(OutOfLineLambdaArrow* ool);
void visitLambdaArrow(LLambdaArrow* lir);
void visitLambdaForSingleton(LLambdaForSingleton* lir);
void visitPointer(LPointer* lir);
@ -326,7 +324,6 @@ class CodeGenerator : public CodeGeneratorSpecific
void visitThrowUninitializedLexical(LThrowUninitializedLexical* ins);
void visitDebugger(LDebugger* ins);
void visitNewTarget(LNewTarget* ins);
void visitArrowNewTarget(LArrowNewTarget* ins);
void visitCheckOverRecursed(LCheckOverRecursed* lir);
void visitCheckOverRecursedFailure(CheckOverRecursedFailure* ool);

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

@ -9443,14 +9443,6 @@ IonBuilder::jsop_newtarget()
}
MOZ_ASSERT(info().funMaybeLazy());
if (info().funMaybeLazy()->isArrow()) {
MArrowNewTarget* arrowNewTarget = MArrowNewTarget::New(alloc(), getCallee());
current->add(arrowNewTarget);
current->push(arrowNewTarget);
return true;
}
if (inliningDepth_ == 0) {
MNewTarget* newTarget = MNewTarget::New(alloc());
current->add(newTarget);
@ -11887,11 +11879,10 @@ IonBuilder::jsop_lambda_arrow(JSFunction* fun)
MOZ_ASSERT(fun->isArrow());
MOZ_ASSERT(!fun->isNative());
MDefinition* newTargetDef = current->pop();
MDefinition* thisDef = current->pop();
MLambdaArrow* ins = MLambdaArrow::New(alloc(), constraints(), current->scopeChain(),
thisDef, newTargetDef, fun);
thisDef, fun);
current->add(ins);
current->push(ins);

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

@ -3990,20 +3990,23 @@ class LLambda : public LInstructionHelper<1, 1, 1>
}
};
class LLambdaArrow : public LInstructionHelper<1, 1 + (2 * BOX_PIECES), 0>
class LLambdaArrow : public LInstructionHelper<1, 1 + BOX_PIECES, 1>
{
public:
LIR_HEADER(LambdaArrow)
static const size_t ThisValue = 1;
static const size_t NewTargetValue = ThisValue + BOX_PIECES;
explicit LLambdaArrow(const LAllocation& scopeChain) {
LLambdaArrow(const LAllocation& scopeChain, const LDefinition& temp) {
setOperand(0, scopeChain);
setTemp(0, temp);
}
const LAllocation* scopeChain() {
return getOperand(0);
}
const LDefinition* temp() {
return getTemp(0);
}
const MLambdaArrow* mir() const {
return mir_->toLambdaArrow();
}
@ -7018,20 +7021,6 @@ class LNewTarget : public LInstructionHelper<BOX_PIECES, 0, 0>
LIR_HEADER(NewTarget)
};
class LArrowNewTarget : public LInstructionHelper<BOX_PIECES, 1, 0>
{
public:
explicit LArrowNewTarget(const LAllocation& callee) {
setOperand(0, callee);
}
LIR_HEADER(ArrowNewTarget)
const LAllocation* callee() {
return getOperand(0);
}
};
} // namespace jit
} // namespace js

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

@ -350,8 +350,7 @@
_(ThrowUninitializedLexical) \
_(NurseryObject) \
_(Debugger) \
_(NewTarget) \
_(ArrowNewTarget)
_(NewTarget)
#if defined(JS_CODEGEN_X86)
# include "jit/x86/LOpcodes-x86.h"

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

@ -385,16 +385,6 @@ LIRGenerator::visitLoadArrowThis(MLoadArrowThis* ins)
defineBox(lir, ins);
}
void
LIRGenerator::visitArrowNewTarget(MArrowNewTarget* ins)
{
MOZ_ASSERT(ins->type() == MIRType_Value);
MOZ_ASSERT(ins->callee()->type() == MIRType_Object);
LArrowNewTarget* lir = new(alloc()) LArrowNewTarget(useRegister(ins->callee()));
defineBox(lir, ins);
}
void
LIRGenerator::lowerCallArguments(MCall* call)
{
@ -2158,11 +2148,9 @@ LIRGenerator::visitLambdaArrow(MLambdaArrow* ins)
{
MOZ_ASSERT(ins->scopeChain()->type() == MIRType_Object);
MOZ_ASSERT(ins->thisDef()->type() == MIRType_Value);
MOZ_ASSERT(ins->newTargetDef()->type() == MIRType_Value);
LLambdaArrow* lir = new(alloc()) LLambdaArrow(useRegister(ins->scopeChain()));
LLambdaArrow* lir = new(alloc()) LLambdaArrow(useRegister(ins->scopeChain()), temp());
useBox(lir, LLambdaArrow::ThisValue, ins->thisDef());
useBox(lir, LLambdaArrow::NewTargetValue, ins->newTargetDef());
define(lir, ins);
assignSafepoint(lir, ins);
}

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

@ -297,7 +297,6 @@ class LIRGenerator : public LIRGeneratorSpecific
void visitDebugger(MDebugger* ins);
void visitNurseryObject(MNurseryObject* ins);
void visitNewTarget(MNewTarget* ins);
void visitArrowNewTarget(MArrowNewTarget* ins);
};
} // namespace jit

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

@ -6707,36 +6707,6 @@ class MLoadArrowThis
}
};
// Load an arrow function's |new.target| value.
class MArrowNewTarget
: public MUnaryInstruction,
public SingleObjectPolicy::Data
{
explicit MArrowNewTarget(MDefinition* callee)
: MUnaryInstruction(callee)
{
setResultType(MIRType_Value);
setMovable();
}
public:
INSTRUCTION_HEADER(ArrowNewTarget)
static MArrowNewTarget* New(TempAllocator& alloc, MDefinition* callee) {
return new(alloc) MArrowNewTarget(callee);
}
MDefinition* callee() const {
return getOperand(0);
}
bool congruentTo(const MDefinition* ins) const override {
return congruentIfOperandsEqual(ins);
}
AliasSet getAliasSet() const override {
// An arrow function's lexical |this| value is immutable.
return AliasSet::None();
}
};
class MPhi final
: public MDefinition,
public InlineListNode<MPhi>,
@ -7569,14 +7539,14 @@ class MLambda
};
class MLambdaArrow
: public MTernaryInstruction,
public Mix3Policy<ObjectPolicy<0>, BoxPolicy<1>, BoxPolicy<2> >::Data
: public MBinaryInstruction,
public MixPolicy<ObjectPolicy<0>, BoxPolicy<1> >::Data
{
const LambdaFunctionInfo info_;
MLambdaArrow(CompilerConstraintList* constraints, MDefinition* scopeChain,
MDefinition* this_, MDefinition* newTarget_, JSFunction* fun)
: MTernaryInstruction(scopeChain, this_, newTarget_), info_(fun)
MDefinition* this_, JSFunction* fun)
: MBinaryInstruction(scopeChain, this_), info_(fun)
{
setResultType(MIRType_Object);
MOZ_ASSERT(!ObjectGroup::useSingletonForClone(fun));
@ -7588,10 +7558,9 @@ class MLambdaArrow
INSTRUCTION_HEADER(LambdaArrow)
static MLambdaArrow* New(TempAllocator& alloc, CompilerConstraintList* constraints,
MDefinition* scopeChain, MDefinition* this_, MDefinition* newTarget_,
JSFunction* fun)
MDefinition* scopeChain, MDefinition* this_, JSFunction* fun)
{
return new(alloc) MLambdaArrow(constraints, scopeChain, this_, newTarget_, fun);
return new(alloc) MLambdaArrow(constraints, scopeChain, this_, fun);
}
MDefinition* scopeChain() const {
return getOperand(0);
@ -7599,9 +7568,6 @@ class MLambdaArrow
MDefinition* thisDef() const {
return getOperand(1);
}
MDefinition* newTargetDef() const {
return getOperand(2);
}
const LambdaFunctionInfo& info() const {
return info_;
}

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

@ -269,8 +269,7 @@ namespace jit {
_(LexicalCheck) \
_(ThrowUninitializedLexical) \
_(Debugger) \
_(NewTarget) \
_(ArrowNewTarget)
_(NewTarget)
// Forward declarations of MIR types.
#define FORWARD_DECLARE(op) class M##op;

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

@ -202,8 +202,6 @@ class RematerializedFrame
Value newTarget() {
MOZ_ASSERT(isFunctionFrame());
if (callee()->isArrow())
return callee()->getExtendedSlot(FunctionExtended::ARROW_NEWTARGET_SLOT);
if (isConstructing())
return argv()[numActualArgs()];
return UndefinedValue();

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

@ -609,7 +609,6 @@ class FunctionExtended : public JSFunction
/* Arrow functions store their lexical |this| in the first extended slot. */
static const unsigned ARROW_THIS_SLOT = 0;
static const unsigned ARROW_NEWTARGET_SLOT = 1;
static const unsigned METHOD_HOMEOBJECT_SLOT = 0;
@ -620,9 +619,6 @@ class FunctionExtended : public JSFunction
static inline size_t offsetOfArrowThisSlot() {
return offsetOfExtendedSlot(ARROW_THIS_SLOT);
}
static inline size_t offsetOfArrowNewTargetSlot() {
return offsetOfExtendedSlot(ARROW_NEWTARGET_SLOT);
}
private:
friend class JSFunction;

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

@ -1,24 +0,0 @@
// new.target is valid in any arrow function not in a global context.
new Function('(() => new.target)()');
// It's also good inside eval, but not global eval
assertThrowsInstanceOf(() => eval('() => new.target'), SyntaxError);
function assertNewTarget(expected) {
assertEq((()=>new.target)(), expected);
assertEq(eval('()=>new.target')(), expected);
// Make sure that arrow functions can escape their original context and
// still get the right answer.
return (() => new.target);
}
const ITERATIONS = 550;
for (let i = 0; i < ITERATIONS; i++)
assertEq(assertNewTarget(undefined)(), undefined);
for (let i = 0; i < ITERATIONS; i++)
assertEq(new assertNewTarget(assertNewTarget)(), assertNewTarget);
if (typeof reportCompare === 'function')
reportCompare(0,0,"OK");

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

@ -4,7 +4,8 @@ try {
assertEq(false, true);
} catch (e if e instanceof SyntaxError) { }
// new.target is invalid inside eval inside top-level arrow functions
// 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.
@ -16,7 +17,6 @@ try {
function assertNewTarget(expected) {
assertEq(eval('new.target'), expected);
assertEq((()=>eval('new.target'))(), expected);
// Also test nestings "by induction"
assertEq(eval('eval("new.target")'), expected);

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

@ -11,8 +11,8 @@ function testNewTarget() {
// invalid in top-level scripts
assertError("new.target", SyntaxError);
// valid in arrow functions inside functions
assertInFunctionExpr("()=>new.target", arrowExpr([], newTarget()));
// invalid (for now!) in any arrow function
assertError("function foo() { (() => new.target) }", SyntaxError);
assertError("(() => new.target))", SyntaxError);
// invalid (for now!) in generators

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

@ -3420,14 +3420,12 @@ CASE(JSOP_LAMBDA_ARROW)
{
/* Load the specified function object literal. */
ReservedRooted<JSFunction*> fun(&rootFunction0, script->getFunction(GET_UINT32_INDEX(REGS.pc)));
ReservedRooted<Value> thisv(&rootValue0, REGS.sp[-2]);
ReservedRooted<Value> newTarget(&rootValue1, REGS.sp[-1]);
JSObject* obj = LambdaArrow(cx, fun, REGS.fp()->scopeChain(), thisv, newTarget);
ReservedRooted<Value> thisv(&rootValue0, REGS.sp[-1]);
JSObject* obj = LambdaArrow(cx, fun, REGS.fp()->scopeChain(), thisv);
if (!obj)
goto error;
MOZ_ASSERT(obj->getProto());
REGS.sp[-2].setObject(*obj);
REGS.sp--;
REGS.sp[-1].setObject(*obj);
}
END_CASE(JSOP_LAMBDA_ARROW)
@ -3967,7 +3965,6 @@ END_CASE(JSOP_SUPERBASE)
CASE(JSOP_NEWTARGET)
PUSH_COPY(REGS.fp()->newTarget());
MOZ_ASSERT(REGS.sp[-1].isObject() || REGS.sp[-1].isUndefined());
END_CASE(JSOP_NEWTARGET)
DEFAULT()
@ -4169,8 +4166,7 @@ js::Lambda(JSContext* cx, HandleFunction fun, HandleObject parent)
}
JSObject*
js::LambdaArrow(JSContext* cx, HandleFunction fun, HandleObject parent, HandleValue thisv,
HandleValue newTargetv)
js::LambdaArrow(JSContext* cx, HandleFunction fun, HandleObject parent, HandleValue thisv)
{
MOZ_ASSERT(fun->isArrow());
@ -4181,7 +4177,6 @@ js::LambdaArrow(JSContext* cx, HandleFunction fun, HandleObject parent, HandleVa
MOZ_ASSERT(clone->as<JSFunction>().isArrow());
clone->as<JSFunction>().setExtendedSlot(0, thisv);
clone->as<JSFunction>().setExtendedSlot(1, newTargetv);
MOZ_ASSERT(fun->global() == clone->global());
return clone;

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

@ -356,8 +356,7 @@ JSObject*
Lambda(JSContext* cx, HandleFunction fun, HandleObject parent);
JSObject*
LambdaArrow(JSContext* cx, HandleFunction fun, HandleObject parent, HandleValue thisv,
HandleValue newTargetv);
LambdaArrow(JSContext* cx, HandleFunction fun, HandleObject parent, HandleValue thisv);
bool
GetElement(JSContext* cx, MutableHandleValue lref, HandleValue rref, MutableHandleValue res);

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

@ -1340,7 +1340,7 @@
* Operands: uint32_t funcIndex
* Stack: this => obj
*/ \
macro(JSOP_LAMBDA_ARROW, 131, "lambda_arrow", NULL, 5, 2, 1, JOF_OBJECT) \
macro(JSOP_LAMBDA_ARROW, 131, "lambda_arrow", NULL, 5, 1, 1, JOF_OBJECT) \
\
/*
* Pushes current callee onto the stack.

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

@ -44,9 +44,6 @@ InterpreterFrame::initExecuteFrame(JSContext* cx, HandleScript script, AbstractF
flags_ = type | HAS_SCOPECHAIN;
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))) {
if (evalInFramePrev) {
@ -73,6 +70,9 @@ 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;

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

@ -755,9 +755,6 @@ class InterpreterFrame
if (isEvalFrame())
return ((Value*)this)[-3];
if (callee().isArrow())
return callee().getExtendedSlot(FunctionExtended::ARROW_NEWTARGET_SLOT);
if (isConstructing()) {
unsigned pushedArgs = Max(numFormalArgs(), numActualArgs());
return argv()[pushedArgs];

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

@ -29,7 +29,7 @@ namespace js {
*
* https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode
*/
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 291;
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 290;
static const uint32_t XDR_BYTECODE_VERSION =
uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);