Bug 722671: Components.utils.getWeakReference should get a reference to the underlying native object if possible. r=mrbkap

This commit is contained in:
Kyle Huey 2012-04-01 19:21:13 -07:00
parent 3fd8367fa5
commit 30907f7e40
4 changed files with 64 additions and 5 deletions

View File

@ -38,6 +38,8 @@
#include "xpcprivate.h"
#include "XPCJSWeakReference.h"
#include "nsContentUtils.h"
xpcJSWeakReference::xpcJSWeakReference()
{
}
@ -55,6 +57,19 @@ nsresult xpcJSWeakReference::Init(JSContext* cx, const JS::Value& object)
XPCCallContext ccx(NATIVE_CALLER, cx);
// See if the object is a wrapped native that supports weak references.
nsISupports* supports =
nsXPConnect::GetXPConnect()->GetNativeOfWrapper(cx, &obj);
if (supports) {
mReferent = do_GetWeakReference(supports);
if (mReferent) {
return NS_OK;
}
}
// If it's not a wrapped native, or it is a wrapped native that does not
// support weak references, fall back to getting a weak ref to the object.
// See if object is a wrapped JSObject.
nsRefPtr<nsXPCWrappedJS> wrapped;
nsresult rv = nsXPCWrappedJS::GetNewOrUsed(ccx,
&obj,
@ -66,7 +81,7 @@ nsresult xpcJSWeakReference::Init(JSContext* cx, const JS::Value& object)
return rv;
}
return wrapped->GetWeakReference(getter_AddRefs(mWrappedJSObject));
return wrapped->GetWeakReference(getter_AddRefs(mReferent));
}
NS_IMETHODIMP
@ -74,15 +89,24 @@ xpcJSWeakReference::Get(JSContext* aCx, JS::Value* aRetval)
{
*aRetval = JSVAL_NULL;
if (!mWrappedJSObject) {
if (!mReferent) {
return NS_OK;
}
nsCOMPtr<nsIXPConnectWrappedJS> wrappedObj = do_QueryReferent(mWrappedJSObject);
if (!wrappedObj) {
nsCOMPtr<nsISupports> supports = do_QueryReferent(mReferent);
if (!supports) {
return NS_OK;
}
nsCOMPtr<nsIXPConnectWrappedJS> wrappedObj = do_QueryInterface(supports);
if (!wrappedObj) {
// We have a generic XPCOM object that supports weak references here.
// Wrap it and pass it out.
return nsContentUtils::WrapNative(aCx, JS_GetGlobalForScopeChain(aCx),
supports, &NS_GET_IID(nsISupports),
aRetval);
}
JSObject *obj;
wrappedObj->GetJSObject(&obj);
if (!obj) {

View File

@ -50,7 +50,7 @@ public:
NS_DECL_XPCIJSWEAKREFERENCE
private:
nsCOMPtr<nsIWeakReference> mWrappedJSObject;
nsCOMPtr<nsIWeakReference> mReferent;
};
#endif // xpcjsweakreference_h___

View File

@ -77,6 +77,7 @@ _CHROME_FILES = \
test_bug706301.xul \
test_watchpoints.xul \
test_exnstack.xul \
test_weakref.xul \
$(NULL)
# Disabled until this test gets updated to test the new proxy based

View File

@ -0,0 +1,34 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=484459
-->
<window title="Weakrefs"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml">
<iframe type="content" id="ifr">
</iframe>
</body>
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
SimpleTest.waitForExplicitFinish();
var util = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
var weakUtil = Components.utils.getWeakReference(util);
util = null;
function callback() {
ok(weakUtil.get(), "Should still be alive here");
SimpleTest.finish();
}
SpecialPowers.exactGC(window, callback);
]]></script>
</window>