Bug 858101 - Run the DefaultValue algorithm directly on the wrapper for Xrays. r=mrbkap, a=akeybl
authorBobby Holley <bobbyholley@gmail.com>
Wed, 05 Jun 2013 08:14:18 -0400
changeset 119533 bdefa0dc9d83db37ecd4a170ea0c4c1ff5f86664
parent 119532 09dc1ae3b1b552ba3e516fde75f0903ed543c34b
child 119534 a9a3b28662b7df131870613b387227409f147c5c
push id860
push userryanvm@gmail.com
push dateWed, 05 Jun 2013 17:50:56 +0000
reviewersmrbkap, akeybl
bugs858101
milestone18.0
Bug 858101 - Run the DefaultValue algorithm directly on the wrapper for Xrays. r=mrbkap, a=akeybl
js/src/jsfriendapi.h
js/src/jsobj.cpp
js/src/jsobj.h
js/xpconnect/wrappers/XrayWrapper.cpp
js/xpconnect/wrappers/XrayWrapper.h
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -1563,13 +1563,17 @@ class JS_FRIEND_API(AutoCTypesActivityCa
     void DoEndCallback() {
         if (callback) {
             callback(cx, endType);
             callback = NULL;
         }
     }
 };
 
+/* ES5 8.12.8. */
+JS_FRIEND_API(JSBool)
+DefaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp);
+
 } /* namespace js */
 
 #endif /* __cplusplus */
 
 #endif /* jsfriendapi_h___ */
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -4857,17 +4857,17 @@ MaybeCallMethod(JSContext *cx, HandleObj
         return false;
     if (!js_IsCallable(vp)) {
         vp.setObject(*obj);
         return true;
     }
     return Invoke(cx, ObjectValue(*obj), vp, 0, NULL, vp.address());
 }
 
-JSBool
+JS_FRIEND_API(JSBool)
 DefaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp)
 {
     JS_ASSERT(hint == JSTYPE_NUMBER || hint == JSTYPE_STRING || hint == JSTYPE_VOID);
 #if JS_HAS_XML_SUPPORT
     JS_ASSERT(!obj->isXML());
 #endif
 
     Rooted<jsid> id(cx);
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -189,20 +189,16 @@ DeleteElement(JSContext *cx, HandleObjec
 extern JSBool
 DeleteSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, MutableHandleValue rval, JSBool strict);
 
 extern JSBool
 DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue rval, JSBool strict);
 
 } /* namespace js::baseops */
 
-/* ES5 8.12.8. */
-extern JSBool
-DefaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp);
-
 extern Class ArrayClass;
 extern Class ArrayBufferClass;
 extern Class BlockClass;
 extern Class BooleanClass;
 extern Class CallableObjectClass;
 extern Class DataViewClass;
 extern Class DateClass;
 extern Class ErrorClass;
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -1856,16 +1856,33 @@ XrayWrapper<Base, Traits>::call(JSContex
 template <typename Base, typename Traits>
 bool
 XrayWrapper<Base, Traits>::construct(JSContext *cx, JSObject *wrapper, unsigned argc,
                                      js::Value *argv, js::Value *rval)
 {
     return Traits::construct(cx, wrapper, argc, argv, rval);
 }
 
+template <typename Base, typename Traits>
+bool
+XrayWrapper<Base, Traits>::defaultValue(JSContext *cx, JSObject *wrapperArg,
+                                        JSType hint, JS::Value *vp)
+{
+    // Even if this isn't a security wrapper, Xray semantics dictate that we
+    // run the DefaultValue algorithm directly on the Xray wrapper.
+    //
+    // NB: We don't have to worry about things with special [[DefaultValue]]
+    // behavior like Date because we'll never have an XrayWrapper to them.
+    RootedObject wrapper(cx, wrapperArg);
+    RootedValue v(cx, *vp);
+    if (!DefaultValue(cx, wrapper, hint, &v))
+        return false;
+    *vp = v;
+    return true;
+}
 
 #define XRAY XrayWrapper<CrossCompartmentSecurityWrapper, XPCWrappedNativeXrayTraits >
 template <> XRAY XRAY::singleton(0);
 template class XRAY;
 #undef XRAY
 
 #define XRAY XrayWrapper<SameCompartmentSecurityWrapper, XPCWrappedNativeXrayTraits >
 template <> XRAY XRAY::singleton(0);
--- a/js/xpconnect/wrappers/XrayWrapper.h
+++ b/js/xpconnect/wrappers/XrayWrapper.h
@@ -82,16 +82,20 @@ class XrayWrapper : public Base {
     virtual bool hasOwn(JSContext *cx, JSObject *wrapper, jsid id, bool *bp);
     virtual bool keys(JSContext *cx, JSObject *wrapper, js::AutoIdVector &props);
     virtual bool iterate(JSContext *cx, JSObject *wrapper, unsigned flags, js::Value *vp);
 
     virtual bool call(JSContext *cx, JSObject *wrapper, unsigned argc, js::Value *vp);
     virtual bool construct(JSContext *cx, JSObject *wrapper,
                            unsigned argc, js::Value *argv, js::Value *rval);
 
+    virtual bool defaultValue(JSContext *cx, JSObject *wrapper,
+                              JSType hint, JS::Value *vp)
+                              MOZ_OVERRIDE;
+
     static XrayWrapper singleton;
 
   private:
     bool enumerate(JSContext *cx, JSObject *wrapper, unsigned flags,
                    JS::AutoIdVector &props);
 };
 
 typedef XrayWrapper<js::CrossCompartmentWrapper, ProxyXrayTraits > XrayProxy;