Bug 1917491 - Part 3: Introduce call-like syntax for resource disposal in DisposableS...
[gecko.git] / js / xpconnect / src / XPCRuntimeService.cpp
blob545dae5db3fa26d461831bdbd204d2e6e8ff0c74
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 "xpc_make_class.h"
10 #include "nsContentUtils.h"
11 #include "BackstagePass.h"
12 #include "mozilla/Result.h"
13 #include "mozilla/dom/BindingUtils.h"
14 #include "mozilla/dom/WebIDLGlobalNameHash.h"
15 #include "mozilla/dom/IndexedDatabaseManager.h"
16 #include "mozilla/ipc/BackgroundUtils.h"
17 #include "mozilla/ipc/PBackgroundSharedTypes.h"
19 using namespace mozilla::dom;
21 NS_IMPL_ISUPPORTS(BackstagePass, nsIXPCScriptable, nsIGlobalObject,
22 nsIClassInfo, nsIScriptObjectPrincipal,
23 nsISupportsWeakReference)
25 BackstagePass::BackstagePass()
26 : mPrincipal(nsContentUtils::GetSystemPrincipal()),
27 mWrapper(nullptr){}
28 // XXX(nika): It appears we don't have support for mayresolve hooks in
29 // nsIXPCScriptable, and I don't really want to add it because I'd rather just
30 // kill nsIXPCScriptable alltogether, so we don't use it here.
32 // The nsIXPCScriptable map declaration that will generate stubs for us...
33 #define XPC_MAP_CLASSNAME BackstagePass
34 #define XPC_MAP_QUOTED_CLASSNAME "BackstagePass"
35 #define XPC_MAP_FLAGS \
36 (XPC_SCRIPTABLE_WANT_RESOLVE | XPC_SCRIPTABLE_WANT_NEWENUMERATE | \
37 XPC_SCRIPTABLE_WANT_FINALIZE | XPC_SCRIPTABLE_WANT_PRECREATE | \
38 XPC_SCRIPTABLE_USE_JSSTUB_FOR_ADDPROPERTY | \
39 XPC_SCRIPTABLE_USE_JSSTUB_FOR_DELPROPERTY | \
40 XPC_SCRIPTABLE_DONT_ENUM_QUERY_INTERFACE | \
41 XPC_SCRIPTABLE_IS_GLOBAL_OBJECT | \
42 XPC_SCRIPTABLE_DONT_REFLECT_INTERFACE_NAMES)
43 #include "xpc_map_end.h" /* This will #undef the above */
45 JSObject
46 * BackstagePass::GetGlobalJSObject() {
47 if (mWrapper) {
48 return mWrapper->GetFlatJSObject();
50 return nullptr;
53 JSObject* BackstagePass::GetGlobalJSObjectPreserveColor() const {
54 if (mWrapper) {
55 return mWrapper->GetFlatJSObjectPreserveColor();
57 return nullptr;
60 void BackstagePass::SetGlobalObject(JSObject* global) {
61 nsISupports* p = XPCWrappedNative::Get(global);
62 MOZ_ASSERT(p);
63 mWrapper = static_cast<XPCWrappedNative*>(p);
66 NS_IMETHODIMP
67 BackstagePass::Resolve(nsIXPConnectWrappedNative* wrapper, JSContext* cx,
68 JSObject* objArg, jsid idArg, bool* resolvedp,
69 bool* _retval) {
70 JS::RootedObject obj(cx, objArg);
71 JS::RootedId id(cx, idArg);
72 *_retval =
73 WebIDLGlobalNameHash::ResolveForSystemGlobal(cx, obj, id, resolvedp);
74 if (!*_retval) {
75 return NS_ERROR_FAILURE;
78 if (*resolvedp) {
79 return NS_OK;
82 XPCJSContext* xpccx = XPCJSContext::Get();
83 if (id == xpccx->GetStringID(XPCJSContext::IDX_FETCH)) {
84 *_retval = xpc::SandboxCreateFetch(cx, obj);
85 if (!*_retval) {
86 return NS_ERROR_FAILURE;
88 *resolvedp = true;
89 } else if (id == xpccx->GetStringID(XPCJSContext::IDX_CRYPTO)) {
90 *_retval = xpc::SandboxCreateCrypto(cx, obj);
91 if (!*_retval) {
92 return NS_ERROR_FAILURE;
94 *resolvedp = true;
95 } else if (id == xpccx->GetStringID(XPCJSContext::IDX_INDEXEDDB)) {
96 *_retval = IndexedDatabaseManager::DefineIndexedDB(cx, obj);
97 if (!*_retval) {
98 return NS_ERROR_FAILURE;
100 *resolvedp = true;
101 } else if (id == xpccx->GetStringID(XPCJSContext::IDX_STRUCTUREDCLONE)) {
102 *_retval = xpc::SandboxCreateStructuredClone(cx, obj);
103 if (!*_retval) {
104 return NS_ERROR_FAILURE;
106 *resolvedp = true;
107 } else if (id == xpccx->GetStringID(XPCJSContext::IDX_LOCKS)) {
108 *_retval = xpc::SandboxCreateLocks(cx, obj);
109 if (!*_retval) {
110 return NS_ERROR_FAILURE;
112 *resolvedp = true;
115 return NS_OK;
118 NS_IMETHODIMP
119 BackstagePass::NewEnumerate(nsIXPConnectWrappedNative* wrapper, JSContext* cx,
120 JSObject* objArg,
121 JS::MutableHandleIdVector properties,
122 bool enumerableOnly, bool* _retval) {
123 JS::RootedObject obj(cx, objArg);
125 XPCJSContext* xpccx = XPCJSContext::Get();
126 if (!properties.append(xpccx->GetStringID(XPCJSContext::IDX_FETCH)) ||
127 !properties.append(xpccx->GetStringID(XPCJSContext::IDX_CRYPTO)) ||
128 !properties.append(xpccx->GetStringID(XPCJSContext::IDX_INDEXEDDB)) ||
129 !properties.append(
130 xpccx->GetStringID(XPCJSContext::IDX_STRUCTUREDCLONE)) ||
131 !properties.append(xpccx->GetStringID(XPCJSContext::IDX_LOCKS))) {
132 return NS_ERROR_FAILURE;
135 *_retval = WebIDLGlobalNameHash::NewEnumerateSystemGlobal(cx, obj, properties,
136 enumerableOnly);
137 return *_retval ? NS_OK : NS_ERROR_FAILURE;
140 /***************************************************************************/
141 NS_IMETHODIMP
142 BackstagePass::GetInterfaces(nsTArray<nsIID>& aArray) {
143 aArray = nsTArray<nsIID>{NS_GET_IID(nsIXPCScriptable),
144 NS_GET_IID(nsIScriptObjectPrincipal)};
145 return NS_OK;
148 NS_IMETHODIMP
149 BackstagePass::GetScriptableHelper(nsIXPCScriptable** retval) {
150 nsCOMPtr<nsIXPCScriptable> scriptable = this;
151 scriptable.forget(retval);
152 return NS_OK;
155 NS_IMETHODIMP
156 BackstagePass::GetContractID(nsACString& aContractID) {
157 aContractID.SetIsVoid(true);
158 return NS_ERROR_NOT_AVAILABLE;
161 NS_IMETHODIMP
162 BackstagePass::GetClassDescription(nsACString& aClassDescription) {
163 aClassDescription.AssignLiteral("BackstagePass");
164 return NS_OK;
167 NS_IMETHODIMP
168 BackstagePass::GetClassID(nsCID** aClassID) {
169 *aClassID = nullptr;
170 return NS_OK;
173 NS_IMETHODIMP
174 BackstagePass::GetFlags(uint32_t* aFlags) {
175 *aFlags = 0;
176 return NS_OK;
179 NS_IMETHODIMP
180 BackstagePass::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc) {
181 return NS_ERROR_NOT_AVAILABLE;
184 NS_IMETHODIMP
185 BackstagePass::Finalize(nsIXPConnectWrappedNative* wrapper, JS::GCContext* gcx,
186 JSObject* obj) {
187 nsCOMPtr<nsIGlobalObject> bsp(do_QueryInterface(wrapper->Native()));
188 MOZ_ASSERT(bsp);
189 static_cast<BackstagePass*>(bsp.get())->ForgetGlobalObject();
190 return NS_OK;
193 NS_IMETHODIMP
194 BackstagePass::PreCreate(nsISupports* nativeObj, JSContext* cx,
195 JSObject* globalObj, JSObject** parentObj) {
196 // We do the same trick here as for WindowSH. Return the js global
197 // as parent, so XPConenct can find the right scope and the wrapper
198 // that already exists.
199 nsCOMPtr<nsIGlobalObject> global(do_QueryInterface(nativeObj));
200 MOZ_ASSERT(global, "nativeObj not a global object!");
202 JSObject* jsglobal = global->GetGlobalJSObject();
203 if (jsglobal) {
204 *parentObj = jsglobal;
206 return NS_OK;
209 mozilla::Result<mozilla::ipc::PrincipalInfo, nsresult>
210 BackstagePass::GetStorageKey() {
211 MOZ_ASSERT(NS_IsMainThread());
213 mozilla::ipc::PrincipalInfo principalInfo;
214 nsresult rv = PrincipalToPrincipalInfo(mPrincipal, &principalInfo);
215 if (NS_FAILED(rv)) {
216 return mozilla::Err(rv);
219 MOZ_ASSERT(principalInfo.type() ==
220 mozilla::ipc::PrincipalInfo::TSystemPrincipalInfo);
222 return std::move(principalInfo);