mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 603201 - Enable primitive receivers in [[Set]]. r=jorendorff
This commit is contained in:
parent
d3cc5fb902
commit
8d8cb64993
@ -1059,7 +1059,8 @@ function traverse (node, cb) {
|
|||||||
cb(node);
|
cb(node);
|
||||||
keys(node).map(key => {
|
keys(node).map(key => {
|
||||||
if (key === 'parent' || !node[key]) return;
|
if (key === 'parent' || !node[key]) return;
|
||||||
node[key].parent = node;
|
if (typeof node[key] === "object")
|
||||||
|
node[key].parent = node;
|
||||||
traverse(node[key], cb);
|
traverse(node[key], cb);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2766,7 +2766,7 @@ DoSetElemFallback(JSContext* cx, BaselineFrame* frame, ICSetElem_Fallback* stub_
|
|||||||
if (!InitArrayElemOperation(cx, pc, obj, index.toInt32(), rhs))
|
if (!InitArrayElemOperation(cx, pc, obj, index.toInt32(), rhs))
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if (!SetObjectElement(cx, obj, index, rhs, JSOp(*pc) == JSOP_STRICTSETELEM, script, pc))
|
if (!SetObjectElement(cx, obj, index, rhs, objv, JSOp(*pc) == JSOP_STRICTSETELEM, script, pc))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4777,9 +4777,12 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_
|
|||||||
} else {
|
} else {
|
||||||
MOZ_ASSERT(op == JSOP_SETPROP || op == JSOP_STRICTSETPROP);
|
MOZ_ASSERT(op == JSOP_SETPROP || op == JSOP_STRICTSETPROP);
|
||||||
|
|
||||||
RootedValue v(cx, rhs);
|
ObjectOpResult result;
|
||||||
if (!PutProperty(cx, obj, id, v, op == JSOP_STRICTSETPROP))
|
if (!SetProperty(cx, obj, id, rhs, lhs, result) ||
|
||||||
|
!result.checkStrictErrorOrWarning(cx, obj, id, op == JSOP_STRICTSETPROP))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leave the RHS on the stack.
|
// Leave the RHS on the stack.
|
||||||
|
@ -7,34 +7,36 @@
|
|||||||
|
|
||||||
#include "jsapi-tests/tests.h"
|
#include "jsapi-tests/tests.h"
|
||||||
|
|
||||||
|
using namespace JS;
|
||||||
|
|
||||||
BEGIN_TEST(testForwardSetProperty)
|
BEGIN_TEST(testForwardSetProperty)
|
||||||
{
|
{
|
||||||
JS::RootedValue v1(cx);
|
RootedValue v1(cx);
|
||||||
EVAL("var foundValue; \n"
|
EVAL("var foundValue; \n"
|
||||||
"var obj1 = { set prop(val) { foundValue = this; } }; \n"
|
"var obj1 = { set prop(val) { foundValue = this; } }; \n"
|
||||||
"obj1;",
|
"obj1;",
|
||||||
&v1);
|
&v1);
|
||||||
|
|
||||||
JS::RootedValue v2(cx);
|
RootedValue v2(cx);
|
||||||
EVAL("var obj2 = Object.create(obj1); \n"
|
EVAL("var obj2 = Object.create(obj1); \n"
|
||||||
"obj2;",
|
"obj2;",
|
||||||
&v2);
|
&v2);
|
||||||
|
|
||||||
JS::RootedValue v3(cx);
|
RootedValue v3(cx);
|
||||||
EVAL("var obj3 = {}; \n"
|
EVAL("var obj3 = {}; \n"
|
||||||
"obj3;",
|
"obj3;",
|
||||||
&v3);
|
&v3);
|
||||||
|
|
||||||
JS::RootedObject obj1(cx, &v1.toObject());
|
RootedObject obj1(cx, &v1.toObject());
|
||||||
JS::RootedObject obj2(cx, &v2.toObject());
|
RootedObject obj2(cx, &v2.toObject());
|
||||||
JS::RootedObject obj3(cx, &v3.toObject());
|
RootedObject obj3(cx, &v3.toObject());
|
||||||
|
|
||||||
JS::RootedValue setval(cx, JS::Int32Value(42));
|
RootedValue setval(cx, Int32Value(42));
|
||||||
|
|
||||||
JS::RootedValue propkey(cx);
|
RootedValue propkey(cx);
|
||||||
EVAL("'prop';", &propkey);
|
EVAL("'prop';", &propkey);
|
||||||
|
|
||||||
JS::RootedId prop(cx);
|
RootedId prop(cx);
|
||||||
CHECK(JS_ValueToId(cx, propkey, &prop));
|
CHECK(JS_ValueToId(cx, propkey, &prop));
|
||||||
|
|
||||||
EXEC("function assertEq(a, b, msg) \n"
|
EXEC("function assertEq(a, b, msg) \n"
|
||||||
@ -68,42 +70,20 @@ BEGIN_TEST(testForwardSetProperty)
|
|||||||
|
|
||||||
// Strict setter
|
// Strict setter
|
||||||
|
|
||||||
EVAL("obj1 = { set prop(val) { 'use strict'; foundValue = this; } }; \n"
|
RootedValue v4(cx);
|
||||||
"obj1;",
|
EVAL("({ set prop(val) { 'use strict'; foundValue = this; } })", &v4);
|
||||||
&v1);
|
RootedObject obj4(cx, &v4.toObject());
|
||||||
|
|
||||||
CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, setval, v3, result));
|
CHECK(JS_ForwardSetPropertyTo(cx, obj4, prop, setval, v3, result));
|
||||||
CHECK(result);
|
CHECK(result);
|
||||||
|
|
||||||
EXEC("assertEq(foundValue, obj3, 'wrong receiver passed to strict setter');");
|
EXEC("assertEq(foundValue, obj3, 'wrong receiver passed to strict setter');");
|
||||||
|
|
||||||
CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, setval, setval, result));
|
CHECK(JS_ForwardSetPropertyTo(cx, obj4, prop, setval, setval, result));
|
||||||
CHECK(result);
|
CHECK(result);
|
||||||
|
|
||||||
JS::RootedValue strictSetSupported(cx);
|
EXEC("assertEq(foundValue, 42, \n"
|
||||||
EVAL("var strictSetSupported = false; \n"
|
" '42 passed as receiver to strict setter was mangled');");
|
||||||
"Object.defineProperty(Object.prototype, \n"
|
|
||||||
" 'strictSetter', \n"
|
|
||||||
" { \n"
|
|
||||||
" set(v) { \n"
|
|
||||||
" 'use strict'; \n"
|
|
||||||
" strictSetSupported = \n"
|
|
||||||
" typeof this === 'number'; \n"
|
|
||||||
" } \n"
|
|
||||||
" }); \n"
|
|
||||||
"17..strictSetter = 42; \n"
|
|
||||||
"strictSetSupported;",
|
|
||||||
&strictSetSupported);
|
|
||||||
CHECK(strictSetSupported.isBoolean());
|
|
||||||
|
|
||||||
if (strictSetSupported.toBoolean()) {
|
|
||||||
// XXX Bug 603201 will fix this.
|
|
||||||
MOZ_ASSERT(false,
|
|
||||||
"remove the support-testing check when bug 603201 is fixt");
|
|
||||||
EXEC("assertEq(foundValue, 42, \n"
|
|
||||||
" '42 passed as receiver to strict setter ' + \n"
|
|
||||||
" 'was mangled');");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,8 @@ Object.defineProperty(Symbol.prototype, "prop", {
|
|||||||
set: function (v) {
|
set: function (v) {
|
||||||
"use strict";
|
"use strict";
|
||||||
sets++;
|
sets++;
|
||||||
assertEq(typeof this, "object");
|
assertEq(typeof this, "symbol");
|
||||||
assertEq(this instanceof Symbol, true);
|
assertEq(this, sym);
|
||||||
assertEq(this.valueOf(), sym);
|
|
||||||
assertEq(v, "newvalue");
|
assertEq(v, "newvalue");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -282,11 +282,8 @@ SetPropertyOperation(JSContext* cx, JSOp op, HandleValue lval, HandleId id, Hand
|
|||||||
if (!obj)
|
if (!obj)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Note: ES6 specifies that the value lval, not obj, is passed as receiver
|
|
||||||
// to obj's [[Set]] internal method. See bug 603201.
|
|
||||||
RootedValue receiver(cx, ObjectValue(*obj));
|
|
||||||
ObjectOpResult result;
|
ObjectOpResult result;
|
||||||
return SetProperty(cx, obj, id, rval, receiver, result) &&
|
return SetProperty(cx, obj, id, rval, lval, result) &&
|
||||||
result.checkStrictErrorOrWarning(cx, obj, id, op == JSOP_STRICTSETPROP);
|
result.checkStrictErrorOrWarning(cx, obj, id, op == JSOP_STRICTSETPROP);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1409,9 +1406,9 @@ ModOperation(JSContext* cx, HandleValue lhs, HandleValue rhs, MutableHandleValue
|
|||||||
}
|
}
|
||||||
|
|
||||||
static MOZ_ALWAYS_INLINE bool
|
static MOZ_ALWAYS_INLINE bool
|
||||||
SetObjectElementOperation(JSContext* cx, HandleObject obj, HandleValue receiver, HandleId id,
|
SetObjectElementOperation(JSContext* cx, HandleObject obj, HandleId id, HandleValue value,
|
||||||
const Value& value, bool strict, JSScript* script = nullptr,
|
HandleValue receiver, bool strict,
|
||||||
jsbytecode* pc = nullptr)
|
JSScript* script = nullptr, jsbytecode* pc = nullptr)
|
||||||
{
|
{
|
||||||
// receiver != obj happens only at super[expr], where we expect to find the property
|
// receiver != obj happens only at super[expr], where we expect to find the property
|
||||||
// People probably aren't building hashtables with |super| anyway.
|
// People probably aren't building hashtables with |super| anyway.
|
||||||
@ -1430,9 +1427,8 @@ SetObjectElementOperation(JSContext* cx, HandleObject obj, HandleValue receiver,
|
|||||||
if (obj->isNative() && !JSID_IS_INT(id) && !obj->setHadElementsAccess(cx))
|
if (obj->isNative() && !JSID_IS_INT(id) && !obj->setHadElementsAccess(cx))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
RootedValue tmp(cx, value);
|
|
||||||
ObjectOpResult result;
|
ObjectOpResult result;
|
||||||
return SetProperty(cx, obj, id, tmp, receiver, result) &&
|
return SetProperty(cx, obj, id, value, receiver, result) &&
|
||||||
result.checkStrictErrorOrWarning(cx, obj, id, strict);
|
result.checkStrictErrorOrWarning(cx, obj, id, strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2677,13 +2673,15 @@ CASE(JSOP_STRICTSETELEM)
|
|||||||
{
|
{
|
||||||
static_assert(JSOP_SETELEM_LENGTH == JSOP_STRICTSETELEM_LENGTH,
|
static_assert(JSOP_SETELEM_LENGTH == JSOP_STRICTSETELEM_LENGTH,
|
||||||
"setelem and strictsetelem must be the same size");
|
"setelem and strictsetelem must be the same size");
|
||||||
|
HandleValue receiver = REGS.stackHandleAt(-3);
|
||||||
ReservedRooted<JSObject*> obj(&rootObject0);
|
ReservedRooted<JSObject*> obj(&rootObject0);
|
||||||
FETCH_OBJECT(cx, -3, obj);
|
obj = ToObjectFromStack(cx, receiver);
|
||||||
|
if (!obj)
|
||||||
|
goto error;
|
||||||
ReservedRooted<jsid> id(&rootId0);
|
ReservedRooted<jsid> id(&rootId0);
|
||||||
FETCH_ELEMENT_ID(-2, id);
|
FETCH_ELEMENT_ID(-2, id);
|
||||||
Value& value = REGS.sp[-1];
|
HandleValue value = REGS.stackHandleAt(-1);
|
||||||
ReservedRooted<Value> receiver(&rootValue0, ObjectValue(*obj));
|
if (!SetObjectElementOperation(cx, obj, id, value, receiver, *REGS.pc == JSOP_STRICTSETELEM))
|
||||||
if (!SetObjectElementOperation(cx, obj, receiver, id, value, *REGS.pc == JSOP_STRICTSETELEM))
|
|
||||||
goto error;
|
goto error;
|
||||||
REGS.sp[-3] = value;
|
REGS.sp[-3] = value;
|
||||||
REGS.sp -= 2;
|
REGS.sp -= 2;
|
||||||
@ -2700,10 +2698,10 @@ CASE(JSOP_STRICTSETELEM_SUPER)
|
|||||||
FETCH_ELEMENT_ID(-4, id);
|
FETCH_ELEMENT_ID(-4, id);
|
||||||
ReservedRooted<Value> receiver(&rootValue0, REGS.sp[-3]);
|
ReservedRooted<Value> receiver(&rootValue0, REGS.sp[-3]);
|
||||||
ReservedRooted<JSObject*> obj(&rootObject1, ®S.sp[-2].toObject());
|
ReservedRooted<JSObject*> obj(&rootObject1, ®S.sp[-2].toObject());
|
||||||
Value& value = REGS.sp[-1];
|
HandleValue value = REGS.stackHandleAt(-1);
|
||||||
|
|
||||||
bool strict = JSOp(*REGS.pc) == JSOP_STRICTSETELEM_SUPER;
|
bool strict = JSOp(*REGS.pc) == JSOP_STRICTSETELEM_SUPER;
|
||||||
if (!SetObjectElementOperation(cx, obj, receiver, id, value, strict))
|
if (!SetObjectElementOperation(cx, obj, id, value, receiver, strict))
|
||||||
goto error;
|
goto error;
|
||||||
REGS.sp[-4] = value;
|
REGS.sp[-4] = value;
|
||||||
REGS.sp -= 3;
|
REGS.sp -= 3;
|
||||||
@ -4333,7 +4331,7 @@ js::SetObjectElement(JSContext* cx, HandleObject obj, HandleValue index, HandleV
|
|||||||
if (!ToPropertyKey(cx, index, &id))
|
if (!ToPropertyKey(cx, index, &id))
|
||||||
return false;
|
return false;
|
||||||
RootedValue receiver(cx, ObjectValue(*obj));
|
RootedValue receiver(cx, ObjectValue(*obj));
|
||||||
return SetObjectElementOperation(cx, obj, receiver, id, value, strict);
|
return SetObjectElementOperation(cx, obj, id, value, receiver, strict);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -4345,7 +4343,18 @@ js::SetObjectElement(JSContext* cx, HandleObject obj, HandleValue index, HandleV
|
|||||||
if (!ToPropertyKey(cx, index, &id))
|
if (!ToPropertyKey(cx, index, &id))
|
||||||
return false;
|
return false;
|
||||||
RootedValue receiver(cx, ObjectValue(*obj));
|
RootedValue receiver(cx, ObjectValue(*obj));
|
||||||
return SetObjectElementOperation(cx, obj, receiver, id, value, strict, script, pc);
|
return SetObjectElementOperation(cx, obj, id, value, receiver, strict, script, pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
js::SetObjectElement(JSContext* cx, HandleObject obj, HandleValue index, HandleValue value,
|
||||||
|
HandleValue receiver, bool strict, HandleScript script, jsbytecode* pc)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(pc);
|
||||||
|
RootedId id(cx);
|
||||||
|
if (!ToPropertyKey(cx, index, &id))
|
||||||
|
return false;
|
||||||
|
return SetObjectElementOperation(cx, obj, id, value, receiver, strict, script, pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -369,6 +369,10 @@ bool
|
|||||||
SetObjectElement(JSContext* cx, HandleObject obj, HandleValue index, HandleValue value,
|
SetObjectElement(JSContext* cx, HandleObject obj, HandleValue index, HandleValue value,
|
||||||
bool strict, HandleScript script, jsbytecode* pc);
|
bool strict, HandleScript script, jsbytecode* pc);
|
||||||
|
|
||||||
|
bool
|
||||||
|
SetObjectElement(JSContext* cx, HandleObject obj, HandleValue index, HandleValue value,
|
||||||
|
HandleValue receiver, bool strict, HandleScript script, jsbytecode* pc);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
InitElementArray(JSContext* cx, jsbytecode* pc,
|
InitElementArray(JSContext* cx, jsbytecode* pc,
|
||||||
HandleObject obj, uint32_t index, HandleValue value);
|
HandleObject obj, uint32_t index, HandleValue value);
|
||||||
|
Loading…
Reference in New Issue
Block a user