Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM AddonManager.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "AddonManagerBinding.h"
4 : #include "AtomList.h"
5 : #include "EventTargetBinding.h"
6 : #include "WrapperFactory.h"
7 : #include "mozilla/AddonManagerWebAPI.h"
8 : #include "mozilla/OwningNonNull.h"
9 : #include "mozilla/dom/BindingUtils.h"
10 : #include "mozilla/dom/DOMJSClass.h"
11 : #include "mozilla/dom/NonRefcountedDOMObject.h"
12 : #include "mozilla/dom/Nullable.h"
13 : #include "mozilla/dom/PrimitiveConversions.h"
14 : #include "mozilla/dom/Promise.h"
15 : #include "mozilla/dom/ScriptSettings.h"
16 : #include "mozilla/dom/SimpleGlobalObject.h"
17 : #include "mozilla/dom/ToJSValue.h"
18 : #include "mozilla/dom/XrayExpandoClass.h"
19 : #include "nsContentUtils.h"
20 : #include "nsIGlobalObject.h"
21 : #include "nsThreadUtils.h"
22 :
23 : namespace mozilla {
24 : namespace dom {
25 :
26 :
27 0 : addonInstallOptions::addonInstallOptions()
28 : {
29 : // Safe to pass a null context if we pass a null value
30 0 : Init(nullptr, JS::NullHandleValue);
31 0 : }
32 :
33 :
34 :
35 : bool
36 0 : addonInstallOptions::InitIds(JSContext* cx, addonInstallOptionsAtoms* atomsCache)
37 : {
38 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
39 :
40 : // Initialize these in reverse order so that any failure leaves the first one
41 : // uninitialized.
42 0 : if (!atomsCache->url_id.init(cx, "url") ||
43 0 : !atomsCache->hash_id.init(cx, "hash")) {
44 0 : return false;
45 : }
46 0 : return true;
47 : }
48 :
49 : bool
50 0 : addonInstallOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
51 : {
52 : // Passing a null JSContext is OK only if we're initing from null,
53 : // Since in that case we will not have to do any property gets
54 : // Also evaluate isNullOrUndefined in order to avoid false-positive
55 : // checkers by static analysis tools
56 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
57 0 : addonInstallOptionsAtoms* atomsCache = nullptr;
58 0 : if (cx) {
59 0 : atomsCache = GetAtomCache<addonInstallOptionsAtoms>(cx);
60 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
61 0 : return false;
62 : }
63 : }
64 :
65 0 : if (!IsConvertibleToDictionary(val)) {
66 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
67 : }
68 :
69 0 : bool isNull = val.isNullOrUndefined();
70 : // We only need these if !isNull, in which case we have |cx|.
71 0 : Maybe<JS::Rooted<JSObject *> > object;
72 0 : Maybe<JS::Rooted<JS::Value> > temp;
73 0 : if (!isNull) {
74 0 : MOZ_ASSERT(cx);
75 0 : object.emplace(cx, &val.toObject());
76 0 : temp.emplace(cx);
77 : }
78 0 : if (!isNull) {
79 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->hash_id, temp.ptr())) {
80 0 : return false;
81 : }
82 : }
83 0 : if (!isNull && !temp->isUndefined()) {
84 0 : if (!ConvertJSValueToString(cx, temp.ref(), eNull, eNull, mHash)) {
85 0 : return false;
86 : }
87 : } else {
88 0 : mHash.SetIsVoid(true);
89 : }
90 0 : mIsAnyMemberPresent = true;
91 :
92 0 : if (!isNull) {
93 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->url_id, temp.ptr())) {
94 0 : return false;
95 : }
96 : }
97 0 : if (!isNull && !temp->isUndefined()) {
98 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mUrl)) {
99 0 : return false;
100 : }
101 0 : mIsAnyMemberPresent = true;
102 0 : } else if (cx) {
103 : // Don't error out if we have no cx. In that
104 : // situation the caller is default-constructing us and we'll
105 : // just assume they know what they're doing.
106 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
107 0 : "'url' member of addonInstallOptions");
108 : }
109 0 : return true;
110 : }
111 :
112 : bool
113 0 : addonInstallOptions::Init(const nsAString& aJSON)
114 : {
115 0 : AutoJSAPI jsapi;
116 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
117 0 : if (!cleanGlobal) {
118 0 : return false;
119 : }
120 0 : if (!jsapi.Init(cleanGlobal)) {
121 0 : return false;
122 : }
123 0 : JSContext* cx = jsapi.cx();
124 0 : JS::Rooted<JS::Value> json(cx);
125 0 : bool ok = ParseJSON(cx, aJSON, &json);
126 0 : NS_ENSURE_TRUE(ok, false);
127 0 : return Init(cx, json);
128 : }
129 :
130 : bool
131 0 : addonInstallOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
132 : {
133 0 : addonInstallOptionsAtoms* atomsCache = GetAtomCache<addonInstallOptionsAtoms>(cx);
134 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
135 0 : return false;
136 : }
137 :
138 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
139 0 : if (!obj) {
140 0 : return false;
141 : }
142 0 : rval.set(JS::ObjectValue(*obj));
143 :
144 : do {
145 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
146 0 : JS::Rooted<JS::Value> temp(cx);
147 0 : nsString const & currentValue = mHash;
148 0 : if (!xpc::StringToJsval(cx, currentValue, &temp)) {
149 0 : return false;
150 : }
151 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->hash_id, temp, JSPROP_ENUMERATE)) {
152 0 : return false;
153 : }
154 0 : break;
155 : } while(0);
156 :
157 : do {
158 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
159 0 : JS::Rooted<JS::Value> temp(cx);
160 0 : nsString const & currentValue = mUrl;
161 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
162 0 : return false;
163 : }
164 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->url_id, temp, JSPROP_ENUMERATE)) {
165 0 : return false;
166 : }
167 0 : break;
168 : } while(0);
169 :
170 0 : return true;
171 : }
172 :
173 : bool
174 0 : addonInstallOptions::ToJSON(nsAString& aJSON) const
175 : {
176 0 : AutoJSAPI jsapi;
177 0 : jsapi.Init();
178 0 : JSContext *cx = jsapi.cx();
179 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
180 : // because we'll only be creating objects, in ways that have no
181 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
182 : // which likewise guarantees no side-effects for the sorts of
183 : // things we will pass it.
184 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
185 0 : JS::Rooted<JS::Value> val(cx);
186 0 : if (!ToObjectInternal(cx, &val)) {
187 0 : return false;
188 : }
189 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
190 0 : return StringifyToJSON(cx, obj, aJSON);
191 : }
192 :
193 : void
194 0 : addonInstallOptions::TraceDictionary(JSTracer* trc)
195 : {
196 0 : }
197 :
198 : addonInstallOptions&
199 0 : addonInstallOptions::operator=(const addonInstallOptions& aOther)
200 : {
201 0 : mHash = aOther.mHash;
202 0 : mUrl = aOther.mUrl;
203 0 : return *this;
204 : }
205 :
206 : namespace binding_detail {
207 : } // namespace binding_detail
208 :
209 :
210 : namespace AddonBinding {
211 :
212 : static bool
213 0 : get_id(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Addon* self, JSJitGetterCallArgs args)
214 : {
215 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
216 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
217 0 : if (objIsXray) {
218 0 : unwrappedObj.emplace(cx, obj);
219 : }
220 0 : if (objIsXray) {
221 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
222 0 : if (!unwrappedObj.ref()) {
223 0 : return false;
224 : }
225 : }
226 0 : binding_detail::FastErrorResult rv;
227 0 : DOMString result;
228 0 : self->GetId(result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
229 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
230 0 : return false;
231 : }
232 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
233 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
234 0 : return false;
235 : }
236 0 : return true;
237 : }
238 :
239 : static const JSJitInfo id_getterinfo = {
240 : { (JSJitGetterOp)get_id },
241 : { prototypes::id::Addon },
242 : { PrototypeTraits<prototypes::id::Addon>::Depth },
243 : JSJitInfo::Getter,
244 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
245 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
246 : false, /* isInfallible. False in setters. */
247 : false, /* isMovable. Not relevant for setters. */
248 : false, /* isEliminatable. Not relevant for setters. */
249 : false, /* isAlwaysInSlot. Only relevant for getters. */
250 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
251 : false, /* isTypedMethod. Only relevant for methods. */
252 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
253 : };
254 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
255 : static_assert(0 < 1, "There is no slot for us");
256 :
257 : static bool
258 0 : get_version(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Addon* self, JSJitGetterCallArgs args)
259 : {
260 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
261 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
262 0 : if (objIsXray) {
263 0 : unwrappedObj.emplace(cx, obj);
264 : }
265 0 : if (objIsXray) {
266 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
267 0 : if (!unwrappedObj.ref()) {
268 0 : return false;
269 : }
270 : }
271 0 : binding_detail::FastErrorResult rv;
272 0 : DOMString result;
273 0 : self->GetVersion(result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
274 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
275 0 : return false;
276 : }
277 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
278 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
279 0 : return false;
280 : }
281 0 : return true;
282 : }
283 :
284 : static const JSJitInfo version_getterinfo = {
285 : { (JSJitGetterOp)get_version },
286 : { prototypes::id::Addon },
287 : { PrototypeTraits<prototypes::id::Addon>::Depth },
288 : JSJitInfo::Getter,
289 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
290 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
291 : false, /* isInfallible. False in setters. */
292 : false, /* isMovable. Not relevant for setters. */
293 : false, /* isEliminatable. Not relevant for setters. */
294 : false, /* isAlwaysInSlot. Only relevant for getters. */
295 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
296 : false, /* isTypedMethod. Only relevant for methods. */
297 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
298 : };
299 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
300 : static_assert(0 < 1, "There is no slot for us");
301 :
302 : static bool
303 0 : get_type(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Addon* self, JSJitGetterCallArgs args)
304 : {
305 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
306 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
307 0 : if (objIsXray) {
308 0 : unwrappedObj.emplace(cx, obj);
309 : }
310 0 : if (objIsXray) {
311 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
312 0 : if (!unwrappedObj.ref()) {
313 0 : return false;
314 : }
315 : }
316 0 : binding_detail::FastErrorResult rv;
317 0 : DOMString result;
318 0 : self->GetType(result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
319 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
320 0 : return false;
321 : }
322 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
323 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
324 0 : return false;
325 : }
326 0 : return true;
327 : }
328 :
329 : static const JSJitInfo type_getterinfo = {
330 : { (JSJitGetterOp)get_type },
331 : { prototypes::id::Addon },
332 : { PrototypeTraits<prototypes::id::Addon>::Depth },
333 : JSJitInfo::Getter,
334 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
335 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
336 : false, /* isInfallible. False in setters. */
337 : false, /* isMovable. Not relevant for setters. */
338 : false, /* isEliminatable. Not relevant for setters. */
339 : false, /* isAlwaysInSlot. Only relevant for getters. */
340 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
341 : false, /* isTypedMethod. Only relevant for methods. */
342 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
343 : };
344 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
345 : static_assert(0 < 1, "There is no slot for us");
346 :
347 : static bool
348 0 : get_name(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Addon* self, JSJitGetterCallArgs args)
349 : {
350 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
351 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
352 0 : if (objIsXray) {
353 0 : unwrappedObj.emplace(cx, obj);
354 : }
355 0 : if (objIsXray) {
356 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
357 0 : if (!unwrappedObj.ref()) {
358 0 : return false;
359 : }
360 : }
361 0 : binding_detail::FastErrorResult rv;
362 0 : DOMString result;
363 0 : self->GetName(result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
364 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
365 0 : return false;
366 : }
367 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
368 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
369 0 : return false;
370 : }
371 0 : return true;
372 : }
373 :
374 : static const JSJitInfo name_getterinfo = {
375 : { (JSJitGetterOp)get_name },
376 : { prototypes::id::Addon },
377 : { PrototypeTraits<prototypes::id::Addon>::Depth },
378 : JSJitInfo::Getter,
379 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
380 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
381 : false, /* isInfallible. False in setters. */
382 : false, /* isMovable. Not relevant for setters. */
383 : false, /* isEliminatable. Not relevant for setters. */
384 : false, /* isAlwaysInSlot. Only relevant for getters. */
385 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
386 : false, /* isTypedMethod. Only relevant for methods. */
387 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
388 : };
389 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
390 : static_assert(0 < 1, "There is no slot for us");
391 :
392 : static bool
393 0 : get_description(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Addon* self, JSJitGetterCallArgs args)
394 : {
395 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
396 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
397 0 : if (objIsXray) {
398 0 : unwrappedObj.emplace(cx, obj);
399 : }
400 0 : if (objIsXray) {
401 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
402 0 : if (!unwrappedObj.ref()) {
403 0 : return false;
404 : }
405 : }
406 0 : binding_detail::FastErrorResult rv;
407 0 : DOMString result;
408 0 : self->GetDescription(result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
409 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
410 0 : return false;
411 : }
412 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
413 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
414 0 : return false;
415 : }
416 0 : return true;
417 : }
418 :
419 : static const JSJitInfo description_getterinfo = {
420 : { (JSJitGetterOp)get_description },
421 : { prototypes::id::Addon },
422 : { PrototypeTraits<prototypes::id::Addon>::Depth },
423 : JSJitInfo::Getter,
424 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
425 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
426 : false, /* isInfallible. False in setters. */
427 : false, /* isMovable. Not relevant for setters. */
428 : false, /* isEliminatable. Not relevant for setters. */
429 : false, /* isAlwaysInSlot. Only relevant for getters. */
430 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
431 : false, /* isTypedMethod. Only relevant for methods. */
432 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
433 : };
434 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
435 : static_assert(0 < 1, "There is no slot for us");
436 :
437 : static bool
438 0 : get_isEnabled(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Addon* self, JSJitGetterCallArgs args)
439 : {
440 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
441 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
442 0 : if (objIsXray) {
443 0 : unwrappedObj.emplace(cx, obj);
444 : }
445 0 : if (objIsXray) {
446 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
447 0 : if (!unwrappedObj.ref()) {
448 0 : return false;
449 : }
450 : }
451 0 : binding_detail::FastErrorResult rv;
452 0 : bool result(self->GetIsEnabled(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
453 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
454 0 : return false;
455 : }
456 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
457 0 : args.rval().setBoolean(result);
458 0 : return true;
459 : }
460 :
461 : static const JSJitInfo isEnabled_getterinfo = {
462 : { (JSJitGetterOp)get_isEnabled },
463 : { prototypes::id::Addon },
464 : { PrototypeTraits<prototypes::id::Addon>::Depth },
465 : JSJitInfo::Getter,
466 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
467 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
468 : false, /* isInfallible. False in setters. */
469 : false, /* isMovable. Not relevant for setters. */
470 : false, /* isEliminatable. Not relevant for setters. */
471 : false, /* isAlwaysInSlot. Only relevant for getters. */
472 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
473 : false, /* isTypedMethod. Only relevant for methods. */
474 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
475 : };
476 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
477 : static_assert(0 < 1, "There is no slot for us");
478 :
479 : static bool
480 0 : get_isActive(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Addon* self, JSJitGetterCallArgs args)
481 : {
482 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
483 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
484 0 : if (objIsXray) {
485 0 : unwrappedObj.emplace(cx, obj);
486 : }
487 0 : if (objIsXray) {
488 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
489 0 : if (!unwrappedObj.ref()) {
490 0 : return false;
491 : }
492 : }
493 0 : binding_detail::FastErrorResult rv;
494 0 : bool result(self->GetIsActive(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
495 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
496 0 : return false;
497 : }
498 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
499 0 : args.rval().setBoolean(result);
500 0 : return true;
501 : }
502 :
503 : static const JSJitInfo isActive_getterinfo = {
504 : { (JSJitGetterOp)get_isActive },
505 : { prototypes::id::Addon },
506 : { PrototypeTraits<prototypes::id::Addon>::Depth },
507 : JSJitInfo::Getter,
508 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
509 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
510 : false, /* isInfallible. False in setters. */
511 : false, /* isMovable. Not relevant for setters. */
512 : false, /* isEliminatable. Not relevant for setters. */
513 : false, /* isAlwaysInSlot. Only relevant for getters. */
514 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
515 : false, /* isTypedMethod. Only relevant for methods. */
516 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
517 : };
518 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
519 : static_assert(0 < 1, "There is no slot for us");
520 :
521 : static bool
522 0 : get_canUninstall(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Addon* self, JSJitGetterCallArgs args)
523 : {
524 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
525 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
526 0 : if (objIsXray) {
527 0 : unwrappedObj.emplace(cx, obj);
528 : }
529 0 : if (objIsXray) {
530 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
531 0 : if (!unwrappedObj.ref()) {
532 0 : return false;
533 : }
534 : }
535 0 : binding_detail::FastErrorResult rv;
536 0 : bool result(self->GetCanUninstall(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
537 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
538 0 : return false;
539 : }
540 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
541 0 : args.rval().setBoolean(result);
542 0 : return true;
543 : }
544 :
545 : static const JSJitInfo canUninstall_getterinfo = {
546 : { (JSJitGetterOp)get_canUninstall },
547 : { prototypes::id::Addon },
548 : { PrototypeTraits<prototypes::id::Addon>::Depth },
549 : JSJitInfo::Getter,
550 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
551 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
552 : false, /* isInfallible. False in setters. */
553 : false, /* isMovable. Not relevant for setters. */
554 : false, /* isEliminatable. Not relevant for setters. */
555 : false, /* isAlwaysInSlot. Only relevant for getters. */
556 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
557 : false, /* isTypedMethod. Only relevant for methods. */
558 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
559 : };
560 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
561 : static_assert(0 < 1, "There is no slot for us");
562 :
563 : static bool
564 0 : uninstall(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Addon* self, const JSJitMethodCallArgs& args)
565 : {
566 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
567 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
568 0 : if (objIsXray) {
569 0 : unwrappedObj.emplace(cx, obj);
570 : }
571 0 : if (objIsXray) {
572 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
573 0 : if (!unwrappedObj.ref()) {
574 0 : return false;
575 : }
576 : }
577 0 : binding_detail::FastErrorResult rv;
578 0 : auto result(StrongOrRawPtr<Promise>(self->Uninstall(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
579 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
580 0 : return false;
581 : }
582 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
583 0 : if (!ToJSValue(cx, result, args.rval())) {
584 0 : return false;
585 : }
586 0 : return true;
587 : }
588 :
589 : static bool
590 0 : uninstall_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Addon* self, const JSJitMethodCallArgs& args)
591 : {
592 : // Make sure to save the callee before someone maybe messes
593 : // with rval().
594 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
595 0 : bool ok = uninstall(cx, obj, self, args);
596 0 : if (ok) {
597 0 : return true;
598 : }
599 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
600 0 : args.rval());
601 : }
602 :
603 : static const JSJitInfo uninstall_methodinfo = {
604 : { (JSJitGetterOp)uninstall_promiseWrapper },
605 : { prototypes::id::Addon },
606 : { PrototypeTraits<prototypes::id::Addon>::Depth },
607 : JSJitInfo::Method,
608 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
609 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
610 : false, /* isInfallible. False in setters. */
611 : false, /* isMovable. Not relevant for setters. */
612 : false, /* isEliminatable. Not relevant for setters. */
613 : false, /* isAlwaysInSlot. Only relevant for getters. */
614 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
615 : false, /* isTypedMethod. Only relevant for methods. */
616 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
617 : };
618 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
619 : static_assert(0 < 1, "There is no slot for us");
620 :
621 : static bool
622 0 : setEnabled(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Addon* self, const JSJitMethodCallArgs& args)
623 : {
624 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
625 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Addon.setEnabled");
626 : }
627 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
628 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
629 0 : if (objIsXray) {
630 0 : unwrappedObj.emplace(cx, obj);
631 : }
632 : bool arg0;
633 0 : if (!ValueToPrimitive<bool, eDefault>(cx, args[0], &arg0)) {
634 0 : return false;
635 : }
636 0 : if (objIsXray) {
637 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
638 0 : if (!unwrappedObj.ref()) {
639 0 : return false;
640 : }
641 : }
642 0 : binding_detail::FastErrorResult rv;
643 0 : auto result(StrongOrRawPtr<Promise>(self->SetEnabled(arg0, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
644 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
645 0 : return false;
646 : }
647 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
648 0 : if (!ToJSValue(cx, result, args.rval())) {
649 0 : return false;
650 : }
651 0 : return true;
652 : }
653 :
654 : static bool
655 0 : setEnabled_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Addon* self, const JSJitMethodCallArgs& args)
656 : {
657 : // Make sure to save the callee before someone maybe messes
658 : // with rval().
659 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
660 0 : bool ok = setEnabled(cx, obj, self, args);
661 0 : if (ok) {
662 0 : return true;
663 : }
664 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
665 0 : args.rval());
666 : }
667 :
668 : static const JSJitInfo setEnabled_methodinfo = {
669 : { (JSJitGetterOp)setEnabled_promiseWrapper },
670 : { prototypes::id::Addon },
671 : { PrototypeTraits<prototypes::id::Addon>::Depth },
672 : JSJitInfo::Method,
673 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
674 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
675 : false, /* isInfallible. False in setters. */
676 : false, /* isMovable. Not relevant for setters. */
677 : false, /* isEliminatable. Not relevant for setters. */
678 : false, /* isAlwaysInSlot. Only relevant for getters. */
679 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
680 : false, /* isTypedMethod. Only relevant for methods. */
681 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
682 : };
683 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
684 : static_assert(0 < 1, "There is no slot for us");
685 :
686 : static bool
687 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
688 : {
689 0 : mozilla::dom::Addon* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Addon>(obj);
690 : // We don't want to preserve if we don't have a wrapper, and we
691 : // obviously can't preserve if we're not initialized.
692 0 : if (self && self->GetWrapperPreserveColor()) {
693 0 : PreserveWrapper(self);
694 : }
695 0 : return true;
696 : }
697 :
698 : static void
699 0 : _finalize(js::FreeOp* fop, JSObject* obj)
700 : {
701 0 : mozilla::dom::Addon* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Addon>(obj);
702 0 : if (self) {
703 0 : ClearWrapper(self, self, obj);
704 0 : AddForDeferredFinalization<mozilla::dom::Addon>(self);
705 : }
706 0 : }
707 :
708 : static void
709 0 : _objectMoved(JSObject* obj, const JSObject* old)
710 : {
711 0 : mozilla::dom::Addon* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Addon>(obj);
712 0 : if (self) {
713 0 : UpdateWrapper(self, self, obj, old);
714 : }
715 0 : }
716 :
717 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
718 : #if defined(__clang__)
719 : #pragma clang diagnostic push
720 : #pragma clang diagnostic ignored "-Wmissing-braces"
721 : #endif
722 : static const JSFunctionSpec sChromeStaticMethods_specs[] = {
723 : JS_FNSPEC("_create", Addon::_Create, nullptr, 2, 0, nullptr),
724 : JS_FS_END
725 : };
726 : #if defined(__clang__)
727 : #pragma clang diagnostic pop
728 : #endif
729 :
730 :
731 : // Can't be const because the pref-enabled boolean needs to be writable
732 : static Prefable<const JSFunctionSpec> sChromeStaticMethods[] = {
733 : { nullptr, &sChromeStaticMethods_specs[0] },
734 : { nullptr, nullptr }
735 : };
736 :
737 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
738 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
739 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
740 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
741 :
742 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
743 : #if defined(__clang__)
744 : #pragma clang diagnostic push
745 : #pragma clang diagnostic ignored "-Wmissing-braces"
746 : #endif
747 : static const JSFunctionSpec sMethods_specs[] = {
748 : JS_FNSPEC("uninstall", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&uninstall_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
749 : JS_FNSPEC("setEnabled", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&setEnabled_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
750 : JS_FS_END
751 : };
752 : #if defined(__clang__)
753 : #pragma clang diagnostic pop
754 : #endif
755 :
756 :
757 : // Can't be const because the pref-enabled boolean needs to be writable
758 : static Prefable<const JSFunctionSpec> sMethods[] = {
759 : { nullptr, &sMethods_specs[0] },
760 : { nullptr, nullptr }
761 : };
762 :
763 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
764 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
765 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
766 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
767 :
768 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
769 : #if defined(__clang__)
770 : #pragma clang diagnostic push
771 : #pragma clang diagnostic ignored "-Wmissing-braces"
772 : #endif
773 : static const JSPropertySpec sAttributes_specs[] = {
774 : { "id", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &id_getterinfo, nullptr, nullptr },
775 : { "version", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &version_getterinfo, nullptr, nullptr },
776 : { "type", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &type_getterinfo, nullptr, nullptr },
777 : { "name", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &name_getterinfo, nullptr, nullptr },
778 : { "description", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &description_getterinfo, nullptr, nullptr },
779 : { "isEnabled", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &isEnabled_getterinfo, nullptr, nullptr },
780 : { "isActive", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &isActive_getterinfo, nullptr, nullptr },
781 : { "canUninstall", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &canUninstall_getterinfo, nullptr, nullptr },
782 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
783 : };
784 : #if defined(__clang__)
785 : #pragma clang diagnostic pop
786 : #endif
787 :
788 :
789 : // Can't be const because the pref-enabled boolean needs to be writable
790 : static Prefable<const JSPropertySpec> sAttributes[] = {
791 : { nullptr, &sAttributes_specs[0] },
792 : { nullptr, nullptr }
793 : };
794 :
795 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
796 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
797 : static_assert(8 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
798 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
799 :
800 :
801 : static uint16_t sNativeProperties_sortedPropertyIndices[10];
802 : static PropertyInfo sNativeProperties_propertyInfos[10];
803 :
804 : static const NativePropertiesN<2> sNativeProperties = {
805 : false, 0,
806 : false, 0,
807 : true, 0 /* sMethods */,
808 : true, 1 /* sAttributes */,
809 : false, 0,
810 : false, 0,
811 : false, 0,
812 : -1,
813 : 10,
814 : sNativeProperties_sortedPropertyIndices,
815 : {
816 : { sMethods, &sNativeProperties_propertyInfos[0] },
817 : { sAttributes, &sNativeProperties_propertyInfos[2] }
818 : }
819 : };
820 : static_assert(10 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
821 : "We have a property info count that is oversized");
822 :
823 : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[1];
824 : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[1];
825 :
826 : static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
827 : true, 0 /* sChromeStaticMethods */,
828 : false, 0,
829 : false, 0,
830 : false, 0,
831 : false, 0,
832 : false, 0,
833 : false, 0,
834 : -1,
835 : 1,
836 : sChromeOnlyNativeProperties_sortedPropertyIndices,
837 : {
838 : { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] }
839 : }
840 : };
841 : static_assert(1 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
842 : "We have a property info count that is oversized");
843 :
844 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
845 : {
846 : "Function",
847 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
848 : &sBoringInterfaceObjectClassClassOps,
849 : JS_NULL_CLASS_SPEC,
850 : JS_NULL_CLASS_EXT,
851 : &sInterfaceObjectClassObjectOps
852 : },
853 : eInterface,
854 : true,
855 : prototypes::id::Addon,
856 : PrototypeTraits<prototypes::id::Addon>::Depth,
857 : sNativePropertyHooks,
858 : "function Addon() {\n [native code]\n}",
859 : JS::GetRealmFunctionPrototype
860 : };
861 :
862 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
863 : {
864 : "AddonPrototype",
865 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
866 : JS_NULL_CLASS_OPS,
867 : JS_NULL_CLASS_SPEC,
868 : JS_NULL_CLASS_EXT,
869 : JS_NULL_OBJECT_OPS
870 : },
871 : eInterfacePrototype,
872 : false,
873 : prototypes::id::Addon,
874 : PrototypeTraits<prototypes::id::Addon>::Depth,
875 : sNativePropertyHooks,
876 : "[object AddonPrototype]",
877 : JS::GetRealmObjectPrototype
878 : };
879 :
880 : bool
881 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
882 : {
883 0 : return nsContentUtils::ThreadsafeIsSystemCaller(aCx);
884 : }
885 :
886 : JSObject*
887 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
888 : {
889 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
890 : }
891 :
892 : static const js::ClassOps sClassOps = {
893 : _addProperty, /* addProperty */
894 : nullptr, /* delProperty */
895 : nullptr, /* getProperty */
896 : nullptr, /* setProperty */
897 : nullptr, /* enumerate */
898 : nullptr, /* newEnumerate */
899 : nullptr, /* resolve */
900 : nullptr, /* mayResolve */
901 : _finalize, /* finalize */
902 : nullptr, /* call */
903 : nullptr, /* hasInstance */
904 : nullptr, /* construct */
905 : nullptr, /* trace */
906 : };
907 :
908 : static const js::ClassExtension sClassExtension = {
909 : nullptr, /* weakmapKeyDelegateOp */
910 : _objectMoved /* objectMovedOp */
911 : };
912 :
913 : static const DOMJSClass sClass = {
914 : { "Addon",
915 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
916 : &sClassOps,
917 : JS_NULL_CLASS_SPEC,
918 : &sClassExtension,
919 : JS_NULL_OBJECT_OPS
920 : },
921 : { prototypes::id::Addon, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
922 : IsBaseOf<nsISupports, mozilla::dom::Addon >::value,
923 : sNativePropertyHooks,
924 : FindAssociatedGlobalForNative<mozilla::dom::Addon>::Get,
925 : GetProtoObjectHandle,
926 : GetCCParticipant<mozilla::dom::Addon>::Get()
927 : };
928 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
929 : "Must have the right minimal number of reserved slots.");
930 : static_assert(1 >= 1,
931 : "Must have enough reserved slots.");
932 :
933 : const JSClass*
934 0 : GetJSClass()
935 : {
936 0 : return sClass.ToJSClass();
937 : }
938 :
939 : bool
940 0 : Wrap(JSContext* aCx, mozilla::dom::Addon* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
941 : {
942 : MOZ_ASSERT(static_cast<mozilla::dom::Addon*>(aObject) ==
943 : reinterpret_cast<mozilla::dom::Addon*>(aObject),
944 : "Multiple inheritance for mozilla::dom::Addon is broken.");
945 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
946 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
947 0 : MOZ_ASSERT(!aCache->GetWrapper(),
948 : "You should probably not be using Wrap() directly; use "
949 : "GetOrCreateDOMReflector instead");
950 :
951 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
952 : "nsISupports must be on our primary inheritance chain");
953 :
954 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
955 0 : if (!global) {
956 0 : return false;
957 : }
958 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
959 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
960 :
961 : // That might have ended up wrapping us already, due to the wonders
962 : // of XBL. Check for that, and bail out as needed.
963 0 : aReflector.set(aCache->GetWrapper());
964 0 : if (aReflector) {
965 : #ifdef DEBUG
966 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
967 : #endif // DEBUG
968 0 : return true;
969 : }
970 :
971 0 : JSAutoCompartment ac(aCx, global);
972 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
973 0 : if (!canonicalProto) {
974 0 : return false;
975 : }
976 0 : JS::Rooted<JSObject*> proto(aCx);
977 0 : if (aGivenProto) {
978 0 : proto = aGivenProto;
979 : // Unfortunately, while aGivenProto was in the compartment of aCx
980 : // coming in, we changed compartments to that of "parent" so may need
981 : // to wrap the proto here.
982 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
983 0 : if (!JS_WrapObject(aCx, &proto)) {
984 0 : return false;
985 : }
986 : }
987 : } else {
988 0 : proto = canonicalProto;
989 : }
990 :
991 0 : BindingJSObjectCreator<mozilla::dom::Addon> creator(aCx);
992 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
993 0 : if (!aReflector) {
994 0 : return false;
995 : }
996 :
997 0 : aCache->SetWrapper(aReflector);
998 0 : creator.InitializationSucceeded();
999 :
1000 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1001 : aCache->GetWrapperPreserveColor() == aReflector);
1002 : // If proto != canonicalProto, we have to preserve our wrapper;
1003 : // otherwise we won't be able to properly recreate it later, since
1004 : // we won't know what proto to use. Note that we don't check
1005 : // aGivenProto here, since it's entirely possible (and even
1006 : // somewhat common) to have a non-null aGivenProto which is the
1007 : // same as canonicalProto.
1008 0 : if (proto != canonicalProto) {
1009 0 : PreserveWrapper(aObject);
1010 : }
1011 :
1012 0 : return true;
1013 : }
1014 :
1015 : const NativePropertyHooks sNativePropertyHooks[] = { {
1016 : nullptr,
1017 : nullptr,
1018 : nullptr,
1019 : { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
1020 : prototypes::id::Addon,
1021 : constructors::id::Addon,
1022 : nullptr,
1023 : &DefaultXrayExpandoObjectClass
1024 : } };
1025 :
1026 : void
1027 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1028 : {
1029 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
1030 0 : if (!parentProto) {
1031 0 : return;
1032 : }
1033 :
1034 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
1035 0 : if (!constructorProto) {
1036 0 : return;
1037 : }
1038 :
1039 : static bool sIdsInited = false;
1040 0 : if (!sIdsInited && NS_IsMainThread()) {
1041 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
1042 0 : return;
1043 : }
1044 0 : if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
1045 0 : return;
1046 : }
1047 0 : sIdsInited = true;
1048 : }
1049 :
1050 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::Addon);
1051 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::Addon);
1052 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1053 : &sPrototypeClass.mBase, protoCache,
1054 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1055 : interfaceCache,
1056 : sNativeProperties.Upcast(),
1057 0 : nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
1058 : "Addon", aDefineOnGlobal,
1059 : nullptr,
1060 0 : false);
1061 : }
1062 :
1063 : JS::Handle<JSObject*>
1064 0 : GetProtoObjectHandle(JSContext* aCx)
1065 : {
1066 : /* Get the interface prototype object for this class. This will create the
1067 : object as needed. */
1068 0 : bool aDefineOnGlobal = true;
1069 :
1070 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1071 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1072 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1073 0 : return nullptr;
1074 : }
1075 :
1076 : /* Check to see whether the interface objects are already installed */
1077 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1078 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::Addon)) {
1079 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1080 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1081 : }
1082 :
1083 : /*
1084 : * The object might _still_ be null, but that's OK.
1085 : *
1086 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1087 : * traced by TraceProtoAndIfaceCache() and its contents are never
1088 : * changed after they have been set.
1089 : *
1090 : * Calling address() avoids the read read barrier that does gray
1091 : * unmarking, but it's not possible for the object to be gray here.
1092 : */
1093 :
1094 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::Addon);
1095 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1096 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1097 : }
1098 :
1099 : JS::Handle<JSObject*>
1100 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
1101 : {
1102 : /* Get the interface object for this class. This will create the object as
1103 : needed. */
1104 :
1105 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1106 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1107 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1108 0 : return nullptr;
1109 : }
1110 :
1111 : /* Check to see whether the interface objects are already installed */
1112 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1113 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::Addon)) {
1114 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1115 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1116 : }
1117 :
1118 : /*
1119 : * The object might _still_ be null, but that's OK.
1120 : *
1121 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1122 : * traced by TraceProtoAndIfaceCache() and its contents are never
1123 : * changed after they have been set.
1124 : *
1125 : * Calling address() avoids the read read barrier that does gray
1126 : * unmarking, but it's not possible for the object to be gray here.
1127 : */
1128 :
1129 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::Addon);
1130 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1131 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1132 : }
1133 :
1134 : JSObject*
1135 0 : GetConstructorObject(JSContext* aCx)
1136 : {
1137 0 : return GetConstructorObjectHandle(aCx);
1138 : }
1139 :
1140 : } // namespace AddonBinding
1141 :
1142 :
1143 :
1144 : namespace AddonInstallBinding {
1145 :
1146 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventTargetBinding::NativeType>::value,
1147 : "Can't inherit from an interface with a different ownership model.");
1148 :
1149 : static bool
1150 0 : get_state(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AddonInstall* self, JSJitGetterCallArgs args)
1151 : {
1152 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
1153 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1154 0 : if (objIsXray) {
1155 0 : unwrappedObj.emplace(cx, obj);
1156 : }
1157 0 : if (objIsXray) {
1158 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
1159 0 : if (!unwrappedObj.ref()) {
1160 0 : return false;
1161 : }
1162 : }
1163 0 : binding_detail::FastErrorResult rv;
1164 0 : DOMString result;
1165 0 : self->GetState(result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
1166 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1167 0 : return false;
1168 : }
1169 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1170 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
1171 0 : return false;
1172 : }
1173 0 : return true;
1174 : }
1175 :
1176 : static const JSJitInfo state_getterinfo = {
1177 : { (JSJitGetterOp)get_state },
1178 : { prototypes::id::AddonInstall },
1179 : { PrototypeTraits<prototypes::id::AddonInstall>::Depth },
1180 : JSJitInfo::Getter,
1181 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1182 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
1183 : false, /* isInfallible. False in setters. */
1184 : false, /* isMovable. Not relevant for setters. */
1185 : false, /* isEliminatable. Not relevant for setters. */
1186 : false, /* isAlwaysInSlot. Only relevant for getters. */
1187 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1188 : false, /* isTypedMethod. Only relevant for methods. */
1189 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1190 : };
1191 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1192 : static_assert(0 < 1, "There is no slot for us");
1193 :
1194 : static bool
1195 0 : get_error(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AddonInstall* self, JSJitGetterCallArgs args)
1196 : {
1197 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
1198 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1199 0 : if (objIsXray) {
1200 0 : unwrappedObj.emplace(cx, obj);
1201 : }
1202 0 : if (objIsXray) {
1203 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
1204 0 : if (!unwrappedObj.ref()) {
1205 0 : return false;
1206 : }
1207 : }
1208 0 : binding_detail::FastErrorResult rv;
1209 0 : DOMString result;
1210 0 : self->GetError(result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
1211 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1212 0 : return false;
1213 : }
1214 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1215 0 : if (!xpc::StringToJsval(cx, result, args.rval())) {
1216 0 : return false;
1217 : }
1218 0 : return true;
1219 : }
1220 :
1221 : static const JSJitInfo error_getterinfo = {
1222 : { (JSJitGetterOp)get_error },
1223 : { prototypes::id::AddonInstall },
1224 : { PrototypeTraits<prototypes::id::AddonInstall>::Depth },
1225 : JSJitInfo::Getter,
1226 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1227 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
1228 : false, /* isInfallible. False in setters. */
1229 : false, /* isMovable. Not relevant for setters. */
1230 : false, /* isEliminatable. Not relevant for setters. */
1231 : false, /* isAlwaysInSlot. Only relevant for getters. */
1232 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1233 : false, /* isTypedMethod. Only relevant for methods. */
1234 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1235 : };
1236 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1237 : static_assert(0 < 1, "There is no slot for us");
1238 :
1239 : static bool
1240 0 : get_progress(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AddonInstall* self, JSJitGetterCallArgs args)
1241 : {
1242 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
1243 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1244 0 : if (objIsXray) {
1245 0 : unwrappedObj.emplace(cx, obj);
1246 : }
1247 0 : if (objIsXray) {
1248 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
1249 0 : if (!unwrappedObj.ref()) {
1250 0 : return false;
1251 : }
1252 : }
1253 0 : binding_detail::FastErrorResult rv;
1254 0 : int64_t result(self->GetProgress(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
1255 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1256 0 : return false;
1257 : }
1258 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1259 0 : args.rval().set(JS_NumberValue(double(result)));
1260 0 : return true;
1261 : }
1262 :
1263 : static const JSJitInfo progress_getterinfo = {
1264 : { (JSJitGetterOp)get_progress },
1265 : { prototypes::id::AddonInstall },
1266 : { PrototypeTraits<prototypes::id::AddonInstall>::Depth },
1267 : JSJitInfo::Getter,
1268 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1269 : JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
1270 : false, /* isInfallible. False in setters. */
1271 : false, /* isMovable. Not relevant for setters. */
1272 : false, /* isEliminatable. Not relevant for setters. */
1273 : false, /* isAlwaysInSlot. Only relevant for getters. */
1274 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1275 : false, /* isTypedMethod. Only relevant for methods. */
1276 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1277 : };
1278 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1279 : static_assert(0 < 1, "There is no slot for us");
1280 :
1281 : static bool
1282 0 : get_maxProgress(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AddonInstall* self, JSJitGetterCallArgs args)
1283 : {
1284 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
1285 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1286 0 : if (objIsXray) {
1287 0 : unwrappedObj.emplace(cx, obj);
1288 : }
1289 0 : if (objIsXray) {
1290 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
1291 0 : if (!unwrappedObj.ref()) {
1292 0 : return false;
1293 : }
1294 : }
1295 0 : binding_detail::FastErrorResult rv;
1296 0 : int64_t result(self->GetMaxProgress(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
1297 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1298 0 : return false;
1299 : }
1300 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1301 0 : args.rval().set(JS_NumberValue(double(result)));
1302 0 : return true;
1303 : }
1304 :
1305 : static const JSJitInfo maxProgress_getterinfo = {
1306 : { (JSJitGetterOp)get_maxProgress },
1307 : { prototypes::id::AddonInstall },
1308 : { PrototypeTraits<prototypes::id::AddonInstall>::Depth },
1309 : JSJitInfo::Getter,
1310 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1311 : JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
1312 : false, /* isInfallible. False in setters. */
1313 : false, /* isMovable. Not relevant for setters. */
1314 : false, /* isEliminatable. Not relevant for setters. */
1315 : false, /* isAlwaysInSlot. Only relevant for getters. */
1316 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1317 : false, /* isTypedMethod. Only relevant for methods. */
1318 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1319 : };
1320 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1321 : static_assert(0 < 1, "There is no slot for us");
1322 :
1323 : static bool
1324 0 : install(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AddonInstall* self, const JSJitMethodCallArgs& args)
1325 : {
1326 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
1327 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1328 0 : if (objIsXray) {
1329 0 : unwrappedObj.emplace(cx, obj);
1330 : }
1331 0 : if (objIsXray) {
1332 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
1333 0 : if (!unwrappedObj.ref()) {
1334 0 : return false;
1335 : }
1336 : }
1337 0 : binding_detail::FastErrorResult rv;
1338 0 : auto result(StrongOrRawPtr<Promise>(self->Install(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
1339 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1340 0 : return false;
1341 : }
1342 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1343 0 : if (!ToJSValue(cx, result, args.rval())) {
1344 0 : return false;
1345 : }
1346 0 : return true;
1347 : }
1348 :
1349 : static bool
1350 0 : install_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AddonInstall* self, const JSJitMethodCallArgs& args)
1351 : {
1352 : // Make sure to save the callee before someone maybe messes
1353 : // with rval().
1354 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
1355 0 : bool ok = install(cx, obj, self, args);
1356 0 : if (ok) {
1357 0 : return true;
1358 : }
1359 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
1360 0 : args.rval());
1361 : }
1362 :
1363 : static const JSJitInfo install_methodinfo = {
1364 : { (JSJitGetterOp)install_promiseWrapper },
1365 : { prototypes::id::AddonInstall },
1366 : { PrototypeTraits<prototypes::id::AddonInstall>::Depth },
1367 : JSJitInfo::Method,
1368 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1369 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
1370 : false, /* isInfallible. False in setters. */
1371 : false, /* isMovable. Not relevant for setters. */
1372 : false, /* isEliminatable. Not relevant for setters. */
1373 : false, /* isAlwaysInSlot. Only relevant for getters. */
1374 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1375 : false, /* isTypedMethod. Only relevant for methods. */
1376 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1377 : };
1378 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1379 : static_assert(0 < 1, "There is no slot for us");
1380 :
1381 : static bool
1382 0 : cancel(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AddonInstall* self, const JSJitMethodCallArgs& args)
1383 : {
1384 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
1385 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1386 0 : if (objIsXray) {
1387 0 : unwrappedObj.emplace(cx, obj);
1388 : }
1389 0 : if (objIsXray) {
1390 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
1391 0 : if (!unwrappedObj.ref()) {
1392 0 : return false;
1393 : }
1394 : }
1395 0 : binding_detail::FastErrorResult rv;
1396 0 : auto result(StrongOrRawPtr<Promise>(self->Cancel(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
1397 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1398 0 : return false;
1399 : }
1400 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1401 0 : if (!ToJSValue(cx, result, args.rval())) {
1402 0 : return false;
1403 : }
1404 0 : return true;
1405 : }
1406 :
1407 : static bool
1408 0 : cancel_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AddonInstall* self, const JSJitMethodCallArgs& args)
1409 : {
1410 : // Make sure to save the callee before someone maybe messes
1411 : // with rval().
1412 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
1413 0 : bool ok = cancel(cx, obj, self, args);
1414 0 : if (ok) {
1415 0 : return true;
1416 : }
1417 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
1418 0 : args.rval());
1419 : }
1420 :
1421 : static const JSJitInfo cancel_methodinfo = {
1422 : { (JSJitGetterOp)cancel_promiseWrapper },
1423 : { prototypes::id::AddonInstall },
1424 : { PrototypeTraits<prototypes::id::AddonInstall>::Depth },
1425 : JSJitInfo::Method,
1426 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1427 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
1428 : false, /* isInfallible. False in setters. */
1429 : false, /* isMovable. Not relevant for setters. */
1430 : false, /* isEliminatable. Not relevant for setters. */
1431 : false, /* isAlwaysInSlot. Only relevant for getters. */
1432 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1433 : false, /* isTypedMethod. Only relevant for methods. */
1434 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1435 : };
1436 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1437 : static_assert(0 < 1, "There is no slot for us");
1438 :
1439 : static bool
1440 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
1441 : {
1442 0 : mozilla::dom::AddonInstall* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AddonInstall>(obj);
1443 : // We don't want to preserve if we don't have a wrapper, and we
1444 : // obviously can't preserve if we're not initialized.
1445 0 : if (self && self->GetWrapperPreserveColor()) {
1446 0 : PreserveWrapper(self);
1447 : }
1448 0 : return true;
1449 : }
1450 :
1451 : static void
1452 0 : _finalize(js::FreeOp* fop, JSObject* obj)
1453 : {
1454 0 : mozilla::dom::AddonInstall* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AddonInstall>(obj);
1455 0 : if (self) {
1456 0 : ClearWrapper(self, self, obj);
1457 0 : AddForDeferredFinalization<mozilla::dom::AddonInstall>(self);
1458 : }
1459 0 : }
1460 :
1461 : static void
1462 0 : _objectMoved(JSObject* obj, const JSObject* old)
1463 : {
1464 0 : mozilla::dom::AddonInstall* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AddonInstall>(obj);
1465 0 : if (self) {
1466 0 : UpdateWrapper(self, self, obj, old);
1467 : }
1468 0 : }
1469 :
1470 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1471 : #if defined(__clang__)
1472 : #pragma clang diagnostic push
1473 : #pragma clang diagnostic ignored "-Wmissing-braces"
1474 : #endif
1475 : static const JSFunctionSpec sChromeStaticMethods_specs[] = {
1476 : JS_FNSPEC("_create", AddonInstall::_Create, nullptr, 2, 0, nullptr),
1477 : JS_FS_END
1478 : };
1479 : #if defined(__clang__)
1480 : #pragma clang diagnostic pop
1481 : #endif
1482 :
1483 :
1484 : // Can't be const because the pref-enabled boolean needs to be writable
1485 : static Prefable<const JSFunctionSpec> sChromeStaticMethods[] = {
1486 : { nullptr, &sChromeStaticMethods_specs[0] },
1487 : { nullptr, nullptr }
1488 : };
1489 :
1490 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1491 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1492 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1493 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1494 :
1495 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1496 : #if defined(__clang__)
1497 : #pragma clang diagnostic push
1498 : #pragma clang diagnostic ignored "-Wmissing-braces"
1499 : #endif
1500 : static const JSFunctionSpec sMethods_specs[] = {
1501 : JS_FNSPEC("install", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&install_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1502 : JS_FNSPEC("cancel", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&cancel_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1503 : JS_FS_END
1504 : };
1505 : #if defined(__clang__)
1506 : #pragma clang diagnostic pop
1507 : #endif
1508 :
1509 :
1510 : // Can't be const because the pref-enabled boolean needs to be writable
1511 : static Prefable<const JSFunctionSpec> sMethods[] = {
1512 : { nullptr, &sMethods_specs[0] },
1513 : { nullptr, nullptr }
1514 : };
1515 :
1516 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1517 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1518 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1519 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1520 :
1521 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1522 : #if defined(__clang__)
1523 : #pragma clang diagnostic push
1524 : #pragma clang diagnostic ignored "-Wmissing-braces"
1525 : #endif
1526 : static const JSPropertySpec sAttributes_specs[] = {
1527 : { "state", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &state_getterinfo, nullptr, nullptr },
1528 : { "error", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &error_getterinfo, nullptr, nullptr },
1529 : { "progress", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &progress_getterinfo, nullptr, nullptr },
1530 : { "maxProgress", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &maxProgress_getterinfo, nullptr, nullptr },
1531 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
1532 : };
1533 : #if defined(__clang__)
1534 : #pragma clang diagnostic pop
1535 : #endif
1536 :
1537 :
1538 : // Can't be const because the pref-enabled boolean needs to be writable
1539 : static Prefable<const JSPropertySpec> sAttributes[] = {
1540 : { nullptr, &sAttributes_specs[0] },
1541 : { nullptr, nullptr }
1542 : };
1543 :
1544 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1545 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1546 : static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1547 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1548 :
1549 :
1550 : static uint16_t sNativeProperties_sortedPropertyIndices[6];
1551 : static PropertyInfo sNativeProperties_propertyInfos[6];
1552 :
1553 : static const NativePropertiesN<2> sNativeProperties = {
1554 : false, 0,
1555 : false, 0,
1556 : true, 0 /* sMethods */,
1557 : true, 1 /* sAttributes */,
1558 : false, 0,
1559 : false, 0,
1560 : false, 0,
1561 : -1,
1562 : 6,
1563 : sNativeProperties_sortedPropertyIndices,
1564 : {
1565 : { sMethods, &sNativeProperties_propertyInfos[0] },
1566 : { sAttributes, &sNativeProperties_propertyInfos[2] }
1567 : }
1568 : };
1569 : static_assert(6 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
1570 : "We have a property info count that is oversized");
1571 :
1572 : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[1];
1573 : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[1];
1574 :
1575 : static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
1576 : true, 0 /* sChromeStaticMethods */,
1577 : false, 0,
1578 : false, 0,
1579 : false, 0,
1580 : false, 0,
1581 : false, 0,
1582 : false, 0,
1583 : -1,
1584 : 1,
1585 : sChromeOnlyNativeProperties_sortedPropertyIndices,
1586 : {
1587 : { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] }
1588 : }
1589 : };
1590 : static_assert(1 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
1591 : "We have a property info count that is oversized");
1592 :
1593 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1594 : {
1595 : "Function",
1596 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1597 : &sBoringInterfaceObjectClassClassOps,
1598 : JS_NULL_CLASS_SPEC,
1599 : JS_NULL_CLASS_EXT,
1600 : &sInterfaceObjectClassObjectOps
1601 : },
1602 : eInterface,
1603 : true,
1604 : prototypes::id::AddonInstall,
1605 : PrototypeTraits<prototypes::id::AddonInstall>::Depth,
1606 : sNativePropertyHooks,
1607 : "function AddonInstall() {\n [native code]\n}",
1608 : EventTargetBinding::GetConstructorObject
1609 : };
1610 :
1611 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1612 : {
1613 : "AddonInstallPrototype",
1614 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
1615 : JS_NULL_CLASS_OPS,
1616 : JS_NULL_CLASS_SPEC,
1617 : JS_NULL_CLASS_EXT,
1618 : JS_NULL_OBJECT_OPS
1619 : },
1620 : eInterfacePrototype,
1621 : false,
1622 : prototypes::id::AddonInstall,
1623 : PrototypeTraits<prototypes::id::AddonInstall>::Depth,
1624 : sNativePropertyHooks,
1625 : "[object AddonInstallPrototype]",
1626 : EventTargetBinding::GetProtoObject
1627 : };
1628 :
1629 : bool
1630 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
1631 : {
1632 0 : return nsContentUtils::ThreadsafeIsSystemCaller(aCx);
1633 : }
1634 :
1635 : JSObject*
1636 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
1637 : {
1638 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
1639 : }
1640 :
1641 : static const js::ClassOps sClassOps = {
1642 : _addProperty, /* addProperty */
1643 : nullptr, /* delProperty */
1644 : nullptr, /* getProperty */
1645 : nullptr, /* setProperty */
1646 : nullptr, /* enumerate */
1647 : nullptr, /* newEnumerate */
1648 : nullptr, /* resolve */
1649 : nullptr, /* mayResolve */
1650 : _finalize, /* finalize */
1651 : nullptr, /* call */
1652 : nullptr, /* hasInstance */
1653 : nullptr, /* construct */
1654 : nullptr, /* trace */
1655 : };
1656 :
1657 : static const js::ClassExtension sClassExtension = {
1658 : nullptr, /* weakmapKeyDelegateOp */
1659 : _objectMoved /* objectMovedOp */
1660 : };
1661 :
1662 : static const DOMJSClass sClass = {
1663 : { "AddonInstall",
1664 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
1665 : &sClassOps,
1666 : JS_NULL_CLASS_SPEC,
1667 : &sClassExtension,
1668 : JS_NULL_OBJECT_OPS
1669 : },
1670 : { prototypes::id::EventTarget, prototypes::id::AddonInstall, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
1671 : IsBaseOf<nsISupports, mozilla::dom::AddonInstall >::value,
1672 : sNativePropertyHooks,
1673 : FindAssociatedGlobalForNative<mozilla::dom::AddonInstall>::Get,
1674 : GetProtoObjectHandle,
1675 : GetCCParticipant<mozilla::dom::AddonInstall>::Get()
1676 : };
1677 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1678 : "Must have the right minimal number of reserved slots.");
1679 : static_assert(1 >= 1,
1680 : "Must have enough reserved slots.");
1681 :
1682 : const JSClass*
1683 0 : GetJSClass()
1684 : {
1685 0 : return sClass.ToJSClass();
1686 : }
1687 :
1688 : bool
1689 0 : Wrap(JSContext* aCx, mozilla::dom::AddonInstall* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1690 : {
1691 : MOZ_ASSERT(static_cast<mozilla::dom::AddonInstall*>(aObject) ==
1692 : reinterpret_cast<mozilla::dom::AddonInstall*>(aObject),
1693 : "Multiple inheritance for mozilla::dom::AddonInstall is broken.");
1694 : MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
1695 : reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
1696 : "Multiple inheritance for mozilla::dom::EventTarget is broken.");
1697 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1698 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1699 0 : MOZ_ASSERT(!aCache->GetWrapper(),
1700 : "You should probably not be using Wrap() directly; use "
1701 : "GetOrCreateDOMReflector instead");
1702 :
1703 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1704 : "nsISupports must be on our primary inheritance chain");
1705 :
1706 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1707 0 : if (!global) {
1708 0 : return false;
1709 : }
1710 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
1711 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
1712 :
1713 : // That might have ended up wrapping us already, due to the wonders
1714 : // of XBL. Check for that, and bail out as needed.
1715 0 : aReflector.set(aCache->GetWrapper());
1716 0 : if (aReflector) {
1717 : #ifdef DEBUG
1718 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1719 : #endif // DEBUG
1720 0 : return true;
1721 : }
1722 :
1723 0 : JSAutoCompartment ac(aCx, global);
1724 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1725 0 : if (!canonicalProto) {
1726 0 : return false;
1727 : }
1728 0 : JS::Rooted<JSObject*> proto(aCx);
1729 0 : if (aGivenProto) {
1730 0 : proto = aGivenProto;
1731 : // Unfortunately, while aGivenProto was in the compartment of aCx
1732 : // coming in, we changed compartments to that of "parent" so may need
1733 : // to wrap the proto here.
1734 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1735 0 : if (!JS_WrapObject(aCx, &proto)) {
1736 0 : return false;
1737 : }
1738 : }
1739 : } else {
1740 0 : proto = canonicalProto;
1741 : }
1742 :
1743 0 : BindingJSObjectCreator<mozilla::dom::AddonInstall> creator(aCx);
1744 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1745 0 : if (!aReflector) {
1746 0 : return false;
1747 : }
1748 :
1749 0 : aCache->SetWrapper(aReflector);
1750 0 : creator.InitializationSucceeded();
1751 :
1752 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1753 : aCache->GetWrapperPreserveColor() == aReflector);
1754 : // If proto != canonicalProto, we have to preserve our wrapper;
1755 : // otherwise we won't be able to properly recreate it later, since
1756 : // we won't know what proto to use. Note that we don't check
1757 : // aGivenProto here, since it's entirely possible (and even
1758 : // somewhat common) to have a non-null aGivenProto which is the
1759 : // same as canonicalProto.
1760 0 : if (proto != canonicalProto) {
1761 0 : PreserveWrapper(aObject);
1762 : }
1763 :
1764 0 : return true;
1765 : }
1766 :
1767 : const NativePropertyHooks sNativePropertyHooks[] = { {
1768 : nullptr,
1769 : nullptr,
1770 : nullptr,
1771 : { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
1772 : prototypes::id::AddonInstall,
1773 : constructors::id::AddonInstall,
1774 : EventTargetBinding::sNativePropertyHooks,
1775 : &DefaultXrayExpandoObjectClass
1776 : } };
1777 :
1778 : void
1779 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1780 : {
1781 0 : JS::Handle<JSObject*> parentProto(EventTargetBinding::GetProtoObjectHandle(aCx));
1782 0 : if (!parentProto) {
1783 0 : return;
1784 : }
1785 :
1786 0 : JS::Handle<JSObject*> constructorProto(EventTargetBinding::GetConstructorObjectHandle(aCx));
1787 0 : if (!constructorProto) {
1788 0 : return;
1789 : }
1790 :
1791 : static bool sIdsInited = false;
1792 0 : if (!sIdsInited && NS_IsMainThread()) {
1793 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
1794 0 : return;
1795 : }
1796 0 : if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
1797 0 : return;
1798 : }
1799 0 : sIdsInited = true;
1800 : }
1801 :
1802 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::AddonInstall);
1803 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::AddonInstall);
1804 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1805 : &sPrototypeClass.mBase, protoCache,
1806 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1807 : interfaceCache,
1808 : sNativeProperties.Upcast(),
1809 0 : nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
1810 : "AddonInstall", aDefineOnGlobal,
1811 : nullptr,
1812 0 : false);
1813 : }
1814 :
1815 : JS::Handle<JSObject*>
1816 0 : GetProtoObjectHandle(JSContext* aCx)
1817 : {
1818 : /* Get the interface prototype object for this class. This will create the
1819 : object as needed. */
1820 0 : bool aDefineOnGlobal = true;
1821 :
1822 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1823 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1824 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1825 0 : return nullptr;
1826 : }
1827 :
1828 : /* Check to see whether the interface objects are already installed */
1829 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1830 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::AddonInstall)) {
1831 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1832 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1833 : }
1834 :
1835 : /*
1836 : * The object might _still_ be null, but that's OK.
1837 : *
1838 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1839 : * traced by TraceProtoAndIfaceCache() and its contents are never
1840 : * changed after they have been set.
1841 : *
1842 : * Calling address() avoids the read read barrier that does gray
1843 : * unmarking, but it's not possible for the object to be gray here.
1844 : */
1845 :
1846 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::AddonInstall);
1847 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1848 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1849 : }
1850 :
1851 : JS::Handle<JSObject*>
1852 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
1853 : {
1854 : /* Get the interface object for this class. This will create the object as
1855 : needed. */
1856 :
1857 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1858 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1859 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1860 0 : return nullptr;
1861 : }
1862 :
1863 : /* Check to see whether the interface objects are already installed */
1864 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1865 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::AddonInstall)) {
1866 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1867 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1868 : }
1869 :
1870 : /*
1871 : * The object might _still_ be null, but that's OK.
1872 : *
1873 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1874 : * traced by TraceProtoAndIfaceCache() and its contents are never
1875 : * changed after they have been set.
1876 : *
1877 : * Calling address() avoids the read read barrier that does gray
1878 : * unmarking, but it's not possible for the object to be gray here.
1879 : */
1880 :
1881 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::AddonInstall);
1882 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1883 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1884 : }
1885 :
1886 : JSObject*
1887 0 : GetConstructorObject(JSContext* aCx)
1888 : {
1889 0 : return GetConstructorObjectHandle(aCx);
1890 : }
1891 :
1892 : } // namespace AddonInstallBinding
1893 :
1894 :
1895 :
1896 : namespace AddonManagerBinding {
1897 :
1898 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventTargetBinding::NativeType>::value,
1899 : "Can't inherit from an interface with a different ownership model.");
1900 :
1901 : static bool
1902 0 : getAddonByID(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AddonManager* self, const JSJitMethodCallArgs& args)
1903 : {
1904 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
1905 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "AddonManager.getAddonByID");
1906 : }
1907 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
1908 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1909 0 : if (objIsXray) {
1910 0 : unwrappedObj.emplace(cx, obj);
1911 : }
1912 0 : binding_detail::FakeString arg0;
1913 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
1914 0 : return false;
1915 : }
1916 0 : if (objIsXray) {
1917 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
1918 0 : if (!unwrappedObj.ref()) {
1919 0 : return false;
1920 : }
1921 : }
1922 0 : binding_detail::FastErrorResult rv;
1923 0 : auto result(StrongOrRawPtr<Promise>(self->GetAddonByID(NonNullHelper(Constify(arg0)), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
1924 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1925 0 : return false;
1926 : }
1927 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1928 0 : if (!ToJSValue(cx, result, args.rval())) {
1929 0 : return false;
1930 : }
1931 0 : return true;
1932 : }
1933 :
1934 : static bool
1935 0 : getAddonByID_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AddonManager* self, const JSJitMethodCallArgs& args)
1936 : {
1937 : // Make sure to save the callee before someone maybe messes
1938 : // with rval().
1939 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
1940 0 : bool ok = getAddonByID(cx, obj, self, args);
1941 0 : if (ok) {
1942 0 : return true;
1943 : }
1944 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
1945 0 : args.rval());
1946 : }
1947 :
1948 : static const JSJitInfo getAddonByID_methodinfo = {
1949 : { (JSJitGetterOp)getAddonByID_promiseWrapper },
1950 : { prototypes::id::AddonManager },
1951 : { PrototypeTraits<prototypes::id::AddonManager>::Depth },
1952 : JSJitInfo::Method,
1953 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1954 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
1955 : false, /* isInfallible. False in setters. */
1956 : false, /* isMovable. Not relevant for setters. */
1957 : false, /* isEliminatable. Not relevant for setters. */
1958 : false, /* isAlwaysInSlot. Only relevant for getters. */
1959 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1960 : false, /* isTypedMethod. Only relevant for methods. */
1961 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1962 : };
1963 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1964 : static_assert(0 < 1, "There is no slot for us");
1965 :
1966 : static bool
1967 0 : createInstall(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AddonManager* self, const JSJitMethodCallArgs& args)
1968 : {
1969 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
1970 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1971 0 : if (objIsXray) {
1972 0 : unwrappedObj.emplace(cx, obj);
1973 : }
1974 0 : binding_detail::FastaddonInstallOptions arg0;
1975 0 : if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1 of AddonManager.createInstall", true)) {
1976 0 : return false;
1977 : }
1978 0 : if (objIsXray) {
1979 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
1980 0 : if (!unwrappedObj.ref()) {
1981 0 : return false;
1982 : }
1983 : }
1984 0 : binding_detail::FastErrorResult rv;
1985 0 : auto result(StrongOrRawPtr<Promise>(self->CreateInstall(Constify(arg0), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
1986 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1987 0 : return false;
1988 : }
1989 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1990 0 : if (!ToJSValue(cx, result, args.rval())) {
1991 0 : return false;
1992 : }
1993 0 : return true;
1994 : }
1995 :
1996 : static bool
1997 0 : createInstall_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AddonManager* self, const JSJitMethodCallArgs& args)
1998 : {
1999 : // Make sure to save the callee before someone maybe messes
2000 : // with rval().
2001 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
2002 0 : bool ok = createInstall(cx, obj, self, args);
2003 0 : if (ok) {
2004 0 : return true;
2005 : }
2006 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
2007 0 : args.rval());
2008 : }
2009 :
2010 : static const JSJitInfo createInstall_methodinfo = {
2011 : { (JSJitGetterOp)createInstall_promiseWrapper },
2012 : { prototypes::id::AddonManager },
2013 : { PrototypeTraits<prototypes::id::AddonManager>::Depth },
2014 : JSJitInfo::Method,
2015 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2016 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
2017 : false, /* isInfallible. False in setters. */
2018 : false, /* isMovable. Not relevant for setters. */
2019 : false, /* isEliminatable. Not relevant for setters. */
2020 : false, /* isAlwaysInSlot. Only relevant for getters. */
2021 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2022 : false, /* isTypedMethod. Only relevant for methods. */
2023 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2024 : };
2025 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2026 : static_assert(0 < 1, "There is no slot for us");
2027 :
2028 : static bool
2029 0 : get_permissionPromptsEnabled(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AddonManager* self, JSJitGetterCallArgs args)
2030 : {
2031 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
2032 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
2033 0 : if (objIsXray) {
2034 0 : unwrappedObj.emplace(cx, obj);
2035 : }
2036 0 : if (objIsXray) {
2037 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
2038 0 : if (!unwrappedObj.ref()) {
2039 0 : return false;
2040 : }
2041 : }
2042 0 : binding_detail::FastErrorResult rv;
2043 0 : bool result(self->GetPermissionPromptsEnabled(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
2044 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2045 0 : return false;
2046 : }
2047 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2048 0 : args.rval().setBoolean(result);
2049 0 : return true;
2050 : }
2051 :
2052 : static const JSJitInfo permissionPromptsEnabled_getterinfo = {
2053 : { (JSJitGetterOp)get_permissionPromptsEnabled },
2054 : { prototypes::id::AddonManager },
2055 : { PrototypeTraits<prototypes::id::AddonManager>::Depth },
2056 : JSJitInfo::Getter,
2057 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2058 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
2059 : false, /* isInfallible. False in setters. */
2060 : false, /* isMovable. Not relevant for setters. */
2061 : false, /* isEliminatable. Not relevant for setters. */
2062 : false, /* isAlwaysInSlot. Only relevant for getters. */
2063 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2064 : false, /* isTypedMethod. Only relevant for methods. */
2065 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2066 : };
2067 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2068 : static_assert(0 < 1, "There is no slot for us");
2069 :
2070 : static bool
2071 0 : eventListenerWasAdded(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AddonManager* self, const JSJitMethodCallArgs& args)
2072 : {
2073 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
2074 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "AddonManager.eventListenerWasAdded");
2075 : }
2076 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
2077 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
2078 0 : if (objIsXray) {
2079 0 : unwrappedObj.emplace(cx, obj);
2080 : }
2081 0 : binding_detail::FakeString arg0;
2082 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
2083 0 : return false;
2084 : }
2085 0 : if (objIsXray) {
2086 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
2087 0 : if (!unwrappedObj.ref()) {
2088 0 : return false;
2089 : }
2090 : }
2091 0 : binding_detail::FastErrorResult rv;
2092 0 : self->EventListenerWasAdded(NonNullHelper(Constify(arg0)), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
2093 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2094 0 : return false;
2095 : }
2096 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2097 0 : args.rval().setUndefined();
2098 0 : return true;
2099 : }
2100 :
2101 : static const JSJitInfo eventListenerWasAdded_methodinfo = {
2102 : { (JSJitGetterOp)eventListenerWasAdded },
2103 : { prototypes::id::AddonManager },
2104 : { PrototypeTraits<prototypes::id::AddonManager>::Depth },
2105 : JSJitInfo::Method,
2106 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2107 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
2108 : false, /* isInfallible. False in setters. */
2109 : false, /* isMovable. Not relevant for setters. */
2110 : false, /* isEliminatable. Not relevant for setters. */
2111 : false, /* isAlwaysInSlot. Only relevant for getters. */
2112 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2113 : false, /* isTypedMethod. Only relevant for methods. */
2114 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2115 : };
2116 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2117 : static_assert(0 < 1, "There is no slot for us");
2118 :
2119 : static bool
2120 0 : eventListenerWasRemoved(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AddonManager* self, const JSJitMethodCallArgs& args)
2121 : {
2122 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
2123 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "AddonManager.eventListenerWasRemoved");
2124 : }
2125 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
2126 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
2127 0 : if (objIsXray) {
2128 0 : unwrappedObj.emplace(cx, obj);
2129 : }
2130 0 : binding_detail::FakeString arg0;
2131 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
2132 0 : return false;
2133 : }
2134 0 : if (objIsXray) {
2135 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
2136 0 : if (!unwrappedObj.ref()) {
2137 0 : return false;
2138 : }
2139 : }
2140 0 : binding_detail::FastErrorResult rv;
2141 0 : self->EventListenerWasRemoved(NonNullHelper(Constify(arg0)), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
2142 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2143 0 : return false;
2144 : }
2145 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2146 0 : args.rval().setUndefined();
2147 0 : return true;
2148 : }
2149 :
2150 : static const JSJitInfo eventListenerWasRemoved_methodinfo = {
2151 : { (JSJitGetterOp)eventListenerWasRemoved },
2152 : { prototypes::id::AddonManager },
2153 : { PrototypeTraits<prototypes::id::AddonManager>::Depth },
2154 : JSJitInfo::Method,
2155 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2156 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
2157 : false, /* isInfallible. False in setters. */
2158 : false, /* isMovable. Not relevant for setters. */
2159 : false, /* isEliminatable. Not relevant for setters. */
2160 : false, /* isAlwaysInSlot. Only relevant for getters. */
2161 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2162 : false, /* isTypedMethod. Only relevant for methods. */
2163 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2164 : };
2165 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2166 : static_assert(0 < 1, "There is no slot for us");
2167 :
2168 : already_AddRefed<AddonManager>
2169 0 : ConstructNavigatorObject(JSContext* cx, JS::Handle<JSObject*> obj, ErrorResult& aRv)
2170 : {
2171 0 : GlobalObject global(cx, obj);
2172 0 : if (global.Failed()) {
2173 0 : aRv.Throw(NS_ERROR_FAILURE);
2174 0 : return nullptr;
2175 : }
2176 0 : JS::Rooted<JSObject*> jsImplObj(cx);
2177 : nsCOMPtr<nsIGlobalObject> globalHolder =
2178 0 : ConstructJSImplementation("@mozilla.org/addon-web-api/manager;1", global, &jsImplObj, aRv);
2179 0 : if (aRv.Failed()) {
2180 0 : return nullptr;
2181 : }
2182 : // Build the C++ implementation.
2183 0 : RefPtr<AddonManager> impl = new AddonManager(jsImplObj, globalHolder);
2184 0 : return impl.forget();
2185 : }
2186 :
2187 : static bool
2188 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
2189 : {
2190 0 : mozilla::dom::AddonManager* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AddonManager>(obj);
2191 : // We don't want to preserve if we don't have a wrapper, and we
2192 : // obviously can't preserve if we're not initialized.
2193 0 : if (self && self->GetWrapperPreserveColor()) {
2194 0 : PreserveWrapper(self);
2195 : }
2196 0 : return true;
2197 : }
2198 :
2199 : static void
2200 0 : _finalize(js::FreeOp* fop, JSObject* obj)
2201 : {
2202 0 : mozilla::dom::AddonManager* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AddonManager>(obj);
2203 0 : if (self) {
2204 0 : ClearWrapper(self, self, obj);
2205 0 : AddForDeferredFinalization<mozilla::dom::AddonManager>(self);
2206 : }
2207 0 : }
2208 :
2209 : static void
2210 0 : _objectMoved(JSObject* obj, const JSObject* old)
2211 : {
2212 0 : mozilla::dom::AddonManager* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AddonManager>(obj);
2213 0 : if (self) {
2214 0 : UpdateWrapper(self, self, obj, old);
2215 : }
2216 0 : }
2217 :
2218 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
2219 : #if defined(__clang__)
2220 : #pragma clang diagnostic push
2221 : #pragma clang diagnostic ignored "-Wmissing-braces"
2222 : #endif
2223 : static const JSFunctionSpec sChromeStaticMethods_specs[] = {
2224 : JS_FNSPEC("_create", AddonManager::_Create, nullptr, 2, 0, nullptr),
2225 : JS_FS_END
2226 : };
2227 : #if defined(__clang__)
2228 : #pragma clang diagnostic pop
2229 : #endif
2230 :
2231 :
2232 : // Can't be const because the pref-enabled boolean needs to be writable
2233 : static Prefable<const JSFunctionSpec> sChromeStaticMethods[] = {
2234 : { nullptr, &sChromeStaticMethods_specs[0] },
2235 : { nullptr, nullptr }
2236 : };
2237 :
2238 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
2239 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
2240 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
2241 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
2242 :
2243 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
2244 : #if defined(__clang__)
2245 : #pragma clang diagnostic push
2246 : #pragma clang diagnostic ignored "-Wmissing-braces"
2247 : #endif
2248 : static const JSFunctionSpec sMethods_specs[] = {
2249 : JS_FNSPEC("getAddonByID", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&getAddonByID_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
2250 : JS_FNSPEC("createInstall", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&createInstall_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
2251 : JS_FS_END
2252 : };
2253 : #if defined(__clang__)
2254 : #pragma clang diagnostic pop
2255 : #endif
2256 :
2257 :
2258 : // Can't be const because the pref-enabled boolean needs to be writable
2259 : static Prefable<const JSFunctionSpec> sMethods[] = {
2260 : { nullptr, &sMethods_specs[0] },
2261 : { nullptr, nullptr }
2262 : };
2263 :
2264 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
2265 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
2266 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
2267 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
2268 :
2269 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
2270 : #if defined(__clang__)
2271 : #pragma clang diagnostic push
2272 : #pragma clang diagnostic ignored "-Wmissing-braces"
2273 : #endif
2274 : static const JSFunctionSpec sChromeMethods_specs[] = {
2275 : JS_FNSPEC("eventListenerWasAdded", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&eventListenerWasAdded_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
2276 : JS_FNSPEC("eventListenerWasRemoved", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&eventListenerWasRemoved_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
2277 : JS_FS_END
2278 : };
2279 : #if defined(__clang__)
2280 : #pragma clang diagnostic pop
2281 : #endif
2282 :
2283 :
2284 : // Can't be const because the pref-enabled boolean needs to be writable
2285 : static Prefable<const JSFunctionSpec> sChromeMethods[] = {
2286 : { nullptr, &sChromeMethods_specs[0] },
2287 : { nullptr, nullptr }
2288 : };
2289 :
2290 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
2291 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
2292 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
2293 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
2294 :
2295 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
2296 : #if defined(__clang__)
2297 : #pragma clang diagnostic push
2298 : #pragma clang diagnostic ignored "-Wmissing-braces"
2299 : #endif
2300 : static const JSPropertySpec sAttributes_specs[] = {
2301 : { "permissionPromptsEnabled", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &permissionPromptsEnabled_getterinfo, nullptr, nullptr },
2302 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
2303 : };
2304 : #if defined(__clang__)
2305 : #pragma clang diagnostic pop
2306 : #endif
2307 :
2308 :
2309 : // Can't be const because the pref-enabled boolean needs to be writable
2310 : static Prefable<const JSPropertySpec> sAttributes[] = {
2311 : { nullptr, &sAttributes_specs[0] },
2312 : { nullptr, nullptr }
2313 : };
2314 :
2315 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
2316 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
2317 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
2318 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
2319 :
2320 :
2321 : static uint16_t sNativeProperties_sortedPropertyIndices[3];
2322 : static PropertyInfo sNativeProperties_propertyInfos[3];
2323 :
2324 : static const NativePropertiesN<2> sNativeProperties = {
2325 : false, 0,
2326 : false, 0,
2327 : true, 0 /* sMethods */,
2328 : true, 1 /* sAttributes */,
2329 : false, 0,
2330 : false, 0,
2331 : false, 0,
2332 : -1,
2333 : 3,
2334 : sNativeProperties_sortedPropertyIndices,
2335 : {
2336 : { sMethods, &sNativeProperties_propertyInfos[0] },
2337 : { sAttributes, &sNativeProperties_propertyInfos[2] }
2338 : }
2339 : };
2340 : static_assert(3 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
2341 : "We have a property info count that is oversized");
2342 :
2343 : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[3];
2344 : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[3];
2345 :
2346 : static const NativePropertiesN<2> sChromeOnlyNativeProperties = {
2347 : true, 0 /* sChromeStaticMethods */,
2348 : false, 0,
2349 : true, 1 /* sChromeMethods */,
2350 : false, 0,
2351 : false, 0,
2352 : false, 0,
2353 : false, 0,
2354 : -1,
2355 : 3,
2356 : sChromeOnlyNativeProperties_sortedPropertyIndices,
2357 : {
2358 : { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] },
2359 : { sChromeMethods, &sChromeOnlyNativeProperties_propertyInfos[1] }
2360 : }
2361 : };
2362 : static_assert(3 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
2363 : "We have a property info count that is oversized");
2364 :
2365 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
2366 : {
2367 : "Function",
2368 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
2369 : &sBoringInterfaceObjectClassClassOps,
2370 : JS_NULL_CLASS_SPEC,
2371 : JS_NULL_CLASS_EXT,
2372 : &sInterfaceObjectClassObjectOps
2373 : },
2374 : eInterface,
2375 : true,
2376 : prototypes::id::AddonManager,
2377 : PrototypeTraits<prototypes::id::AddonManager>::Depth,
2378 : sNativePropertyHooks,
2379 : "function AddonManager() {\n [native code]\n}",
2380 : EventTargetBinding::GetConstructorObject
2381 : };
2382 :
2383 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
2384 : {
2385 : "AddonManagerPrototype",
2386 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
2387 : JS_NULL_CLASS_OPS,
2388 : JS_NULL_CLASS_SPEC,
2389 : JS_NULL_CLASS_EXT,
2390 : JS_NULL_OBJECT_OPS
2391 : },
2392 : eInterfacePrototype,
2393 : false,
2394 : prototypes::id::AddonManager,
2395 : PrototypeTraits<prototypes::id::AddonManager>::Depth,
2396 : sNativePropertyHooks,
2397 : "[object AddonManagerPrototype]",
2398 : EventTargetBinding::GetProtoObject
2399 : };
2400 :
2401 : bool
2402 1 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
2403 : {
2404 1 : return mozilla::AddonManagerWebAPI::IsAPIEnabled(aCx, aObj);
2405 : }
2406 :
2407 : JSObject*
2408 1 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
2409 : {
2410 1 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
2411 : }
2412 :
2413 : static const js::ClassOps sClassOps = {
2414 : _addProperty, /* addProperty */
2415 : nullptr, /* delProperty */
2416 : nullptr, /* getProperty */
2417 : nullptr, /* setProperty */
2418 : nullptr, /* enumerate */
2419 : nullptr, /* newEnumerate */
2420 : nullptr, /* resolve */
2421 : nullptr, /* mayResolve */
2422 : _finalize, /* finalize */
2423 : nullptr, /* call */
2424 : nullptr, /* hasInstance */
2425 : nullptr, /* construct */
2426 : nullptr, /* trace */
2427 : };
2428 :
2429 : static const js::ClassExtension sClassExtension = {
2430 : nullptr, /* weakmapKeyDelegateOp */
2431 : _objectMoved /* objectMovedOp */
2432 : };
2433 :
2434 : static const DOMJSClass sClass = {
2435 : { "AddonManager",
2436 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
2437 : &sClassOps,
2438 : JS_NULL_CLASS_SPEC,
2439 : &sClassExtension,
2440 : JS_NULL_OBJECT_OPS
2441 : },
2442 : { prototypes::id::EventTarget, prototypes::id::AddonManager, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
2443 : IsBaseOf<nsISupports, mozilla::dom::AddonManager >::value,
2444 : sNativePropertyHooks,
2445 : FindAssociatedGlobalForNative<mozilla::dom::AddonManager>::Get,
2446 : GetProtoObjectHandle,
2447 : GetCCParticipant<mozilla::dom::AddonManager>::Get()
2448 : };
2449 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
2450 : "Must have the right minimal number of reserved slots.");
2451 : static_assert(1 >= 1,
2452 : "Must have enough reserved slots.");
2453 :
2454 : const JSClass*
2455 0 : GetJSClass()
2456 : {
2457 0 : return sClass.ToJSClass();
2458 : }
2459 :
2460 : bool
2461 0 : Wrap(JSContext* aCx, mozilla::dom::AddonManager* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
2462 : {
2463 : MOZ_ASSERT(static_cast<mozilla::dom::AddonManager*>(aObject) ==
2464 : reinterpret_cast<mozilla::dom::AddonManager*>(aObject),
2465 : "Multiple inheritance for mozilla::dom::AddonManager is broken.");
2466 : MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
2467 : reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
2468 : "Multiple inheritance for mozilla::dom::EventTarget is broken.");
2469 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
2470 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
2471 0 : MOZ_ASSERT(!aCache->GetWrapper(),
2472 : "You should probably not be using Wrap() directly; use "
2473 : "GetOrCreateDOMReflector instead");
2474 :
2475 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
2476 : "nsISupports must be on our primary inheritance chain");
2477 :
2478 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
2479 0 : if (!global) {
2480 0 : return false;
2481 : }
2482 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
2483 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
2484 :
2485 : // That might have ended up wrapping us already, due to the wonders
2486 : // of XBL. Check for that, and bail out as needed.
2487 0 : aReflector.set(aCache->GetWrapper());
2488 0 : if (aReflector) {
2489 : #ifdef DEBUG
2490 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
2491 : #endif // DEBUG
2492 0 : return true;
2493 : }
2494 :
2495 0 : JSAutoCompartment ac(aCx, global);
2496 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
2497 0 : if (!canonicalProto) {
2498 0 : return false;
2499 : }
2500 0 : JS::Rooted<JSObject*> proto(aCx);
2501 0 : if (aGivenProto) {
2502 0 : proto = aGivenProto;
2503 : // Unfortunately, while aGivenProto was in the compartment of aCx
2504 : // coming in, we changed compartments to that of "parent" so may need
2505 : // to wrap the proto here.
2506 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
2507 0 : if (!JS_WrapObject(aCx, &proto)) {
2508 0 : return false;
2509 : }
2510 : }
2511 : } else {
2512 0 : proto = canonicalProto;
2513 : }
2514 :
2515 0 : BindingJSObjectCreator<mozilla::dom::AddonManager> creator(aCx);
2516 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
2517 0 : if (!aReflector) {
2518 0 : return false;
2519 : }
2520 :
2521 0 : aCache->SetWrapper(aReflector);
2522 0 : creator.InitializationSucceeded();
2523 :
2524 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
2525 : aCache->GetWrapperPreserveColor() == aReflector);
2526 : // If proto != canonicalProto, we have to preserve our wrapper;
2527 : // otherwise we won't be able to properly recreate it later, since
2528 : // we won't know what proto to use. Note that we don't check
2529 : // aGivenProto here, since it's entirely possible (and even
2530 : // somewhat common) to have a non-null aGivenProto which is the
2531 : // same as canonicalProto.
2532 0 : if (proto != canonicalProto) {
2533 0 : PreserveWrapper(aObject);
2534 : }
2535 :
2536 0 : return true;
2537 : }
2538 :
2539 : const NativePropertyHooks sNativePropertyHooks[] = { {
2540 : nullptr,
2541 : nullptr,
2542 : nullptr,
2543 : { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
2544 : prototypes::id::AddonManager,
2545 : constructors::id::AddonManager,
2546 : EventTargetBinding::sNativePropertyHooks,
2547 : &DefaultXrayExpandoObjectClass
2548 : } };
2549 :
2550 : void
2551 1 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
2552 : {
2553 1 : JS::Handle<JSObject*> parentProto(EventTargetBinding::GetProtoObjectHandle(aCx));
2554 1 : if (!parentProto) {
2555 0 : return;
2556 : }
2557 :
2558 1 : JS::Handle<JSObject*> constructorProto(EventTargetBinding::GetConstructorObjectHandle(aCx));
2559 1 : if (!constructorProto) {
2560 0 : return;
2561 : }
2562 :
2563 : static bool sIdsInited = false;
2564 1 : if (!sIdsInited && NS_IsMainThread()) {
2565 1 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
2566 0 : return;
2567 : }
2568 1 : if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
2569 0 : return;
2570 : }
2571 1 : sIdsInited = true;
2572 : }
2573 :
2574 1 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::AddonManager);
2575 1 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::AddonManager);
2576 2 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
2577 : &sPrototypeClass.mBase, protoCache,
2578 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
2579 : interfaceCache,
2580 : sNativeProperties.Upcast(),
2581 1 : nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
2582 : "AddonManager", aDefineOnGlobal,
2583 : nullptr,
2584 1 : false);
2585 : }
2586 :
2587 : JS::Handle<JSObject*>
2588 0 : GetProtoObjectHandle(JSContext* aCx)
2589 : {
2590 : /* Get the interface prototype object for this class. This will create the
2591 : object as needed. */
2592 0 : bool aDefineOnGlobal = true;
2593 :
2594 : /* Make sure our global is sane. Hopefully we can remove this sometime */
2595 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
2596 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
2597 0 : return nullptr;
2598 : }
2599 :
2600 : /* Check to see whether the interface objects are already installed */
2601 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
2602 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::AddonManager)) {
2603 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
2604 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
2605 : }
2606 :
2607 : /*
2608 : * The object might _still_ be null, but that's OK.
2609 : *
2610 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
2611 : * traced by TraceProtoAndIfaceCache() and its contents are never
2612 : * changed after they have been set.
2613 : *
2614 : * Calling address() avoids the read read barrier that does gray
2615 : * unmarking, but it's not possible for the object to be gray here.
2616 : */
2617 :
2618 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::AddonManager);
2619 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
2620 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
2621 : }
2622 :
2623 : JS::Handle<JSObject*>
2624 1 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
2625 : {
2626 : /* Get the interface object for this class. This will create the object as
2627 : needed. */
2628 :
2629 : /* Make sure our global is sane. Hopefully we can remove this sometime */
2630 1 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
2631 1 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
2632 0 : return nullptr;
2633 : }
2634 :
2635 : /* Check to see whether the interface objects are already installed */
2636 1 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
2637 1 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::AddonManager)) {
2638 2 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
2639 1 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
2640 : }
2641 :
2642 : /*
2643 : * The object might _still_ be null, but that's OK.
2644 : *
2645 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
2646 : * traced by TraceProtoAndIfaceCache() and its contents are never
2647 : * changed after they have been set.
2648 : *
2649 : * Calling address() avoids the read read barrier that does gray
2650 : * unmarking, but it's not possible for the object to be gray here.
2651 : */
2652 :
2653 1 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::AddonManager);
2654 1 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
2655 1 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
2656 : }
2657 :
2658 : JSObject*
2659 0 : GetConstructorObject(JSContext* aCx)
2660 : {
2661 0 : return GetConstructorObjectHandle(aCx);
2662 : }
2663 :
2664 : } // namespace AddonManagerBinding
2665 :
2666 :
2667 :
2668 : namespace AddonManagerPermissionsBinding {
2669 :
2670 : static bool
2671 0 : isHostPermitted(JSContext* cx, unsigned argc, JS::Value* vp)
2672 : {
2673 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2674 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
2675 :
2676 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
2677 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "AddonManagerPermissions.isHostPermitted");
2678 : }
2679 0 : GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2680 0 : if (global.Failed()) {
2681 0 : return false;
2682 : }
2683 :
2684 0 : binding_detail::FakeString arg0;
2685 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
2686 0 : return false;
2687 : }
2688 0 : bool result(mozilla::dom::AddonManagerPermissions::IsHostPermitted(global, NonNullHelper(Constify(arg0))));
2689 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2690 0 : args.rval().setBoolean(result);
2691 0 : return true;
2692 : }
2693 :
2694 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
2695 : #if defined(__clang__)
2696 : #pragma clang diagnostic push
2697 : #pragma clang diagnostic ignored "-Wmissing-braces"
2698 : #endif
2699 : static const JSFunctionSpec sStaticMethods_specs[] = {
2700 : JS_FNSPEC("isHostPermitted", isHostPermitted, nullptr, 1, JSPROP_ENUMERATE, nullptr),
2701 : JS_FS_END
2702 : };
2703 : #if defined(__clang__)
2704 : #pragma clang diagnostic pop
2705 : #endif
2706 :
2707 :
2708 : // Can't be const because the pref-enabled boolean needs to be writable
2709 : static Prefable<const JSFunctionSpec> sStaticMethods[] = {
2710 : { nullptr, &sStaticMethods_specs[0] },
2711 : { nullptr, nullptr }
2712 : };
2713 :
2714 :
2715 : static const NativePropertiesN<1> sNativeProperties = {
2716 : true, 0 /* sStaticMethods */,
2717 : false, 0,
2718 : false, 0,
2719 : false, 0,
2720 : false, 0,
2721 : false, 0,
2722 : false, 0,
2723 : -1,
2724 : 0,
2725 : nullptr,
2726 : {
2727 : { sStaticMethods, nullptr }
2728 : }
2729 : };
2730 :
2731 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
2732 : {
2733 : "Function",
2734 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
2735 : &sBoringInterfaceObjectClassClassOps,
2736 : JS_NULL_CLASS_SPEC,
2737 : JS_NULL_CLASS_EXT,
2738 : &sInterfaceObjectClassObjectOps
2739 : },
2740 : eInterface,
2741 : false,
2742 : prototypes::id::_ID_Count,
2743 : 0,
2744 : &sEmptyNativePropertyHooks,
2745 : "function AddonManagerPermissions() {\n [native code]\n}",
2746 : JS::GetRealmFunctionPrototype
2747 : };
2748 :
2749 : bool
2750 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
2751 : {
2752 0 : return nsContentUtils::ThreadsafeIsSystemCaller(aCx);
2753 : }
2754 :
2755 : void
2756 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
2757 : {
2758 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
2759 0 : if (!constructorProto) {
2760 0 : return;
2761 : }
2762 :
2763 0 : JS::Heap<JSObject*>* protoCache = nullptr;
2764 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::AddonManagerPermissions);
2765 0 : dom::CreateInterfaceObjects(aCx, aGlobal, nullptr,
2766 : nullptr, protoCache,
2767 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
2768 : interfaceCache,
2769 : sNativeProperties.Upcast(),
2770 : nullptr,
2771 : "AddonManagerPermissions", aDefineOnGlobal,
2772 : nullptr,
2773 0 : false);
2774 : }
2775 :
2776 : JS::Handle<JSObject*>
2777 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
2778 : {
2779 : /* Get the interface object for this class. This will create the object as
2780 : needed. */
2781 :
2782 : /* Make sure our global is sane. Hopefully we can remove this sometime */
2783 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
2784 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
2785 0 : return nullptr;
2786 : }
2787 :
2788 : /* Check to see whether the interface objects are already installed */
2789 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
2790 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::AddonManagerPermissions)) {
2791 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
2792 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
2793 : }
2794 :
2795 : /*
2796 : * The object might _still_ be null, but that's OK.
2797 : *
2798 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
2799 : * traced by TraceProtoAndIfaceCache() and its contents are never
2800 : * changed after they have been set.
2801 : *
2802 : * Calling address() avoids the read read barrier that does gray
2803 : * unmarking, but it's not possible for the object to be gray here.
2804 : */
2805 :
2806 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::AddonManagerPermissions);
2807 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
2808 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
2809 : }
2810 :
2811 : JSObject*
2812 0 : GetConstructorObject(JSContext* aCx)
2813 : {
2814 0 : return GetConstructorObjectHandle(aCx);
2815 : }
2816 :
2817 : } // namespace AddonManagerPermissionsBinding
2818 :
2819 :
2820 :
2821 : already_AddRefed<Promise>
2822 0 : AddonJSImpl::Uninstall(ErrorResult& aRv, JSCompartment* aCompartment)
2823 : {
2824 0 : CallSetup s(this, aRv, "Addon.uninstall", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
2825 0 : JSContext* cx = s.GetContext();
2826 0 : if (!cx) {
2827 0 : MOZ_ASSERT(aRv.Failed());
2828 0 : return nullptr;
2829 : }
2830 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
2831 :
2832 0 : JS::Rooted<JS::Value> callable(cx);
2833 0 : AddonAtoms* atomsCache = GetAtomCache<AddonAtoms>(cx);
2834 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
2835 0 : !GetCallableProperty(cx, atomsCache->uninstall_id, &callable)) {
2836 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
2837 0 : return nullptr;
2838 : }
2839 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
2840 0 : if (!JS::Call(cx, thisValue, callable,
2841 0 : JS::HandleValueArray::empty(), &rval)) {
2842 0 : aRv.NoteJSContextException(cx);
2843 0 : return nullptr;
2844 : }
2845 0 : RefPtr<Promise> rvalDecl;
2846 : { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
2847 : // etc.
2848 :
2849 0 : JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
2850 0 : if (!rval.isObject()) {
2851 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of Addon.uninstall"));
2852 0 : return nullptr;
2853 : }
2854 0 : JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
2855 0 : if (!unwrappedVal) {
2856 : // A slight lie, but not much of one, for a dead object wrapper.
2857 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of Addon.uninstall"));
2858 0 : return nullptr;
2859 : }
2860 0 : globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
2861 0 : JSAutoCompartment ac(cx, globalObj);
2862 0 : GlobalObject promiseGlobal(cx, globalObj);
2863 0 : if (promiseGlobal.Failed()) {
2864 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
2865 0 : return nullptr;
2866 : }
2867 :
2868 0 : JS::Rooted<JS::Value> valueToResolve(cx, rval);
2869 0 : if (!JS_WrapValue(cx, &valueToResolve)) {
2870 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
2871 0 : return nullptr;
2872 : }
2873 0 : binding_detail::FastErrorResult promiseRv;
2874 : nsCOMPtr<nsIGlobalObject> global =
2875 0 : do_QueryInterface(promiseGlobal.GetAsSupports());
2876 0 : if (!global) {
2877 0 : promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
2878 0 : MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
2879 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
2880 0 : return nullptr;
2881 : }
2882 0 : rvalDecl = Promise::Resolve(global, cx, valueToResolve,
2883 0 : promiseRv);
2884 0 : if (promiseRv.MaybeSetPendingException(cx)) {
2885 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
2886 0 : return nullptr;
2887 : }
2888 : }
2889 0 : return rvalDecl.forget();
2890 : }
2891 :
2892 : already_AddRefed<Promise>
2893 0 : AddonJSImpl::SetEnabled(bool value, ErrorResult& aRv, JSCompartment* aCompartment)
2894 : {
2895 0 : CallSetup s(this, aRv, "Addon.setEnabled", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
2896 0 : JSContext* cx = s.GetContext();
2897 0 : if (!cx) {
2898 0 : MOZ_ASSERT(aRv.Failed());
2899 0 : return nullptr;
2900 : }
2901 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
2902 0 : JS::AutoValueVector argv(cx);
2903 0 : if (!argv.resize(1)) {
2904 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
2905 0 : return nullptr;
2906 : }
2907 0 : unsigned argc = 1;
2908 :
2909 : do {
2910 0 : argv[0].setBoolean(value);
2911 0 : break;
2912 : } while (0);
2913 :
2914 0 : JS::Rooted<JS::Value> callable(cx);
2915 0 : AddonAtoms* atomsCache = GetAtomCache<AddonAtoms>(cx);
2916 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
2917 0 : !GetCallableProperty(cx, atomsCache->setEnabled_id, &callable)) {
2918 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
2919 0 : return nullptr;
2920 : }
2921 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
2922 0 : if (!JS::Call(cx, thisValue, callable,
2923 0 : JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
2924 0 : aRv.NoteJSContextException(cx);
2925 0 : return nullptr;
2926 : }
2927 0 : RefPtr<Promise> rvalDecl;
2928 : { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
2929 : // etc.
2930 :
2931 0 : JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
2932 0 : if (!rval.isObject()) {
2933 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of Addon.setEnabled"));
2934 0 : return nullptr;
2935 : }
2936 0 : JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
2937 0 : if (!unwrappedVal) {
2938 : // A slight lie, but not much of one, for a dead object wrapper.
2939 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of Addon.setEnabled"));
2940 0 : return nullptr;
2941 : }
2942 0 : globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
2943 0 : JSAutoCompartment ac(cx, globalObj);
2944 0 : GlobalObject promiseGlobal(cx, globalObj);
2945 0 : if (promiseGlobal.Failed()) {
2946 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
2947 0 : return nullptr;
2948 : }
2949 :
2950 0 : JS::Rooted<JS::Value> valueToResolve(cx, rval);
2951 0 : if (!JS_WrapValue(cx, &valueToResolve)) {
2952 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
2953 0 : return nullptr;
2954 : }
2955 0 : binding_detail::FastErrorResult promiseRv;
2956 : nsCOMPtr<nsIGlobalObject> global =
2957 0 : do_QueryInterface(promiseGlobal.GetAsSupports());
2958 0 : if (!global) {
2959 0 : promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
2960 0 : MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
2961 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
2962 0 : return nullptr;
2963 : }
2964 0 : rvalDecl = Promise::Resolve(global, cx, valueToResolve,
2965 0 : promiseRv);
2966 0 : if (promiseRv.MaybeSetPendingException(cx)) {
2967 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
2968 0 : return nullptr;
2969 : }
2970 : }
2971 0 : return rvalDecl.forget();
2972 : }
2973 :
2974 : bool
2975 0 : AddonJSImpl::InitIds(JSContext* cx, AddonAtoms* atomsCache)
2976 : {
2977 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
2978 :
2979 : // Initialize these in reverse order so that any failure leaves the first one
2980 : // uninitialized.
2981 0 : if (!atomsCache->setEnabled_id.init(cx, "setEnabled") ||
2982 0 : !atomsCache->uninstall_id.init(cx, "uninstall") ||
2983 0 : !atomsCache->canUninstall_id.init(cx, "canUninstall") ||
2984 0 : !atomsCache->isActive_id.init(cx, "isActive") ||
2985 0 : !atomsCache->isEnabled_id.init(cx, "isEnabled") ||
2986 0 : !atomsCache->description_id.init(cx, "description") ||
2987 0 : !atomsCache->name_id.init(cx, "name") ||
2988 0 : !atomsCache->type_id.init(cx, "type") ||
2989 0 : !atomsCache->version_id.init(cx, "version") ||
2990 0 : !atomsCache->id_id.init(cx, "id")) {
2991 0 : return false;
2992 : }
2993 0 : return true;
2994 : }
2995 :
2996 :
2997 : void
2998 0 : AddonJSImpl::GetId(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
2999 : {
3000 0 : CallSetup s(this, aRv, "Addon.id", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3001 0 : JSContext* cx = s.GetContext();
3002 0 : if (!cx) {
3003 0 : MOZ_ASSERT(aRv.Failed());
3004 0 : return;
3005 : }
3006 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3007 :
3008 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
3009 0 : AddonAtoms* atomsCache = GetAtomCache<AddonAtoms>(cx);
3010 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3011 0 : !JS_GetPropertyById(cx, callback, atomsCache->id_id, &rval)) {
3012 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3013 0 : return;
3014 : }
3015 0 : binding_detail::FakeString rvalDecl;
3016 0 : if (!ConvertJSValueToString(cx, rval, eStringify, eStringify, rvalDecl)) {
3017 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3018 0 : return;
3019 : }
3020 0 : aRetVal = rvalDecl;
3021 : }
3022 :
3023 : void
3024 0 : AddonJSImpl::GetVersion(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
3025 : {
3026 0 : CallSetup s(this, aRv, "Addon.version", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3027 0 : JSContext* cx = s.GetContext();
3028 0 : if (!cx) {
3029 0 : MOZ_ASSERT(aRv.Failed());
3030 0 : return;
3031 : }
3032 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3033 :
3034 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
3035 0 : AddonAtoms* atomsCache = GetAtomCache<AddonAtoms>(cx);
3036 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3037 0 : !JS_GetPropertyById(cx, callback, atomsCache->version_id, &rval)) {
3038 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3039 0 : return;
3040 : }
3041 0 : binding_detail::FakeString rvalDecl;
3042 0 : if (!ConvertJSValueToString(cx, rval, eStringify, eStringify, rvalDecl)) {
3043 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3044 0 : return;
3045 : }
3046 0 : aRetVal = rvalDecl;
3047 : }
3048 :
3049 : void
3050 0 : AddonJSImpl::GetType(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
3051 : {
3052 0 : CallSetup s(this, aRv, "Addon.type", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3053 0 : JSContext* cx = s.GetContext();
3054 0 : if (!cx) {
3055 0 : MOZ_ASSERT(aRv.Failed());
3056 0 : return;
3057 : }
3058 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3059 :
3060 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
3061 0 : AddonAtoms* atomsCache = GetAtomCache<AddonAtoms>(cx);
3062 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3063 0 : !JS_GetPropertyById(cx, callback, atomsCache->type_id, &rval)) {
3064 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3065 0 : return;
3066 : }
3067 0 : binding_detail::FakeString rvalDecl;
3068 0 : if (!ConvertJSValueToString(cx, rval, eStringify, eStringify, rvalDecl)) {
3069 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3070 0 : return;
3071 : }
3072 0 : aRetVal = rvalDecl;
3073 : }
3074 :
3075 : void
3076 0 : AddonJSImpl::GetName(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
3077 : {
3078 0 : CallSetup s(this, aRv, "Addon.name", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3079 0 : JSContext* cx = s.GetContext();
3080 0 : if (!cx) {
3081 0 : MOZ_ASSERT(aRv.Failed());
3082 0 : return;
3083 : }
3084 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3085 :
3086 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
3087 0 : AddonAtoms* atomsCache = GetAtomCache<AddonAtoms>(cx);
3088 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3089 0 : !JS_GetPropertyById(cx, callback, atomsCache->name_id, &rval)) {
3090 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3091 0 : return;
3092 : }
3093 0 : binding_detail::FakeString rvalDecl;
3094 0 : if (!ConvertJSValueToString(cx, rval, eStringify, eStringify, rvalDecl)) {
3095 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3096 0 : return;
3097 : }
3098 0 : aRetVal = rvalDecl;
3099 : }
3100 :
3101 : void
3102 0 : AddonJSImpl::GetDescription(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
3103 : {
3104 0 : CallSetup s(this, aRv, "Addon.description", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3105 0 : JSContext* cx = s.GetContext();
3106 0 : if (!cx) {
3107 0 : MOZ_ASSERT(aRv.Failed());
3108 0 : return;
3109 : }
3110 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3111 :
3112 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
3113 0 : AddonAtoms* atomsCache = GetAtomCache<AddonAtoms>(cx);
3114 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3115 0 : !JS_GetPropertyById(cx, callback, atomsCache->description_id, &rval)) {
3116 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3117 0 : return;
3118 : }
3119 0 : binding_detail::FakeString rvalDecl;
3120 0 : if (!ConvertJSValueToString(cx, rval, eStringify, eStringify, rvalDecl)) {
3121 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3122 0 : return;
3123 : }
3124 0 : aRetVal = rvalDecl;
3125 : }
3126 :
3127 : bool
3128 0 : AddonJSImpl::GetIsEnabled(ErrorResult& aRv, JSCompartment* aCompartment)
3129 : {
3130 0 : CallSetup s(this, aRv, "Addon.isEnabled", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3131 0 : JSContext* cx = s.GetContext();
3132 0 : if (!cx) {
3133 0 : MOZ_ASSERT(aRv.Failed());
3134 0 : return bool(0);
3135 : }
3136 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3137 :
3138 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
3139 0 : AddonAtoms* atomsCache = GetAtomCache<AddonAtoms>(cx);
3140 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3141 0 : !JS_GetPropertyById(cx, callback, atomsCache->isEnabled_id, &rval)) {
3142 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3143 0 : return bool(0);
3144 : }
3145 : bool rvalDecl;
3146 0 : if (!ValueToPrimitive<bool, eDefault>(cx, rval, &rvalDecl)) {
3147 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3148 0 : return bool(0);
3149 : }
3150 0 : return rvalDecl;
3151 : }
3152 :
3153 : bool
3154 0 : AddonJSImpl::GetIsActive(ErrorResult& aRv, JSCompartment* aCompartment)
3155 : {
3156 0 : CallSetup s(this, aRv, "Addon.isActive", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3157 0 : JSContext* cx = s.GetContext();
3158 0 : if (!cx) {
3159 0 : MOZ_ASSERT(aRv.Failed());
3160 0 : return bool(0);
3161 : }
3162 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3163 :
3164 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
3165 0 : AddonAtoms* atomsCache = GetAtomCache<AddonAtoms>(cx);
3166 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3167 0 : !JS_GetPropertyById(cx, callback, atomsCache->isActive_id, &rval)) {
3168 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3169 0 : return bool(0);
3170 : }
3171 : bool rvalDecl;
3172 0 : if (!ValueToPrimitive<bool, eDefault>(cx, rval, &rvalDecl)) {
3173 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3174 0 : return bool(0);
3175 : }
3176 0 : return rvalDecl;
3177 : }
3178 :
3179 : bool
3180 0 : AddonJSImpl::GetCanUninstall(ErrorResult& aRv, JSCompartment* aCompartment)
3181 : {
3182 0 : CallSetup s(this, aRv, "Addon.canUninstall", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3183 0 : JSContext* cx = s.GetContext();
3184 0 : if (!cx) {
3185 0 : MOZ_ASSERT(aRv.Failed());
3186 0 : return bool(0);
3187 : }
3188 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3189 :
3190 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
3191 0 : AddonAtoms* atomsCache = GetAtomCache<AddonAtoms>(cx);
3192 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3193 0 : !JS_GetPropertyById(cx, callback, atomsCache->canUninstall_id, &rval)) {
3194 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3195 0 : return bool(0);
3196 : }
3197 : bool rvalDecl;
3198 0 : if (!ValueToPrimitive<bool, eDefault>(cx, rval, &rvalDecl)) {
3199 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3200 0 : return bool(0);
3201 : }
3202 0 : return rvalDecl;
3203 : }
3204 :
3205 :
3206 : NS_IMPL_CYCLE_COLLECTION_CLASS(Addon)
3207 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Addon)
3208 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mImpl)
3209 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
3210 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
3211 0 : tmp->ClearWeakReferences();
3212 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
3213 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Addon)
3214 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImpl)
3215 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
3216 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
3217 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(Addon)
3218 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(Addon)
3219 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(Addon)
3220 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Addon)
3221 0 : NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
3222 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
3223 0 : NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
3224 0 : NS_INTERFACE_MAP_END
3225 :
3226 0 : Addon::Addon(JS::Handle<JSObject*> aJSImplObject, nsIGlobalObject* aParent)
3227 0 : : mImpl(new AddonJSImpl(nullptr, aJSImplObject, /* aIncumbentGlobal = */ nullptr)),
3228 0 : mParent(aParent)
3229 : {
3230 0 : }
3231 :
3232 :
3233 0 : Addon::~Addon()
3234 : {
3235 0 : }
3236 :
3237 : nsISupports*
3238 0 : Addon::GetParentObject() const
3239 : {
3240 0 : return mParent;
3241 : }
3242 :
3243 : JSObject*
3244 0 : Addon::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
3245 : {
3246 0 : JS::Rooted<JSObject*> obj(aCx, AddonBinding::Wrap(aCx, this, aGivenProto));
3247 0 : if (!obj) {
3248 0 : return nullptr;
3249 : }
3250 :
3251 : // Now define it on our chrome object
3252 0 : JSAutoCompartment ac(aCx, mImpl->CallbackOrNull());
3253 0 : if (!JS_WrapObject(aCx, &obj)) {
3254 0 : return nullptr;
3255 : }
3256 0 : if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
3257 0 : return nullptr;
3258 : }
3259 0 : return obj;
3260 : }
3261 :
3262 : void
3263 0 : Addon::GetId(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment) const
3264 : {
3265 0 : return mImpl->GetId(aRetVal, aRv, aCompartment);
3266 : }
3267 :
3268 : void
3269 0 : Addon::GetVersion(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment) const
3270 : {
3271 0 : return mImpl->GetVersion(aRetVal, aRv, aCompartment);
3272 : }
3273 :
3274 : void
3275 0 : Addon::GetType(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment) const
3276 : {
3277 0 : return mImpl->GetType(aRetVal, aRv, aCompartment);
3278 : }
3279 :
3280 : void
3281 0 : Addon::GetName(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment) const
3282 : {
3283 0 : return mImpl->GetName(aRetVal, aRv, aCompartment);
3284 : }
3285 :
3286 : void
3287 0 : Addon::GetDescription(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment) const
3288 : {
3289 0 : return mImpl->GetDescription(aRetVal, aRv, aCompartment);
3290 : }
3291 :
3292 : bool
3293 0 : Addon::GetIsEnabled(ErrorResult& aRv, JSCompartment* aCompartment) const
3294 : {
3295 0 : return mImpl->GetIsEnabled(aRv, aCompartment);
3296 : }
3297 :
3298 : bool
3299 0 : Addon::GetIsActive(ErrorResult& aRv, JSCompartment* aCompartment) const
3300 : {
3301 0 : return mImpl->GetIsActive(aRv, aCompartment);
3302 : }
3303 :
3304 : bool
3305 0 : Addon::GetCanUninstall(ErrorResult& aRv, JSCompartment* aCompartment) const
3306 : {
3307 0 : return mImpl->GetCanUninstall(aRv, aCompartment);
3308 : }
3309 :
3310 : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
3311 : already_AddRefed<Promise>
3312 0 : Addon::Uninstall(ErrorResult& aRv, JSCompartment* aCompartment)
3313 : {
3314 0 : return mImpl->Uninstall(aRv, aCompartment);
3315 : }
3316 :
3317 : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
3318 : already_AddRefed<Promise>
3319 0 : Addon::SetEnabled(bool value, ErrorResult& aRv, JSCompartment* aCompartment)
3320 : {
3321 0 : return mImpl->SetEnabled(value, aRv, aCompartment);
3322 : }
3323 :
3324 : bool
3325 0 : Addon::_Create(JSContext* cx, unsigned argc, JS::Value* vp)
3326 : {
3327 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
3328 0 : if (args.length() < 2) {
3329 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Addon._create");
3330 : }
3331 0 : if (!args[0].isObject()) {
3332 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of Addon._create");
3333 : }
3334 0 : if (!args[1].isObject()) {
3335 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of Addon._create");
3336 : }
3337 :
3338 : // GlobalObject will go through wrappers as needed for us, and
3339 : // is simpler than the right UnwrapArg incantation.
3340 0 : GlobalObject global(cx, &args[0].toObject());
3341 0 : if (global.Failed()) {
3342 0 : return false;
3343 : }
3344 0 : nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports());
3345 0 : MOZ_ASSERT(globalHolder);
3346 0 : JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
3347 0 : RefPtr<Addon> impl = new Addon(arg, globalHolder);
3348 0 : MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
3349 0 : return GetOrCreateDOMReflector(cx, impl, args.rval());
3350 : }
3351 :
3352 :
3353 : already_AddRefed<Promise>
3354 0 : AddonInstallJSImpl::Install(ErrorResult& aRv, JSCompartment* aCompartment)
3355 : {
3356 0 : CallSetup s(this, aRv, "AddonInstall.install", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3357 0 : JSContext* cx = s.GetContext();
3358 0 : if (!cx) {
3359 0 : MOZ_ASSERT(aRv.Failed());
3360 0 : return nullptr;
3361 : }
3362 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3363 :
3364 0 : JS::Rooted<JS::Value> callable(cx);
3365 0 : AddonInstallAtoms* atomsCache = GetAtomCache<AddonInstallAtoms>(cx);
3366 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3367 0 : !GetCallableProperty(cx, atomsCache->install_id, &callable)) {
3368 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3369 0 : return nullptr;
3370 : }
3371 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
3372 0 : if (!JS::Call(cx, thisValue, callable,
3373 0 : JS::HandleValueArray::empty(), &rval)) {
3374 0 : aRv.NoteJSContextException(cx);
3375 0 : return nullptr;
3376 : }
3377 0 : RefPtr<Promise> rvalDecl;
3378 : { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
3379 : // etc.
3380 :
3381 0 : JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
3382 0 : if (!rval.isObject()) {
3383 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of AddonInstall.install"));
3384 0 : return nullptr;
3385 : }
3386 0 : JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
3387 0 : if (!unwrappedVal) {
3388 : // A slight lie, but not much of one, for a dead object wrapper.
3389 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of AddonInstall.install"));
3390 0 : return nullptr;
3391 : }
3392 0 : globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
3393 0 : JSAutoCompartment ac(cx, globalObj);
3394 0 : GlobalObject promiseGlobal(cx, globalObj);
3395 0 : if (promiseGlobal.Failed()) {
3396 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3397 0 : return nullptr;
3398 : }
3399 :
3400 0 : JS::Rooted<JS::Value> valueToResolve(cx, rval);
3401 0 : if (!JS_WrapValue(cx, &valueToResolve)) {
3402 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3403 0 : return nullptr;
3404 : }
3405 0 : binding_detail::FastErrorResult promiseRv;
3406 : nsCOMPtr<nsIGlobalObject> global =
3407 0 : do_QueryInterface(promiseGlobal.GetAsSupports());
3408 0 : if (!global) {
3409 0 : promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
3410 0 : MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
3411 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3412 0 : return nullptr;
3413 : }
3414 0 : rvalDecl = Promise::Resolve(global, cx, valueToResolve,
3415 0 : promiseRv);
3416 0 : if (promiseRv.MaybeSetPendingException(cx)) {
3417 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3418 0 : return nullptr;
3419 : }
3420 : }
3421 0 : return rvalDecl.forget();
3422 : }
3423 :
3424 : already_AddRefed<Promise>
3425 0 : AddonInstallJSImpl::Cancel(ErrorResult& aRv, JSCompartment* aCompartment)
3426 : {
3427 0 : CallSetup s(this, aRv, "AddonInstall.cancel", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3428 0 : JSContext* cx = s.GetContext();
3429 0 : if (!cx) {
3430 0 : MOZ_ASSERT(aRv.Failed());
3431 0 : return nullptr;
3432 : }
3433 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3434 :
3435 0 : JS::Rooted<JS::Value> callable(cx);
3436 0 : AddonInstallAtoms* atomsCache = GetAtomCache<AddonInstallAtoms>(cx);
3437 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3438 0 : !GetCallableProperty(cx, atomsCache->cancel_id, &callable)) {
3439 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3440 0 : return nullptr;
3441 : }
3442 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
3443 0 : if (!JS::Call(cx, thisValue, callable,
3444 0 : JS::HandleValueArray::empty(), &rval)) {
3445 0 : aRv.NoteJSContextException(cx);
3446 0 : return nullptr;
3447 : }
3448 0 : RefPtr<Promise> rvalDecl;
3449 : { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
3450 : // etc.
3451 :
3452 0 : JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
3453 0 : if (!rval.isObject()) {
3454 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of AddonInstall.cancel"));
3455 0 : return nullptr;
3456 : }
3457 0 : JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
3458 0 : if (!unwrappedVal) {
3459 : // A slight lie, but not much of one, for a dead object wrapper.
3460 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of AddonInstall.cancel"));
3461 0 : return nullptr;
3462 : }
3463 0 : globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
3464 0 : JSAutoCompartment ac(cx, globalObj);
3465 0 : GlobalObject promiseGlobal(cx, globalObj);
3466 0 : if (promiseGlobal.Failed()) {
3467 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3468 0 : return nullptr;
3469 : }
3470 :
3471 0 : JS::Rooted<JS::Value> valueToResolve(cx, rval);
3472 0 : if (!JS_WrapValue(cx, &valueToResolve)) {
3473 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3474 0 : return nullptr;
3475 : }
3476 0 : binding_detail::FastErrorResult promiseRv;
3477 : nsCOMPtr<nsIGlobalObject> global =
3478 0 : do_QueryInterface(promiseGlobal.GetAsSupports());
3479 0 : if (!global) {
3480 0 : promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
3481 0 : MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
3482 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3483 0 : return nullptr;
3484 : }
3485 0 : rvalDecl = Promise::Resolve(global, cx, valueToResolve,
3486 0 : promiseRv);
3487 0 : if (promiseRv.MaybeSetPendingException(cx)) {
3488 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3489 0 : return nullptr;
3490 : }
3491 : }
3492 0 : return rvalDecl.forget();
3493 : }
3494 :
3495 : bool
3496 0 : AddonInstallJSImpl::InitIds(JSContext* cx, AddonInstallAtoms* atomsCache)
3497 : {
3498 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
3499 :
3500 : // Initialize these in reverse order so that any failure leaves the first one
3501 : // uninitialized.
3502 0 : if (!atomsCache->cancel_id.init(cx, "cancel") ||
3503 0 : !atomsCache->install_id.init(cx, "install") ||
3504 0 : !atomsCache->maxProgress_id.init(cx, "maxProgress") ||
3505 0 : !atomsCache->progress_id.init(cx, "progress") ||
3506 0 : !atomsCache->error_id.init(cx, "error") ||
3507 0 : !atomsCache->state_id.init(cx, "state")) {
3508 0 : return false;
3509 : }
3510 0 : return true;
3511 : }
3512 :
3513 :
3514 : void
3515 0 : AddonInstallJSImpl::GetState(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
3516 : {
3517 0 : CallSetup s(this, aRv, "AddonInstall.state", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3518 0 : JSContext* cx = s.GetContext();
3519 0 : if (!cx) {
3520 0 : MOZ_ASSERT(aRv.Failed());
3521 0 : return;
3522 : }
3523 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3524 :
3525 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
3526 0 : AddonInstallAtoms* atomsCache = GetAtomCache<AddonInstallAtoms>(cx);
3527 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3528 0 : !JS_GetPropertyById(cx, callback, atomsCache->state_id, &rval)) {
3529 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3530 0 : return;
3531 : }
3532 0 : binding_detail::FakeString rvalDecl;
3533 0 : if (!ConvertJSValueToString(cx, rval, eStringify, eStringify, rvalDecl)) {
3534 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3535 0 : return;
3536 : }
3537 0 : aRetVal = rvalDecl;
3538 : }
3539 :
3540 : void
3541 0 : AddonInstallJSImpl::GetError(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
3542 : {
3543 0 : CallSetup s(this, aRv, "AddonInstall.error", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3544 0 : JSContext* cx = s.GetContext();
3545 0 : if (!cx) {
3546 0 : MOZ_ASSERT(aRv.Failed());
3547 0 : return;
3548 : }
3549 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3550 :
3551 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
3552 0 : AddonInstallAtoms* atomsCache = GetAtomCache<AddonInstallAtoms>(cx);
3553 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3554 0 : !JS_GetPropertyById(cx, callback, atomsCache->error_id, &rval)) {
3555 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3556 0 : return;
3557 : }
3558 0 : binding_detail::FakeString rvalDecl;
3559 0 : if (!ConvertJSValueToString(cx, rval, eNull, eNull, rvalDecl)) {
3560 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3561 0 : return;
3562 : }
3563 0 : aRetVal = rvalDecl;
3564 : }
3565 :
3566 : int64_t
3567 0 : AddonInstallJSImpl::GetProgress(ErrorResult& aRv, JSCompartment* aCompartment)
3568 : {
3569 0 : CallSetup s(this, aRv, "AddonInstall.progress", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3570 0 : JSContext* cx = s.GetContext();
3571 0 : if (!cx) {
3572 0 : MOZ_ASSERT(aRv.Failed());
3573 0 : return int64_t(0);
3574 : }
3575 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3576 :
3577 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
3578 0 : AddonInstallAtoms* atomsCache = GetAtomCache<AddonInstallAtoms>(cx);
3579 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3580 0 : !JS_GetPropertyById(cx, callback, atomsCache->progress_id, &rval)) {
3581 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3582 0 : return int64_t(0);
3583 : }
3584 : int64_t rvalDecl;
3585 0 : if (!ValueToPrimitive<int64_t, eDefault>(cx, rval, &rvalDecl)) {
3586 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3587 0 : return int64_t(0);
3588 : }
3589 0 : return rvalDecl;
3590 : }
3591 :
3592 : int64_t
3593 0 : AddonInstallJSImpl::GetMaxProgress(ErrorResult& aRv, JSCompartment* aCompartment)
3594 : {
3595 0 : CallSetup s(this, aRv, "AddonInstall.maxProgress", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3596 0 : JSContext* cx = s.GetContext();
3597 0 : if (!cx) {
3598 0 : MOZ_ASSERT(aRv.Failed());
3599 0 : return int64_t(0);
3600 : }
3601 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3602 :
3603 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
3604 0 : AddonInstallAtoms* atomsCache = GetAtomCache<AddonInstallAtoms>(cx);
3605 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3606 0 : !JS_GetPropertyById(cx, callback, atomsCache->maxProgress_id, &rval)) {
3607 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3608 0 : return int64_t(0);
3609 : }
3610 : int64_t rvalDecl;
3611 0 : if (!ValueToPrimitive<int64_t, eDefault>(cx, rval, &rvalDecl)) {
3612 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3613 0 : return int64_t(0);
3614 : }
3615 0 : return rvalDecl;
3616 : }
3617 :
3618 :
3619 0 : NS_IMPL_CYCLE_COLLECTION_INHERITED(AddonInstall, mozilla::DOMEventTargetHelper, mImpl, mParent)
3620 0 : NS_IMPL_ADDREF_INHERITED(AddonInstall, mozilla::DOMEventTargetHelper)
3621 0 : NS_IMPL_RELEASE_INHERITED(AddonInstall, mozilla::DOMEventTargetHelper)
3622 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(AddonInstall)
3623 0 : NS_INTERFACE_MAP_END_INHERITING(mozilla::DOMEventTargetHelper)
3624 :
3625 0 : AddonInstall::AddonInstall(JS::Handle<JSObject*> aJSImplObject, nsIGlobalObject* aParent)
3626 : : mozilla::DOMEventTargetHelper(aParent),
3627 0 : mImpl(new AddonInstallJSImpl(nullptr, aJSImplObject, /* aIncumbentGlobal = */ nullptr)),
3628 0 : mParent(aParent)
3629 : {
3630 0 : }
3631 :
3632 :
3633 0 : AddonInstall::~AddonInstall()
3634 : {
3635 0 : }
3636 :
3637 : nsISupports*
3638 0 : AddonInstall::GetParentObject() const
3639 : {
3640 0 : return mParent;
3641 : }
3642 :
3643 : JSObject*
3644 0 : AddonInstall::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
3645 : {
3646 0 : JS::Rooted<JSObject*> obj(aCx, AddonInstallBinding::Wrap(aCx, this, aGivenProto));
3647 0 : if (!obj) {
3648 0 : return nullptr;
3649 : }
3650 :
3651 : // Now define it on our chrome object
3652 0 : JSAutoCompartment ac(aCx, mImpl->CallbackOrNull());
3653 0 : if (!JS_WrapObject(aCx, &obj)) {
3654 0 : return nullptr;
3655 : }
3656 0 : if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
3657 0 : return nullptr;
3658 : }
3659 0 : return obj;
3660 : }
3661 :
3662 : void
3663 0 : AddonInstall::GetState(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment) const
3664 : {
3665 0 : return mImpl->GetState(aRetVal, aRv, aCompartment);
3666 : }
3667 :
3668 : void
3669 0 : AddonInstall::GetError(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment) const
3670 : {
3671 0 : return mImpl->GetError(aRetVal, aRv, aCompartment);
3672 : }
3673 :
3674 : int64_t
3675 0 : AddonInstall::GetProgress(ErrorResult& aRv, JSCompartment* aCompartment) const
3676 : {
3677 0 : return mImpl->GetProgress(aRv, aCompartment);
3678 : }
3679 :
3680 : int64_t
3681 0 : AddonInstall::GetMaxProgress(ErrorResult& aRv, JSCompartment* aCompartment) const
3682 : {
3683 0 : return mImpl->GetMaxProgress(aRv, aCompartment);
3684 : }
3685 :
3686 : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
3687 : already_AddRefed<Promise>
3688 0 : AddonInstall::Install(ErrorResult& aRv, JSCompartment* aCompartment)
3689 : {
3690 0 : return mImpl->Install(aRv, aCompartment);
3691 : }
3692 :
3693 : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
3694 : already_AddRefed<Promise>
3695 0 : AddonInstall::Cancel(ErrorResult& aRv, JSCompartment* aCompartment)
3696 : {
3697 0 : return mImpl->Cancel(aRv, aCompartment);
3698 : }
3699 :
3700 : bool
3701 0 : AddonInstall::_Create(JSContext* cx, unsigned argc, JS::Value* vp)
3702 : {
3703 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
3704 0 : if (args.length() < 2) {
3705 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "AddonInstall._create");
3706 : }
3707 0 : if (!args[0].isObject()) {
3708 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of AddonInstall._create");
3709 : }
3710 0 : if (!args[1].isObject()) {
3711 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of AddonInstall._create");
3712 : }
3713 :
3714 : // GlobalObject will go through wrappers as needed for us, and
3715 : // is simpler than the right UnwrapArg incantation.
3716 0 : GlobalObject global(cx, &args[0].toObject());
3717 0 : if (global.Failed()) {
3718 0 : return false;
3719 : }
3720 0 : nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports());
3721 0 : MOZ_ASSERT(globalHolder);
3722 0 : JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
3723 0 : RefPtr<AddonInstall> impl = new AddonInstall(arg, globalHolder);
3724 0 : MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
3725 0 : return GetOrCreateDOMReflector(cx, impl, args.rval());
3726 : }
3727 :
3728 :
3729 : already_AddRefed<Promise>
3730 0 : AddonManagerJSImpl::GetAddonByID(const nsAString& id, ErrorResult& aRv, JSCompartment* aCompartment)
3731 : {
3732 0 : CallSetup s(this, aRv, "AddonManager.getAddonByID", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3733 0 : JSContext* cx = s.GetContext();
3734 0 : if (!cx) {
3735 0 : MOZ_ASSERT(aRv.Failed());
3736 0 : return nullptr;
3737 : }
3738 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3739 0 : JS::AutoValueVector argv(cx);
3740 0 : if (!argv.resize(1)) {
3741 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
3742 0 : return nullptr;
3743 : }
3744 0 : unsigned argc = 1;
3745 :
3746 : do {
3747 0 : nsString mutableStr(id);
3748 0 : if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
3749 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3750 0 : return nullptr;
3751 : }
3752 0 : break;
3753 : } while (0);
3754 :
3755 0 : JS::Rooted<JS::Value> callable(cx);
3756 0 : AddonManagerAtoms* atomsCache = GetAtomCache<AddonManagerAtoms>(cx);
3757 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3758 0 : !GetCallableProperty(cx, atomsCache->getAddonByID_id, &callable)) {
3759 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3760 0 : return nullptr;
3761 : }
3762 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
3763 0 : if (!JS::Call(cx, thisValue, callable,
3764 0 : JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
3765 0 : aRv.NoteJSContextException(cx);
3766 0 : return nullptr;
3767 : }
3768 0 : RefPtr<Promise> rvalDecl;
3769 : { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
3770 : // etc.
3771 :
3772 0 : JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
3773 0 : if (!rval.isObject()) {
3774 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of AddonManager.getAddonByID"));
3775 0 : return nullptr;
3776 : }
3777 0 : JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
3778 0 : if (!unwrappedVal) {
3779 : // A slight lie, but not much of one, for a dead object wrapper.
3780 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of AddonManager.getAddonByID"));
3781 0 : return nullptr;
3782 : }
3783 0 : globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
3784 0 : JSAutoCompartment ac(cx, globalObj);
3785 0 : GlobalObject promiseGlobal(cx, globalObj);
3786 0 : if (promiseGlobal.Failed()) {
3787 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3788 0 : return nullptr;
3789 : }
3790 :
3791 0 : JS::Rooted<JS::Value> valueToResolve(cx, rval);
3792 0 : if (!JS_WrapValue(cx, &valueToResolve)) {
3793 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3794 0 : return nullptr;
3795 : }
3796 0 : binding_detail::FastErrorResult promiseRv;
3797 : nsCOMPtr<nsIGlobalObject> global =
3798 0 : do_QueryInterface(promiseGlobal.GetAsSupports());
3799 0 : if (!global) {
3800 0 : promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
3801 0 : MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
3802 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3803 0 : return nullptr;
3804 : }
3805 0 : rvalDecl = Promise::Resolve(global, cx, valueToResolve,
3806 0 : promiseRv);
3807 0 : if (promiseRv.MaybeSetPendingException(cx)) {
3808 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3809 0 : return nullptr;
3810 : }
3811 : }
3812 0 : return rvalDecl.forget();
3813 : }
3814 :
3815 : already_AddRefed<Promise>
3816 0 : AddonManagerJSImpl::CreateInstall(const addonInstallOptions& options, ErrorResult& aRv, JSCompartment* aCompartment)
3817 : {
3818 0 : CallSetup s(this, aRv, "AddonManager.createInstall", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3819 0 : JSContext* cx = s.GetContext();
3820 0 : if (!cx) {
3821 0 : MOZ_ASSERT(aRv.Failed());
3822 0 : return nullptr;
3823 : }
3824 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3825 0 : JS::AutoValueVector argv(cx);
3826 0 : if (!argv.resize(1)) {
3827 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
3828 0 : return nullptr;
3829 : }
3830 0 : unsigned argc = 1;
3831 :
3832 : do {
3833 0 : if (!options.ToObjectInternal(cx, argv[0])) {
3834 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3835 0 : return nullptr;
3836 : }
3837 0 : break;
3838 : } while (0);
3839 :
3840 0 : JS::Rooted<JS::Value> callable(cx);
3841 0 : AddonManagerAtoms* atomsCache = GetAtomCache<AddonManagerAtoms>(cx);
3842 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3843 0 : !GetCallableProperty(cx, atomsCache->createInstall_id, &callable)) {
3844 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3845 0 : return nullptr;
3846 : }
3847 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
3848 0 : if (!JS::Call(cx, thisValue, callable,
3849 0 : JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
3850 0 : aRv.NoteJSContextException(cx);
3851 0 : return nullptr;
3852 : }
3853 0 : RefPtr<Promise> rvalDecl;
3854 : { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
3855 : // etc.
3856 :
3857 0 : JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
3858 0 : if (!rval.isObject()) {
3859 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of AddonManager.createInstall"));
3860 0 : return nullptr;
3861 : }
3862 0 : JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
3863 0 : if (!unwrappedVal) {
3864 : // A slight lie, but not much of one, for a dead object wrapper.
3865 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of AddonManager.createInstall"));
3866 0 : return nullptr;
3867 : }
3868 0 : globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
3869 0 : JSAutoCompartment ac(cx, globalObj);
3870 0 : GlobalObject promiseGlobal(cx, globalObj);
3871 0 : if (promiseGlobal.Failed()) {
3872 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3873 0 : return nullptr;
3874 : }
3875 :
3876 0 : JS::Rooted<JS::Value> valueToResolve(cx, rval);
3877 0 : if (!JS_WrapValue(cx, &valueToResolve)) {
3878 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3879 0 : return nullptr;
3880 : }
3881 0 : binding_detail::FastErrorResult promiseRv;
3882 : nsCOMPtr<nsIGlobalObject> global =
3883 0 : do_QueryInterface(promiseGlobal.GetAsSupports());
3884 0 : if (!global) {
3885 0 : promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
3886 0 : MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
3887 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3888 0 : return nullptr;
3889 : }
3890 0 : rvalDecl = Promise::Resolve(global, cx, valueToResolve,
3891 0 : promiseRv);
3892 0 : if (promiseRv.MaybeSetPendingException(cx)) {
3893 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3894 0 : return nullptr;
3895 : }
3896 : }
3897 0 : return rvalDecl.forget();
3898 : }
3899 :
3900 : void
3901 0 : AddonManagerJSImpl::EventListenerWasAdded(const nsAString& type, ErrorResult& aRv, JSCompartment* aCompartment)
3902 : {
3903 0 : CallSetup s(this, aRv, "AddonManager.eventListenerWasAdded", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3904 0 : JSContext* cx = s.GetContext();
3905 0 : if (!cx) {
3906 0 : MOZ_ASSERT(aRv.Failed());
3907 0 : return;
3908 : }
3909 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3910 0 : JS::AutoValueVector argv(cx);
3911 0 : if (!argv.resize(1)) {
3912 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
3913 0 : return;
3914 : }
3915 0 : unsigned argc = 1;
3916 :
3917 : do {
3918 0 : nsString mutableStr(type);
3919 0 : if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
3920 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3921 0 : return;
3922 : }
3923 0 : break;
3924 : } while (0);
3925 :
3926 0 : JS::Rooted<JS::Value> callable(cx);
3927 0 : AddonManagerAtoms* atomsCache = GetAtomCache<AddonManagerAtoms>(cx);
3928 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3929 0 : !GetCallableProperty(cx, atomsCache->eventListenerWasAdded_id, &callable)) {
3930 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3931 0 : return;
3932 : }
3933 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
3934 0 : if (!JS::Call(cx, thisValue, callable,
3935 0 : JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
3936 0 : aRv.NoteJSContextException(cx);
3937 0 : return;
3938 : }
3939 : }
3940 :
3941 : void
3942 0 : AddonManagerJSImpl::EventListenerWasRemoved(const nsAString& type, ErrorResult& aRv, JSCompartment* aCompartment)
3943 : {
3944 0 : CallSetup s(this, aRv, "AddonManager.eventListenerWasRemoved", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
3945 0 : JSContext* cx = s.GetContext();
3946 0 : if (!cx) {
3947 0 : MOZ_ASSERT(aRv.Failed());
3948 0 : return;
3949 : }
3950 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
3951 0 : JS::AutoValueVector argv(cx);
3952 0 : if (!argv.resize(1)) {
3953 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
3954 0 : return;
3955 : }
3956 0 : unsigned argc = 1;
3957 :
3958 : do {
3959 0 : nsString mutableStr(type);
3960 0 : if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
3961 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3962 0 : return;
3963 : }
3964 0 : break;
3965 : } while (0);
3966 :
3967 0 : JS::Rooted<JS::Value> callable(cx);
3968 0 : AddonManagerAtoms* atomsCache = GetAtomCache<AddonManagerAtoms>(cx);
3969 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
3970 0 : !GetCallableProperty(cx, atomsCache->eventListenerWasRemoved_id, &callable)) {
3971 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
3972 0 : return;
3973 : }
3974 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
3975 0 : if (!JS::Call(cx, thisValue, callable,
3976 0 : JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
3977 0 : aRv.NoteJSContextException(cx);
3978 0 : return;
3979 : }
3980 : }
3981 :
3982 : bool
3983 0 : AddonManagerJSImpl::InitIds(JSContext* cx, AddonManagerAtoms* atomsCache)
3984 : {
3985 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
3986 :
3987 : // Initialize these in reverse order so that any failure leaves the first one
3988 : // uninitialized.
3989 0 : if (!atomsCache->eventListenerWasRemoved_id.init(cx, "eventListenerWasRemoved") ||
3990 0 : !atomsCache->eventListenerWasAdded_id.init(cx, "eventListenerWasAdded") ||
3991 0 : !atomsCache->permissionPromptsEnabled_id.init(cx, "permissionPromptsEnabled") ||
3992 0 : !atomsCache->createInstall_id.init(cx, "createInstall") ||
3993 0 : !atomsCache->getAddonByID_id.init(cx, "getAddonByID")) {
3994 0 : return false;
3995 : }
3996 0 : return true;
3997 : }
3998 :
3999 :
4000 : bool
4001 0 : AddonManagerJSImpl::GetPermissionPromptsEnabled(ErrorResult& aRv, JSCompartment* aCompartment)
4002 : {
4003 0 : CallSetup s(this, aRv, "AddonManager.permissionPromptsEnabled", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
4004 0 : JSContext* cx = s.GetContext();
4005 0 : if (!cx) {
4006 0 : MOZ_ASSERT(aRv.Failed());
4007 0 : return bool(0);
4008 : }
4009 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
4010 :
4011 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
4012 0 : AddonManagerAtoms* atomsCache = GetAtomCache<AddonManagerAtoms>(cx);
4013 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
4014 0 : !JS_GetPropertyById(cx, callback, atomsCache->permissionPromptsEnabled_id, &rval)) {
4015 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4016 0 : return bool(0);
4017 : }
4018 : bool rvalDecl;
4019 0 : if (!ValueToPrimitive<bool, eDefault>(cx, rval, &rvalDecl)) {
4020 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
4021 0 : return bool(0);
4022 : }
4023 0 : return rvalDecl;
4024 : }
4025 :
4026 :
4027 0 : NS_IMPL_CYCLE_COLLECTION_INHERITED(AddonManager, mozilla::DOMEventTargetHelper, mImpl, mParent)
4028 0 : NS_IMPL_ADDREF_INHERITED(AddonManager, mozilla::DOMEventTargetHelper)
4029 0 : NS_IMPL_RELEASE_INHERITED(AddonManager, mozilla::DOMEventTargetHelper)
4030 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(AddonManager)
4031 0 : NS_INTERFACE_MAP_END_INHERITING(mozilla::DOMEventTargetHelper)
4032 :
4033 0 : AddonManager::AddonManager(JS::Handle<JSObject*> aJSImplObject, nsIGlobalObject* aParent)
4034 : : mozilla::DOMEventTargetHelper(aParent),
4035 0 : mImpl(new AddonManagerJSImpl(nullptr, aJSImplObject, /* aIncumbentGlobal = */ nullptr)),
4036 0 : mParent(aParent)
4037 : {
4038 0 : }
4039 :
4040 :
4041 0 : AddonManager::~AddonManager()
4042 : {
4043 0 : }
4044 :
4045 : nsISupports*
4046 0 : AddonManager::GetParentObject() const
4047 : {
4048 0 : return mParent;
4049 : }
4050 :
4051 : JSObject*
4052 0 : AddonManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
4053 : {
4054 0 : JS::Rooted<JSObject*> obj(aCx, AddonManagerBinding::Wrap(aCx, this, aGivenProto));
4055 0 : if (!obj) {
4056 0 : return nullptr;
4057 : }
4058 :
4059 : // Now define it on our chrome object
4060 0 : JSAutoCompartment ac(aCx, mImpl->CallbackOrNull());
4061 0 : if (!JS_WrapObject(aCx, &obj)) {
4062 0 : return nullptr;
4063 : }
4064 0 : if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
4065 0 : return nullptr;
4066 : }
4067 0 : return obj;
4068 : }
4069 :
4070 : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
4071 : already_AddRefed<Promise>
4072 0 : AddonManager::GetAddonByID(const nsAString& id, ErrorResult& aRv, JSCompartment* aCompartment)
4073 : {
4074 0 : return mImpl->GetAddonByID(id, aRv, aCompartment);
4075 : }
4076 :
4077 : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
4078 : already_AddRefed<Promise>
4079 0 : AddonManager::CreateInstall(const addonInstallOptions& options, ErrorResult& aRv, JSCompartment* aCompartment)
4080 : {
4081 0 : return mImpl->CreateInstall(options, aRv, aCompartment);
4082 : }
4083 :
4084 : bool
4085 0 : AddonManager::GetPermissionPromptsEnabled(ErrorResult& aRv, JSCompartment* aCompartment) const
4086 : {
4087 0 : return mImpl->GetPermissionPromptsEnabled(aRv, aCompartment);
4088 : }
4089 :
4090 : void
4091 0 : AddonManager::EventListenerWasAdded(const nsAString& type, ErrorResult& aRv, JSCompartment* aCompartment)
4092 : {
4093 0 : return mImpl->EventListenerWasAdded(type, aRv, aCompartment);
4094 : }
4095 :
4096 : void
4097 0 : AddonManager::EventListenerWasRemoved(const nsAString& type, ErrorResult& aRv, JSCompartment* aCompartment)
4098 : {
4099 0 : return mImpl->EventListenerWasRemoved(type, aRv, aCompartment);
4100 : }
4101 :
4102 : bool
4103 0 : AddonManager::_Create(JSContext* cx, unsigned argc, JS::Value* vp)
4104 : {
4105 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
4106 0 : if (args.length() < 2) {
4107 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "AddonManager._create");
4108 : }
4109 0 : if (!args[0].isObject()) {
4110 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of AddonManager._create");
4111 : }
4112 0 : if (!args[1].isObject()) {
4113 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of AddonManager._create");
4114 : }
4115 :
4116 : // GlobalObject will go through wrappers as needed for us, and
4117 : // is simpler than the right UnwrapArg incantation.
4118 0 : GlobalObject global(cx, &args[0].toObject());
4119 0 : if (global.Failed()) {
4120 0 : return false;
4121 : }
4122 0 : nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports());
4123 0 : MOZ_ASSERT(globalHolder);
4124 0 : JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
4125 0 : RefPtr<AddonManager> impl = new AddonManager(arg, globalHolder);
4126 0 : MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
4127 0 : return GetOrCreateDOMReflector(cx, impl, args.rval());
4128 : }
4129 :
4130 :
4131 : } // namespace dom
4132 : } // namespace mozilla
|