Bug 500691 - Call JS_ClearScope before XPConnect tries to update our outer window's scope's concept of what {Function,Object}.prototype are so that we forward correctly to the inner window's versions. r=jst sr=bzbarsky a=ss
authorBlake Kaplan <mrbkap@gmail.com>
Wed, 01 Jul 2009 16:43:50 -0700
changeset 26061 bb79d3a42c012b8dfdaed04ee1696e6f5091c17d
parent 26060 79292a9fdeb1bfda94750fb77de64cf4bf1ca2ad
child 26062 f3031a3f5fc62f30b8bdef41767bd4f74ff253d6
push id1769
push usermrbkap@mozilla.com
push dateTue, 14 Jul 2009 18:01:48 +0000
reviewersjst, bzbarsky, ss
bugs500691
milestone1.9.1.1pre
Bug 500691 - Call JS_ClearScope before XPConnect tries to update our outer window's scope's concept of what {Function,Object}.prototype are so that we forward correctly to the inner window's versions. r=jst sr=bzbarsky a=ss
dom/src/base/nsJSEnvironment.cpp
js/src/xpconnect/tests/mochitest/Makefile.in
js/src/xpconnect/tests/mochitest/test_bug500691.html
--- a/dom/src/base/nsJSEnvironment.cpp
+++ b/dom/src/base/nsJSEnvironment.cpp
@@ -2362,21 +2362,16 @@ nsJSContext::CreateNativeGlobalForInner(
 
 nsresult
 nsJSContext::ConnectToInner(nsIScriptGlobalObject *aNewInner, void *aOuterGlobal)
 {
   NS_ENSURE_ARG(aNewInner);
   JSObject *newInnerJSObject = (JSObject *)aNewInner->GetScriptGlobal(JAVASCRIPT);
   JSObject *myobject = (JSObject *)aOuterGlobal;
 
-  // Call ClearScope to nuke any properties (e.g. Function and Object) on the
-  // outer object. From now on, anybody asking the outer object for these
-  // properties will be forwarded to the inner window.
-  ::JS_ClearScope(mContext, myobject);
-
   // Make the inner and outer window both share the same
   // prototype. The prototype we share is the outer window's
   // prototype, this way XPConnect can still find the wrapper to
   // use when making a call like alert() (w/o qualifying it with
   // "window."). XPConnect looks up the wrapper based on the
   // function object's parent, which is the object the function
   // was called on, and when calling alert() we'll be calling the
   // alert() function from the outer window's prototype off of the
@@ -2469,21 +2464,33 @@ nsJSContext::InitContext(nsIScriptGlobal
     // Now check whether we need to grab a pointer to the
     // XPCNativeWrapper class
     if (!NS_DOMClassInfo_GetXPCNativeWrapperClass()) {
       JSAutoRequest ar(mContext);
       rv = FindXPCNativeWrapperClass(holder);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   } else {
-    // If there's already a global object in mContext we're called
-    // after ::JS_ClearScope() was called. We'll have to tell
-    // XPConnect to re-initialize the global object to do things like
+    // There's already a global object. We are preparing this outer window
+    // object for use as a real outer window (i.e. everything needs to live on
+    // the inner window).
+
+    // Call ClearScope to nuke any properties (e.g. Function and Object) on the
+    // outer object. From now on, anybody asking the outer object for these
+    // properties will be forwarded to the inner window.
+    ::JS_ClearScope(mContext, global);
+
+    // Tell XPConnect to re-initialize the global object to do things like
     // define the Components object on the global again and forget all
     // old prototypes in this scope.
+    // XXX Except that now, the global is thawed and has an inner window. So
+    // anything that XPConnect does to our global will be forwarded. So I
+    // think the only thing that this does for real is to call SetGlobal on
+    // our XPCWrappedNativeScope. Perhaps XPConnect should have a more
+    // targeted API?
     rv = xpc->InitClasses(mContext, global);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIClassInfo> ci(do_QueryInterface(aGlobalObject));
 
     if (ci) {
       rv = xpc->WrapNative(mContext, global, aGlobalObject,
                            NS_GET_IID(nsISupports),
--- a/js/src/xpconnect/tests/mochitest/Makefile.in
+++ b/js/src/xpconnect/tests/mochitest/Makefile.in
@@ -52,12 +52,13 @@ include $(topsrcdir)/config/rules.mk
 		test_bug428021.html \
 		test_bug448587.html \
 		test_wrappers.html \
 		test_bug446584.html \
 		test_bug462428.html \
 		test_bug478438.html \
 		test_bug484107.html \
 		test_bug484459.html \
+		test_bug500691.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/js/src/xpconnect/tests/mochitest/test_bug500691.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=500691
+-->
+<head>
+  <title>Test for Bug 500691</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=500691">Mozilla Bug 500691</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 500691 **/
+ok(Function === alert.constructor, "alert's constructor is our Function");
+ok(window.Function === alert.constructor, "window.Function is also correct");
+
+</script>
+</pre>
+</body>
+</html>