Bug 1317943 - Fix ThrowReadOnlyError to pass the index instead of the object to the error reporter. r=nbp

This commit is contained in:
Jan de Mooij 2016-11-19 11:14:13 +01:00
Родитель 29aef77ff6
Коммит e472d96785
4 изменённых файлов: 33 добавлений и 11 удалений

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

@ -0,0 +1,14 @@
"use strict";
function test() {
for (var i=0; i<10; i++) {
try {
var arr = [];
arr[0] = 1;
Object.freeze(arr);
arr[0] = 2;
} catch (e) {
assertEq(e.toString().includes("TypeError: 0 is read-only"), true);
}
}
}
test();

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

@ -8306,7 +8306,7 @@ CodeGenerator::visitStoreElementHoleV(LStoreElementHoleV* lir)
emitStoreElementHoleV(lir);
}
typedef bool (*ThrowReadOnlyFn)(JSContext*, HandleObject);
typedef bool (*ThrowReadOnlyFn)(JSContext*, int32_t);
static const VMFunction ThrowReadOnlyInfo =
FunctionInfo<ThrowReadOnlyFn>(ThrowReadOnlyError, "ThrowReadOnlyError");
@ -8321,9 +8321,12 @@ CodeGenerator::visitFallibleStoreElementT(LFallibleStoreElementT* lir)
if (!lir->mir()->strict()) {
masm.branchTest32(Assembler::NonZero, flags, Imm32(ObjectElements::FROZEN), &isFrozen);
} else {
Register object = ToRegister(lir->object());
OutOfLineCode* ool = oolCallVM(ThrowReadOnlyInfo, lir,
ArgList(object), StoreNothing());
const LAllocation* index = lir->index();
OutOfLineCode* ool;
if (index->isConstant())
ool = oolCallVM(ThrowReadOnlyInfo, lir, ArgList(Imm32(ToInt32(index))), StoreNothing());
else
ool = oolCallVM(ThrowReadOnlyInfo, lir, ArgList(ToRegister(index)), StoreNothing());
masm.branchTest32(Assembler::NonZero, flags, Imm32(ObjectElements::FROZEN), ool->entry());
// This OOL code should have thrown an exception, so will never return.
// So, do not bind ool->rejoin() anywhere, so that it implicitly (and without the cost
@ -8346,9 +8349,12 @@ CodeGenerator::visitFallibleStoreElementV(LFallibleStoreElementV* lir)
if (!lir->mir()->strict()) {
masm.branchTest32(Assembler::NonZero, flags, Imm32(ObjectElements::FROZEN), &isFrozen);
} else {
Register object = ToRegister(lir->object());
OutOfLineCode* ool = oolCallVM(ThrowReadOnlyInfo, lir,
ArgList(object), StoreNothing());
const LAllocation* index = lir->index();
OutOfLineCode* ool;
if (index->isConstant())
ool = oolCallVM(ThrowReadOnlyInfo, lir, ArgList(Imm32(ToInt32(index))), StoreNothing());
else
ool = oolCallVM(ThrowReadOnlyInfo, lir, ArgList(ToRegister(index)), StoreNothing());
masm.branchTest32(Assembler::NonZero, flags, Imm32(ObjectElements::FROZEN), ool->entry());
// This OOL code should have thrown an exception, so will never return.
// So, do not bind ool->rejoin() anywhere, so that it implicitly (and without the cost

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

@ -1316,10 +1316,9 @@ ThrowRuntimeLexicalError(JSContext* cx, unsigned errorNumber)
}
bool
ThrowReadOnlyError(JSContext* cx, HandleObject handle)
ThrowReadOnlyError(JSContext* cx, int32_t index)
{
HandleNativeObject obj = handle.as<NativeObject>();
RootedValue val(cx, ObjectValue(*obj));
RootedValue val(cx, Int32Value(index));
ReportValueError(cx, JSMSG_READ_ONLY, JSDVG_IGNORE_STACK, val, nullptr);
return false;
}

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

@ -786,10 +786,13 @@ bool ObjectIsConstructor(JSObject* obj);
MOZ_MUST_USE bool
ThrowRuntimeLexicalError(JSContext* cx, unsigned errorNumber);
MOZ_MUST_USE bool
ThrowReadOnlyError(JSContext* cx, HandleObject obj);
ThrowReadOnlyError(JSContext* cx, int32_t index);
MOZ_MUST_USE bool
BaselineThrowUninitializedThis(JSContext* cx, BaselineFrame* frame);
MOZ_MUST_USE bool
ThrowBadDerivedReturn(JSContext* cx, HandleValue v);