Bug 987111 - Implement delete_ for Object Xrays. r=gabor
☠☠ backed out by fe14647a422d ☠ ☠
authorBobby Holley <bobbyholley@gmail.com>
Wed, 04 Jun 2014 15:12:27 -0700
changeset 205926 cdfd24ddf448cfda953b1810077158c8c6bcd5c5
parent 205925 7883150e5471699a27121eebf3a69e0f08ef9f7e
child 205927 5f88b5ef94963726e73ee81f9c3b1b6c45a05161
push id3741
push userasasaki@mozilla.com
push dateMon, 21 Jul 2014 20:25:18 +0000
treeherdermozilla-beta@4d6f46f5af68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgabor
bugs987111
milestone32.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 987111 - Implement delete_ for Object Xrays. r=gabor
js/xpconnect/wrappers/XrayWrapper.cpp
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -154,16 +154,21 @@ public:
     // NB: resolveOwnProperty may decide whether or not to cache what it finds
     // on the holder. If the result is not cached, the lookup will happen afresh
     // for each access, which is the right thing for things like dynamic NodeList
     // properties.
     virtual bool resolveOwnProperty(JSContext *cx, Wrapper &jsWrapper,
                                     HandleObject wrapper, HandleObject holder,
                                     HandleId id, MutableHandle<JSPropertyDescriptor> desc);
 
+    bool delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) {
+        *bp = true;
+        return true;
+    }
+
     virtual void preserveWrapper(JSObject *target) = 0;
 
     static bool set(JSContext *cx, HandleObject wrapper, HandleObject receiver, HandleId id,
                     bool strict, MutableHandleValue vp);
 
     JSObject* getExpandoObject(JSContext *cx, HandleObject target,
                                HandleObject consumer);
     JSObject* ensureExpandoObject(JSContext *cx, HandleObject wrapper,
@@ -300,16 +305,18 @@ public:
     {
         MOZ_ASSUME_UNREACHABLE("resolveNativeProperty hook should never be called with HasPrototype = 1");
     }
 
     virtual bool resolveOwnProperty(JSContext *cx, Wrapper &jsWrapper, HandleObject wrapper,
                                     HandleObject holder, HandleId id,
                                     MutableHandle<JSPropertyDescriptor> desc) MOZ_OVERRIDE;
 
+    bool delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp);
+
     bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
                         MutableHandle<JSPropertyDescriptor> desc,
                         Handle<JSPropertyDescriptor> existingDesc, bool *defined);
 
     virtual bool enumerateNames(JSContext *cx, HandleObject wrapper, unsigned flags,
                                 AutoIdVector &props);
 
     static bool call(JSContext *cx, HandleObject wrapper,
@@ -646,16 +653,38 @@ JSXrayTraits::resolveOwnProperty(JSConte
                                      desc.getter(), desc.setter()) &&
                JS_GetPropertyDescriptorById(cx, holder, id, desc);
     }
 
     return true;
 }
 
 bool
+JSXrayTraits::delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp)
+{
+    RootedObject holder(cx, ensureHolder(cx, wrapper));
+
+    // If we're using Object Xrays, we allow callers to attempt to delete any
+    // property from the underlying object that they are able to resolve. Note
+    // that this deleting may fail if the property is non-configurable.
+    bool isObjectInstance = getProtoKey(holder) == JSProto_Object && !isPrototype(holder);
+    if (isObjectInstance) {
+        RootedObject target(cx, getTargetObject(wrapper));
+        JSAutoCompartment ac(cx, target);
+        Rooted<JSPropertyDescriptor> desc(cx);
+        if (!getOwnPropertyFromTargetIfSafe(cx, target, wrapper, id, &desc))
+            return false;
+        if (desc.object())
+            return JS_DeletePropertyById2(cx, target, id, bp);
+    }
+    *bp = true;
+    return true;
+}
+
+bool
 JSXrayTraits::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
                                MutableHandle<JSPropertyDescriptor> desc,
                                Handle<JSPropertyDescriptor> existingDesc,
                                bool *defined)
 {
     *defined = false;
     RootedObject holder(cx, ensureHolder(cx, wrapper));
     if (!holder)
@@ -2309,18 +2338,18 @@ XrayWrapper<Base, Traits>::delete_(JSCon
 
     // Check the expando object.
     RootedObject target(cx, Traits::getTargetObject(wrapper));
     RootedObject expando(cx, Traits::singleton.getExpandoObject(cx, target, wrapper));
     if (expando) {
         JSAutoCompartment ac(cx, expando);
         return JS_DeletePropertyById2(cx, expando, id, bp);
     }
-    *bp = true;
-    return true;
+
+    return Traits::singleton.delete_(cx, wrapper, id, bp);
 }
 
 template <typename Base, typename Traits>
 bool
 XrayWrapper<Base, Traits>::enumerate(JSContext *cx, HandleObject wrapper, unsigned flags,
                                      AutoIdVector &props)
 {
     assertEnteredPolicy(cx, wrapper, JSID_VOID, BaseProxyHandler::ENUMERATE);