mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1130537 - Reimplement js::SetPropertyIgnoringNamedGetter to follow ES6 draft rev 32 9.1.9 [[Set]]. r=efaust.
This commit is contained in:
parent
02b07f6efa
commit
89bb3ca00b
@ -239,7 +239,6 @@ DOMProxyHandler::set(JSContext *cx, Handle<JSObject*> proxy, Handle<JSObject*> r
|
||||
&desc)) {
|
||||
return false;
|
||||
}
|
||||
bool descIsOwn = desc.object() != nullptr;
|
||||
if (!desc.object()) {
|
||||
// Don't just use getPropertyDescriptor, unlike BaseProxyHandler::set,
|
||||
// because that would call getOwnPropertyDescriptor on ourselves. Instead,
|
||||
@ -253,8 +252,7 @@ DOMProxyHandler::set(JSContext *cx, Handle<JSObject*> proxy, Handle<JSObject*> r
|
||||
}
|
||||
}
|
||||
|
||||
return js::SetPropertyIgnoringNamedGetter(cx, this, proxy, receiver, id,
|
||||
&desc, descIsOwn, vp, result);
|
||||
return js::SetPropertyIgnoringNamedGetter(cx, proxy, id, vp, receiver, &desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -33,8 +33,7 @@ class CustomProxyHandler : public DirectProxyHandler {
|
||||
Rooted<JSPropertyDescriptor> desc(cx);
|
||||
if (!DirectProxyHandler::getPropertyDescriptor(cx, proxy, id, &desc))
|
||||
return false;
|
||||
return SetPropertyIgnoringNamedGetter(cx, this, proxy, receiver, id, &desc,
|
||||
desc.object() == proxy, vp, result);
|
||||
return SetPropertyIgnoringNamedGetter(cx, proxy, id, vp, receiver, &desc, result);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -2625,17 +2625,15 @@ ForwardToNative(JSContext *cx, JSNative native, const JS::CallArgs &args);
|
||||
*
|
||||
* SetPropertyIgnoringNamedGetter is exposed to make it easier to override
|
||||
* set() in this way. It carries out all the steps of BaseProxyHandler::set()
|
||||
* except the initial getOwnPropertyDescriptor()/getPropertyDescriptor() calls.
|
||||
* The caller must supply those results as the 'desc' and 'descIsOwn'
|
||||
* parameters.
|
||||
* except the initial getOwnPropertyDescriptor() call. The caller must supply
|
||||
* that descriptor as the 'ownDesc' parameter.
|
||||
*
|
||||
* Implemented in jsproxy.cpp.
|
||||
* Implemented in proxy/BaseProxyHandler.cpp.
|
||||
*/
|
||||
JS_FRIEND_API(bool)
|
||||
SetPropertyIgnoringNamedGetter(JSContext *cx, const BaseProxyHandler *handler,
|
||||
JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
JS::HandleId id, JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool descIsOwn, JS::MutableHandleValue vp,
|
||||
SetPropertyIgnoringNamedGetter(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::MutableHandleValue vp, JS::HandleObject receiver,
|
||||
JS::MutableHandle<JSPropertyDescriptor> ownDesc,
|
||||
JS::ObjectOpResult &result);
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
|
@ -86,12 +86,23 @@ BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
if (!getOwnPropertyDescriptor(cx, proxy, id, &ownDesc))
|
||||
return false;
|
||||
|
||||
// The rest is factored out into a separate function with a weird name.
|
||||
// This algorithm continues just below.
|
||||
return SetPropertyIgnoringNamedGetter(cx, proxy, id, vp, receiver, &ownDesc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id,
|
||||
MutableHandleValue vp, HandleObject receiver,
|
||||
MutableHandle<PropertyDescriptor> ownDesc,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
// Step 4.
|
||||
if (!ownDesc.object()) {
|
||||
// The spec calls this variable "parent", but that word has weird
|
||||
// connotations in SpiderMonkey, so let's go with "proto".
|
||||
RootedObject proto(cx);
|
||||
if (!GetPrototype(cx, proxy, &proto))
|
||||
if (!GetPrototype(cx, obj, &proto))
|
||||
return false;
|
||||
if (proto)
|
||||
return SetProperty(cx, proto, receiver, id, vp, result);
|
||||
@ -149,52 +160,6 @@ BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
bool
|
||||
js::SetPropertyIgnoringNamedGetter(JSContext *cx, const BaseProxyHandler *handler,
|
||||
HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandle<PropertyDescriptor> desc,
|
||||
bool descIsOwn, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
/* The control-flow here differs from ::get() because of the fall-through case below. */
|
||||
MOZ_ASSERT_IF(descIsOwn, desc.object());
|
||||
if (desc.object()) {
|
||||
MOZ_ASSERT(desc.getter() != JS_PropertyStub);
|
||||
MOZ_ASSERT(desc.setter() != JS_StrictPropertyStub);
|
||||
|
||||
// Check for read-only properties.
|
||||
if (desc.isReadonly())
|
||||
return result.fail(descIsOwn ? JSMSG_READ_ONLY : JSMSG_CANT_REDEFINE_PROP);
|
||||
|
||||
if (desc.hasSetterObject() || desc.setter()) {
|
||||
if (!CallSetter(cx, receiver, id, desc.setter(), desc.attributes(), vp, result))
|
||||
return false;
|
||||
if (!result)
|
||||
return true;
|
||||
if (!proxy->is<ProxyObject>() ||
|
||||
proxy->as<ProxyObject>().handler() != handler ||
|
||||
desc.isShared())
|
||||
{
|
||||
return result.succeed();
|
||||
}
|
||||
}
|
||||
desc.value().set(vp.get());
|
||||
|
||||
if (descIsOwn) {
|
||||
MOZ_ASSERT(desc.object() == proxy);
|
||||
return handler->defineProperty(cx, proxy, id, desc, result);
|
||||
}
|
||||
return DefineProperty(cx, receiver, id, desc.value(), desc.getter(), desc.setter(),
|
||||
desc.attributes(), result);
|
||||
}
|
||||
desc.object().set(receiver);
|
||||
desc.value().set(vp.get());
|
||||
desc.setAttributes(JSPROP_ENUMERATE);
|
||||
desc.setGetter(nullptr);
|
||||
desc.setSetter(nullptr); // Pick up the class getter/setter.
|
||||
return DefineProperty(cx, receiver, id, desc.value(), nullptr, nullptr, JSPROP_ENUMERATE,
|
||||
result);
|
||||
}
|
||||
|
||||
bool
|
||||
BaseProxyHandler::getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy,
|
||||
AutoIdVector &props) const
|
||||
|
@ -332,6 +332,12 @@ ScriptedIndirectProxyHandler::derivedSet(JSContext *cx, HandleObject proxy, Hand
|
||||
// Find an own or inherited property. The code here is strange for maximum
|
||||
// backward compatibility with earlier code written before ES6 and before
|
||||
// SetPropertyIgnoringNamedGetter.
|
||||
//
|
||||
// As of March 2015, testing/specialpowers/content/specialpowersAPI.js
|
||||
// depends on the call to getPropertyDescriptor below, because it does
|
||||
// support inherited setters but makes no attempt to provide a meaningful
|
||||
// prototype chain.
|
||||
|
||||
Rooted<PropertyDescriptor> desc(cx);
|
||||
if (!getOwnPropertyDescriptor(cx, proxy, id, &desc))
|
||||
return false;
|
||||
@ -341,7 +347,42 @@ ScriptedIndirectProxyHandler::derivedSet(JSContext *cx, HandleObject proxy, Hand
|
||||
return false;
|
||||
}
|
||||
|
||||
return SetPropertyIgnoringNamedGetter(cx, this, proxy, receiver, id, &desc, descIsOwn, vp,
|
||||
MOZ_ASSERT_IF(descIsOwn, desc.object());
|
||||
if (desc.object()) {
|
||||
MOZ_ASSERT(desc.getter() != JS_PropertyStub);
|
||||
MOZ_ASSERT(desc.setter() != JS_StrictPropertyStub);
|
||||
|
||||
// Check for read-only properties.
|
||||
if (desc.isReadonly())
|
||||
return result.fail(descIsOwn ? JSMSG_READ_ONLY : JSMSG_CANT_REDEFINE_PROP);
|
||||
|
||||
if (desc.hasSetterObject() || desc.setter()) {
|
||||
if (!CallSetter(cx, receiver, id, desc.setter(), desc.attributes(), vp, result))
|
||||
return false;
|
||||
if (!result)
|
||||
return true;
|
||||
if (!proxy->is<ProxyObject>() ||
|
||||
proxy->as<ProxyObject>().handler() != this ||
|
||||
desc.isShared())
|
||||
{
|
||||
return result.succeed();
|
||||
}
|
||||
}
|
||||
desc.value().set(vp.get());
|
||||
|
||||
if (descIsOwn) {
|
||||
MOZ_ASSERT(desc.object() == proxy);
|
||||
return this->defineProperty(cx, proxy, id, &desc, result);
|
||||
}
|
||||
return DefineProperty(cx, receiver, id, desc.value(), desc.getter(), desc.setter(),
|
||||
desc.attributes(), result);
|
||||
}
|
||||
desc.object().set(receiver);
|
||||
desc.value().set(vp.get());
|
||||
desc.setAttributes(JSPROP_ENUMERATE);
|
||||
desc.setGetter(nullptr);
|
||||
desc.setSetter(nullptr); // Pick up the class getter/setter.
|
||||
return DefineProperty(cx, receiver, id, desc.value(), nullptr, nullptr, JSPROP_ENUMERATE,
|
||||
result);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user