Bug 890729 - Implement the missing CPOW traps. r=dvander

This commit is contained in:
Tom Schuster 2013-07-09 22:45:08 -04:00
parent 8713e6bb02
commit ea3f2fa14f
8 changed files with 176 additions and 81 deletions

View File

@ -251,7 +251,6 @@ JavaScriptChild::AnswerSet(const ObjectId &objId, const ObjectId &receiverId,
MOZ_ASSERT(obj == receiver);
RootedValue val(cx);
if (!toValue(cx, value, &val))
return fail(cx, rs);
@ -364,6 +363,7 @@ JavaScriptChild::AnswerCall(const ObjectId &objId,
return ok(rs);
}
bool
JavaScriptChild::AnswerInstanceOf(const ObjectId &objId,
const JSIID &iid,
@ -471,9 +471,39 @@ JavaScriptChild::AnswerGetOwnPropertyDescriptor(const ObjectId &objId,
}
bool
JavaScriptChild::AnswerGetOwnPropertyNames(const ObjectId &objId,
ReturnStatus *rs,
nsTArray<nsString> *names)
JavaScriptChild::AnswerDefineProperty(const ObjectId &objId, const nsString &id,
const PPropertyDescriptor &descriptor, ReturnStatus *rs)
{
AutoSafeJSContext cx;
JSAutoRequest request(cx);
RootedObject obj(cx, findObject(objId));
if (!obj)
return false;
JSAutoCompartment comp(cx, obj);
RootedId internedId(cx);
if (!convertGeckoStringToId(cx, id, &internedId))
return fail(cx, rs);
JSPropertyDescriptor desc;
if (!toDescriptor(cx, descriptor, &desc))
return false;
RootedValue v(cx, desc.value);
if (!js::CheckDefineProperty(cx, obj, internedId, v, desc.getter, desc.setter, desc.attrs) ||
!JS_DefinePropertyById(cx, obj, internedId, v, desc.getter, desc.setter, desc.attrs))
{
return fail(cx, rs);
}
return ok(rs);
}
bool
JavaScriptChild::AnswerGetPropertyNames(const ObjectId &objId, const uint32_t &flags,
ReturnStatus *rs, nsTArray<nsString> *names)
{
AutoSafeJSContext cx;
JSAutoRequest request(cx);
@ -485,7 +515,7 @@ JavaScriptChild::AnswerGetOwnPropertyNames(const ObjectId &objId,
JSAutoCompartment comp(cx, obj);
AutoIdVector props(cx);
if (!js::GetPropertyNames(cx, obj, JSITER_OWNONLY | JSITER_HIDDEN, &props))
if (!js::GetPropertyNames(cx, obj, flags, &props))
return fail(cx, rs);
for (size_t i = 0; i < props.length(); i++) {
@ -603,3 +633,33 @@ JavaScriptChild::AnswerPreventExtensions(const ObjectId &objId,
return ok(rs);
}
bool
JavaScriptChild::AnswerDelete(const ObjectId &objId, const nsString &id,
ReturnStatus *rs, bool *success)
{
AutoSafeJSContext cx;
JSAutoRequest request(cx);
JSObject *obj = findObject(objId);
if (!obj)
return false;
JSAutoCompartment comp(cx, obj);
RootedId internedId(cx);
if (!convertGeckoStringToId(cx, id, &internedId))
return fail(cx, rs);
RootedValue v(cx);
if (!JS_DeletePropertyById2(cx, obj, internedId, v.address()))
return fail(cx, rs);
JSBool b;
if (!JS_ValueToBoolean(cx, v, &b))
return fail(cx, rs);
*success = !!b;
return ok(rs);
}

View File

@ -58,9 +58,14 @@ class JavaScriptChild
const uint32_t &flags,
ReturnStatus *rs,
PPropertyDescriptor *out);
bool AnswerGetOwnPropertyNames(const ObjectId &objId,
ReturnStatus *rs,
nsTArray<nsString> *names);
bool AnswerDefineProperty(const ObjectId &objId,
const nsString &id,
const PPropertyDescriptor &flags,
ReturnStatus *rs);
bool AnswerGetPropertyNames(const ObjectId &objId,
const uint32_t &flags,
ReturnStatus *rs,
nsTArray<nsString> *names);
bool AnswerKeys(const ObjectId &objId,
ReturnStatus *rs,
nsTArray<nsString> *names);
@ -74,6 +79,8 @@ class JavaScriptChild
bool *result);
bool AnswerPreventExtensions(const ObjectId &objId,
ReturnStatus *rs);
bool AnswerDelete(const ObjectId &objId, const nsString &id,
ReturnStatus *rs, bool *success);
protected:
JSObject *unwrap(JSContext *cx, ObjectId id);

View File

@ -78,8 +78,6 @@ class CPOWProxyHandler : public BaseProxyHandler
virtual bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
JS::HandleId id, bool strict, JS::MutableHandleValue vp) MOZ_OVERRIDE;
virtual bool keys(JSContext *cx, HandleObject proxy, AutoIdVector &props) MOZ_OVERRIDE;
virtual bool iterate(JSContext *cx, HandleObject proxy, unsigned flags,
MutableHandleValue vp) MOZ_OVERRIDE;
virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
virtual void finalize(JSFreeOp *fop, JSObject *proxy) MOZ_OVERRIDE;
@ -151,7 +149,28 @@ bool
CPOWProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
PropertyDescriptor *desc)
{
MOZ_CRASH("unimplemented");
return ParentOf(proxy)->defineProperty(cx, proxy, id, desc);
}
bool
JavaScriptParent::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
PropertyDescriptor *desc)
{
ObjectId objId = idOf(proxy);
nsString idstr;
if (!convertIdToGeckoString(cx, id, &idstr))
return false;
PPropertyDescriptor descriptor;
if (!fromDescriptor(cx, *desc, &descriptor))
return false;
ReturnStatus status;
if (!CallDefineProperty(objId, idstr, descriptor, &status))
return ipcfail(cx);
return ok(cx, status);
}
bool
@ -163,24 +182,7 @@ CPOWProxyHandler::getOwnPropertyNames(JSContext *cx, HandleObject proxy, AutoIdV
bool
JavaScriptParent::getOwnPropertyNames(JSContext *cx, HandleObject proxy, AutoIdVector &props)
{
ObjectId objId = idOf(proxy);
ReturnStatus status;
InfallibleTArray<nsString> names;
if (!CallGetOwnPropertyNames(objId, &status, &names))
return ipcfail(cx);
if (!ok(cx, status))
return false;
RootedId name(cx);
for (size_t i = 0; i < names.Length(); i++) {
if (!convertGeckoStringToId(cx, names[i], &name))
return false;
if (!props.append(name))
return false;
}
return true;
return getPropertyNames(cx, proxy, JSITER_OWNONLY | JSITER_HIDDEN, props);
}
bool
@ -192,36 +194,41 @@ CPOWProxyHandler::keys(JSContext *cx, HandleObject proxy, AutoIdVector &props)
bool
JavaScriptParent::keys(JSContext *cx, HandleObject proxy, AutoIdVector &props)
{
ObjectId objId = idOf(proxy);
ReturnStatus status;
InfallibleTArray<nsString> names;
if (!CallKeys(objId, &status, &names))
return ipcfail(cx);
if (!ok(cx, status))
return false;
RootedId name(cx);
for (size_t i = 0; i < names.Length(); i++) {
if (!convertGeckoStringToId(cx, names[i], &name))
return false;
if (!props.append(name))
return false;
}
return true;
}
bool
CPOWProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
{
MOZ_CRASH("unimplemented");
return getPropertyNames(cx, proxy, JSITER_OWNONLY, props);
}
bool
CPOWProxyHandler::enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props)
{
MOZ_CRASH("unimplemented");
return ParentOf(proxy)->enumerate(cx, proxy, props);
}
bool
JavaScriptParent::enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props)
{
return getPropertyNames(cx, proxy, 0, props);
}
bool
CPOWProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
{
return ParentOf(proxy)->delete_(cx, proxy, id, bp);
}
bool
JavaScriptParent::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
{
ObjectId objId = idOf(proxy);
nsString idstr;
if (!convertIdToGeckoString(cx, id, &idstr))
return false;
ReturnStatus status;
if (!CallDelete(objId, idstr, &status, bp))
return ipcfail(cx);
return ok(cx, status);
}
bool
@ -366,13 +373,6 @@ JavaScriptParent::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject re
return toValue(cx, result, vp);
}
bool
CPOWProxyHandler::iterate(JSContext *cx, HandleObject proxy, unsigned flags,
MutableHandleValue vp)
{
MOZ_CRASH("unimplemented");
}
bool
CPOWProxyHandler::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
{
@ -525,6 +525,29 @@ JavaScriptParent::makeId(JSContext *cx, JSObject *obj, ObjectId *idp)
return true;
}
bool
JavaScriptParent::getPropertyNames(JSContext *cx, HandleObject proxy, uint32_t flags, AutoIdVector &props)
{
ObjectId objId = idOf(proxy);
ReturnStatus status;
InfallibleTArray<nsString> names;
if (!CallGetPropertyNames(objId, flags, &status, &names))
return ipcfail(cx);
if (!ok(cx, status))
return false;
for (size_t i = 0; i < names.Length(); i++) {
RootedId name(cx);
if (!convertGeckoStringToId(cx, names[i], &name))
return false;
if (!props.append(name))
return false;
}
return true;
}
JSObject *
JavaScriptParent::unwrap(JSContext *cx, ObjectId objId)
{

View File

@ -41,8 +41,12 @@ class JavaScriptParent
JSPropertyDescriptor *desc, unsigned flags);
bool getOwnPropertyDescriptor(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
JSPropertyDescriptor *desc, unsigned flags);
bool defineProperty(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
JSPropertyDescriptor *desc);
bool getOwnPropertyNames(JSContext *cx, JS::HandleObject proxy, js::AutoIdVector &props);
bool keys(JSContext *cx, JS::HandleObject proxy, js::AutoIdVector &props);
bool enumerate(JSContext *cx, JS::HandleObject proxy, js::AutoIdVector &props);
bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
bool objectClassIs(JSContext *cx, JS::HandleObject obj, js::ESClassValue classValue);
const char* className(JSContext *cx, JS::HandleObject proxy);
bool preventExtensions(JSContext *cx, JS::HandleObject proxy);
@ -64,6 +68,7 @@ class JavaScriptParent
private:
bool makeId(JSContext *cx, JSObject *obj, ObjectId *idp);
bool getPropertyNames(JSContext *cx, JS::HandleObject proxy, uint32_t flags, js::AutoIdVector &props);
ObjectId idOf(JSObject *obj);
// Catastrophic IPC failure.

View File

@ -32,12 +32,13 @@ child:
urgent InstanceOf(uint64_t objId, JSIID iid) returns (ReturnStatus rs, bool instanceof);
urgent GetPropertyDescriptor(uint64_t objId, nsString id, uint32_t flags) returns (ReturnStatus rs, PPropertyDescriptor result);
urgent GetOwnPropertyDescriptor(uint64_t objId, nsString id, uint32_t flags) returns (ReturnStatus rs, PPropertyDescriptor result);
urgent GetOwnPropertyNames(uint64_t objId) returns (ReturnStatus rs, nsString[] names);
urgent Keys(uint64_t objId) returns (ReturnStatus rs, nsString[] names);
urgent DefineProperty(uint64_t objId, nsString id, PPropertyDescriptor descriptor) returns (ReturnStatus rs);
urgent GetPropertyNames(uint64_t objId, uint32_t flags) returns (ReturnStatus rs, nsString[] names);
urgent ObjectClassIs(uint64_t objId, uint32_t classValue) returns (bool result);
urgent ClassName(uint64_t objId) returns (nsString name);
urgent IsExtensible(uint64_t objId) returns (ReturnStatus rs, bool result);
urgent PreventExtensions(uint64_t objId) returns (ReturnStatus rs);
urgent Delete(uint64_t objId, nsString id) returns (ReturnStatus rs, bool successful);
parent:
async __delete__();

View File

@ -1758,6 +1758,22 @@ GetObjectMetadata(JSObject *obj);
extern JS_FRIEND_API(JSBool)
DefaultValue(JSContext *cx, JS::HandleObject obj, JSType hint, MutableHandleValue vp);
/*
* Helper function. To approximate a call to the [[DefineOwnProperty]] internal
* method described in ES5, first call this, then call JS_DefinePropertyById.
*
* JS_DefinePropertyById by itself does not enforce the invariants on
* non-configurable properties when obj->isNative(). This function performs the
* relevant checks (specified in ES5 8.12.9 [[DefineOwnProperty]] steps 1-11),
* but only if obj is native.
*
* The reason for the messiness here is that ES5 uses [[DefineOwnProperty]] as
* a sort of extension point, but there is no hook in js::Class,
* js::ProxyHandler, or the JSAPI with precisely the right semantics for it.
*/
extern JS_FRIEND_API(bool)
CheckDefineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value,
PropertyOp getter, StrictPropertyOp setter, unsigned attrs);
} /* namespace js */

View File

@ -553,7 +553,7 @@ Reject(JSContext *cx, HandleId id, unsigned errorNumber, bool throwError, bool *
//
// DefinePropertyOnObject has its own implementation of these checks.
//
bool
JS_FRIEND_API(bool)
js::CheckDefineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value,
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
{

View File

@ -1553,23 +1553,6 @@ Throw(JSContext *cx, jsid id, unsigned errorNumber);
extern bool
Throw(JSContext *cx, JSObject *obj, unsigned errorNumber);
/*
* Helper function. To approximate a call to the [[DefineOwnProperty]] internal
* method described in ES5, first call this, then call JS_DefinePropertyById.
*
* JS_DefinePropertyById by itself does not enforce the invariants on
* non-configurable properties when obj->isNative(). This function performs the
* relevant checks (specified in ES5 8.12.9 [[DefineOwnProperty]] steps 1-11),
* but only if obj is native.
*
* The reason for the messiness here is that ES5 uses [[DefineOwnProperty]] as
* a sort of extension point, but there is no hook in js::Class,
* js::ProxyHandler, or the JSAPI with precisely the right semantics for it.
*/
extern bool
CheckDefineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value,
PropertyOp getter, StrictPropertyOp setter, unsigned attrs);
} /* namespace js */
#endif /* jsobj_h */