Bug 1374462 - Fix super getprop and super getelem to not box 'this' values. (r=jorendorff)

This commit is contained in:
Shu-yu Guo 2017-06-27 13:17:59 -07:00
Родитель e09978bd8b
Коммит 9e991dd02b
4 изменённых файлов: 41 добавлений и 12 удалений

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

@ -25,10 +25,9 @@ derivedInstance.testCPN(derivedInstance);
let obj = { test: derivedInstance.test };
obj.test(obj);
// Classes are strict, so primitives are not boxed/turned into globals
let testSolo = derivedInstance.test;
// Hah! The engine is not prepared for non-object receivers, since this couldn't
// happen before. Hope Waldo fixes this soon as he claims he will :)
assertThrowsInstanceOf(() =>testSolo(undefined), TypeError);
testSolo(undefined);
let anotherObject = { };
derivedInstance.test.call(anotherObject, anotherObject);

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

@ -0,0 +1,31 @@
class C {
get prop_this() { return this; }
}
var g_prop_this = 'prop_this';
class D extends C {
super_prop() { return super.prop_this; }
super_elem() { return super[g_prop_this]; }
}
var barsym = Symbol("bar");
// Test that primitive |this| values are not boxed, and undefined/null are not
// globals for super.property.
assertEq(new D().super_prop.call(3), 3);
assertEq(new D().super_prop.call("foo"), "foo");
assertEq(new D().super_prop.call(true), true);
assertEq(new D().super_prop.call(barsym), barsym);
assertEq(new D().super_prop.call(null), null);
assertEq(new D().super_prop.call(undefined), undefined);
// Ditto for super[elem]
assertEq(new D().super_elem.call(3), 3);
assertEq(new D().super_elem.call("foo"), "foo");
assertEq(new D().super_elem.call(true), true);
assertEq(new D().super_elem.call(barsym), barsym);
assertEq(new D().super_elem.call(null), null);
assertEq(new D().super_elem.call(undefined), undefined);
if (typeof reportCompare === 'function')
reportCompare(0, 0);

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

@ -488,11 +488,11 @@ ToIdOperation(JSContext* cx, HandleScript script, jsbytecode* pc, HandleValue id
}
static MOZ_ALWAYS_INLINE bool
GetObjectElementOperation(JSContext* cx, JSOp op, JS::HandleObject obj, JS::HandleObject receiver,
GetObjectElementOperation(JSContext* cx, JSOp op, JS::HandleObject obj, JS::HandleValue receiver,
HandleValue key, MutableHandleValue res)
{
MOZ_ASSERT(op == JSOP_GETELEM || op == JSOP_CALLELEM || op == JSOP_GETELEM_SUPER);
MOZ_ASSERT_IF(op == JSOP_GETELEM || op == JSOP_CALLELEM, obj == receiver);
MOZ_ASSERT_IF(op == JSOP_GETELEM || op == JSOP_CALLELEM, obj == &receiver.toObject());
do {
uint32_t index;
@ -626,8 +626,9 @@ GetElementOperation(JSContext* cx, JSOp op, HandleValue lref, HandleValue rref,
return GetPrimitiveElementOperation(cx, op, thisv, rref, res);
}
RootedObject thisv(cx, &lref.toObject());
return GetObjectElementOperation(cx, op, thisv, thisv, rref, res);
RootedObject obj(cx, &lref.toObject());
RootedValue thisv(cx, lref);
return GetObjectElementOperation(cx, op, obj, thisv, rref, res);
}
static MOZ_ALWAYS_INLINE JSString*

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

@ -2786,8 +2786,7 @@ END_CASE(JSOP_GETPROP)
CASE(JSOP_GETPROP_SUPER)
{
ReservedRooted<JSObject*> receiver(&rootObject0);
FETCH_OBJECT(cx, -2, receiver);
ReservedRooted<Value> receiver(&rootValue0, REGS.sp[-2]);
ReservedRooted<JSObject*> obj(&rootObject1, &REGS.sp[-1].toObject());
MutableHandleValue rref = REGS.stackHandleAt(-2);
@ -2911,9 +2910,8 @@ END_CASE(JSOP_GETELEM)
CASE(JSOP_GETELEM_SUPER)
{
HandleValue rval = REGS.stackHandleAt(-3);
ReservedRooted<JSObject*> receiver(&rootObject0);
FETCH_OBJECT(cx, -2, receiver);
ReservedRooted<Value> rval(&rootValue0, REGS.sp[-3]);
ReservedRooted<Value> receiver(&rootValue1, REGS.sp[-2]);
ReservedRooted<JSObject*> obj(&rootObject1, &REGS.sp[-1].toObject());
MutableHandleValue res = REGS.stackHandleAt(-3);