Coverage Report

Created: 2018-09-25 14:53

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