Bug 1346028 - Allow MCallInitElementArray to take dynamic index
MozReview-Commit-ID: L0UE9MtnxmS
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -10144,18 +10144,21 @@ CodeGenerator::visitCallSetElement(LCall
typedef bool (*InitElementArrayFn)(JSContext*, jsbytecode*, HandleObject, uint32_t, HandleValue);
static const VMFunction InitElementArrayInfo =
FunctionInfo<InitElementArrayFn>(js::InitElementArray, "InitElementArray");
void
CodeGenerator::visitCallInitElementArray(LCallInitElementArray* lir)
{
pushArg(ToValue(lir, LCallInitElementArray::Value));
- pushArg(Imm32(lir->mir()->index()));
- pushArg(ToRegister(lir->getOperand(0)));
+ if (lir->index()->isConstant())
+ pushArg(Imm32(ToInt32(lir->index())));
+ else
+ pushArg(ToRegister(lir->index()));
+ pushArg(ToRegister(lir->object()));
pushArg(ImmPtr(lir->mir()->resumePoint()->pc()));
callVM(InitElementArrayInfo, lir);
}
void
CodeGenerator::visitLoadFixedSlotV(LLoadFixedSlotV* ins)
{
const Register obj = ToRegister(ins->getOperand(0));
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -6137,17 +6137,22 @@ IonBuilder::jsop_initelem_array()
elemTypes.freeze(constraints());
needStub = true;
}
}
}
uint32_t index = GET_UINT32(pc);
if (needStub) {
- MCallInitElementArray* store = MCallInitElementArray::New(alloc(), obj, index, value);
+ MOZ_ASSERT(index <= INT32_MAX,
+ "the bytecode emitter must fail to compile code that would "
+ "produce JSOP_INITELEM_ARRAY with an index exceeding "
+ "int32_t range");
+ MCallInitElementArray* store = MCallInitElementArray::New(alloc(), obj,
+ constantInt(index), value);
current->add(store);
return resumeAfter(store);
}
return initializeArrayElement(obj, index, value, unboxedType, /* addResumePoint = */ true);
}
AbortReasonOr<Ok>
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -4011,18 +4011,20 @@ LIRGenerator::visitCallSetElement(MCallS
useBoxAtStart(ins->value()));
add(lir, ins);
assignSafepoint(lir, ins);
}
void
LIRGenerator::visitCallInitElementArray(MCallInitElementArray* ins)
{
- LCallInitElementArray* lir = new(alloc()) LCallInitElementArray(useRegisterAtStart(ins->object()),
- useBoxAtStart(ins->value()));
+ LCallInitElementArray* lir =
+ new(alloc()) LCallInitElementArray(useRegisterAtStart(ins->object()),
+ useRegisterOrConstantAtStart(ins->index()),
+ useBoxAtStart(ins->value()));
add(lir, ins);
assignSafepoint(lir, ins);
}
void
LIRGenerator::visitIteratorStart(MIteratorStart* ins)
{
if (ins->object()->type() == MIRType::Value) {
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -11935,36 +11935,29 @@ class MCallSetElement
TRIVIAL_NEW_WRAPPERS
bool possiblyCalls() const override {
return true;
}
};
class MCallInitElementArray
- : public MAryInstruction<2>,
- public MixPolicy<ObjectPolicy<0>, BoxPolicy<1> >::Data
-{
- uint32_t index_;
-
- MCallInitElementArray(MDefinition* obj, uint32_t index, MDefinition* val)
- : index_(index)
- {
- initOperand(0, obj);
- initOperand(1, val);
+ : public MTernaryInstruction,
+ public Mix3Policy<ObjectPolicy<0>, IntPolicy<1>, BoxPolicy<2> >::Data
+{
+ MCallInitElementArray(MDefinition* obj, MDefinition* index, MDefinition* val)
+ : MTernaryInstruction(obj, index, val)
+ {
+ MOZ_ASSERT(index->type() == MIRType::Int32);
}
public:
INSTRUCTION_HEADER(CallInitElementArray)
TRIVIAL_NEW_WRAPPERS
- NAMED_OPERANDS((0, object), (1, value))
-
- uint32_t index() const {
- return index_;
- }
+ NAMED_OPERANDS((0, object), (1, index), (2, value))
bool possiblyCalls() const override {
return true;
}
};
class MSetDOMProperty
: public MAryInstruction<2>,
--- a/js/src/jit/shared/LIR-shared.h
+++ b/js/src/jit/shared/LIR-shared.h
@@ -7149,28 +7149,35 @@ class LCallSetElement : public LCallInst
}
const MCallSetElement* mir() const {
return mir_->toCallSetElement();
}
};
// Call js::InitElementArray.
-class LCallInitElementArray : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0>
+class LCallInitElementArray : public LCallInstructionHelper<0, 2 + BOX_PIECES, 0>
{
public:
LIR_HEADER(CallInitElementArray)
- static const size_t Value = 1;
-
- LCallInitElementArray(const LAllocation& obj, const LBoxAllocation& value) {
+ static const size_t Value = 2;
+
+ LCallInitElementArray(const LAllocation& obj, const LAllocation& index,
+ const LBoxAllocation& value) {
setOperand(0, obj);
+ setOperand(1, index);
setBoxOperand(Value, value);
}
-
+ const LAllocation* object() {
+ return getOperand(0);
+ }
+ const LAllocation* index() {
+ return getOperand(1);
+ }
const MCallInitElementArray* mir() const {
return mir_->toCallInitElementArray();
}
};
// Call a VM function to perform a property or name assignment of a generic value.
class LCallSetProperty : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0>
{