Bug 843231 - Compute whether to use an XBL scope exactly once. r=bz
authorBobby Holley <bobbyholley@gmail.com>
Wed, 27 Mar 2013 11:40:43 -0700
changeset 128702 033f2f8ee525c5b135c306b1227c288b0b549db8
parent 128701 dedc70b52eaa50a7b14828de3da0e1f1ebd0e4f1
child 128703 413d5d8de3c89fb919e124e13d570729ae342ac9
push id3562
push userbobbyholley@gmail.com
push dateWed, 27 Mar 2013 18:41:22 +0000
treeherdermozilla-aurora@c5add7fbc027 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs843231
milestone21.0a2
Bug 843231 - Compute whether to use an XBL scope exactly once. r=bz
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/xpcprivate.h
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -123,16 +123,29 @@ XPCWrappedNativeScope::XPCWrappedNativeS
     }
 
     DEBUG_TrackNewScope(this);
     MOZ_COUNT_CTOR(XPCWrappedNativeScope);
 
     // Attach ourselves to the compartment private.
     CompartmentPrivate *priv = EnsureCompartmentPrivate(aGlobal);
     priv->scope = this;
+
+    // Determine whether to use an XBL scope or not.
+    mUseXBLScope = XPCJSRuntime::Get()->XBLScopesEnabled();
+    if (mUseXBLScope) {
+      js::Class *clasp = js::GetObjectClass(mGlobalJSObject);
+      mUseXBLScope = !strcmp(clasp->name, "Window") ||
+                     !strcmp(clasp->name, "ChromeWindow") ||
+                     !strcmp(clasp->name, "ModalContentWindow");
+    }
+    if (mUseXBLScope) {
+      nsIPrincipal *principal = GetPrincipal();
+      mUseXBLScope = principal && !nsContentUtils::IsSystemPrincipal(principal);
+    }
 }
 
 // static
 JSBool
 XPCWrappedNativeScope::IsDyingScope(XPCWrappedNativeScope *scope)
 {
     for (XPCWrappedNativeScope *cur = gDyingScopes; cur; cur = cur->mNext) {
         if (scope == cur)
@@ -175,31 +188,18 @@ XPCWrappedNativeScope::EnsureXBLScope(JS
     MOZ_ASSERT(!mIsXBLScope);
     MOZ_ASSERT(strcmp(js::GetObjectClass(global)->name,
                       "nsXBLPrototypeScript compilation scope"));
 
     // If we already have a special XBL scope object, we know what to use.
     if (mXBLScope)
         return mXBLScope;
 
-    // We should only be applying XBL bindings in DOM scopes.
-    MOZ_ASSERT(!strcmp(js::GetObjectClass(mGlobalJSObject)->name, "Window") ||
-               !strcmp(js::GetObjectClass(mGlobalJSObject)->name, "ChromeWindow") ||
-               !strcmp(js::GetObjectClass(mGlobalJSObject)->name, "ModalContentWindow"));
-
-    // Get the scope principal. If it's system, there's no reason to make
-    // a separate XBL scope.
-    nsIPrincipal *principal = GetPrincipal();
-    if (!principal)
-        return nullptr;
-    if (nsContentUtils::IsSystemPrincipal(principal))
-        return global;
-
-    // Check the pref. If XBL scopes are disabled, just return the global.
-    if (!XPCJSRuntime::Get()->XBLScopesEnabled())
+    // If this scope doesn't need an XBL scope, just return the global.
+    if (!mUseXBLScope)
         return global;
 
     // Set up the sandbox options. Note that we use the DOM global as the
     // sandboxPrototype so that the XBL scope can access all the DOM objects
     // it's accustomed to accessing.
     //
     // NB: One would think that wantXrays wouldn't make a difference here.
     // However, wantXrays lives a secret double life, and one of its other
@@ -207,16 +207,17 @@ XPCWrappedNativeScope::EnsureXBLScope(JS
     // So make sure to keep this set to true, here.
     SandboxOptions options;
     options.wantXrays = true;
     options.wantComponents = true;
     options.wantXHRConstructor = false;
     options.proto = global;
 
     // Use an nsExpandedPrincipal to create asymmetric security.
+    nsIPrincipal *principal = GetPrincipal();
     nsCOMPtr<nsIExpandedPrincipal> ep;
     MOZ_ASSERT(!(ep = do_QueryInterface(principal)));
     nsTArray< nsCOMPtr<nsIPrincipal> > principalAsArray(1);
     principalAsArray.AppendElement(principal);
     ep = new nsExpandedPrincipal(principalAsArray);
 
     // Create the sandbox.
     JSAutoRequest ar(cx);
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -1755,16 +1755,17 @@ private:
     JSObject*                        mPrototypeNoHelper;
 
     XPCContext*                      mContext;
 
     nsAutoPtr<DOMExpandoMap> mDOMExpandoMap;
 
     JSBool mExperimentalBindingsEnabled;
     bool mIsXBLScope;
+    bool mUseXBLScope;
 };
 
 /***************************************************************************/
 // XPCNativeMember represents a single idl declared method, attribute or
 // constant.
 
 // Tight. No virtual methods. Can be bitwise copied (until any resolution done).