зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1270331 - Pass JS_IS_CONSTRUCTING as |this| to constructing functions from bytecode. (r=Waldo, r=jandem)
This commit is contained in:
Родитель
2739ec5b28
Коммит
f45a2ae8f5
|
@ -7708,13 +7708,21 @@ BytecodeEmitter::emitCallOrNew(ParseNode* pn)
|
|||
callop = false; /* trigger JSOP_UNDEFINED after */
|
||||
break;
|
||||
}
|
||||
if (!callop) {
|
||||
if (!emit1(JSOP_UNDEFINED))
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isNewOp = pn->getOp() == JSOP_NEW || pn->getOp() == JSOP_SPREADNEW ||
|
||||
pn->getOp() == JSOP_SUPERCALL || pn->getOp() == JSOP_SPREADSUPERCALL;;
|
||||
pn->getOp() == JSOP_SUPERCALL || pn->getOp() == JSOP_SPREADSUPERCALL;
|
||||
|
||||
|
||||
// Emit room for |this|.
|
||||
if (!callop) {
|
||||
if (isNewOp) {
|
||||
if (!emit1(JSOP_IS_CONSTRUCTING))
|
||||
return false;
|
||||
} else {
|
||||
if (!emit1(JSOP_UNDEFINED))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit code for each argument in order, then emit the JSOP_*CALL or
|
||||
|
|
|
@ -4328,6 +4328,13 @@ BaselineCompiler::emit_JSOP_DEBUGCHECKSELFHOSTED()
|
|||
|
||||
}
|
||||
|
||||
bool
|
||||
BaselineCompiler::emit_JSOP_IS_CONSTRUCTING()
|
||||
{
|
||||
frame.push(MagicValue(JS_IS_CONSTRUCTING));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BaselineCompiler::emit_JSOP_JUMPTARGET()
|
||||
{
|
||||
|
|
|
@ -224,7 +224,8 @@ namespace jit {
|
|||
_(JSOP_INITHIDDENELEM_SETTER) \
|
||||
_(JSOP_CHECKOBJCOERCIBLE) \
|
||||
_(JSOP_DEBUGCHECKSELFHOSTED) \
|
||||
_(JSOP_JUMPTARGET)
|
||||
_(JSOP_JUMPTARGET) \
|
||||
_(JSOP_IS_CONSTRUCTING)
|
||||
|
||||
class BaselineCompiler : public BaselineCompilerSpecific
|
||||
{
|
||||
|
|
|
@ -6972,12 +6972,6 @@ ICCall_Native::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
else
|
||||
pushCallArguments(masm, regs, argcReg, /* isJitCall = */ false, isConstructing_);
|
||||
|
||||
if (isConstructing_) {
|
||||
// Stack looks like: [ ..., Arg0Val, ThisVal, CalleeVal ]
|
||||
// Replace ThisVal with MagicValue(JS_IS_CONSTRUCTING)
|
||||
masm.storeValue(MagicValue(JS_IS_CONSTRUCTING), Address(masm.getStackPointer(), sizeof(Value)));
|
||||
}
|
||||
|
||||
|
||||
// Native functions have the signature:
|
||||
//
|
||||
|
@ -7070,12 +7064,6 @@ ICCall_ClassHook::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
pushCallArguments(masm, regs, argcReg, /* isJitCall = */ false, isConstructing_);
|
||||
regs.take(scratch);
|
||||
|
||||
if (isConstructing_) {
|
||||
// Stack looks like: [ ..., Arg0Val, ThisVal, CalleeVal ]
|
||||
// Replace ThisVal with MagicValue(JS_IS_CONSTRUCTING)
|
||||
masm.storeValue(MagicValue(JS_IS_CONSTRUCTING), Address(masm.getStackPointer(), sizeof(Value)));
|
||||
}
|
||||
|
||||
masm.checkStackAlignment();
|
||||
|
||||
// Native functions have the signature:
|
||||
|
|
|
@ -2791,6 +2791,7 @@ IsResumableMIRType(MIRType type)
|
|||
case MIRType::MagicOptimizedArguments:
|
||||
case MIRType::MagicOptimizedOut:
|
||||
case MIRType::MagicUninitializedLexical:
|
||||
case MIRType::MagicIsConstructing:
|
||||
case MIRType::Value:
|
||||
case MIRType::Int32x4:
|
||||
case MIRType::Int16x8:
|
||||
|
@ -2802,7 +2803,6 @@ IsResumableMIRType(MIRType type)
|
|||
return true;
|
||||
|
||||
case MIRType::MagicHole:
|
||||
case MIRType::MagicIsConstructing:
|
||||
case MIRType::ObjectOrNull:
|
||||
case MIRType::None:
|
||||
case MIRType::Slots:
|
||||
|
|
|
@ -2160,6 +2160,9 @@ IonBuilder::inspectOpcode(JSOp op)
|
|||
return true;
|
||||
}
|
||||
|
||||
case JSOP_IS_CONSTRUCTING:
|
||||
pushConstant(MagicValue(JS_IS_CONSTRUCTING));
|
||||
return true;
|
||||
|
||||
#ifdef DEBUG
|
||||
case JSOP_PUSHBLOCKSCOPE:
|
||||
|
|
|
@ -485,13 +485,28 @@ CodeGeneratorShared::encodeAllocation(LSnapshot* snapshot, MDefinition* mir,
|
|||
case MIRType::MagicOptimizedArguments:
|
||||
case MIRType::MagicOptimizedOut:
|
||||
case MIRType::MagicUninitializedLexical:
|
||||
case MIRType::MagicIsConstructing:
|
||||
{
|
||||
uint32_t index;
|
||||
Value v = MagicValue(type == MIRType::MagicOptimizedArguments
|
||||
? JS_OPTIMIZED_ARGUMENTS
|
||||
: (type == MIRType::MagicOptimizedOut
|
||||
? JS_OPTIMIZED_OUT
|
||||
: JS_UNINITIALIZED_LEXICAL));
|
||||
JSWhyMagic why = JS_GENERIC_MAGIC;
|
||||
switch (type) {
|
||||
case MIRType::MagicOptimizedArguments:
|
||||
why = JS_OPTIMIZED_ARGUMENTS;
|
||||
break;
|
||||
case MIRType::MagicOptimizedOut:
|
||||
why = JS_OPTIMIZED_OUT;
|
||||
break;
|
||||
case MIRType::MagicUninitializedLexical:
|
||||
why = JS_UNINITIALIZED_LEXICAL;
|
||||
break;
|
||||
case MIRType::MagicIsConstructing:
|
||||
why = JS_IS_CONSTRUCTING;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Invalid Magic MIRType");
|
||||
}
|
||||
|
||||
Value v = MagicValue(why);
|
||||
masm.propagateOOM(graph.addConstantToPool(v, &index));
|
||||
alloc = RValueAllocation::ConstantPool(index);
|
||||
break;
|
||||
|
|
|
@ -321,6 +321,7 @@ RunState::maybeCreateThisForConstructor(JSContext* cx)
|
|||
MOZ_ASSERT(callee->as<JSFunction>().isClassConstructor());
|
||||
invoke.args().setThis(MagicValue(JS_UNINITIALIZED_LEXICAL));
|
||||
} else {
|
||||
MOZ_ASSERT(invoke.args().thisv().isMagic(JS_IS_CONSTRUCTING));
|
||||
RootedObject newTarget(cx, &invoke.args().newTarget().toObject());
|
||||
NewObjectKind newKind = invoke.createSingleton() ? SingletonObject : GenericObject;
|
||||
JSObject* obj = CreateThisForFunction(cx, callee, newTarget, newKind);
|
||||
|
@ -533,6 +534,8 @@ InternalConstruct(JSContext* cx, const AnyConstructArgs& args)
|
|||
MOZ_ASSERT(IsConstructor(args.CallArgs::newTarget()),
|
||||
"provided new.target value must be a constructor");
|
||||
|
||||
MOZ_ASSERT(args.thisv().isMagic(JS_IS_CONSTRUCTING) || args.thisv().isObject());
|
||||
|
||||
JSObject& callee = args.callee();
|
||||
if (callee.is<JSFunction>()) {
|
||||
RootedFunction fun(cx, &callee.as<JSFunction>());
|
||||
|
@ -576,7 +579,6 @@ js::ConstructFromStack(JSContext* cx, const CallArgs& args)
|
|||
if (!StackCheckIsConstructorCalleeNewTarget(cx, args.calleev(), args.newTarget()))
|
||||
return false;
|
||||
|
||||
args.setThis(MagicValue(JS_IS_CONSTRUCTING));
|
||||
return InternalConstruct(cx, static_cast<const AnyConstructArgs&>(args));
|
||||
}
|
||||
|
||||
|
@ -584,9 +586,10 @@ bool
|
|||
js::Construct(JSContext* cx, HandleValue fval, const AnyConstructArgs& args, HandleValue newTarget,
|
||||
MutableHandleObject objp)
|
||||
{
|
||||
MOZ_ASSERT(args.thisv().isMagic(JS_IS_CONSTRUCTING));
|
||||
|
||||
// Explicitly qualify to bypass AnyConstructArgs's deliberate shadowing.
|
||||
args.CallArgs::setCallee(fval);
|
||||
args.CallArgs::setThis(MagicValue(JS_IS_CONSTRUCTING));
|
||||
args.CallArgs::newTarget().set(newTarget);
|
||||
|
||||
if (!InternalConstruct(cx, args))
|
||||
|
@ -1265,8 +1268,7 @@ HandleError(JSContext* cx, InterpreterRegs& regs)
|
|||
#define PUSH_STRING(s) do { REGS.sp++->setString(s); assertSameCompartmentDebugOnly(cx, REGS.sp[-1]); } while (0)
|
||||
#define PUSH_OBJECT(obj) do { REGS.sp++->setObject(obj); assertSameCompartmentDebugOnly(cx, REGS.sp[-1]); } while (0)
|
||||
#define PUSH_OBJECT_OR_NULL(obj) do { REGS.sp++->setObjectOrNull(obj); assertSameCompartmentDebugOnly(cx, REGS.sp[-1]); } while (0)
|
||||
#define PUSH_HOLE() REGS.sp++->setMagic(JS_ELEMENTS_HOLE)
|
||||
#define PUSH_UNINITIALIZED() REGS.sp++->setMagic(JS_UNINITIALIZED_LEXICAL)
|
||||
#define PUSH_MAGIC(magic) REGS.sp++->setMagic(magic)
|
||||
#define POP_COPY_TO(v) (v) = *--REGS.sp
|
||||
#define POP_RETURN_VALUE() REGS.fp()->setReturnValue(*--REGS.sp)
|
||||
|
||||
|
@ -1824,7 +1826,6 @@ CASE(EnableInterruptsPseudoOpcode)
|
|||
CASE(JSOP_NOP)
|
||||
CASE(JSOP_NOP_DESTRUCTURING)
|
||||
CASE(JSOP_UNUSED14)
|
||||
CASE(JSOP_UNUSED65)
|
||||
CASE(JSOP_UNUSED149)
|
||||
CASE(JSOP_UNUSED179)
|
||||
CASE(JSOP_UNUSED180)
|
||||
|
@ -3295,7 +3296,7 @@ CASE(JSOP_INITGLEXICAL)
|
|||
END_CASE(JSOP_INITGLEXICAL)
|
||||
|
||||
CASE(JSOP_UNINITIALIZED)
|
||||
PUSH_UNINITIALIZED();
|
||||
PUSH_MAGIC(JS_UNINITIALIZED_LEXICAL);
|
||||
END_CASE(JSOP_UNINITIALIZED)
|
||||
|
||||
CASE(JSOP_GETARG)
|
||||
|
@ -3470,7 +3471,7 @@ CASE(JSOP_INITHIDDENELEM_SETTER)
|
|||
END_CASE(JSOP_INITELEM_GETTER)
|
||||
|
||||
CASE(JSOP_HOLE)
|
||||
PUSH_HOLE();
|
||||
PUSH_MAGIC(JS_ELEMENTS_HOLE);
|
||||
END_CASE(JSOP_HOLE)
|
||||
|
||||
CASE(JSOP_NEWINIT)
|
||||
|
@ -4026,6 +4027,10 @@ CASE(JSOP_DEBUGCHECKSELFHOSTED)
|
|||
}
|
||||
END_CASE(JSOP_DEBUGCHECKSELFHOSTED)
|
||||
|
||||
CASE(JSOP_IS_CONSTRUCTING)
|
||||
PUSH_MAGIC(JS_IS_CONSTRUCTING);
|
||||
END_CASE(JSOP_IS_CONSTRUCTING)
|
||||
|
||||
DEFAULT()
|
||||
{
|
||||
char numBuf[12];
|
||||
|
|
|
@ -603,7 +603,14 @@
|
|||
* Stack: => null
|
||||
*/ \
|
||||
macro(JSOP_NULL, 64, js_null_str, js_null_str, 1, 0, 1, JOF_BYTE) \
|
||||
macro(JSOP_UNUSED65, 65, "unused65", NULL, 1, 0, 1, JOF_BYTE) \
|
||||
/*
|
||||
* Pushes 'JS_IS_CONSTRUCTING'
|
||||
* Category: Literals
|
||||
* Type: Constants
|
||||
* Operands:
|
||||
* Stack: => JS_IS_CONSTRUCTING
|
||||
*/ \
|
||||
macro(JSOP_IS_CONSTRUCTING, 65, "is-constructing", NULL, 1, 0, 1, JOF_BYTE) \
|
||||
/*
|
||||
* Pushes boolean value onto the stack.
|
||||
* Category: Literals
|
||||
|
|
|
@ -224,7 +224,10 @@ InterpreterFrame::prologue(JSContext* cx)
|
|||
} else if (script->isDerivedClassConstructor()) {
|
||||
MOZ_ASSERT(callee().isClassConstructor());
|
||||
thisArgument() = MagicValue(JS_UNINITIALIZED_LEXICAL);
|
||||
} else if (thisArgument().isPrimitive()) {
|
||||
} else if (thisArgument().isObject()) {
|
||||
// Nothing to do. Correctly set.
|
||||
} else {
|
||||
MOZ_ASSERT(thisArgument().isMagic(JS_IS_CONSTRUCTING));
|
||||
RootedObject callee(cx, &this->callee());
|
||||
RootedObject newTarget(cx, &this->newTarget().toObject());
|
||||
JSObject* obj = CreateThisForFunction(cx, callee, newTarget,
|
||||
|
|
|
@ -966,6 +966,8 @@ class GenericArgsBase
|
|||
|
||||
*static_cast<JS::CallArgs*>(this) = CallArgsFromVp(argc, v_.begin());
|
||||
this->constructing_ = Construct;
|
||||
if (Construct)
|
||||
this->CallArgs::setThis(MagicValue(JS_IS_CONSTRUCTING));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -981,6 +983,8 @@ class FixedArgsBase
|
|||
explicit FixedArgsBase(JSContext* cx) : v_(cx) {
|
||||
*static_cast<JS::CallArgs*>(this) = CallArgsFromVp(N, v_.begin());
|
||||
this->constructing_ = Construct;
|
||||
if (Construct)
|
||||
this->CallArgs::setThis(MagicValue(JS_IS_CONSTRUCTING));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче