diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index b3ce5b47ea5..3aa2a68526e 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -1526,25 +1526,17 @@ nsIDOMDocument * nsContentUtils::GetDocumentFromCaller() { JSContext *cx = nsnull; - sThreadJSContextStack->Peek(&cx); + JSObject *obj = nsnull; + sXPConnect->GetCaller(&cx, &obj); + NS_ASSERTION(cx && obj, "Caller ensures something is running"); - nsIDOMDocument *doc = nsnull; - - if (cx) { - JSObject *callee = nsnull; - JSStackFrame *fp = nsnull; - while (!callee && (fp = ::JS_FrameIterator(cx, &fp))) { - callee = ::JS_GetFrameCalleeObject(cx, fp); - } - - nsCOMPtr win = - do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(cx, callee)); - if (win) { - doc = win->GetExtantDocument(); - } + nsCOMPtr win = + do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(cx, obj)); + if (!win) { + return nsnull; } - return doc; + return win->GetExtantDocument(); } nsIDOMDocument * diff --git a/js/src/xpconnect/idl/nsIXPConnect.idl b/js/src/xpconnect/idl/nsIXPConnect.idl index 9a1d897a560..e443f4aba7e 100644 --- a/js/src/xpconnect/idl/nsIXPConnect.idl +++ b/js/src/xpconnect/idl/nsIXPConnect.idl @@ -399,7 +399,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports { 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } } %} -[uuid(7a3c8687-6f52-47d5-9b8e-2ed8bf86c415)] +[uuid(227ab41e-24dc-42a6-9e7b-e3a62132d781)] interface nsIXPConnect : nsISupports { %{ C++ @@ -892,4 +892,10 @@ interface nsIXPConnect : nsISupports */ nsIXPConnectJSObjectHolder holdObject(in JSContextPtr aJSContext, in JSObjectPtr aObject); + + /** + * Return the caller object of the current call from JS. + */ + [noscript,notxpcom] void getCaller(out JSContextPtr aJSContext, + out JSObjectPtr aObject); }; diff --git a/js/src/xpconnect/src/nsXPConnect.cpp b/js/src/xpconnect/src/nsXPConnect.cpp index 717443f787d..d7fdc852df9 100644 --- a/js/src/xpconnect/src/nsXPConnect.cpp +++ b/js/src/xpconnect/src/nsXPConnect.cpp @@ -2781,6 +2781,16 @@ nsXPConnect::HoldObject(JSContext *aJSContext, JSObject *aObject, return NS_OK; } +NS_IMETHODIMP_(void) +nsXPConnect::GetCaller(JSContext **aJSContext, JSObject **aObj) +{ + XPCCallContext *ccx = XPCPerThreadData::GetData(nsnull)->GetCallContext(); + *aJSContext = ccx->GetJSContext(); + + // Set to the caller in XPC_WN_Helper_{Call,Construct} + *aObj = ccx->GetFlattenedJSObject(); +} + /* These are here to be callable from a debugger */ JS_BEGIN_EXTERN_C JS_EXPORT_API(void) DumpJSStack() diff --git a/js/src/xpconnect/src/xpcwrappednativejsops.cpp b/js/src/xpconnect/src/xpcwrappednativejsops.cpp index 0dc8568201d..483b1551b1c 100644 --- a/js/src/xpconnect/src/xpcwrappednativejsops.cpp +++ b/js/src/xpconnect/src/xpcwrappednativejsops.cpp @@ -1069,6 +1069,12 @@ XPC_WN_Helper_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, if(!(obj = JSVAL_TO_OBJECT(argv[-2]))) return JS_FALSE; + XPCCallContext ccx(JS_CALLER, cx, obj, nsnull, JSID_VOID, argc, argv, rval); + if(!ccx.IsValid()) + return JS_FALSE; + + JS_ASSERT(obj == ccx.GetFlattenedJSObject()); + SLIM_LOG_WILL_MORPH(cx, obj); PRE_HELPER_STUB_NO_SLIM Call(wrapper, cx, obj, argc, argv, rval, &retval); @@ -1084,6 +1090,12 @@ XPC_WN_Helper_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, if(!(obj = JSVAL_TO_OBJECT(argv[-2]))) return JS_FALSE; + XPCCallContext ccx(JS_CALLER, cx, obj, nsnull, JSID_VOID, argc, argv, rval); + if(!ccx.IsValid()) + return JS_FALSE; + + JS_ASSERT(obj == ccx.GetFlattenedJSObject()); + SLIM_LOG_WILL_MORPH(cx, obj); PRE_HELPER_STUB_NO_SLIM Construct(wrapper, cx, obj, argc, argv, rval, &retval); diff --git a/js/src/xpconnect/tests/mochitest/Makefile.in b/js/src/xpconnect/tests/mochitest/Makefile.in index c49ca629817..7579b3f3a78 100644 --- a/js/src/xpconnect/tests/mochitest/Makefile.in +++ b/js/src/xpconnect/tests/mochitest/Makefile.in @@ -75,6 +75,8 @@ _TEST_FILES = bug500931_helper.html \ test_bug564330.html \ test_cows.html \ test_frameWrapping.html \ + test_bug589028.html \ + bug589028_helper.html \ $(NULL) libs:: $(_TEST_FILES) diff --git a/js/src/xpconnect/tests/mochitest/bug589028_helper.html b/js/src/xpconnect/tests/mochitest/bug589028_helper.html new file mode 100644 index 00000000000..dc56ecbc3c7 --- /dev/null +++ b/js/src/xpconnect/tests/mochitest/bug589028_helper.html @@ -0,0 +1,27 @@ + + + + + + the iframe + + diff --git a/js/src/xpconnect/tests/mochitest/test_bug589028.html b/js/src/xpconnect/tests/mochitest/test_bug589028.html new file mode 100644 index 00000000000..41971cea842 --- /dev/null +++ b/js/src/xpconnect/tests/mochitest/test_bug589028.html @@ -0,0 +1,63 @@ + + + + + Test for Bug 589028 + + + + + +Mozilla Bug 589028 +

+ +
+
+
+ + +