1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "xpcprivate.h"
8 #include "XPCJSWeakReference.h"
10 #include "nsContentUtils.h"
14 xpcJSWeakReference::xpcJSWeakReference() = default;
16 NS_IMPL_ISUPPORTS(xpcJSWeakReference
, xpcIJSWeakReference
)
18 nsresult
xpcJSWeakReference::Init(JSContext
* cx
, const JS::Value
& object
) {
19 if (!object
.isObject()) {
23 JS::RootedObject
obj(cx
, &object
.toObject());
25 XPCCallContext
ccx(cx
);
27 // See if the object is a wrapped native that supports weak references.
28 nsCOMPtr
<nsISupports
> supports
= xpc::ReflectorToISupportsDynamic(obj
, cx
);
29 nsCOMPtr
<nsISupportsWeakReference
> supportsWeakRef
=
30 do_QueryInterface(supports
);
31 if (supportsWeakRef
) {
32 supportsWeakRef
->GetWeakReference(getter_AddRefs(mReferent
));
37 // If it's not a wrapped native, or it is a wrapped native that does not
38 // support weak references, fall back to getting a weak ref to the object.
40 // See if object is a wrapped JSObject.
41 RefPtr
<nsXPCWrappedJS
> wrapped
;
42 nsresult rv
= nsXPCWrappedJS::GetNewOrUsed(cx
, obj
, NS_GET_IID(nsISupports
),
43 getter_AddRefs(wrapped
));
45 NS_ERROR("can't get nsISupportsWeakReference wrapper for obj");
49 return wrapped
->GetWeakReference(getter_AddRefs(mReferent
));
53 xpcJSWeakReference::Get(JSContext
* aCx
, MutableHandleValue aRetval
) {
60 nsCOMPtr
<nsISupports
> supports
= do_QueryReferent(mReferent
);
65 nsCOMPtr
<nsIXPConnectWrappedJS
> wrappedObj
= do_QueryInterface(supports
);
67 // We have a generic XPCOM object that supports weak references here.
68 // Wrap it and pass it out.
69 return nsContentUtils::WrapNative(aCx
, supports
, &NS_GET_IID(nsISupports
),
73 JS::RootedObject
obj(aCx
, wrappedObj
->GetJSObject());
78 // Most users of XPCWrappedJS don't need to worry about
79 // re-wrapping because things are implicitly rewrapped by
80 // xpcconvert. However, because we're doing this directly
81 // through the native call context, we need to call
83 if (!JS_WrapObject(aCx
, &obj
)) {
84 return NS_ERROR_FAILURE
;
87 aRetval
.setObject(*obj
);