Bug 1043690, part 1 - Provide helper function for HTMLDocument and HTMLFormElement proxies to use from [[Set]]. r=efaust

This commit is contained in:
Jason Orendorff
2014-07-29 20:27:18 -05:00
parent fda79eb5fe
commit 52b304e825
4 changed files with 151 additions and 8 deletions

View File

@@ -162,11 +162,32 @@ BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
{
assertEnteredPolicy(cx, proxy, id, SET);
// Find an own or inherited property. The code here is strange for maximum
// backward compatibility with earlier code written before ES6 and before
// SetPropertyIgnoringNamedGetter.
Rooted<PropertyDescriptor> desc(cx);
if (!getOwnPropertyDescriptor(cx, proxy, id, &desc))
return false;
bool descIsOwn = desc.object() != nullptr;
if (!descIsOwn) {
if (!getPropertyDescriptor(cx, proxy, id, &desc))
return false;
}
return SetPropertyIgnoringNamedGetter(cx, this, proxy, receiver, id, &desc, descIsOwn, strict,
vp);
}
bool
js::SetPropertyIgnoringNamedGetter(JSContext *cx, const BaseProxyHandler *handler,
HandleObject proxy, HandleObject receiver,
HandleId id, MutableHandle<PropertyDescriptor> desc,
bool descIsOwn, bool strict, MutableHandleValue vp)
{
/* The control-flow here differs from ::get() because of the fall-through case below. */
if (desc.object()) {
if (descIsOwn) {
JS_ASSERT(desc.object());
// Check for read-only properties.
if (desc.isReadonly())
return strict ? Throw(cx, id, JSMSG_READ_ONLY) : true;
@@ -178,7 +199,7 @@ BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
} else if (desc.hasSetterObject() || desc.setter() != JS_StrictPropertyStub) {
if (!CallSetter(cx, receiver, id, desc.setter(), desc.attributes(), strict, vp))
return false;
if (!proxy->is<ProxyObject>() || proxy->as<ProxyObject>().handler() != this)
if (!proxy->is<ProxyObject>() || proxy->as<ProxyObject>().handler() != handler)
return true;
if (desc.isShared())
return true;
@@ -189,10 +210,8 @@ BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
desc.setGetter(JS_PropertyStub);
}
desc.value().set(vp.get());
return defineProperty(cx, receiver, id, &desc);
return handler->defineProperty(cx, receiver, id, desc);
}
if (!getPropertyDescriptor(cx, proxy, id, &desc))
return false;
if (desc.object()) {
// Check for read-only properties.
if (desc.isReadonly())
@@ -205,7 +224,7 @@ BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
} else if (desc.hasSetterObject() || desc.setter() != JS_StrictPropertyStub) {
if (!CallSetter(cx, receiver, id, desc.setter(), desc.attributes(), strict, vp))
return false;
if (!proxy->is<ProxyObject>() || proxy->as<ProxyObject>().handler() != this)
if (!proxy->is<ProxyObject>() || proxy->as<ProxyObject>().handler() != handler)
return true;
if (desc.isShared())
return true;
@@ -216,7 +235,7 @@ BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
desc.setGetter(JS_PropertyStub);
}
desc.value().set(vp.get());
return defineProperty(cx, receiver, id, &desc);
return handler->defineProperty(cx, receiver, id, desc);
}
desc.object().set(receiver);
@@ -224,7 +243,7 @@ BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
desc.setAttributes(JSPROP_ENUMERATE);
desc.setGetter(nullptr);
desc.setSetter(nullptr); // Pick up the class getter/setter.
return defineProperty(cx, receiver, id, &desc);
return handler->defineProperty(cx, receiver, id, desc);
}
bool