mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 829896 - Make typed array element accesses return undefined if the element is out of bounds, rather than accessing the prototype chain r=jandem
This commit is contained in:
parent
c92f991c16
commit
07257e7a4c
@ -6363,43 +6363,25 @@ CodeGenerator::visitLoadTypedArrayElement(LLoadTypedArrayElement *lir)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class OutOfLineLoadTypedArray : public OutOfLineCodeBase<CodeGenerator>
|
|
||||||
{
|
|
||||||
LLoadTypedArrayElementHole *ins_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
OutOfLineLoadTypedArray(LLoadTypedArrayElementHole *ins)
|
|
||||||
: ins_(ins)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
bool accept(CodeGenerator *codegen) {
|
|
||||||
return codegen->visitOutOfLineLoadTypedArray(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
LLoadTypedArrayElementHole *ins() const {
|
|
||||||
return ins_;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CodeGenerator::visitLoadTypedArrayElementHole(LLoadTypedArrayElementHole *lir)
|
CodeGenerator::visitLoadTypedArrayElementHole(LLoadTypedArrayElementHole *lir)
|
||||||
{
|
{
|
||||||
Register object = ToRegister(lir->object());
|
Register object = ToRegister(lir->object());
|
||||||
const ValueOperand out = ToOutValue(lir);
|
const ValueOperand out = ToOutValue(lir);
|
||||||
|
|
||||||
OutOfLineLoadTypedArray *ool = new OutOfLineLoadTypedArray(lir);
|
|
||||||
if (!addOutOfLineCode(ool))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Load the length.
|
// Load the length.
|
||||||
Register scratch = out.scratchReg();
|
Register scratch = out.scratchReg();
|
||||||
Int32Key key = ToInt32Key(lir->index());
|
Int32Key key = ToInt32Key(lir->index());
|
||||||
masm.unboxInt32(Address(object, TypedArrayObject::lengthOffset()), scratch);
|
masm.unboxInt32(Address(object, TypedArrayObject::lengthOffset()), scratch);
|
||||||
|
|
||||||
// OOL path if index >= length.
|
// Load undefined unless length > key.
|
||||||
masm.branchKey(Assembler::BelowOrEqual, scratch, key, ool->entry());
|
Label inbounds, done;
|
||||||
|
masm.branchKey(Assembler::Above, scratch, key, &inbounds);
|
||||||
|
masm.moveValue(UndefinedValue(), out);
|
||||||
|
masm.jump(&done);
|
||||||
|
|
||||||
// Load the elements vector.
|
// Load the elements vector.
|
||||||
|
masm.bind(&inbounds);
|
||||||
masm.loadPtr(Address(object, TypedArrayObject::dataOffset()), scratch);
|
masm.loadPtr(Address(object, TypedArrayObject::dataOffset()), scratch);
|
||||||
|
|
||||||
int arrayType = lir->mir()->arrayType();
|
int arrayType = lir->mir()->arrayType();
|
||||||
@ -6419,35 +6401,7 @@ CodeGenerator::visitLoadTypedArrayElementHole(LLoadTypedArrayElementHole *lir)
|
|||||||
if (fail.used() && !bailoutFrom(&fail, lir->snapshot()))
|
if (fail.used() && !bailoutFrom(&fail, lir->snapshot()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
masm.bind(ool->rejoin());
|
masm.bind(&done);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef bool (*GetElementMonitoredFn)(JSContext *, MutableHandleValue, HandleValue, MutableHandleValue);
|
|
||||||
static const VMFunction GetElementMonitoredInfo =
|
|
||||||
FunctionInfo<GetElementMonitoredFn>(js::GetElementMonitored);
|
|
||||||
|
|
||||||
bool
|
|
||||||
CodeGenerator::visitOutOfLineLoadTypedArray(OutOfLineLoadTypedArray *ool)
|
|
||||||
{
|
|
||||||
LLoadTypedArrayElementHole *ins = ool->ins();
|
|
||||||
saveLive(ins);
|
|
||||||
|
|
||||||
Register object = ToRegister(ins->object());
|
|
||||||
ValueOperand out = ToOutValue(ins);
|
|
||||||
|
|
||||||
if (ins->index()->isConstant())
|
|
||||||
pushArg(*ins->index()->toConstant());
|
|
||||||
else
|
|
||||||
pushArg(TypedOrValueRegister(MIRType_Int32, ToAnyRegister(ins->index())));
|
|
||||||
pushArg(TypedOrValueRegister(MIRType_Object, AnyRegister(object)));
|
|
||||||
if (!callVM(GetElementMonitoredInfo, ins))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
masm.storeCallResultValue(out);
|
|
||||||
restoreLive(ins);
|
|
||||||
|
|
||||||
masm.jump(ool->rejoin());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +212,6 @@ class CodeGenerator : public CodeGeneratorSpecific
|
|||||||
bool visitClampIToUint8(LClampIToUint8 *lir);
|
bool visitClampIToUint8(LClampIToUint8 *lir);
|
||||||
bool visitClampDToUint8(LClampDToUint8 *lir);
|
bool visitClampDToUint8(LClampDToUint8 *lir);
|
||||||
bool visitClampVToUint8(LClampVToUint8 *lir);
|
bool visitClampVToUint8(LClampVToUint8 *lir);
|
||||||
bool visitOutOfLineLoadTypedArray(OutOfLineLoadTypedArray *ool);
|
|
||||||
bool visitCallIteratorStart(LCallIteratorStart *lir);
|
bool visitCallIteratorStart(LCallIteratorStart *lir);
|
||||||
bool visitIteratorStart(LIteratorStart *lir);
|
bool visitIteratorStart(LIteratorStart *lir);
|
||||||
bool visitIteratorNext(LIteratorNext *lir);
|
bool visitIteratorNext(LIteratorNext *lir);
|
||||||
|
@ -6666,7 +6666,7 @@ IonBuilder::jsop_getelem_typed(int arrayType)
|
|||||||
current->add(load);
|
current->add(load);
|
||||||
current->push(load);
|
current->push(load);
|
||||||
|
|
||||||
return resumeAfter(load) && pushTypeBarrier(load, types, needsBarrier);
|
return pushTypeBarrier(load, types, needsBarrier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5001,9 +5001,7 @@ class MLoadTypedArrayElementHole
|
|||||||
return getOperand(1);
|
return getOperand(1);
|
||||||
}
|
}
|
||||||
AliasSet getAliasSet() const {
|
AliasSet getAliasSet() const {
|
||||||
// Out-of-bounds accesses are handled using a VM call, this may
|
return AliasSet::Load(AliasSet::TypedArrayElement);
|
||||||
// invoke getters on the prototype chain.
|
|
||||||
return AliasSet::Store(AliasSet::Any);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,6 +14,9 @@ function f1() {
|
|||||||
f1();
|
f1();
|
||||||
|
|
||||||
function f2() {
|
function f2() {
|
||||||
|
// Test that values on the prototype are ignored,
|
||||||
|
// even for OOB accesses. This behavior is new
|
||||||
|
// with ECMA 6 (see bug 829896).
|
||||||
Object.prototype[50] = 4.4;
|
Object.prototype[50] = 4.4;
|
||||||
Object.prototype[55] = Math;
|
Object.prototype[55] = Math;
|
||||||
|
|
||||||
@ -22,10 +25,6 @@ function f2() {
|
|||||||
var x = a[i];
|
var x = a[i];
|
||||||
if (i < a.length)
|
if (i < a.length)
|
||||||
assertEq(x, 0);
|
assertEq(x, 0);
|
||||||
else if (i === 50)
|
|
||||||
assertEq(x, 4.4);
|
|
||||||
else if (i === 55)
|
|
||||||
assertEq(x, Math);
|
|
||||||
else
|
else
|
||||||
assertEq(x, undefined);
|
assertEq(x, undefined);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ function test()
|
|||||||
for (var i = 0, sz = 9; i < sz; i++)
|
for (var i = 0, sz = 9; i < sz; i++)
|
||||||
{
|
{
|
||||||
var ta = new Int8Array();
|
var ta = new Int8Array();
|
||||||
assertEq(ta[0], r);
|
assertEq(ta[0], undefined);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
test();
|
test();
|
||||||
|
@ -11,8 +11,6 @@ function test1() {
|
|||||||
assertEq(res, 0xffffee00);
|
assertEq(res, 0xffffee00);
|
||||||
else if (i == 84)
|
else if (i == 84)
|
||||||
assertEq(res, 444);
|
assertEq(res, 444);
|
||||||
else if (i == 105)
|
|
||||||
assertEq(res, true);
|
|
||||||
else if (i >= 100)
|
else if (i >= 100)
|
||||||
assertEq(res, undefined);
|
assertEq(res, undefined);
|
||||||
}
|
}
|
||||||
|
4
js/src/jit-test/tests/parallelarray/bug890465.js
Normal file
4
js/src/jit-test/tests/parallelarray/bug890465.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
x = Uint8ClampedArray()
|
||||||
|
ParallelArray([320], function() {
|
||||||
|
return x[8]
|
||||||
|
})
|
@ -3706,17 +3706,6 @@ js::GetElement(JSContext *cx, MutableHandleValue lref, HandleValue rref, Mutable
|
|||||||
return GetElementOperation(cx, JSOP_GETELEM, lref, rref, vp);
|
return GetElementOperation(cx, JSOP_GETELEM, lref, rref, vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
js::GetElementMonitored(JSContext *cx, MutableHandleValue lref, HandleValue rref,
|
|
||||||
MutableHandleValue vp)
|
|
||||||
{
|
|
||||||
if (!GetElement(cx, lref, rref, vp))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
TypeScript::Monitor(cx, vp);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
js::CallElement(JSContext *cx, MutableHandleValue lref, HandleValue rref, MutableHandleValue res)
|
js::CallElement(JSContext *cx, MutableHandleValue lref, HandleValue rref, MutableHandleValue res)
|
||||||
{
|
{
|
||||||
|
@ -415,9 +415,6 @@ Lambda(JSContext *cx, HandleFunction fun, HandleObject parent);
|
|||||||
bool
|
bool
|
||||||
GetElement(JSContext *cx, MutableHandleValue lref, HandleValue rref, MutableHandleValue res);
|
GetElement(JSContext *cx, MutableHandleValue lref, HandleValue rref, MutableHandleValue res);
|
||||||
|
|
||||||
bool
|
|
||||||
GetElementMonitored(JSContext *cx, MutableHandleValue lref, HandleValue rref, MutableHandleValue res);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CallElement(JSContext *cx, MutableHandleValue lref, HandleValue rref, MutableHandleValue res);
|
CallElement(JSContext *cx, MutableHandleValue lref, HandleValue rref, MutableHandleValue res);
|
||||||
|
|
||||||
|
@ -1442,13 +1442,8 @@ class TypedArrayObjectTemplate : public TypedArrayObject
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RootedObject proto(cx, tarray->getProto());
|
vp.setUndefined();
|
||||||
if (!proto) {
|
return true;
|
||||||
vp.setUndefined();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JSObject::getElement(cx, proto, receiver, index, vp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
|
Loading…
Reference in New Issue
Block a user