Bug 966609 - nsWrapperCache for SandboxPrivate. r=bholley
authorGabor Krizsanits <gkrizsanits@mozilla.com>
Mon, 24 Mar 2014 16:00:52 +0100
changeset 175089 f4e975c7d8d3f4f7865443e32aab224d3f789aec
parent 175088 0015731e2e29489367cc1dcdd54efa347a21f003
child 175090 94c92db0b503fce7f52659022734f4eb9582bbb0
push id26480
push userryanvm@gmail.com
push dateMon, 24 Mar 2014 20:46:23 +0000
treeherdermozilla-central@5c0673441fc8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs966609
milestone31.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 966609 - nsWrapperCache for SandboxPrivate. r=bholley
content/test/unit/test_range.js
js/xpconnect/public/SandboxPrivate.h
js/xpconnect/src/Sandbox.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/tests/unit/test_allowedDomainsXHR.js
--- a/content/test/unit/test_range.js
+++ b/content/test/unit/test_range.js
@@ -355,25 +355,25 @@ function run_miscellaneous_tests() {
   if ((endOffset > startOffset) &&
       (startContainer == endContainer) &&
       (startContainer instanceof C_i.nsIDOMText)) {
     // Invalid start node
     try {
       baseRange.setStart(null, 0);
       do_throw("Should have thrown NOT_OBJECT_ERR!");
     } catch (e) {
-      do_check_eq(e instanceof TypeError, true);
+      do_check_eq(e.constructor.name, "TypeError");
     }
 
     // Invalid start node
     try {
       baseRange.setStart({}, 0);
       do_throw("Should have thrown SecurityError!");
     } catch (e) {
-      do_check_true(e instanceof TypeError);
+      do_check_eq(e.constructor.name, "TypeError");
     }
 
     // Invalid index
     try {
       baseRange.setStart(startContainer, -1);
       do_throw("Should have thrown IndexSizeError!");
     } catch (e) {
       do_check_eq(e.name, "IndexSizeError");
--- a/js/xpconnect/public/SandboxPrivate.h
+++ b/js/xpconnect/public/SandboxPrivate.h
@@ -4,48 +4,51 @@
 
 #ifndef __SANDBOXPRIVATE_H__
 #define __SANDBOXPRIVATE_H__
 
 #include "nsIGlobalObject.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIPrincipal.h"
 #include "nsWeakReference.h"
+#include "nsWrapperCache.h"
 
 #include "js/RootingAPI.h"
 
 // This interface is public only because it is used in jsd.
 // Once jsd is gone this file should be moved back to xpconnect/src.
 
 class SandboxPrivate : public nsIGlobalObject,
                        public nsIScriptObjectPrincipal,
-                       public nsSupportsWeakReference
+                       public nsSupportsWeakReference,
+                       public nsWrapperCache
 {
 public:
     SandboxPrivate(nsIPrincipal *principal, JSObject *global)
         : mPrincipal(principal)
-        , mGlobalJSObject(global)
     {
+        SetWrapper(global);
     }
     virtual ~SandboxPrivate() { }
 
-    NS_DECL_ISUPPORTS
+    NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+    NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(SandboxPrivate,
+                                                           nsIGlobalObject)
 
     nsIPrincipal *GetPrincipal()
     {
         return mPrincipal;
     }
 
     JSObject *GetGlobalJSObject()
     {
-        return mGlobalJSObject;
+        return GetWrapper();
     }
 
     void ForgetGlobalObject()
     {
-        mGlobalJSObject = nullptr;
+        ClearWrapper();
     }
 private:
     nsCOMPtr<nsIPrincipal> mPrincipal;
-    JS::TenuredHeap<JSObject*> mGlobalJSObject;
 };
 
 #endif // __SANDBOXPRIVATE_H__
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -38,20 +38,26 @@
 using namespace mozilla;
 using namespace JS;
 using namespace js;
 using namespace xpc;
 
 using mozilla::dom::DestroyProtoAndIfaceCache;
 using mozilla::dom::indexedDB::IndexedDatabaseManager;
 
-NS_IMPL_ISUPPORTS3(SandboxPrivate,
-                   nsIScriptObjectPrincipal,
-                   nsIGlobalObject,
-                   nsISupportsWeakReference)
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(SandboxPrivate)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(SandboxPrivate)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(SandboxPrivate)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SandboxPrivate)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIScriptObjectPrincipal)
+  NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
+  NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
+  NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+NS_INTERFACE_MAP_END
 
 const char kScriptSecurityManagerContractID[] = NS_SCRIPTSECURITYMANAGER_CONTRACTID;
 
 class nsXPCComponents_utils_Sandbox : public nsIXPCComponents_utils_Sandbox,
                                       public nsIXPCScriptable
 {
 public:
     // Aren't macros nice?
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -814,34 +814,27 @@ XPCConvert::NativeInterface2JSObject(Mut
     // First, see if this object supports the wrapper cache.
     // Note: If |cache->IsDOMBinding()| is true, then it means that the object
     // implementing it doesn't want a wrapped native as its JS Object, but
     // instead it provides its own proxy object. In that case, the object
     // to use is found as cache->GetWrapper(). If that is null, then the
     // object will create (and fill the cache) from its WrapObject call.
     nsWrapperCache *cache = aHelper.GetWrapperCache();
 
-    RootedObject flat(cx);
-    if (cache) {
-        flat = cache->GetWrapper();
-        if (cache->IsDOMBinding()) {
-            if (!flat) {
-                RootedObject global(cx, xpcscope->GetGlobalJSObject());
-                flat = cache->WrapObject(cx, global);
-                if (!flat)
-                    return false;
-            }
-
-            if (allowNativeWrapper && !JS_WrapObject(cx, &flat))
-                return false;
-
-            return CreateHolderIfNeeded(flat, d, dest);
-        }
-    } else {
-        flat = nullptr;
+    RootedObject flat(cx, cache ? cache->GetWrapper() : nullptr);
+    if (!flat && cache && cache->IsDOMBinding()) {
+        RootedObject global(cx, xpcscope->GetGlobalJSObject());
+        flat = cache->WrapObject(cx, global);
+        if (!flat)
+            return false;
+    }
+    if (flat) {
+        if (allowNativeWrapper && !JS_WrapObject(cx, &flat))
+            return false;
+        return CreateHolderIfNeeded(flat, d, dest);
     }
 
     // Don't double wrap CPOWs. This is a temporary measure for compatibility
     // with objects that don't provide necessary QIs (such as objects under
     // the new DOM bindings). We expect the other side of the CPOW to have
     // the appropriate wrappers in place.
     RootedObject cpow(cx, UnwrapNativeCPOW(aHelper.Object()));
     if (cpow) {
--- a/js/xpconnect/tests/unit/test_allowedDomainsXHR.js
+++ b/js/xpconnect/tests/unit/test_allowedDomainsXHR.js
@@ -65,19 +65,23 @@ function run_test()
 
   httpserver2.stop(finishIfDone);
 
   // Test async XHR sending
   sb.finish = function(){
     httpserver.stop(finishIfDone);
   }
 
-  sb.checkResults = checkResults;
-  
+  // We want to execute checkResults from the scope of the sandbox as well to
+  // make sure that there are no permission errors related to nsEP. For that
+  // we need to clone the function into the sandbox and make a few things
+  // available for it.
+  cu.evalInSandbox('var checkResults = ' + checkResults.toSource(), sb);
   sb.do_check_eq = do_check_eq;
+  sb.httpbody = httpbody;
 
   function changeListener(event) {
     if (checkResults(async))
       finish();
   }
 
   var async = cu.evalInSandbox('var async = createXHR("4444/simple", true);' +
                                'async.addEventListener("readystatechange", ' +