Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* vim: set ts=8 sts=4 et sw=4 tw=99: */
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/. */
6 :
7 : #include "xpcprivate.h"
8 : #include "XPCJSWeakReference.h"
9 :
10 : #include "nsContentUtils.h"
11 :
12 : using namespace JS;
13 :
14 0 : xpcJSWeakReference::xpcJSWeakReference()
15 : {
16 0 : }
17 :
18 0 : NS_IMPL_ISUPPORTS(xpcJSWeakReference, xpcIJSWeakReference)
19 :
20 0 : nsresult xpcJSWeakReference::Init(JSContext* cx, const JS::Value& object)
21 : {
22 0 : if (!object.isObject())
23 0 : return NS_OK;
24 :
25 0 : JS::RootedObject obj(cx, &object.toObject());
26 :
27 0 : XPCCallContext ccx(cx);
28 :
29 : // See if the object is a wrapped native that supports weak references.
30 0 : nsCOMPtr<nsISupports> supports = xpc::UnwrapReflectorToISupports(obj);
31 : nsCOMPtr<nsISupportsWeakReference> supportsWeakRef =
32 0 : do_QueryInterface(supports);
33 0 : if (supportsWeakRef) {
34 0 : supportsWeakRef->GetWeakReference(getter_AddRefs(mReferent));
35 0 : if (mReferent) {
36 0 : return NS_OK;
37 : }
38 : }
39 : // If it's not a wrapped native, or it is a wrapped native that does not
40 : // support weak references, fall back to getting a weak ref to the object.
41 :
42 : // See if object is a wrapped JSObject.
43 0 : RefPtr<nsXPCWrappedJS> wrapped;
44 0 : nsresult rv = nsXPCWrappedJS::GetNewOrUsed(obj,
45 : NS_GET_IID(nsISupports),
46 0 : getter_AddRefs(wrapped));
47 0 : if (!wrapped) {
48 0 : NS_ERROR("can't get nsISupportsWeakReference wrapper for obj");
49 0 : return rv;
50 : }
51 :
52 0 : return wrapped->GetWeakReference(getter_AddRefs(mReferent));
53 : }
54 :
55 : NS_IMETHODIMP
56 0 : xpcJSWeakReference::Get(JSContext* aCx, MutableHandleValue aRetval)
57 : {
58 0 : aRetval.setNull();
59 :
60 0 : if (!mReferent) {
61 0 : return NS_OK;
62 : }
63 :
64 0 : nsCOMPtr<nsISupports> supports = do_QueryReferent(mReferent);
65 0 : if (!supports) {
66 0 : return NS_OK;
67 : }
68 :
69 0 : nsCOMPtr<nsIXPConnectWrappedJS> wrappedObj = do_QueryInterface(supports);
70 0 : if (!wrappedObj) {
71 : // We have a generic XPCOM object that supports weak references here.
72 : // Wrap it and pass it out.
73 0 : return nsContentUtils::WrapNative(aCx, supports,
74 : &NS_GET_IID(nsISupports),
75 0 : aRetval);
76 : }
77 :
78 0 : JS::RootedObject obj(aCx, wrappedObj->GetJSObject());
79 0 : if (!obj) {
80 0 : return NS_OK;
81 : }
82 :
83 : // Most users of XPCWrappedJS don't need to worry about
84 : // re-wrapping because things are implicitly rewrapped by
85 : // xpcconvert. However, because we're doing this directly
86 : // through the native call context, we need to call
87 : // JS_WrapObject().
88 0 : if (!JS_WrapObject(aCx, &obj)) {
89 0 : return NS_ERROR_FAILURE;
90 : }
91 :
92 0 : aRetval.setObject(*obj);
93 0 : return NS_OK;
94 : }
|