Bug 890729 - Reorder the CPOW traps. r=dvander
authorTom Schuster <evilpies@gmail.com>
Thu, 11 Jul 2013 11:23:34 -0400
changeset 150463 3d3141bc359878dcb273cda502e4bbef2c9063e7
parent 150462 df7f5e54f08743e2ad5ae539397ada395db86c23
child 150464 121171dddc5b534c48429131ade5c5dff3324b0e
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander
bugs890729
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 890729 - Reorder the CPOW traps. r=dvander
js/ipc/JavaScriptChild.cpp
js/ipc/JavaScriptChild.h
js/ipc/JavaScriptParent.cpp
js/ipc/JavaScriptParent.h
js/ipc/PJavaScript.ipdl
--- a/js/ipc/JavaScriptChild.cpp
+++ b/js/ipc/JavaScriptChild.cpp
@@ -135,18 +135,171 @@ JavaScriptChild::fail(JSContext *cx, Ret
 bool
 JavaScriptChild::ok(ReturnStatus *rs)
 {
     *rs = ReturnStatus(true, JSVariant(void_t()));
     return true;
 }
 
 bool
-JavaScriptChild::AnswerHas(const ObjectId &objId, const nsString &id,
-                               ReturnStatus *rs, bool *bp)
+JavaScriptChild::AnswerPreventExtensions(const ObjectId &objId, ReturnStatus *rs)
+{
+    AutoSafeJSContext cx;
+    JSAutoRequest request(cx);
+
+    RootedObject obj(cx, findObject(objId));
+    if (!obj)
+        return false;
+
+    JSAutoCompartment comp(cx, obj);
+    if (!JS_PreventExtensions(cx, obj))
+        return fail(cx, rs);
+
+    return ok(rs);
+}
+
+static void
+EmptyDesc(PPropertyDescriptor *desc)
+{
+    desc->objId() = 0;
+    desc->attrs() = 0;
+    desc->shortid() = 0;
+    desc->value() = void_t();
+    desc->getter() = 0;
+    desc->setter() = 0;
+}
+
+bool
+JavaScriptChild::AnswerGetPropertyDescriptor(const ObjectId &objId, const nsString &id,
+                                             const uint32_t &flags, ReturnStatus *rs,
+                                             PPropertyDescriptor *out)
+{
+    AutoSafeJSContext cx;
+    JSAutoRequest request(cx);
+
+    EmptyDesc(out);
+
+    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 (!JS_GetPropertyDescriptorById(cx, obj, internedId, flags, &desc))
+        return fail(cx, rs);
+
+    if (!desc.obj)
+        return ok(rs);
+
+    if (!fromDescriptor(cx, desc, out))
+        return fail(cx, rs);
+
+    return ok(rs);
+}
+
+bool
+JavaScriptChild::AnswerGetOwnPropertyDescriptor(const ObjectId &objId, const nsString &id,
+                                                const uint32_t &flags, ReturnStatus *rs,
+                                                PPropertyDescriptor *out)
+{
+    AutoSafeJSContext cx;
+    JSAutoRequest request(cx);
+
+    EmptyDesc(out);
+
+    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 (!JS_GetPropertyDescriptorById(cx, obj, internedId, flags, &desc))
+        return fail(cx, rs);
+
+    if (desc.obj != obj)
+        return ok(rs);
+
+    if (!fromDescriptor(cx, desc, out))
+        return fail(cx, rs);
+
+    return ok(rs);
+}
+
+bool
+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::AnswerDelete(const ObjectId &objId, const nsString &id, ReturnStatus *rs,
+                              bool *success)
+{
+    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);
+
+    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);
+}
+
+bool
+JavaScriptChild::AnswerHas(const ObjectId &objId, const nsString &id, ReturnStatus *rs, bool *bp)
 {
     AutoSafeJSContext cx;
     JSAutoRequest request(cx);
 
     RootedObject obj(cx, findObject(objId));
     if (!obj)
         return false;
 
@@ -160,18 +313,17 @@ JavaScriptChild::AnswerHas(const ObjectI
     if (!JS_HasPropertyById(cx, obj, internedId, &found))
         return fail(cx, rs);
     *bp = !!found;
 
     return ok(rs);
 }
 
 bool
-JavaScriptChild::AnswerHasOwn(const ObjectId &objId, const nsString &id,
-                                  ReturnStatus *rs, bool *bp)
+JavaScriptChild::AnswerHasOwn(const ObjectId &objId, const nsString &id, ReturnStatus *rs, bool *bp)
 {
     AutoSafeJSContext cx;
     JSAutoRequest request(cx);
 
     RootedObject obj(cx, findObject(objId));
     if (!obj)
         return false;
 
@@ -185,23 +337,24 @@ JavaScriptChild::AnswerHasOwn(const Obje
     if (!JS_GetPropertyDescriptorById(cx, obj, internedId, 0, &desc))
         return fail(cx, rs);
     *bp = (desc.obj == obj);
 
     return ok(rs);
 }
 
 bool
-JavaScriptChild::AnswerGet(const ObjectId &objId, const ObjectId &receiverId,
-                               const nsString &id,
-                               ReturnStatus *rs, JSVariant *result)
+JavaScriptChild::AnswerGet(const ObjectId &objId, const ObjectId &receiverId, const nsString &id,
+                           ReturnStatus *rs, JSVariant *result)
 {
     AutoSafeJSContext cx;
     JSAutoRequest request(cx);
 
+    *result = void_t();
+
     RootedObject obj(cx, findObject(objId));
     if (!obj)
         return false;
 
     RootedObject receiver(cx, findObject(receiverId));
     if (!receiver)
         return false;
 
@@ -217,20 +370,19 @@ JavaScriptChild::AnswerGet(const ObjectI
 
     if (!toVariant(cx, val, result))
         return fail(cx, rs);
 
     return ok(rs);
 }
 
 bool
-JavaScriptChild::AnswerSet(const ObjectId &objId, const ObjectId &receiverId,
-                               const nsString &id, const bool &strict,
-                               const JSVariant &value,
-                               ReturnStatus *rs, JSVariant *result)
+JavaScriptChild::AnswerSet(const ObjectId &objId, const ObjectId &receiverId, const nsString &id,
+                           const bool &strict, const JSVariant &value, ReturnStatus *rs,
+                           JSVariant *result)
 {
     AutoSafeJSContext cx;
     JSAutoRequest request(cx);
 
     // The outparam will be written to the buffer, so it must be set even if
     // the parent won't read it.
     *result = void_t();
 
@@ -259,21 +411,38 @@ JavaScriptChild::AnswerSet(const ObjectI
 
     if (!toVariant(cx, val, result))
         return fail(cx, rs);
 
     return ok(rs);
 }
 
 bool
-JavaScriptChild::AnswerCall(const ObjectId &objId,
-                            const nsTArray<JSParam> &argv,
-                            ReturnStatus *rs,
-                            JSVariant *result,
-                            nsTArray<JSParam> *outparams)
+JavaScriptChild::AnswerIsExtensible(const ObjectId &objId, ReturnStatus *rs, bool *result)
+{
+    AutoSafeJSContext cx;
+    JSAutoRequest request(cx);
+
+    *result = false;
+
+    RootedObject obj(cx, findObject(objId));
+    if (!obj)
+        return false;
+
+    JSBool extensible;
+    if (!JS_IsExtensible(cx, obj, &extensible))
+        return fail(cx, rs);
+
+    *result = !!extensible;
+    return true;
+}
+
+bool
+JavaScriptChild::AnswerCall(const ObjectId &objId, const nsTArray<JSParam> &argv, ReturnStatus *rs,
+                            JSVariant *result, nsTArray<JSParam> *outparams)
 {
     AutoSafeJSContext cx;
     JSAutoRequest request(cx);
 
     // The outparam will be written to the buffer, so it must be set even if
     // the parent won't read it.
     *result = void_t();
 
@@ -286,18 +455,18 @@ JavaScriptChild::AnswerCall(const Object
     RootedValue objv(cx);
     if (!toValue(cx, argv[0], &objv))
         return fail(cx, rs);
 
     JSAutoCompartment comp(cx, &objv.toObject());
 
     *result = JSVariant(void_t());
 
-    JS::AutoValueVector vals(cx);
-    JS::AutoValueVector outobjects(cx);
+    AutoValueVector vals(cx);
+    AutoValueVector outobjects(cx);
     for (size_t i = 0; i < argv.Length(); i++) {
         if (argv[i].type() == JSParam::Tvoid_t) {
             // This is an outparam.
             JSCompartment *compartment = js::GetContextCompartment(cx);
             RootedObject global(cx, JS_GetGlobalForCompartmentOrNull(cx, compartment));
             RootedObject obj(cx, xpc::NewOutObject(cx, global));
             if (!obj)
                 return fail(cx, rs);
@@ -358,152 +527,48 @@ JavaScriptChild::AnswerCall(const Object
         if (!toVariant(cx, vals[i], &variant))
             return fail(cx, rs);
         outparams->ReplaceElementAt(i, JSParam(variant));
     }
 
     return ok(rs);
 }
 
-
 bool
-JavaScriptChild::AnswerInstanceOf(const ObjectId &objId,
-                                  const JSIID &iid,
-                                  ReturnStatus *rs,
-                                  bool *instanceof)
-{
-    AutoSafeJSContext cx;
-    JSAutoRequest request(cx);
-
-    RootedObject obj(cx, findObject(objId));
-    if (!obj)
-        return false;
-
-    JSAutoCompartment comp(cx, obj);
-
-    nsID nsiid;
-    ConvertID(iid, &nsiid);
-
-    nsresult rv = xpc::HasInstance(cx, obj, &nsiid, instanceof);
-    if (rv != NS_OK)
-        return fail(cx, rs);
-
-    return ok(rs);
-}
-
-void
-EmptyDesc(PPropertyDescriptor *desc)
-{
-    desc->objId() = 0;
-    desc->attrs() = 0;
-    desc->shortid() = 0;
-    desc->value() = void_t();
-    desc->getter() = 0;
-    desc->setter() = 0;
-}
-
-bool
-JavaScriptChild::AnswerGetPropertyDescriptor(const ObjectId &objId,
-                                             const nsString &id,
-                                             const uint32_t &flags,
-                                             ReturnStatus *rs,
-                                             PPropertyDescriptor *out)
+JavaScriptChild::AnswerObjectClassIs(const ObjectId &objId, const uint32_t &classValue,
+                                     bool *result)
 {
     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 (!JS_GetPropertyDescriptorById(cx, obj, internedId, flags, &desc))
-        return fail(cx, rs);
+    *result = js_ObjectClassIs(cx, obj, (js::ESClassValue)classValue);
 
-    if (!desc.obj) {
-        EmptyDesc(out);
-        return ok(rs);
-    }
-
-    if (!fromDescriptor(cx, desc, out))
-        return fail(cx, rs);
-
-    return ok(rs);
+    return true;
 }
 
 bool
-JavaScriptChild::AnswerGetOwnPropertyDescriptor(const ObjectId &objId,
-                                                const nsString &id,
-                                                const uint32_t &flags,
-                                                ReturnStatus *rs,
-                                                PPropertyDescriptor *out)
+JavaScriptChild::AnswerClassName(const ObjectId &objId, nsString *name)
 {
     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 (!JS_GetPropertyDescriptorById(cx, obj, internedId, flags, &desc))
-        return fail(cx, rs);
-
-    if (desc.obj != obj) {
-        EmptyDesc(out);
-        return ok(rs);
-    }
-
-    if (!fromDescriptor(cx, desc, out))
-        return fail(cx, rs);
-
-    return ok(rs);
-}
-
-bool
-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);
+    *name = NS_ConvertASCIItoUTF16(js_ObjectClassName(cx, obj));
+    return true;
 }
 
 bool
 JavaScriptChild::AnswerGetPropertyNames(const ObjectId &objId, const uint32_t &flags,
                                         ReturnStatus *rs, nsTArray<nsString> *names)
 {
     AutoSafeJSContext cx;
     JSAutoRequest request(cx);
@@ -525,141 +590,29 @@ JavaScriptChild::AnswerGetPropertyNames(
 
         names->AppendElement(name);
     }
 
     return ok(rs);
 }
 
 bool
-JavaScriptChild::AnswerKeys(const ObjectId &objId,
-                            ReturnStatus *rs,
-                            nsTArray<nsString> *names)
-{
-    AutoSafeJSContext cx;
-    JSAutoRequest request(cx);
-
-    RootedObject obj(cx, findObject(objId));
-    if (!obj)
-        return false;
-
-    JSAutoCompartment comp(cx, obj);
-
-    AutoIdVector props(cx);
-    if (!js::GetPropertyNames(cx, obj, JSITER_OWNONLY, &props))
-        return fail(cx, rs);
-
-    for (size_t i = 0; i < props.length(); i++) {
-        nsString name;
-        if (!convertIdToGeckoString(cx, props.handleAt(i), &name))
-            return false;
-
-        names->AppendElement(name);
-    }
-
-    return ok(rs);
-}
-
-bool
-JavaScriptChild::AnswerObjectClassIs(const ObjectId &objId,
-                                     const uint32_t &classValue,
-                                     bool *result)
-{
-    AutoSafeJSContext cx;
-    JSAutoRequest request(cx);
-
-    RootedObject obj(cx, findObject(objId));
-    if (!obj)
-        return false;
-
-    JSAutoCompartment comp(cx, obj);
-
-    *result = js_ObjectClassIs(cx, obj, (js::ESClassValue)classValue);
-
-    return true;
-}
-
-bool
-JavaScriptChild::AnswerClassName(const ObjectId &objId,
-                                 nsString *name)
+JavaScriptChild::AnswerInstanceOf(const ObjectId &objId, const JSIID &iid, ReturnStatus *rs,
+                                  bool *instanceof)
 {
     AutoSafeJSContext cx;
     JSAutoRequest request(cx);
 
     RootedObject obj(cx, findObject(objId));
     if (!obj)
         return false;
 
     JSAutoCompartment comp(cx, obj);
 
-    *name = NS_ConvertASCIItoUTF16(js_ObjectClassName(cx, obj));
-    return true;
-}
-
-bool
-JavaScriptChild::AnswerIsExtensible(const ObjectId &objId,
-                                    ReturnStatus *rs,
-                                    bool *result)
-{
-    AutoSafeJSContext cx;
-    JSAutoRequest request(cx);
-
-    *result = false;
-
-    RootedObject obj(cx, findObject(objId));
-    if (!obj)
-        return false;
+    nsID nsiid;
+    ConvertID(iid, &nsiid);
 
-    JSBool extensible;
-    if (!JS_IsExtensible(cx, obj, &extensible))
-        return fail(cx, rs);
-
-    *result = !!extensible;
-    return true;
-}
-
-bool
-JavaScriptChild::AnswerPreventExtensions(const ObjectId &objId,
-                                         ReturnStatus *rs)
-{
-    AutoSafeJSContext cx;
-    JSAutoRequest request(cx);
-
-    RootedObject obj(cx, findObject(objId));
-    if (!obj)
-        return false;
-
-    JSAutoCompartment comp(cx, obj);
-    if (!JS_PreventExtensions(cx, obj))
+    nsresult rv = xpc::HasInstance(cx, obj, &nsiid, instanceof);
+    if (rv != NS_OK)
         return fail(cx, rs);
 
     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);
-}
--- a/js/ipc/JavaScriptChild.h
+++ b/js/ipc/JavaScriptChild.h
@@ -22,70 +22,55 @@ class JavaScriptChild
     JavaScriptChild(JSRuntime *rt);
     ~JavaScriptChild();
 
     bool init();
     void trace(JSTracer *trc);
 
     bool RecvDropObject(const ObjectId &objId);
 
+    bool AnswerPreventExtensions(const ObjectId &objId, ReturnStatus *rs);
+    bool AnswerGetPropertyDescriptor(const ObjectId &objId, const nsString &id,
+                                     const uint32_t &flags, ReturnStatus *rs,
+                                     PPropertyDescriptor *out);
+    bool AnswerGetOwnPropertyDescriptor(const ObjectId &objId,
+                                        const nsString &id,
+                                        const uint32_t &flags,
+                                        ReturnStatus *rs,
+                                        PPropertyDescriptor *out);
+    bool AnswerDefineProperty(const ObjectId &objId, const nsString &id,
+                              const PPropertyDescriptor &flags,
+                              ReturnStatus *rs);
+    bool AnswerDelete(const ObjectId &objId, const nsString &id,
+                      ReturnStatus *rs, bool *success);
+
     bool AnswerHas(const ObjectId &objId, const nsString &id,
                        ReturnStatus *rs, bool *bp);
     bool AnswerHasOwn(const ObjectId &objId, const nsString &id,
                           ReturnStatus *rs, bool *bp);
     bool AnswerGet(const ObjectId &objId, const ObjectId &receiverId,
                        const nsString &id,
                        ReturnStatus *rs, JSVariant *result);
     bool AnswerSet(const ObjectId &objId, const ObjectId &receiverId,
-                       const nsString &id, const bool &strict,
-                       const JSVariant &value,
-                       ReturnStatus *rs, JSVariant *result);
-    bool AnswerCall(const ObjectId &objId,
-                        const nsTArray<JSParam> &argv,
-                        ReturnStatus *rs,
-                        JSVariant *result,
-                        nsTArray<JSParam> *outparams);
+                   const nsString &id, const bool &strict,
+                   const JSVariant &value, ReturnStatus *rs, JSVariant *result);
 
-    bool AnswerInstanceOf(const ObjectId &objId,
-                          const JSIID &iid,
-                          ReturnStatus *rs,
-                          bool *instanceof);
-    bool AnswerGetPropertyDescriptor(const ObjectId &objId,
-                                     const nsString &id,
-                                     const uint32_t &flags,
-                                     ReturnStatus *rs,
-                                     PPropertyDescriptor *out);
-    bool AnswerGetOwnPropertyDescriptor(const ObjectId &objId,
-                                        const nsString &id,
-                                        const uint32_t &flags,
-                                        ReturnStatus *rs,
-                                        PPropertyDescriptor *out);
-    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);
-    bool AnswerObjectClassIs(const ObjectId &objId,
-                             const uint32_t &classValue,
+    bool AnswerIsExtensible(const ObjectId &objId, ReturnStatus *rs,
+                            bool *result);
+    bool AnswerCall(const ObjectId &objId, const nsTArray<JSParam> &argv,
+                    ReturnStatus *rs, JSVariant *result,
+                    nsTArray<JSParam> *outparams);
+    bool AnswerObjectClassIs(const ObjectId &objId, const uint32_t &classValue,
                              bool *result);
-    bool AnswerClassName(const ObjectId &objId,
-                             nsString *result);
-    bool AnswerIsExtensible(const ObjectId &objId,
-                            ReturnStatus *rs,
-                            bool *result);
-    bool AnswerPreventExtensions(const ObjectId &objId,
-                                 ReturnStatus *rs);
-    bool AnswerDelete(const ObjectId &objId, const nsString &id,
-                      ReturnStatus *rs, bool *success);
+    bool AnswerClassName(const ObjectId &objId, nsString *result);
+
+    bool AnswerGetPropertyNames(const ObjectId &objId, const uint32_t &flags,
+                                ReturnStatus *rs, nsTArray<nsString> *names);
+    bool AnswerInstanceOf(const ObjectId &objId, const JSIID &iid,
+                          ReturnStatus *rs, bool *instanceof);
 
   protected:
     JSObject *unwrap(JSContext *cx, ObjectId id);
 
   private:
     bool makeId(JSContext *cx, JSObject *obj, ObjectId *idp);
     bool fail(JSContext *cx, ReturnStatus *rs);
     bool ok(ReturnStatus *rs);
--- a/js/ipc/JavaScriptParent.cpp
+++ b/js/ipc/JavaScriptParent.cpp
@@ -55,16 +55,17 @@ class CPOWProxyHandler : public BaseProx
     CPOWProxyHandler()
       : BaseProxyHandler(&sCPOWProxyHandler) {}
     virtual ~CPOWProxyHandler() {}
 
     virtual bool finalizeInBackground(Value priv) MOZ_OVERRIDE {
         return false;
     }
 
+    virtual bool preventExtensions(JSContext *cx, HandleObject proxy) MOZ_OVERRIDE;
     virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                        PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy,
                                           HandleId id, PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
     virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
                                 PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool getOwnPropertyNames(JSContext *cx, HandleObject proxy,
                                      AutoIdVector &props) MOZ_OVERRIDE;
@@ -74,29 +75,46 @@ class CPOWProxyHandler : public BaseProx
     virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) MOZ_OVERRIDE;
     virtual bool hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) MOZ_OVERRIDE;
     virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver,
                      HandleId id, MutableHandleValue vp) MOZ_OVERRIDE;
     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 isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) MOZ_OVERRIDE;
     virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
-    virtual void finalize(JSFreeOp *fop, JSObject *proxy) MOZ_OVERRIDE;
     virtual bool objectClassIs(HandleObject obj, js::ESClassValue classValue, JSContext *cx) MOZ_OVERRIDE;
     virtual const char* className(JSContext *cx, HandleObject proxy) MOZ_OVERRIDE;
-    virtual bool preventExtensions(JSContext *cx, HandleObject proxy) MOZ_OVERRIDE;
-    virtual bool isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) MOZ_OVERRIDE;
+    virtual void finalize(JSFreeOp *fop, JSObject *proxy) MOZ_OVERRIDE;
 
     static CPOWProxyHandler singleton;
 };
 
 CPOWProxyHandler CPOWProxyHandler::singleton;
 
 bool
+CPOWProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy)
+{
+    return ParentOf(proxy)->preventExtensions(cx, proxy);
+}
+
+bool
+JavaScriptParent::preventExtensions(JSContext *cx, HandleObject proxy)
+{
+    ObjectId objId = idOf(proxy);
+
+    ReturnStatus status;
+    if (!CallPreventExtensions(objId, &status))
+        return ipcfail(cx);
+
+    return ok(cx, status);
+}
+
+bool
 CPOWProxyHandler::getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                         PropertyDescriptor *desc, unsigned flags)
 {
     return ParentOf(proxy)->getPropertyDescriptor(cx, proxy, id, desc, flags);
 }
 
 bool
 JavaScriptParent::getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
@@ -181,40 +199,16 @@ CPOWProxyHandler::getOwnPropertyNames(JS
 
 bool
 JavaScriptParent::getOwnPropertyNames(JSContext *cx, HandleObject proxy, AutoIdVector &props)
 {
     return getPropertyNames(cx, proxy, JSITER_OWNONLY | JSITER_HIDDEN, props);
 }
 
 bool
-CPOWProxyHandler::keys(JSContext *cx, HandleObject proxy, AutoIdVector &props)
-{
-    return ParentOf(proxy)->keys(cx, proxy, props);
-}
-
-bool
-JavaScriptParent::keys(JSContext *cx, HandleObject proxy, AutoIdVector &props)
-{
-    return getPropertyNames(cx, proxy, JSITER_OWNONLY, props);
-}
-
-bool
-CPOWProxyHandler::enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props)
-{
-    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)
 {
@@ -227,49 +221,25 @@ JavaScriptParent::delete_(JSContext *cx,
     ReturnStatus status;
     if (!CallDelete(objId, idstr, &status, bp))
         return ipcfail(cx);
 
     return ok(cx, status);
 }
 
 bool
-CPOWProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy)
+CPOWProxyHandler::enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props)
 {
-    return ParentOf(proxy)->preventExtensions(cx, proxy);
+    return ParentOf(proxy)->enumerate(cx, proxy, props);
 }
 
 bool
-JavaScriptParent::preventExtensions(JSContext *cx, HandleObject proxy)
-{
-    ObjectId objId = idOf(proxy);
-
-    ReturnStatus status;
-    if (!CallPreventExtensions(objId, &status))
-        return ipcfail(cx);
-
-    return ok(cx, status);
-}
-
-bool
-CPOWProxyHandler::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible)
+JavaScriptParent::enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props)
 {
-    return ParentOf(proxy)->isExtensible(cx, proxy, extensible);
-}
-
-bool
-JavaScriptParent::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible)
-{
-    ObjectId objId = idOf(proxy);
-
-    ReturnStatus status;
-    if (!CallIsExtensible(objId, &status, extensible))
-        return ipcfail(cx);
-
-    return ok(cx, status);
+    return getPropertyNames(cx, proxy, 0, props);
 }
 
 bool
 CPOWProxyHandler::has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp)
 {
     return ParentOf(proxy)->has(cx, proxy, id, bp);
 }
 
@@ -369,16 +339,46 @@ JavaScriptParent::set(JSContext *cx, JS:
 
     if (!ok(cx, status))
         return false;
 
     return toValue(cx, result, vp);
 }
 
 bool
+CPOWProxyHandler::keys(JSContext *cx, HandleObject proxy, AutoIdVector &props)
+{
+    return ParentOf(proxy)->keys(cx, proxy, props);
+}
+
+bool
+JavaScriptParent::keys(JSContext *cx, HandleObject proxy, AutoIdVector &props)
+{
+    return getPropertyNames(cx, proxy, JSITER_OWNONLY, props);
+}
+
+bool
+CPOWProxyHandler::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible)
+{
+    return ParentOf(proxy)->isExtensible(cx, proxy, extensible);
+}
+
+bool
+JavaScriptParent::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible)
+{
+    ObjectId objId = idOf(proxy);
+
+    ReturnStatus status;
+    if (!CallIsExtensible(objId, &status, extensible))
+        return ipcfail(cx);
+
+    return ok(cx, status);
+}
+
+bool
 CPOWProxyHandler::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
 {
     return ParentOf(proxy)->call(cx, proxy, args);
 }
 
 bool
 JavaScriptParent::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
 {
@@ -441,35 +441,16 @@ JavaScriptParent::call(JSContext *cx, Ha
     }
 
     if (!toValue(cx, result, args.rval()))
         return false;
 
     return true;
 }
 
-void
-CPOWProxyHandler::finalize(JSFreeOp *fop, JSObject *proxy)
-{
-    ParentOf(proxy)->drop(proxy);
-}
-
-void
-JavaScriptParent::drop(JSObject *obj)
-{
-    if (inactive_)
-        return;
-
-    ObjectId objId = idOf(obj);
-
-    objects_.remove(objId);
-    if (!SendDropObject(objId))
-        MOZ_CRASH();
-    decref();
-}
 
 bool
 CPOWProxyHandler::objectClassIs(HandleObject proxy, js::ESClassValue classValue, JSContext *cx)
 {
     return ParentOf(proxy)->objectClassIs(cx, proxy, classValue);
 }
 
 bool
@@ -499,16 +480,36 @@ JavaScriptParent::className(JSContext *c
 
     nsString name;
     if (!CallClassName(objId, &name))
         return NULL;
 
     return ToNewCString(name);
 }
 
+void
+CPOWProxyHandler::finalize(JSFreeOp *fop, JSObject *proxy)
+{
+    ParentOf(proxy)->drop(proxy);
+}
+
+void
+JavaScriptParent::drop(JSObject *obj)
+{
+    if (inactive_)
+        return;
+
+    ObjectId objId = idOf(obj);
+
+    objects_.remove(objId);
+    if (!SendDropObject(objId))
+        MOZ_CRASH();
+    decref();
+}
+
 bool
 JavaScriptParent::init()
 {
     if (!JavaScriptShared::init())
         return false;
 
     return true;
 }
--- a/js/ipc/JavaScriptParent.h
+++ b/js/ipc/JavaScriptParent.h
@@ -25,37 +25,44 @@ class JavaScriptParent
     public JavaScriptShared
 {
   public:
     JavaScriptParent();
 
     bool init();
 
   public:
-    bool has(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
-    bool hasOwn(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
-    bool get(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
-             JS::HandleId id, JS::MutableHandleValue vp);
-    bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
-             JS::HandleId id, bool strict, JS::MutableHandleValue vp);
-    bool call(JSContext *cx, JS::HandleObject proxy, const JS::CallArgs &args);
+    // Fundamental proxy traps. These are required.
+    // (The traps should be in the same order like js/src/jsproxy.h)
+    bool preventExtensions(JSContext *cx, JS::HandleObject proxy);
     bool getPropertyDescriptor(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
                                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 delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
     bool enumerate(JSContext *cx, JS::HandleObject proxy, js::AutoIdVector &props);
-    bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
+
+    // Derived proxy traps. Implementing these is useful for perfomance.
+    bool has(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
+    bool hasOwn(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
+    bool get(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
+             JS::HandleId id, JS::MutableHandleValue vp);
+    bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
+             JS::HandleId id, bool strict, JS::MutableHandleValue vp);
+    bool keys(JSContext *cx, JS::HandleObject proxy, js::AutoIdVector &props);
+    // We use "iterate" provided by the base class here.
+
+    // SpiderMonkey Extensions.
+    bool isExtensible(JSContext *cx, JS::HandleObject proxy, bool *extensible);
+    bool call(JSContext *cx, JS::HandleObject proxy, const JS::CallArgs &args);
     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);
-    bool isExtensible(JSContext *cx, JS::HandleObject proxy, bool *extensible);
 
     void decref();
     void incref();
     void destroyFromContent();
 
     void drop(JSObject *obj);
 
     static bool IsCPOW(JSObject *obj);
--- a/js/ipc/PJavaScript.ipdl
+++ b/js/ipc/PJavaScript.ipdl
@@ -18,31 +18,33 @@ rpc protocol PJavaScript
 {
     manager PContent;
 
 child:
     // The parent process no longer holds any references to the child object.
     async DropObject(uint64_t objId);
 
     // These roughly map to the ProxyHandler hooks that CPOWs need.
+    urgent PreventExtensions(uint64_t objId) returns (ReturnStatus rs);
+    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 DefineProperty(uint64_t objId, nsString id, PPropertyDescriptor descriptor) returns (ReturnStatus rs);
+    urgent Delete(uint64_t objId, nsString id) returns (ReturnStatus rs, bool successful);
+
     urgent Has(uint64_t objId, nsString id) returns (ReturnStatus rs, bool has);
     urgent HasOwn(uint64_t objId, nsString id) returns (ReturnStatus rs, bool has);
     urgent Get(uint64_t objId, uint64_t receiverId, nsString id) returns (ReturnStatus rs, JSVariant result);
     urgent Set(uint64_t objId, uint64_t receiverId, nsString id, bool strict, JSVariant value) returns (ReturnStatus rs, JSVariant result);
+
+    urgent IsExtensible(uint64_t objId) returns (ReturnStatus rs, bool result);
     urgent Call(uint64_t objId, JSParam[] argv) returns (ReturnStatus rs, JSVariant result, JSParam[] outparams);
-
-    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 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);
+
+    urgent GetPropertyNames(uint64_t objId, uint32_t flags) returns (ReturnStatus rs, nsString[] names);
+    urgent InstanceOf(uint64_t objId, JSIID iid) returns (ReturnStatus rs, bool instanceof);
 
 parent:
     async __delete__();
 };
 
 }
 }