mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-03 18:47:53 +00:00
Bug 940525 - Fix Baseline typed array stubs to handle double indexes. r=djvj
This commit is contained in:
parent
3af8ea7ca7
commit
2826a95d85
@ -3881,7 +3881,7 @@ TryAttachGetElemStub(JSContext *cx, HandleScript script, jsbytecode *pc, ICGetEl
|
||||
}
|
||||
|
||||
// Check for TypedArray[int] => Number accesses.
|
||||
if (obj->is<TypedArrayObject>() && rhs.isInt32() && res.isNumber() &&
|
||||
if (obj->is<TypedArrayObject>() && rhs.isNumber() && res.isNumber() &&
|
||||
!TypedArrayGetElemStubExists(stub, obj))
|
||||
{
|
||||
// Don't attach CALLELEM stubs for accesses on typed array expected to yield numbers.
|
||||
@ -3891,8 +3891,11 @@ TryAttachGetElemStub(JSContext *cx, HandleScript script, jsbytecode *pc, ICGetEl
|
||||
#endif
|
||||
|
||||
Rooted<TypedArrayObject*> tarr(cx, &obj->as<TypedArrayObject>());
|
||||
if (!cx->runtime()->jitSupportsFloatingPoint && TypedArrayRequiresFloatingPoint(tarr))
|
||||
if (!cx->runtime()->jitSupportsFloatingPoint &&
|
||||
(TypedArrayRequiresFloatingPoint(tarr) || rhs.isDouble()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
IonSpew(IonSpew_BaselineIC, " Generating GetElem(TypedArray[Int32]) stub");
|
||||
ICGetElem_TypedArray::Compiler compiler(cx, tarr->lastProperty(), tarr->type());
|
||||
@ -4502,7 +4505,6 @@ ICGetElem_TypedArray::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
masm.branchTestObject(Assembler::NotEqual, R0, &failure);
|
||||
masm.branchTestInt32(Assembler::NotEqual, R1, &failure);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
Register scratchReg = regs.takeAny();
|
||||
@ -4512,6 +4514,24 @@ ICGetElem_TypedArray::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
masm.loadPtr(Address(BaselineStubReg, ICGetElem_TypedArray::offsetOfShape()), scratchReg);
|
||||
masm.branchTestObjShape(Assembler::NotEqual, obj, scratchReg, &failure);
|
||||
|
||||
// Ensure the index is an integer.
|
||||
if (cx->runtime()->jitSupportsFloatingPoint) {
|
||||
Label isInt32;
|
||||
masm.branchTestInt32(Assembler::Equal, R1, &isInt32);
|
||||
{
|
||||
// If the index is a double, try to convert it to int32. It's okay
|
||||
// to convert -0 to 0: the shape check ensures the object is a typed
|
||||
// array so the difference is not observable.
|
||||
masm.branchTestDouble(Assembler::NotEqual, R1, &failure);
|
||||
masm.unboxDouble(R1, FloatReg0);
|
||||
masm.convertDoubleToInt32(FloatReg0, scratchReg, &failure, /* negZeroCheck = */false);
|
||||
masm.tagValue(JSVAL_TYPE_INT32, scratchReg, R1);
|
||||
}
|
||||
masm.bind(&isInt32);
|
||||
} else {
|
||||
masm.branchTestInt32(Assembler::NotEqual, R1, &failure);
|
||||
}
|
||||
|
||||
// Unbox key.
|
||||
Register key = masm.extractInt32(R1, ExtractTemp1);
|
||||
|
||||
@ -4940,14 +4960,17 @@ DoSetElemFallback(JSContext *cx, BaselineFrame *frame, ICSetElem_Fallback *stub,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj->is<TypedArrayObject>() && index.isInt32() && rhs.isNumber()) {
|
||||
if (obj->is<TypedArrayObject>() && index.isNumber() && rhs.isNumber()) {
|
||||
Rooted<TypedArrayObject*> tarr(cx, &obj->as<TypedArrayObject>());
|
||||
if (!cx->runtime()->jitSupportsFloatingPoint && TypedArrayRequiresFloatingPoint(tarr))
|
||||
if (!cx->runtime()->jitSupportsFloatingPoint &&
|
||||
(TypedArrayRequiresFloatingPoint(tarr) || index.isDouble()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t len = tarr->length();
|
||||
int32_t idx = index.toInt32();
|
||||
bool expectOutOfBounds = (idx < 0) || (static_cast<uint32_t>(idx) >= len);
|
||||
double idx = index.toNumber();
|
||||
bool expectOutOfBounds = (idx < 0 || idx >= double(len));
|
||||
|
||||
if (!TypedArraySetElemStubExists(stub, tarr, expectOutOfBounds)) {
|
||||
// Remove any existing TypedArraySetElemStub that doesn't handle out-of-bounds
|
||||
@ -5340,7 +5363,6 @@ ICSetElem_TypedArray::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
masm.branchTestObject(Assembler::NotEqual, R0, &failure);
|
||||
masm.branchTestInt32(Assembler::NotEqual, R1, &failure);
|
||||
|
||||
GeneralRegisterSet regs(availableGeneralRegs(2));
|
||||
Register scratchReg = regs.takeAny();
|
||||
@ -5350,6 +5372,24 @@ ICSetElem_TypedArray::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
masm.loadPtr(Address(BaselineStubReg, ICSetElem_TypedArray::offsetOfShape()), scratchReg);
|
||||
masm.branchTestObjShape(Assembler::NotEqual, obj, scratchReg, &failure);
|
||||
|
||||
// Ensure the index is an integer.
|
||||
if (cx->runtime()->jitSupportsFloatingPoint) {
|
||||
Label isInt32;
|
||||
masm.branchTestInt32(Assembler::Equal, R1, &isInt32);
|
||||
{
|
||||
// If the index is a double, try to convert it to int32. It's okay
|
||||
// to convert -0 to 0: the shape check ensures the object is a typed
|
||||
// array so the difference is not observable.
|
||||
masm.branchTestDouble(Assembler::NotEqual, R1, &failure);
|
||||
masm.unboxDouble(R1, FloatReg0);
|
||||
masm.convertDoubleToInt32(FloatReg0, scratchReg, &failure, /* negZeroCheck = */false);
|
||||
masm.tagValue(JSVAL_TYPE_INT32, scratchReg, R1);
|
||||
}
|
||||
masm.bind(&isInt32);
|
||||
} else {
|
||||
masm.branchTestInt32(Assembler::NotEqual, R1, &failure);
|
||||
}
|
||||
|
||||
// Unbox key.
|
||||
Register key = masm.extractInt32(R1, ExtractTemp1);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user