Bug 939166 - Be more direct in GetStaticScriptGlobal. r=bz
authorBobby Holley <bobbyholley@gmail.com>
Wed, 20 Nov 2013 08:48:00 -0800
changeset 171208 c8e22393c13732fd47d633555f33c8080f75025f
parent 171207 bc384ede1d1a6fd19cfac624886fdf9d596f7b77
child 171209 181e285a7d51a79d50feb1e8916b91ec9d601943
push id3224
push userlsblakk@mozilla.com
push dateTue, 04 Feb 2014 01:06:49 +0000
treeherdermozilla-beta@60c04d0987f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs939166
milestone28.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 939166 - Be more direct in GetStaticScriptGlobal. r=bz This can all collapse because of the following facts: * Ever since we introduced SandboxPrivate, we never actually use a Window as an SOP for a sandbox. * nsGlobalWindow is actually the only thing that implements nsIScriptGlobalObject.
dom/base/nsJSUtils.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/xpcpublic.h
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -21,16 +21,17 @@
 #include "nsCOMPtr.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsPIDOMWindow.h"
 #include "GeckoProfiler.h"
 #include "nsDOMJSUtils.h" // for GetScriptContextFromJSContext
 #include "nsJSPrincipals.h"
 #include "xpcpublic.h"
 #include "nsContentUtils.h"
+#include "nsGlobalWindow.h"
 
 bool
 nsJSUtils::GetCallingLocation(JSContext* aContext, const char* *aFilename,
                               uint32_t* aLineno)
 {
   JS::Rooted<JSScript*> script(aContext);
   unsigned lineno = 0;
 
@@ -42,56 +43,19 @@ nsJSUtils::GetCallingLocation(JSContext*
   *aLineno = lineno;
 
   return true;
 }
 
 nsIScriptGlobalObject *
 nsJSUtils::GetStaticScriptGlobal(JSObject* aObj)
 {
-  const JSClass* clazz;
-  JSObject* glob = aObj; // starting point for search
-
-  if (!glob)
-    return nullptr;
-
-  glob = js::GetGlobalForObjectCrossCompartment(glob);
-  NS_ABORT_IF_FALSE(glob, "Infallible returns null");
-
-  clazz = JS_GetClass(glob);
-
-  // Whenever we end up with globals that are JSCLASS_IS_DOMJSCLASS
-  // and have an nsISupports DOM object, we will need to modify this
-  // check here.
-  MOZ_ASSERT(!(clazz->flags & JSCLASS_IS_DOMJSCLASS));
-  nsISupports* supports;
-  if (!(clazz->flags & JSCLASS_HAS_PRIVATE) ||
-      !(clazz->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS) ||
-      !(supports = (nsISupports*)::JS_GetPrivate(glob))) {
+  if (!aObj)
     return nullptr;
-  }
-
-  // We might either have a window directly (e.g. if the global is a
-  // sandbox whose script object principal pointer is a window), or an
-  // XPCWrappedNative for a window.  We could also have other
-  // sandbox-related script object principals, but we can't do much
-  // about those short of trying to walk the proto chain of |glob|
-  // looking for a window or something.
-  nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryInterface(supports));
-  if (!sgo) {
-    nsCOMPtr<nsIXPConnectWrappedNative> wrapper(do_QueryInterface(supports));
-    if (!wrapper) {
-      return nullptr;
-    }
-    sgo = do_QueryWrappedNative(wrapper);
-  }
-
-  // We're returning a pointer to something that's about to be
-  // released, but that's ok here.
-  return sgo;
+  return xpc::WindowGlobalOrNull(aObj);
 }
 
 nsIScriptContext *
 nsJSUtils::GetStaticScriptContext(JSObject* aObj)
 {
   nsIScriptGlobalObject *nativeGlobal = GetStaticScriptGlobal(aObj);
   if (!nativeGlobal)
     return nullptr;
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -32,16 +32,17 @@
 #include "nsScriptLoader.h"
 #include "jsfriendapi.h"
 #include "jsprf.h"
 #include "js/MemoryMetrics.h"
 #include "js/OldDebugAPI.h"
 #include "mozilla/dom/GeneratedAtomList.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/WindowBinding.h"
 #include "mozilla/Attributes.h"
 #include "AccessCheck.h"
 #include "nsGlobalWindow.h"
 #include "nsAboutProtocolUtils.h"
 
 #include "GeckoProfiler.h"
 #include "nsJSPrincipals.h"
 
@@ -561,16 +562,38 @@ GetJunkScopeGlobal()
     JSObject *junkScope = GetJunkScope();
     // GetJunkScope would ideally never fail, currently it is not yet the case
     // unfortunately...(see Bug 874158)
     if (!junkScope)
         return nullptr;
     return GetNativeForGlobal(junkScope);
 }
 
+nsGlobalWindow*
+WindowGlobalOrNull(JSObject *aObj)
+{
+    MOZ_ASSERT(aObj);
+    JSObject *glob = js::GetGlobalForObjectCrossCompartment(aObj);
+    MOZ_ASSERT(glob);
+
+    // This will always return null until we have Window on WebIDL bindings,
+    // at which point it will do the right thing.
+    if (!IS_WN_CLASS(js::GetObjectClass(glob))) {
+        nsGlobalWindow* win = nullptr;
+        UNWRAP_OBJECT(Window, nullptr, glob, win);
+        return win;
+    }
+
+    nsISupports* supports = XPCWrappedNative::Get(glob)->GetIdentityObject();
+    nsCOMPtr<nsPIDOMWindow> piWin = do_QueryInterface(supports);
+    if (!piWin)
+        return nullptr;
+    return static_cast<nsGlobalWindow*>(piWin.get());
+}
+
 }
 
 static void
 CompartmentDestroyedCallback(JSFreeOp *fop, JSCompartment *compartment)
 {
     XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance();
     if (!self)
         return;
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -399,16 +399,23 @@ GetJunkScope();
 
 /**
  * Returns the native global of the junk scope. See comment of GetJunkScope
  * about the conditions of using it.
  */
 nsIGlobalObject *
 GetJunkScopeGlobal();
 
+/**
+ * If |aObj| has a window for a global, returns the associated nsGlobalWindow.
+ * Otherwise, returns null.
+ */
+nsGlobalWindow*
+WindowGlobalOrNull(JSObject *aObj);
+
 // Error reporter used when there is no associated DOM window on to which to
 // report errors and warnings.
 void
 SystemErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep);
 
 // We have a separate version that's exported with external linkage for use by
 // xpcshell, since external linkage on windows changes the signature to make it
 // incompatible with the JSErrorReporter type, causing JS_SetErrorReporter calls