зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1090537, part 3 - Pass receiver argument through from JSObject::setGeneric and setElement to Proxy::set. r=efaust.
ES6 specifies [[Set]] as an operation taking both a "this" object and a "receiver" parameter. Both JSObject::setGeneric and Proxy::set support the receiver parameter, but ObjectOps::setGeneric does not; in this patch, we add a little workaround for that. The test shows how this is observable using only standard builtins. The changes in JSObject::setElement are untestable since currently all call sites pass the same value for obj as for receiver. (This was reviewed as "part 2" but it was necessary to switch parts 2 and 3 and add part 2b.) --HG-- extra : rebase_source : 617decfa9be34b01a0f923a9717ad2544d913af9
This commit is contained in:
Родитель
2c1490915a
Коммит
7915208511
|
@ -0,0 +1,15 @@
|
|||
// The receiver argument is passed through proxies with no "set" handler.
|
||||
|
||||
var hits;
|
||||
var a = new Proxy({}, {
|
||||
set(t, id, value, receiver) {
|
||||
assertEq(id, "prop");
|
||||
assertEq(value, 3);
|
||||
assertEq(receiver, b);
|
||||
hits++;
|
||||
}
|
||||
});
|
||||
var b = new Proxy(a, {});
|
||||
hits = 0;
|
||||
b.prop = 3;
|
||||
assertEq(hits, 1);
|
|
@ -1840,7 +1840,7 @@ js::CreateThisForFunction(JSContext *cx, HandleObject callee, NewObjectKind newK
|
|||
}
|
||||
|
||||
/* static */ bool
|
||||
JSObject::nonNativeSetProperty(JSContext *cx, HandleObject obj,
|
||||
JSObject::nonNativeSetProperty(JSContext *cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, bool strict)
|
||||
{
|
||||
if (MOZ_UNLIKELY(obj->watched())) {
|
||||
|
@ -1848,11 +1848,13 @@ JSObject::nonNativeSetProperty(JSContext *cx, HandleObject obj,
|
|||
if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, vp))
|
||||
return false;
|
||||
}
|
||||
if (obj->is<ProxyObject>())
|
||||
return Proxy::set(cx, obj, receiver, id, strict, vp);
|
||||
return obj->getOps()->setGeneric(cx, obj, id, vp, strict);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
JSObject::nonNativeSetElement(JSContext *cx, HandleObject obj,
|
||||
JSObject::nonNativeSetElement(JSContext *cx, HandleObject obj, HandleObject receiver,
|
||||
uint32_t index, MutableHandleValue vp, bool strict)
|
||||
{
|
||||
if (MOZ_UNLIKELY(obj->watched())) {
|
||||
|
@ -1864,6 +1866,11 @@ JSObject::nonNativeSetElement(JSContext *cx, HandleObject obj,
|
|||
if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, vp))
|
||||
return false;
|
||||
}
|
||||
if (obj->is<ProxyObject>()) {
|
||||
RootedId id(cx);
|
||||
return IndexToId(cx, index, &id) &&
|
||||
Proxy::set(cx, obj, receiver, id, strict, vp);
|
||||
}
|
||||
return obj->getOps()->setElement(cx, obj, index, vp, strict);
|
||||
}
|
||||
|
||||
|
|
|
@ -655,9 +655,11 @@ class JSObject : public js::gc::Cell
|
|||
uint32_t index, js::MutableHandleValue vp, bool strict);
|
||||
|
||||
static bool nonNativeSetProperty(JSContext *cx, js::HandleObject obj,
|
||||
js::HandleId id, js::MutableHandleValue vp, bool strict);
|
||||
js::HandleObject receiver, js::HandleId id,
|
||||
js::MutableHandleValue vp, bool strict);
|
||||
static bool nonNativeSetElement(JSContext *cx, js::HandleObject obj,
|
||||
uint32_t index, js::MutableHandleValue vp, bool strict);
|
||||
js::HandleObject receiver, uint32_t index,
|
||||
js::MutableHandleValue vp, bool strict);
|
||||
|
||||
static inline bool getGenericAttributes(JSContext *cx, js::HandleObject obj,
|
||||
js::HandleId id, unsigned *attrsp);
|
||||
|
|
|
@ -1414,7 +1414,7 @@ JSObject::setGeneric(JSContext *cx, js::HandleObject obj, js::HandleObject recei
|
|||
js::HandleId id, js::MutableHandleValue vp, bool strict)
|
||||
{
|
||||
if (obj->getOps()->setGeneric)
|
||||
return nonNativeSetProperty(cx, obj, id, vp, strict);
|
||||
return nonNativeSetProperty(cx, obj, receiver, id, vp, strict);
|
||||
return js::baseops::SetPropertyHelper<js::SequentialExecution>(
|
||||
cx, obj.as<js::NativeObject>(), receiver, id, js::baseops::Qualified, vp, strict);
|
||||
}
|
||||
|
@ -1424,7 +1424,7 @@ JSObject::setElement(JSContext *cx, js::HandleObject obj, js::HandleObject recei
|
|||
uint32_t index, js::MutableHandleValue vp, bool strict)
|
||||
{
|
||||
if (obj->getOps()->setElement)
|
||||
return nonNativeSetElement(cx, obj, index, vp, strict);
|
||||
return nonNativeSetElement(cx, obj, receiver, index, vp, strict);
|
||||
return js::baseops::SetElementHelper(cx, obj.as<js::NativeObject>(),
|
||||
receiver, index, vp, strict);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче