Bug 793969 - Define an identity transformation at the Xray layer. r=mrbkap a=akeybl GECKO1009_2012101115_RELBRANCH
authorBobby Holley <bobbyholley@gmail.com>
Fri, 19 Oct 2012 21:00:48 +0200
branchGECKO1009_2012101115_RELBRANCH
changeset 82048 246c665f50d32cc064ba4c5b91997df21c796342
parent 82047 cb285a7281796968c6e90ed194807e0064f897ed
child 82049 6564d2216240ff6c1742cb4a3b7436800135d9dc
push id311
push userbobbyholley@gmail.com
push dateWed, 24 Oct 2012 10:26:28 +0000
reviewersmrbkap, akeybl
bugs793969
milestone10.0.9
Bug 793969 - Define an identity transformation at the Xray layer. r=mrbkap a=akeybl
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/wrappers/XrayWrapper.cpp
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -65,16 +65,17 @@ using namespace mozilla;
 using namespace mozilla::xpconnect::memory;
 
 /***************************************************************************/
 
 const char* XPCJSRuntime::mStrings[] = {
     "constructor",          // IDX_CONSTRUCTOR
     "toString",             // IDX_TO_STRING
     "toSource",             // IDX_TO_SOURCE
+    "valueOf",              // IDX_VALUE_OF
     "lastResult",           // IDX_LAST_RESULT
     "returnCode",           // IDX_RETURN_CODE
     "value",                // IDX_VALUE
     "QueryInterface",       // IDX_QUERY_INTERFACE
     "Components",           // IDX_COMPONENTS
     "wrappedJSObject",      // IDX_WRAPPED_JSOBJECT
     "Object",               // IDX_OBJECT
     "Function",             // IDX_FUNCTION
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -721,16 +721,17 @@ public:
     // Mapping of often used strings to jsid atoms that live 'forever'.
     //
     // To add a new string: add to this list and to XPCJSRuntime::mStrings
     // at the top of xpcjsruntime.cpp
     enum {
         IDX_CONSTRUCTOR             = 0 ,
         IDX_TO_STRING               ,
         IDX_TO_SOURCE               ,
+        IDX_VALUE_OF                ,
         IDX_LAST_RESULT             ,
         IDX_RETURN_CODE             ,
         IDX_VALUE                   ,
         IDX_QUERY_INTERFACE         ,
         IDX_COMPONENTS              ,
         IDX_WRAPPED_JSOBJECT        ,
         IDX_OBJECT                  ,
         IDX_FUNCTION                ,
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -241,26 +241,61 @@ holder_set(JSContext *cx, JSObject *wrap
             if (retval)
                 XPCThrower::Throw(rv, cx);
             return false;
         }
     }
     return true;
 }
 
+template <typename T>
+static bool
+Is(JSObject *wrapper)
+{
+    JSObject *holder = GetHolder(wrapper);
+    XPCWrappedNative *wn = GetWrappedNativeFromHolder(holder);
+    nsCOMPtr<T> native = do_QueryWrappedNative(wn);
+    return !!native;
+}
+
+static JSBool
+IdentityValueOf(JSContext *cx, unsigned argc, jsval *vp)
+{
+    JS_SET_RVAL(cx, vp, JS_THIS(cx, vp));
+    return true;
+}
+
 static bool
 ResolveNativeProperty(JSContext *cx, JSObject *wrapper, JSObject *holder, jsid id, bool set,
                       JSPropertyDescriptor *desc)
 {
     desc->obj = NULL;
 
     NS_ASSERTION(js::GetObjectJSClass(holder) == &HolderClass, "expected a native property holder object");
     JSObject *wnObject = GetWrappedNativeObjectFromHolder(holder);
     XPCWrappedNative *wn = GetWrappedNative(wnObject);
 
+    // Explicitly make valueOf an identity operation so that it plays better
+    // with the rest of the Xray infrastructure.
+    XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
+    if (id == rt->GetStringID(XPCJSRuntime::IDX_VALUE_OF) &&
+        Is<nsIDOMLocation>(wrapper))
+    {
+        JSFunction *fun = JS_NewFunctionById(cx, &IdentityValueOf, 0, 0, NULL, id);
+        if (!fun)
+            return false;
+        desc->obj = wrapper;
+        desc->attrs = 0;
+        desc->getter = NULL;
+        desc->setter = NULL;
+        desc->shortid = 0;
+        desc->value = ObjectValue(*JS_GetFunctionObject(fun));
+        return true;
+    }
+
     // This will do verification and the method lookup for us.
     XPCCallContext ccx(JS_CALLER, cx, wnObject, nsnull, id);
 
     // There are no native numeric properties, so we can shortcut here. We will not
     // find the property.
     if (!JSID_IS_ATOM(id)) {
         /* Not found */
         return true;
@@ -339,26 +374,16 @@ wrappedJSObject_getter(JSContext *cx, JS
         return false;
     }
 
     *vp = OBJECT_TO_JSVAL(wrapper);
 
     return WrapperFactory::WaiveXrayAndWrap(cx, vp);
 }
 
-template <typename T>
-static bool
-Is(JSObject *wrapper)
-{
-    JSObject *holder = GetHolder(wrapper);
-    XPCWrappedNative *wn = GetWrappedNativeFromHolder(holder);
-    nsCOMPtr<T> native = do_QueryWrappedNative(wn);
-    return !!native;
-}
-
 static JSBool
 WrapURI(JSContext *cx, nsIURI *uri, jsval *vp)
 {
     JSObject *scope = JS_GetGlobalForScopeChain(cx);
     nsresult rv =
         nsXPConnect::FastGetXPConnect()->WrapNativeToJSVal(cx, scope, uri, nsnull,
                                                            &NS_GET_IID(nsIURI), true,
                                                            vp, nsnull);