Bug 899367 - Have nsGlobalWindow go through nsJSContext to access the outer. r=mccr8
☠☠ backed out by 4fa161a24995 ☠ ☠
authorBobby Holley <bobbyholley@gmail.com>
Tue, 27 Aug 2013 15:21:39 -0700
changeset 157501 4c396b8a51d002e2fb51c236a89f6d3ac2f78d07
parent 157500 c8c30176639afcd782ced7b8801c4d0d338b121a
child 157502 1dd262d146a6b7bbb93df4494cd13fe51e33cd19
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs899367
milestone26.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 899367 - Have nsGlobalWindow go through nsJSContext to access the outer. r=mccr8
dom/base/nsGlobalWindow.cpp
dom/base/nsIScriptContext.h
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -2043,18 +2043,19 @@ nsGlobalWindow::CreateOuterObject(nsGlob
   return SetOuterObject(cx, outer);
 }
 
 nsresult
 nsGlobalWindow::SetOuterObject(JSContext* aCx, JS::Handle<JSObject*> aOuterObject)
 {
   JSAutoCompartment ac(aCx, aOuterObject);
 
-  // Indicate the default compartment object associated with this cx.
-  js::SetDefaultObjectForContext(aCx, aOuterObject);
+  // Inform the nsJSContext, which is the canonical holder of the outer.
+  MOZ_ASSERT(IsOuterWindow());
+  mContext->SetWindowProxy(aOuterObject);
 
   // Set up the prototype for the outer object.
   JS::Rooted<JSObject*> inner(aCx, JS_GetParent(aOuterObject));
   JS::Rooted<JSObject*> proto(aCx);
   if (!JS_GetPrototype(aCx, inner, &proto)) {
     return NS_ERROR_FAILURE;
   }
   JS_SetPrototype(aCx, aOuterObject, proto);
@@ -2440,21 +2441,17 @@ nsGlobalWindow::SetNewDocument(nsIDocume
 
     // Now that both the the inner and outer windows are initialized
     // let the script context do its magic to hook them together.
 #ifdef DEBUG
     JS::Rooted<JSObject*> newInnerJSObject(cx,
         newInnerWindow->FastGetGlobalJSObject());
 #endif
 
-    // Now that we're connecting the outer global to the inner one,
-    // we must have transplanted it. The JS engine tries to maintain
-    // the global object's compartment as its default compartment,
-    // so update that now since it might have changed.
-    js::SetDefaultObjectForContext(cx, mJSObject);
+    MOZ_ASSERT(mContext->GetWindowProxy() == mJSObject);
 #ifdef DEBUG
     JS::Rooted<JSObject*> rootedJSObject(cx, mJSObject);
     JS::Rooted<JSObject*> proto1(cx), proto2(cx);
     JS_GetPrototype(cx, rootedJSObject, &proto1);
     JS_GetPrototype(cx, newInnerJSObject, &proto2);
     NS_ASSERTION(proto1 == proto2,
                  "outer and inner globals should have the same prototype");
 #endif
--- a/dom/base/nsIScriptContext.h
+++ b/dom/base/nsIScriptContext.h
@@ -22,18 +22,18 @@ class nsIArray;
 class nsIVariant;
 class nsIObjectInputStream;
 class nsIObjectOutputStream;
 class nsIScriptObjectPrincipal;
 class nsIDOMWindow;
 class nsIURI;
 
 #define NS_ISCRIPTCONTEXT_IID \
-{ 0x1d931a17, 0x453a, 0x47fb, \
-  { 0x94, 0x66, 0x2d, 0x3e, 0xd1, 0xef, 0x7a, 0xc5 } }
+{ 0x03c0874e, 0xcb49, 0x41c8, \
+  { 0xa3, 0x0b, 0xef, 0x3e, 0xc1, 0x88, 0xb1, 0x1f } }
 
 /* This MUST match JSVERSION_DEFAULT.  This version stuff if we don't
    know what language we have is a little silly... */
 #define SCRIPTVERSION_DEFAULT JSVERSION_DEFAULT
 
 class nsIOffThreadScriptReceiver;
 
 /**
@@ -160,16 +160,22 @@ public:
    * Tell the context we're about to be reinitialize it.
    */
   virtual void WillInitializeContext() = 0;
 
   /**
    * Tell the context we're done reinitializing it.
    */
   virtual void DidInitializeContext() = 0;
+
+  /**
+   * Access the Window Proxy. The setter should only be called by nsGlobalWindow.
+   */
+  virtual void SetWindowProxy(JS::Handle<JSObject*> aWindowProxy) = 0;
+  virtual JSObject* GetWindowProxy() = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContext, NS_ISCRIPTCONTEXT_IID)
 
 #define NS_IOFFTHREADSCRIPTRECEIVER_IID \
 {0x3a980010, 0x878d, 0x46a9,            \
   {0x93, 0xad, 0xbc, 0xfd, 0xd3, 0x8e, 0xa0, 0xc2}}
 
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1132,17 +1132,17 @@ nsJSContext::GetGlobalObject()
   // This'll return a pointer to something we're about to release, but
   // that's ok, the JS object will hold it alive long enough.
   return sgo;
 }
 
 JSObject*
 nsJSContext::GetNativeGlobal()
 {
-    return js::DefaultObjectForContextOrNull(mContext);
+    return GetWindowProxy();
 }
 
 JSContext*
 nsJSContext::GetNativeContext()
 {
   return xpc_UnmarkGrayContext(mContext);
 }
 
@@ -2577,16 +2577,28 @@ void
 nsJSContext::ReportPendingException()
 {
   if (mIsInitialized) {
     nsJSUtils::ReportPendingException(mContext);
   }
 }
 
 void
+nsJSContext::SetWindowProxy(JS::Handle<JSObject*> aWindowProxy)
+{
+  js::SetDefaultObjectForContext(mContext, aWindowProxy);
+}
+
+JSObject*
+nsJSContext::GetWindowProxy()
+{
+  return xpc_UnmarkGrayObject(js::DefaultObjectForContextOrNull(mContext));
+}
+
+void
 nsJSContext::LikelyShortLivingObjectCreated()
 {
   ++sLikelyShortLivingObjectsNeedingGC;
 }
 
 void
 mozilla::dom::StartupJSEnvironment()
 {
--- a/dom/base/nsJSEnvironment.h
+++ b/dom/base/nsJSEnvironment.h
@@ -75,16 +75,19 @@ public:
   virtual bool GetProcessingScriptTag() MOZ_OVERRIDE;
   virtual void SetProcessingScriptTag(bool aResult) MOZ_OVERRIDE;
 
   virtual nsresult InitClasses(JS::Handle<JSObject*> aGlobalObj) MOZ_OVERRIDE;
 
   virtual void WillInitializeContext() MOZ_OVERRIDE;
   virtual void DidInitializeContext() MOZ_OVERRIDE;
 
+  virtual void SetWindowProxy(JS::Handle<JSObject*> aWindowProxy) MOZ_OVERRIDE;
+  virtual JSObject* GetWindowProxy() MOZ_OVERRIDE;
+
   static void LoadStart();
   static void LoadEnd();
 
   enum IsCompartment {
     CompartmentGC,
     NonCompartmentGC
   };