Bug 987111 - Implement delete_ for Object Xrays. r=gabor
authorBobby Holley <bobbyholley@gmail.com>
Thu, 05 Jun 2014 22:32:39 -0700
changeset 207334 5c0a8d16c227df8babf3a31ef7f8e22f1220b4b4
parent 207333 5951773bbbe348fdebd1f539c445221f2d15516c
child 207335 9592f7abff55fdf582292cdc38991849d6c8d942
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [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
@@ -155,16 +155,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,
@@ -301,16 +306,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,
@@ -647,16 +654,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)
@@ -2332,18 +2361,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);