author | Blake Kaplan <mrbkap@gmail.com> |
Fri, 10 Dec 2010 16:05:20 -0800 | |
changeset 59873 | b445e3e2dff0b4d51063d589faeb2136f98c60bb |
parent 59253 | c86a79eb18b95217369d7dc02e0ce3c79a6fdb68 |
child 59874 | ddcee925424589d422427669e969fa48f40f9a78 |
push id | 17820 |
push user | cleary@mozilla.com |
push date | Tue, 04 Jan 2011 21:40:57 +0000 |
treeherder | mozilla-central@969691cfe40e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jst |
bugs | 612267 |
milestone | 2.0b8pre |
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
|
--- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -2543,47 +2543,24 @@ nsJSContext::CreateNativeGlobalForInner( nsresult nsJSContext::ConnectToInner(nsIScriptGlobalObject *aNewInner, void *aOuterGlobal) { NS_ENSURE_ARG(aNewInner); JSObject *newInnerJSObject = (JSObject *)aNewInner->GetScriptGlobal(JAVASCRIPT); JSObject *outerGlobal = (JSObject *)aOuterGlobal; - // 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 - // inner window. In this case XPConnect is able to find the - // outer (through the JSExtendedClass hook outerObject), so this - // prototype sharing works. - // 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_SetGlobalObject(mContext, outerGlobal); - - // We do *not* want to use anything else out of the outer - // object's prototype chain than the first prototype, which is - // the XPConnect prototype. The rest we want from the inner - // window's prototype, i.e. the global scope polluter and - // Object.prototype. This way the outer also gets the benefits - // of the global scope polluter, and the inner window's - // Object.prototype. - JSObject *proto = JS_GetPrototype(mContext, outerGlobal); - JSObject *innerProto = JS_GetPrototype(mContext, newInnerJSObject); - JSObject *innerProtoProto = JS_GetPrototype(mContext, innerProto); - - JS_SetPrototype(mContext, newInnerJSObject, proto); - JS_SetPrototype(mContext, proto, innerProtoProto); + NS_ASSERTION(JS_GetPrototype(mContext, outerGlobal) == + JS_GetPrototype(mContext, newInnerJSObject), + "outer and inner globals should have the same prototype"); return NS_OK; } void * nsJSContext::GetNativeContext() { return mContext; @@ -2621,45 +2598,46 @@ nsJSContext::CreateOuterObject(nsIScript // Always enable E4X for XUL and other chrome content -- there is no // need to preserve the <!-- script hiding hack from JS-in-HTML daze // (introduced in 1995 for graceful script degradation in Netscape 1, // Mosaic, and other pre-JS browsers). JS_SetOptions(mContext, JS_GetOptions(mContext) | JSOPTION_XML); } - nsIXPConnect *xpc = nsContentUtils::XPConnect(); - nsCOMPtr<nsIXPConnectJSObjectHolder> holder; - - nsresult rv = xpc->WrapNative(mContext, aCurrentInner->GetGlobalJSObject(), - aCurrentInner, NS_GET_IID(nsISupports), - getter_AddRefs(holder)); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr<nsIXPConnectWrappedNative> wrapper(do_QueryInterface(holder)); - NS_ABORT_IF_FALSE(wrapper, "bad wrapper"); - - wrapper->RefreshPrototype(); - JSObject *outer = NS_NewOuterWindowProxy(mContext, aCurrentInner->GetGlobalJSObject()); if (!outer) { return NS_ERROR_FAILURE; } return SetOuterObject(outer); } nsresult nsJSContext::SetOuterObject(void *aOuterObject) { JSObject *outer = static_cast<JSObject *>(aOuterObject); // Force our context's global object to be the outer. JS_SetGlobalObject(mContext, outer); + + // NB: JS_SetGlobalObject sets mContext->compartment. + JSObject *inner = JS_GetParent(mContext, outer); + + nsIXPConnect *xpc = nsContentUtils::XPConnect(); + nsCOMPtr<nsIXPConnectWrappedNative> wrapper; + nsresult rv = xpc->GetWrappedNativeOfJSObject(mContext, inner, + getter_AddRefs(wrapper)); + NS_ENSURE_SUCCESS(rv, rv); + NS_ABORT_IF_FALSE(wrapper, "bad wrapper"); + + wrapper->RefreshPrototype(); + JS_SetPrototype(mContext, outer, JS_GetPrototype(mContext, inner)); + return NS_OK; } nsresult nsJSContext::InitOuterWindow() { JSObject *global = JS_GetGlobalObject(mContext); OBJ_TO_INNER_OBJECT(mContext, global);
--- a/dom/tests/mochitest/bugs/Makefile.in +++ b/dom/tests/mochitest/bugs/Makefile.in @@ -121,12 +121,13 @@ include $(topsrcdir)/config/rules.mk test_DOMWindowCreated_chromeonly.html \ test_bug581072.html \ test_bug583225.html \ test_bug585240.html \ test_bug585819.html \ test_bug369306.html \ test_bug61098.html \ test_bug597809.html \ + test_bug612267.html \ $(NULL) libs:: $(_TEST_FILES) $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644 --- /dev/null +++ b/dom/tests/mochitest/bugs/test_bug612267.html @@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=612267 +--> +<head> + <title>Test for Bug 393974</title> + <script type="text/javascript" src="/MochiKit/packed.js"></script> + <script type="text/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=612267">Mozilla Bug 612267</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +Window.prototype.test = 'PASS'; +is(window.test, 'PASS', "setting Window.prototype affects window.__proto__"); +is(test, 'PASS', "setting Window.prototype affects the inner window lookup for sure"); + +</script> +</pre> +</body> +</html>
--- a/js/src/xpconnect/src/nsXPConnect.cpp +++ b/js/src/xpconnect/src/nsXPConnect.cpp @@ -1143,17 +1143,17 @@ nsXPConnect::InitClassesWithNewWrappedGl XPCWrappedNative* wrapper = reinterpret_cast<XPCWrappedNative*>(holder.get()); XPCWrappedNativeScope* scope = wrapper->GetScope(); if(!scope) return UnexpectedFailure(NS_ERROR_FAILURE); // Note: This call cooperates with a call to wrapper->RefreshPrototype() - // in nsJSEnvironment::CreateOuterObject in order to ensure that the + // in nsJSEnvironment::SetOuterObject in order to ensure that the // prototype defines its constructor on the right global object. if(wrapper->GetProto()->GetScriptableInfo()) scope->RemoveWrappedNativeProtos(); NS_ASSERTION(scope->GetGlobalJSObject() == tempGlobal, "stealing scope!"); scope->SetGlobal(ccx, globalJSObj);