Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/PushManagerBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM PushManager.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "AtomList.h"
4
#include "PushManagerBinding.h"
5
#include "WrapperFactory.h"
6
#include "jsapi.h"
7
#include "mozilla/OwningNonNull.h"
8
#include "mozilla/UseCounter.h"
9
#include "mozilla/dom/BindingUtils.h"
10
#include "mozilla/dom/DOMJSClass.h"
11
#include "mozilla/dom/DOMPrefs.h"
12
#include "mozilla/dom/NonRefcountedDOMObject.h"
13
#include "mozilla/dom/Promise.h"
14
#include "mozilla/dom/PushManager.h"
15
#include "mozilla/dom/ScriptSettings.h"
16
#include "mozilla/dom/ToJSValue.h"
17
#include "mozilla/dom/UnionConversions.h"
18
#include "mozilla/dom/XrayExpandoClass.h"
19
#include "nsContentUtils.h"
20
#include "nsIGlobalObject.h"
21
22
namespace mozilla {
23
namespace dom {
24
25
namespace binding_detail {}; // Just to make sure it's known as a namespace
26
using namespace mozilla::dom::binding_detail;
27
28
29
namespace PushPermissionStateValues {
30
extern const EnumEntry strings[4] = {
31
  {"granted", 7},
32
  {"denied", 6},
33
  {"prompt", 6},
34
  { nullptr, 0 }
35
};
36
} // namespace PushPermissionStateValues
37
38
bool
39
ToJSValue(JSContext* aCx, PushPermissionState aArgument, JS::MutableHandle<JS::Value> aValue)
40
0
{
41
0
  MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(PushPermissionStateValues::strings));
42
0
  JSString* resultStr =
43
0
    JS_NewStringCopyN(aCx, PushPermissionStateValues::strings[uint32_t(aArgument)].value,
44
0
                      PushPermissionStateValues::strings[uint32_t(aArgument)].length);
45
0
  if (!resultStr) {
46
0
    return false;
47
0
  }
48
0
  aValue.setString(resultStr);
49
0
  return true;
50
0
}
51
52
53
bool
54
ArrayBufferViewOrArrayBufferOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
55
0
{
56
0
  switch (mType) {
57
0
    case eUninitialized: {
58
0
      return false;
59
0
      break;
60
0
    }
61
0
    case eArrayBufferView: {
62
0
      rval.setObject(*mValue.mArrayBufferView.Value().Obj());
63
0
      if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
64
0
        return false;
65
0
      }
66
0
      return true;
67
0
      break;
68
0
    }
69
0
    case eArrayBuffer: {
70
0
      rval.setObject(*mValue.mArrayBuffer.Value().Obj());
71
0
      if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
72
0
        return false;
73
0
      }
74
0
      return true;
75
0
      break;
76
0
    }
77
0
    case eString: {
78
0
      if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
79
0
        return false;
80
0
      }
81
0
      return true;
82
0
      break;
83
0
    }
84
0
    default: {
85
0
      return false;
86
0
      break;
87
0
    }
88
0
  }
89
0
90
0
  return false;
91
0
}
92
93
94
ArrayBufferView&
95
OwningArrayBufferViewOrArrayBufferOrString::RawSetAsArrayBufferView()
96
0
{
97
0
  if (mType == eArrayBufferView) {
98
0
    return mValue.mArrayBufferView.Value();
99
0
  }
100
0
  MOZ_ASSERT(mType == eUninitialized);
101
0
  mType = eArrayBufferView;
102
0
  return mValue.mArrayBufferView.SetValue();
103
0
}
104
105
ArrayBufferView&
106
OwningArrayBufferViewOrArrayBufferOrString::SetAsArrayBufferView()
107
0
{
108
0
  if (mType == eArrayBufferView) {
109
0
    return mValue.mArrayBufferView.Value();
110
0
  }
111
0
  Uninit();
112
0
  mType = eArrayBufferView;
113
0
  return mValue.mArrayBufferView.SetValue();
114
0
}
115
116
bool
117
OwningArrayBufferViewOrArrayBufferOrString::TrySetToArrayBufferView(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
118
0
{
119
0
  tryNext = false;
120
0
  { // scope for memberSlot
121
0
    ArrayBufferView& memberSlot = RawSetAsArrayBufferView();
122
0
    if (!memberSlot.Init(&value.toObject())) {
123
0
      DestroyArrayBufferView();
124
0
      tryNext = true;
125
0
      return true;
126
0
    }
127
0
  }
128
0
  return true;
129
0
}
130
131
void
132
OwningArrayBufferViewOrArrayBufferOrString::DestroyArrayBufferView()
133
0
{
134
0
  MOZ_ASSERT(IsArrayBufferView(), "Wrong type!");
135
0
  mValue.mArrayBufferView.Destroy();
136
0
  mType = eUninitialized;
137
0
}
138
139
140
141
142
ArrayBuffer&
143
OwningArrayBufferViewOrArrayBufferOrString::RawSetAsArrayBuffer()
144
0
{
145
0
  if (mType == eArrayBuffer) {
146
0
    return mValue.mArrayBuffer.Value();
147
0
  }
148
0
  MOZ_ASSERT(mType == eUninitialized);
149
0
  mType = eArrayBuffer;
150
0
  return mValue.mArrayBuffer.SetValue();
151
0
}
152
153
ArrayBuffer&
154
OwningArrayBufferViewOrArrayBufferOrString::SetAsArrayBuffer()
155
0
{
156
0
  if (mType == eArrayBuffer) {
157
0
    return mValue.mArrayBuffer.Value();
158
0
  }
159
0
  Uninit();
160
0
  mType = eArrayBuffer;
161
0
  return mValue.mArrayBuffer.SetValue();
162
0
}
163
164
bool
165
OwningArrayBufferViewOrArrayBufferOrString::TrySetToArrayBuffer(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
166
0
{
167
0
  tryNext = false;
168
0
  { // scope for memberSlot
169
0
    ArrayBuffer& memberSlot = RawSetAsArrayBuffer();
170
0
    if (!memberSlot.Init(&value.toObject())) {
171
0
      DestroyArrayBuffer();
172
0
      tryNext = true;
173
0
      return true;
174
0
    }
175
0
  }
176
0
  return true;
177
0
}
178
179
void
180
OwningArrayBufferViewOrArrayBufferOrString::DestroyArrayBuffer()
181
0
{
182
0
  MOZ_ASSERT(IsArrayBuffer(), "Wrong type!");
183
0
  mValue.mArrayBuffer.Destroy();
184
0
  mType = eUninitialized;
185
0
}
186
187
188
189
190
nsString&
191
OwningArrayBufferViewOrArrayBufferOrString::RawSetAsString()
192
0
{
193
0
  if (mType == eString) {
194
0
    return mValue.mString.Value();
195
0
  }
196
0
  MOZ_ASSERT(mType == eUninitialized);
197
0
  mType = eString;
198
0
  return mValue.mString.SetValue();
199
0
}
200
201
nsString&
202
OwningArrayBufferViewOrArrayBufferOrString::SetAsString()
203
0
{
204
0
  if (mType == eString) {
205
0
    return mValue.mString.Value();
206
0
  }
207
0
  Uninit();
208
0
  mType = eString;
209
0
  return mValue.mString.SetValue();
210
0
}
211
212
bool
213
OwningArrayBufferViewOrArrayBufferOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
214
0
{
215
0
  tryNext = false;
216
0
  { // scope for memberSlot
217
0
    nsString& memberSlot = RawSetAsString();
218
0
    if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
219
0
      return false;
220
0
    }
221
0
  }
222
0
  return true;
223
0
}
224
225
226
void
227
OwningArrayBufferViewOrArrayBufferOrString::DestroyString()
228
0
{
229
0
  MOZ_ASSERT(IsString(), "Wrong type!");
230
0
  mValue.mString.Destroy();
231
0
  mType = eUninitialized;
232
0
}
233
234
235
236
237
void
238
OwningArrayBufferViewOrArrayBufferOrString::Uninit()
239
{
240
  switch (mType) {
241
    case eUninitialized: {
242
      break;
243
    }
244
    case eArrayBufferView: {
245
      DestroyArrayBufferView();
246
      break;
247
    }
248
    case eArrayBuffer: {
249
      DestroyArrayBuffer();
250
      break;
251
    }
252
    case eString: {
253
      DestroyString();
254
      break;
255
    }
256
  }
257
}
258
259
bool
260
OwningArrayBufferViewOrArrayBufferOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
261
0
{
262
0
  switch (mType) {
263
0
    case eUninitialized: {
264
0
      return false;
265
0
      break;
266
0
    }
267
0
    case eArrayBufferView: {
268
0
      rval.setObject(*mValue.mArrayBufferView.Value().Obj());
269
0
      if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
270
0
        return false;
271
0
      }
272
0
      return true;
273
0
      break;
274
0
    }
275
0
    case eArrayBuffer: {
276
0
      rval.setObject(*mValue.mArrayBuffer.Value().Obj());
277
0
      if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
278
0
        return false;
279
0
      }
280
0
      return true;
281
0
      break;
282
0
    }
283
0
    case eString: {
284
0
      if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
285
0
        return false;
286
0
      }
287
0
      return true;
288
0
      break;
289
0
    }
290
0
    default: {
291
0
      return false;
292
0
      break;
293
0
    }
294
0
  }
295
0
296
0
  return false;
297
0
}
298
299
void
300
OwningArrayBufferViewOrArrayBufferOrString::TraceUnion(JSTracer* trc)
301
{
302
  switch (mType) {
303
    case eArrayBufferView: {
304
      mValue.mArrayBufferView.Value().TraceSelf(trc);
305
      break;
306
    }
307
    case eArrayBuffer: {
308
      mValue.mArrayBuffer.Value().TraceSelf(trc);
309
      break;
310
    }
311
    default: {
312
      break;
313
    }
314
  }
315
}
316
317
318
319
PushSubscriptionOptionsInit::PushSubscriptionOptionsInit()
320
0
{
321
0
  // Safe to pass a null context if we pass a null value
322
0
  Init(nullptr, JS::NullHandleValue);
323
0
}
324
325
326
bool
327
PushSubscriptionOptionsInit::InitIds(JSContext* cx, PushSubscriptionOptionsInitAtoms* atomsCache)
328
0
{
329
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
330
0
331
0
  // Initialize these in reverse order so that any failure leaves the first one
332
0
  // uninitialized.
333
0
  if (!atomsCache->applicationServerKey_id.init(cx, "applicationServerKey")) {
334
0
    return false;
335
0
  }
336
0
  return true;
337
0
}
338
339
bool
340
PushSubscriptionOptionsInit::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
341
0
{
342
0
  // Passing a null JSContext is OK only if we're initing from null,
343
0
  // Since in that case we will not have to do any property gets
344
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
345
0
  // checkers by static analysis tools
346
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
347
0
  PushSubscriptionOptionsInitAtoms* atomsCache = nullptr;
348
0
  if (cx) {
349
0
    atomsCache = GetAtomCache<PushSubscriptionOptionsInitAtoms>(cx);
350
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
351
0
      return false;
352
0
    }
353
0
  }
354
0
355
0
  if (!IsConvertibleToDictionary(val)) {
356
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
357
0
  }
358
0
359
0
  bool isNull = val.isNullOrUndefined();
360
0
  // We only need these if !isNull, in which case we have |cx|.
361
0
  Maybe<JS::Rooted<JSObject *> > object;
362
0
  Maybe<JS::Rooted<JS::Value> > temp;
363
0
  if (!isNull) {
364
0
    MOZ_ASSERT(cx);
365
0
    object.emplace(cx, &val.toObject());
366
0
    temp.emplace(cx);
367
0
  }
368
0
  if (!isNull) {
369
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->applicationServerKey_id, temp.ptr())) {
370
0
      return false;
371
0
    }
372
0
  }
373
0
  if (!(!isNull && !temp->isUndefined()) || temp.ref().isNullOrUndefined()) {
374
0
    mApplicationServerKey.SetNull();
375
0
  } else {
376
0
    {
377
0
      bool done = false, failed = false, tryNext;
378
0
      if (temp.ref().isObject()) {
379
0
        done = (failed = !mApplicationServerKey.SetValue().TrySetToArrayBufferView(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
380
0
               (failed = !mApplicationServerKey.SetValue().TrySetToArrayBuffer(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext;
381
0
382
0
      }
383
0
      if (!done) {
384
0
        do {
385
0
          done = (failed = !mApplicationServerKey.SetValue().TrySetToString(cx, temp.ref(), tryNext)) || !tryNext;
386
0
          break;
387
0
        } while (false);
388
0
      }
389
0
      if (failed) {
390
0
        return false;
391
0
      }
392
0
      if (!done) {
393
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'applicationServerKey' member of PushSubscriptionOptionsInit", "ArrayBufferView, ArrayBuffer");
394
0
        return false;
395
0
      }
396
0
    }
397
0
  }
398
0
  mIsAnyMemberPresent = true;
399
0
  return true;
400
0
}
401
402
bool
403
PushSubscriptionOptionsInit::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
404
0
{
405
0
  PushSubscriptionOptionsInitAtoms* atomsCache = GetAtomCache<PushSubscriptionOptionsInitAtoms>(cx);
406
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
407
0
    return false;
408
0
  }
409
0
410
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
411
0
  if (!obj) {
412
0
    return false;
413
0
  }
414
0
  rval.set(JS::ObjectValue(*obj));
415
0
416
0
  do {
417
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
418
0
    JS::Rooted<JS::Value> temp(cx);
419
0
    Nullable<OwningArrayBufferViewOrArrayBufferOrString > const & currentValue = mApplicationServerKey;
420
0
    if (currentValue.IsNull()) {
421
0
      temp.setNull();
422
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->applicationServerKey_id, temp, JSPROP_ENUMERATE)) {
423
0
        return false;
424
0
      }
425
0
      break;
426
0
    }
427
0
    if (!currentValue.Value().ToJSVal(cx, obj, &temp)) {
428
0
      return false;
429
0
    }
430
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->applicationServerKey_id, temp, JSPROP_ENUMERATE)) {
431
0
      return false;
432
0
    }
433
0
    break;
434
0
  } while(false);
435
0
436
0
  return true;
437
0
}
438
439
void
440
PushSubscriptionOptionsInit::TraceDictionary(JSTracer* trc)
441
0
{
442
0
  if (!mApplicationServerKey.IsNull()) {
443
0
    mApplicationServerKey.Value().TraceUnion(trc);
444
0
  }
445
0
}
446
447
namespace binding_detail {
448
} // namespace binding_detail
449
450
451
namespace PushManager_Binding {
452
453
MOZ_CAN_RUN_SCRIPT static bool
454
subscribe(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PushManager* self, const JSJitMethodCallArgs& args)
455
0
{
456
0
  AUTO_PROFILER_LABEL_FAST("PushManager.subscribe", DOM, cx);
457
0
458
0
  RootedDictionary<binding_detail::FastPushSubscriptionOptionsInit> arg0(cx);
459
0
  if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue,  "Argument 1 of PushManager.subscribe", false)) {
460
0
    return false;
461
0
  }
462
0
  FastErrorResult rv;
463
0
  auto result(StrongOrRawPtr<Promise>(self->Subscribe(Constify(arg0), rv)));
464
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
465
0
    return false;
466
0
  }
467
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
468
0
  SetDocumentAndPageUseCounter(obj, eUseCounter_PushManager_subscribe);
469
0
  if (!ToJSValue(cx, result, args.rval())) {
470
0
    return false;
471
0
  }
472
0
  return true;
473
0
}
474
475
MOZ_CAN_RUN_SCRIPT static bool
476
subscribe_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PushManager* self, const JSJitMethodCallArgs& args)
477
0
{
478
0
  bool ok = subscribe(cx, obj, self, args);
479
0
  if (ok) {
480
0
    return true;
481
0
  }
482
0
  return ConvertExceptionToPromise(cx, args.rval());
483
0
}
484
485
static const JSJitInfo subscribe_methodinfo = {
486
  { (JSJitGetterOp)subscribe_promiseWrapper },
487
  { prototypes::id::PushManager },
488
  { PrototypeTraits<prototypes::id::PushManager>::Depth },
489
  JSJitInfo::Method,
490
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
491
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
492
  false,  /* isInfallible. False in setters. */
493
  false,  /* isMovable.  Not relevant for setters. */
494
  false, /* isEliminatable.  Not relevant for setters. */
495
  false, /* isAlwaysInSlot.  Only relevant for getters. */
496
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
497
  false,  /* isTypedMethod.  Only relevant for methods. */
498
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
499
};
500
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
501
static_assert(0 < 1, "There is no slot for us");
502
503
MOZ_CAN_RUN_SCRIPT static bool
504
getSubscription(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PushManager* self, const JSJitMethodCallArgs& args)
505
0
{
506
0
  AUTO_PROFILER_LABEL_FAST("PushManager.getSubscription", DOM, cx);
507
0
508
0
  FastErrorResult rv;
509
0
  auto result(StrongOrRawPtr<Promise>(self->GetSubscription(rv)));
510
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
511
0
    return false;
512
0
  }
513
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
514
0
  if (!ToJSValue(cx, result, args.rval())) {
515
0
    return false;
516
0
  }
517
0
  return true;
518
0
}
519
520
MOZ_CAN_RUN_SCRIPT static bool
521
getSubscription_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PushManager* self, const JSJitMethodCallArgs& args)
522
0
{
523
0
  bool ok = getSubscription(cx, obj, self, args);
524
0
  if (ok) {
525
0
    return true;
526
0
  }
527
0
  return ConvertExceptionToPromise(cx, args.rval());
528
0
}
529
530
static const JSJitInfo getSubscription_methodinfo = {
531
  { (JSJitGetterOp)getSubscription_promiseWrapper },
532
  { prototypes::id::PushManager },
533
  { PrototypeTraits<prototypes::id::PushManager>::Depth },
534
  JSJitInfo::Method,
535
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
536
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
537
  false,  /* isInfallible. False in setters. */
538
  false,  /* isMovable.  Not relevant for setters. */
539
  false, /* isEliminatable.  Not relevant for setters. */
540
  false, /* isAlwaysInSlot.  Only relevant for getters. */
541
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
542
  false,  /* isTypedMethod.  Only relevant for methods. */
543
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
544
};
545
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
546
static_assert(0 < 1, "There is no slot for us");
547
548
MOZ_CAN_RUN_SCRIPT static bool
549
permissionState(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PushManager* self, const JSJitMethodCallArgs& args)
550
0
{
551
0
  AUTO_PROFILER_LABEL_FAST("PushManager.permissionState", DOM, cx);
552
0
553
0
  RootedDictionary<binding_detail::FastPushSubscriptionOptionsInit> arg0(cx);
554
0
  if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue,  "Argument 1 of PushManager.permissionState", false)) {
555
0
    return false;
556
0
  }
557
0
  FastErrorResult rv;
558
0
  auto result(StrongOrRawPtr<Promise>(self->PermissionState(Constify(arg0), rv)));
559
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
560
0
    return false;
561
0
  }
562
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
563
0
  if (!ToJSValue(cx, result, args.rval())) {
564
0
    return false;
565
0
  }
566
0
  return true;
567
0
}
568
569
MOZ_CAN_RUN_SCRIPT static bool
570
permissionState_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PushManager* self, const JSJitMethodCallArgs& args)
571
0
{
572
0
  bool ok = permissionState(cx, obj, self, args);
573
0
  if (ok) {
574
0
    return true;
575
0
  }
576
0
  return ConvertExceptionToPromise(cx, args.rval());
577
0
}
578
579
static const JSJitInfo permissionState_methodinfo = {
580
  { (JSJitGetterOp)permissionState_promiseWrapper },
581
  { prototypes::id::PushManager },
582
  { PrototypeTraits<prototypes::id::PushManager>::Depth },
583
  JSJitInfo::Method,
584
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
585
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
586
  false,  /* isInfallible. False in setters. */
587
  false,  /* isMovable.  Not relevant for setters. */
588
  false, /* isEliminatable.  Not relevant for setters. */
589
  false, /* isAlwaysInSlot.  Only relevant for getters. */
590
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
591
  false,  /* isTypedMethod.  Only relevant for methods. */
592
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
593
};
594
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
595
static_assert(0 < 1, "There is no slot for us");
596
597
static bool
598
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
599
0
{
600
0
  mozilla::dom::PushManager* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PushManager>(obj);
601
0
  // We don't want to preserve if we don't have a wrapper, and we
602
0
  // obviously can't preserve if we're not initialized.
603
0
  if (self && self->GetWrapperPreserveColor()) {
604
0
    PreserveWrapper(self);
605
0
  }
606
0
  return true;
607
0
}
608
609
static void
610
_finalize(js::FreeOp* fop, JSObject* obj)
611
0
{
612
0
  mozilla::dom::PushManager* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PushManager>(obj);
613
0
  if (self) {
614
0
    ClearWrapper(self, self, obj);
615
0
    AddForDeferredFinalization<mozilla::dom::PushManager>(self);
616
0
  }
617
0
}
618
619
static size_t
620
_objectMoved(JSObject* obj, JSObject* old)
621
0
{
622
0
  mozilla::dom::PushManager* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PushManager>(obj);
623
0
  if (self) {
624
0
    UpdateWrapper(self, self, obj, old);
625
0
  }
626
0
627
0
  return 0;
628
0
}
629
630
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
631
#if defined(__clang__)
632
#pragma clang diagnostic push
633
#pragma clang diagnostic ignored "-Wmissing-braces"
634
#endif
635
static const JSFunctionSpec sMethods_specs[] = {
636
  JS_FNSPEC("subscribe", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&subscribe_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
637
  JS_FNSPEC("getSubscription", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&getSubscription_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
638
  JS_FNSPEC("permissionState", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&permissionState_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
639
  JS_FS_END
640
};
641
#if defined(__clang__)
642
#pragma clang diagnostic pop
643
#endif
644
645
646
static const Prefable<const JSFunctionSpec> sMethods[] = {
647
  { nullptr, &sMethods_specs[0] },
648
  { nullptr, nullptr }
649
};
650
651
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
652
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
653
static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
654
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
655
656
657
static uint16_t sNativeProperties_sortedPropertyIndices[3];
658
static PropertyInfo sNativeProperties_propertyInfos[3];
659
660
static const NativePropertiesN<1> sNativeProperties = {
661
  false, 0,
662
  false, 0,
663
  true,  0 /* sMethods */,
664
  false, 0,
665
  false, 0,
666
  false, 0,
667
  false, 0,
668
  -1,
669
  3,
670
  sNativeProperties_sortedPropertyIndices,
671
  {
672
    { sMethods, &sNativeProperties_propertyInfos[0] }
673
  }
674
};
675
static_assert(3 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
676
    "We have a property info count that is oversized");
677
678
static bool
679
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
680
0
{
681
0
  AUTO_PROFILER_LABEL_FAST("PushManager constructor", DOM, cx);
682
0
683
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
684
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
685
0
  if (!nsContentUtils::ThreadsafeIsSystemCaller(cx)) {
686
0
    return ThrowingConstructor(cx, argc, vp);
687
0
  }
688
0
689
0
  if (!args.isConstructing()) {
690
0
    // XXXbz wish I could get the name from the callee instead of
691
0
    // Adding more relocations
692
0
    return ThrowConstructorWithoutNew(cx, "PushManager");
693
0
  }
694
0
695
0
  JS::Rooted<JSObject*> desiredProto(cx);
696
0
  if (!GetDesiredProto(cx, args, &desiredProto)) {
697
0
    return false;
698
0
  }
699
0
700
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
701
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "PushManager");
702
0
  }
703
0
  GlobalObject global(cx, obj);
704
0
  if (global.Failed()) {
705
0
    return false;
706
0
  }
707
0
708
0
  bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
709
0
  binding_detail::FakeString arg0;
710
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
711
0
    return false;
712
0
  }
713
0
  Maybe<JSAutoRealm> ar;
714
0
  if (objIsXray) {
715
0
    obj = js::CheckedUnwrap(obj);
716
0
    if (!obj) {
717
0
      return false;
718
0
    }
719
0
    ar.emplace(cx, obj);
720
0
    if (!JS_WrapObject(cx, &desiredProto)) {
721
0
      return false;
722
0
    }
723
0
  }
724
0
  FastErrorResult rv;
725
0
  auto result(StrongOrRawPtr<mozilla::dom::PushManager>(mozilla::dom::PushManager::Constructor(global, NonNullHelper(Constify(arg0)), rv)));
726
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
727
0
    return false;
728
0
  }
729
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
730
0
  static_assert(!IsPointer<decltype(result)>::value,
731
0
                "NewObject implies that we need to keep the object alive with a strong reference.");
732
0
  if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
733
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
734
0
    return false;
735
0
  }
736
0
  return true;
737
0
}
738
739
static const js::ClassOps sInterfaceObjectClassOps = {
740
    nullptr,               /* addProperty */
741
    nullptr,               /* delProperty */
742
    nullptr,               /* enumerate */
743
    nullptr,               /* newEnumerate */
744
    nullptr,               /* resolve */
745
    nullptr,               /* mayResolve */
746
    nullptr,               /* finalize */
747
    _constructor, /* call */
748
    nullptr,               /* hasInstance */
749
    _constructor, /* construct */
750
    nullptr,               /* trace */
751
};
752
753
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
754
  {
755
    "Function",
756
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
757
    &sInterfaceObjectClassOps,
758
    JS_NULL_CLASS_SPEC,
759
    JS_NULL_CLASS_EXT,
760
    &sInterfaceObjectClassObjectOps
761
  },
762
  eInterface,
763
  true,
764
  prototypes::id::PushManager,
765
  PrototypeTraits<prototypes::id::PushManager>::Depth,
766
  sNativePropertyHooks,
767
  "function PushManager() {\n    [native code]\n}",
768
  JS::GetRealmFunctionPrototype
769
};
770
771
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
772
  {
773
    "PushManagerPrototype",
774
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
775
    JS_NULL_CLASS_OPS,
776
    JS_NULL_CLASS_SPEC,
777
    JS_NULL_CLASS_EXT,
778
    JS_NULL_OBJECT_OPS
779
  },
780
  eInterfacePrototype,
781
  false,
782
  prototypes::id::PushManager,
783
  PrototypeTraits<prototypes::id::PushManager>::Depth,
784
  sNativePropertyHooks,
785
  "[object PushManagerPrototype]",
786
  JS::GetRealmObjectPrototype
787
};
788
789
bool
790
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
791
0
{
792
0
  return mozilla::dom::DOMPrefs::dom_push_enabled(aCx, aObj);
793
0
}
794
795
static const js::ClassOps sClassOps = {
796
  _addProperty, /* addProperty */
797
  nullptr,               /* delProperty */
798
  nullptr,               /* enumerate */
799
  nullptr, /* newEnumerate */
800
  nullptr, /* resolve */
801
  nullptr, /* mayResolve */
802
  _finalize, /* finalize */
803
  nullptr, /* call */
804
  nullptr,               /* hasInstance */
805
  nullptr,               /* construct */
806
  nullptr, /* trace */
807
};
808
809
static const js::ClassExtension sClassExtension = {
810
  nullptr, /* weakmapKeyDelegateOp */
811
  _objectMoved /* objectMovedOp */
812
};
813
814
static const DOMJSClass sClass = {
815
  { "PushManager",
816
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
817
    &sClassOps,
818
    JS_NULL_CLASS_SPEC,
819
    &sClassExtension,
820
    JS_NULL_OBJECT_OPS
821
  },
822
  { prototypes::id::PushManager, 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 },
823
  IsBaseOf<nsISupports, mozilla::dom::PushManager >::value,
824
  sNativePropertyHooks,
825
  FindAssociatedGlobalForNative<mozilla::dom::PushManager>::Get,
826
  GetProtoObjectHandle,
827
  GetCCParticipant<mozilla::dom::PushManager>::Get()
828
};
829
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
830
              "Must have the right minimal number of reserved slots.");
831
static_assert(1 >= 1,
832
              "Must have enough reserved slots.");
833
834
const JSClass*
835
GetJSClass()
836
0
{
837
0
  return sClass.ToJSClass();
838
0
}
839
840
bool
841
Wrap(JSContext* aCx, mozilla::dom::PushManager* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
842
0
{
843
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::PushManager>::value,
844
0
                "Shouldn't have wrappercached things that are not refcounted.");
845
0
  MOZ_ASSERT(static_cast<mozilla::dom::PushManager*>(aObject) ==
846
0
             reinterpret_cast<mozilla::dom::PushManager*>(aObject),
847
0
             "Multiple inheritance for mozilla::dom::PushManager is broken.");
848
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
849
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
850
0
  MOZ_ASSERT(!aCache->GetWrapper(),
851
0
             "You should probably not be using Wrap() directly; use "
852
0
             "GetOrCreateDOMReflector instead");
853
0
854
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
855
0
             "nsISupports must be on our primary inheritance chain");
856
0
857
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
858
0
  if (!global) {
859
0
    return false;
860
0
  }
861
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
862
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
863
0
864
0
  // That might have ended up wrapping us already, due to the wonders
865
0
  // of XBL.  Check for that, and bail out as needed.
866
0
  aReflector.set(aCache->GetWrapper());
867
0
  if (aReflector) {
868
#ifdef DEBUG
869
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
870
#endif // DEBUG
871
    return true;
872
0
  }
873
0
874
0
  JSAutoRealm ar(aCx, global);
875
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
876
0
  if (!canonicalProto) {
877
0
    return false;
878
0
  }
879
0
  JS::Rooted<JSObject*> proto(aCx);
880
0
  if (aGivenProto) {
881
0
    proto = aGivenProto;
882
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
883
0
    // coming in, we changed compartments to that of "parent" so may need
884
0
    // to wrap the proto here.
885
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
886
0
      if (!JS_WrapObject(aCx, &proto)) {
887
0
        return false;
888
0
      }
889
0
    }
890
0
  } else {
891
0
    proto = canonicalProto;
892
0
  }
893
0
894
0
  BindingJSObjectCreator<mozilla::dom::PushManager> creator(aCx);
895
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
896
0
  if (!aReflector) {
897
0
    return false;
898
0
  }
899
0
900
0
  aCache->SetWrapper(aReflector);
901
0
  creator.InitializationSucceeded();
902
0
903
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
904
0
             aCache->GetWrapperPreserveColor() == aReflector);
905
0
  // If proto != canonicalProto, we have to preserve our wrapper;
906
0
  // otherwise we won't be able to properly recreate it later, since
907
0
  // we won't know what proto to use.  Note that we don't check
908
0
  // aGivenProto here, since it's entirely possible (and even
909
0
  // somewhat common) to have a non-null aGivenProto which is the
910
0
  // same as canonicalProto.
911
0
  if (proto != canonicalProto) {
912
0
    PreserveWrapper(aObject);
913
0
  }
914
0
915
0
  return true;
916
0
}
917
918
const NativePropertyHooks sNativePropertyHooks[] = { {
919
  nullptr,
920
  nullptr,
921
  nullptr,
922
  { sNativeProperties.Upcast(), nullptr },
923
  prototypes::id::PushManager,
924
  constructors::id::PushManager,
925
  nullptr,
926
  &DefaultXrayExpandoObjectClass
927
} };
928
929
void
930
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
931
0
{
932
0
  JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
933
0
  if (!parentProto) {
934
0
    return;
935
0
  }
936
0
937
0
  JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
938
0
  if (!constructorProto) {
939
0
    return;
940
0
  }
941
0
942
0
  static bool sIdsInited = false;
943
0
  if (!sIdsInited && NS_IsMainThread()) {
944
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
945
0
      return;
946
0
    }
947
0
    sIdsInited = true;
948
0
  }
949
0
950
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::PushManager);
951
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::PushManager);
952
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
953
0
                              &sPrototypeClass.mBase, protoCache,
954
0
                              nullptr,
955
0
                              constructorProto, &sInterfaceObjectClass.mBase, 1, nullptr,
956
0
                              interfaceCache,
957
0
                              sNativeProperties.Upcast(),
958
0
                              nullptr,
959
0
                              "PushManager", aDefineOnGlobal,
960
0
                              nullptr,
961
0
                              false);
962
0
}
963
964
JSObject*
965
GetConstructorObject(JSContext* aCx)
966
0
{
967
0
  return GetConstructorObjectHandle(aCx);
968
0
}
969
970
} // namespace PushManager_Binding
971
972
973
974
namespace PushManagerImpl_Binding {
975
976
MOZ_CAN_RUN_SCRIPT static bool
977
subscribe(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PushManagerImpl* self, const JSJitMethodCallArgs& args)
978
0
{
979
0
  AUTO_PROFILER_LABEL_FAST("PushManagerImpl.subscribe", DOM, cx);
980
0
981
0
  Maybe<JS::Rooted<JSObject*> > unwrappedObj;
982
0
  bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
983
0
  if (objIsXray) {
984
0
    unwrappedObj.emplace(cx, obj);
985
0
  }
986
0
  RootedDictionary<binding_detail::FastPushSubscriptionOptionsInit> arg0(cx);
987
0
  if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue,  "Argument 1 of PushManagerImpl.subscribe", true)) {
988
0
    return false;
989
0
  }
990
0
  if (objIsXray) {
991
0
    unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
992
0
    if (!unwrappedObj.ref()) {
993
0
      return false;
994
0
    }
995
0
  }
996
0
  FastErrorResult rv;
997
0
  auto result(StrongOrRawPtr<Promise>(self->Subscribe(Constify(arg0), rv, (unwrappedObj ? js::GetNonCCWObjectRealm(*unwrappedObj) : js::GetContextRealm(cx)))));
998
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
999
0
    return false;
1000
0
  }
1001
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1002
0
  if (!ToJSValue(cx, result, args.rval())) {
1003
0
    return false;
1004
0
  }
1005
0
  return true;
1006
0
}
1007
1008
MOZ_CAN_RUN_SCRIPT static bool
1009
subscribe_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PushManagerImpl* self, const JSJitMethodCallArgs& args)
1010
0
{
1011
0
  bool ok = subscribe(cx, obj, self, args);
1012
0
  if (ok) {
1013
0
    return true;
1014
0
  }
1015
0
  return ConvertExceptionToPromise(cx, args.rval());
1016
0
}
1017
1018
static const JSJitInfo subscribe_methodinfo = {
1019
  { (JSJitGetterOp)subscribe_promiseWrapper },
1020
  { prototypes::id::PushManagerImpl },
1021
  { PrototypeTraits<prototypes::id::PushManagerImpl>::Depth },
1022
  JSJitInfo::Method,
1023
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
1024
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
1025
  false,  /* isInfallible. False in setters. */
1026
  false,  /* isMovable.  Not relevant for setters. */
1027
  false, /* isEliminatable.  Not relevant for setters. */
1028
  false, /* isAlwaysInSlot.  Only relevant for getters. */
1029
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
1030
  false,  /* isTypedMethod.  Only relevant for methods. */
1031
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
1032
};
1033
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1034
static_assert(0 < 1, "There is no slot for us");
1035
1036
MOZ_CAN_RUN_SCRIPT static bool
1037
getSubscription(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PushManagerImpl* self, const JSJitMethodCallArgs& args)
1038
0
{
1039
0
  AUTO_PROFILER_LABEL_FAST("PushManagerImpl.getSubscription", DOM, cx);
1040
0
1041
0
  Maybe<JS::Rooted<JSObject*> > unwrappedObj;
1042
0
  bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1043
0
  if (objIsXray) {
1044
0
    unwrappedObj.emplace(cx, obj);
1045
0
  }
1046
0
  if (objIsXray) {
1047
0
    unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
1048
0
    if (!unwrappedObj.ref()) {
1049
0
      return false;
1050
0
    }
1051
0
  }
1052
0
  FastErrorResult rv;
1053
0
  auto result(StrongOrRawPtr<Promise>(self->GetSubscription(rv, (unwrappedObj ? js::GetNonCCWObjectRealm(*unwrappedObj) : js::GetContextRealm(cx)))));
1054
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1055
0
    return false;
1056
0
  }
1057
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1058
0
  if (!ToJSValue(cx, result, args.rval())) {
1059
0
    return false;
1060
0
  }
1061
0
  return true;
1062
0
}
1063
1064
MOZ_CAN_RUN_SCRIPT static bool
1065
getSubscription_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PushManagerImpl* self, const JSJitMethodCallArgs& args)
1066
0
{
1067
0
  bool ok = getSubscription(cx, obj, self, args);
1068
0
  if (ok) {
1069
0
    return true;
1070
0
  }
1071
0
  return ConvertExceptionToPromise(cx, args.rval());
1072
0
}
1073
1074
static const JSJitInfo getSubscription_methodinfo = {
1075
  { (JSJitGetterOp)getSubscription_promiseWrapper },
1076
  { prototypes::id::PushManagerImpl },
1077
  { PrototypeTraits<prototypes::id::PushManagerImpl>::Depth },
1078
  JSJitInfo::Method,
1079
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
1080
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
1081
  false,  /* isInfallible. False in setters. */
1082
  false,  /* isMovable.  Not relevant for setters. */
1083
  false, /* isEliminatable.  Not relevant for setters. */
1084
  false, /* isAlwaysInSlot.  Only relevant for getters. */
1085
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
1086
  false,  /* isTypedMethod.  Only relevant for methods. */
1087
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
1088
};
1089
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1090
static_assert(0 < 1, "There is no slot for us");
1091
1092
MOZ_CAN_RUN_SCRIPT static bool
1093
permissionState(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PushManagerImpl* self, const JSJitMethodCallArgs& args)
1094
0
{
1095
0
  AUTO_PROFILER_LABEL_FAST("PushManagerImpl.permissionState", DOM, cx);
1096
0
1097
0
  Maybe<JS::Rooted<JSObject*> > unwrappedObj;
1098
0
  bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1099
0
  if (objIsXray) {
1100
0
    unwrappedObj.emplace(cx, obj);
1101
0
  }
1102
0
  RootedDictionary<binding_detail::FastPushSubscriptionOptionsInit> arg0(cx);
1103
0
  if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue,  "Argument 1 of PushManagerImpl.permissionState", true)) {
1104
0
    return false;
1105
0
  }
1106
0
  if (objIsXray) {
1107
0
    unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
1108
0
    if (!unwrappedObj.ref()) {
1109
0
      return false;
1110
0
    }
1111
0
  }
1112
0
  FastErrorResult rv;
1113
0
  auto result(StrongOrRawPtr<Promise>(self->PermissionState(Constify(arg0), rv, (unwrappedObj ? js::GetNonCCWObjectRealm(*unwrappedObj) : js::GetContextRealm(cx)))));
1114
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1115
0
    return false;
1116
0
  }
1117
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1118
0
  if (!ToJSValue(cx, result, args.rval())) {
1119
0
    return false;
1120
0
  }
1121
0
  return true;
1122
0
}
1123
1124
MOZ_CAN_RUN_SCRIPT static bool
1125
permissionState_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PushManagerImpl* self, const JSJitMethodCallArgs& args)
1126
0
{
1127
0
  bool ok = permissionState(cx, obj, self, args);
1128
0
  if (ok) {
1129
0
    return true;
1130
0
  }
1131
0
  return ConvertExceptionToPromise(cx, args.rval());
1132
0
}
1133
1134
static const JSJitInfo permissionState_methodinfo = {
1135
  { (JSJitGetterOp)permissionState_promiseWrapper },
1136
  { prototypes::id::PushManagerImpl },
1137
  { PrototypeTraits<prototypes::id::PushManagerImpl>::Depth },
1138
  JSJitInfo::Method,
1139
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
1140
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
1141
  false,  /* isInfallible. False in setters. */
1142
  false,  /* isMovable.  Not relevant for setters. */
1143
  false, /* isEliminatable.  Not relevant for setters. */
1144
  false, /* isAlwaysInSlot.  Only relevant for getters. */
1145
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
1146
  false,  /* isTypedMethod.  Only relevant for methods. */
1147
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
1148
};
1149
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1150
static_assert(0 < 1, "There is no slot for us");
1151
1152
static bool
1153
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
1154
0
{
1155
0
  mozilla::dom::PushManagerImpl* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PushManagerImpl>(obj);
1156
0
  // We don't want to preserve if we don't have a wrapper, and we
1157
0
  // obviously can't preserve if we're not initialized.
1158
0
  if (self && self->GetWrapperPreserveColor()) {
1159
0
    PreserveWrapper(self);
1160
0
  }
1161
0
  return true;
1162
0
}
1163
1164
static void
1165
_finalize(js::FreeOp* fop, JSObject* obj)
1166
0
{
1167
0
  mozilla::dom::PushManagerImpl* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PushManagerImpl>(obj);
1168
0
  if (self) {
1169
0
    ClearWrapper(self, self, obj);
1170
0
    AddForDeferredFinalization<mozilla::dom::PushManagerImpl>(self);
1171
0
  }
1172
0
}
1173
1174
static size_t
1175
_objectMoved(JSObject* obj, JSObject* old)
1176
0
{
1177
0
  mozilla::dom::PushManagerImpl* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PushManagerImpl>(obj);
1178
0
  if (self) {
1179
0
    UpdateWrapper(self, self, obj, old);
1180
0
  }
1181
0
1182
0
  return 0;
1183
0
}
1184
1185
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
1186
#if defined(__clang__)
1187
#pragma clang diagnostic push
1188
#pragma clang diagnostic ignored "-Wmissing-braces"
1189
#endif
1190
static const JSFunctionSpec sChromeStaticMethods_specs[] = {
1191
  JS_FNSPEC("_create", PushManagerImpl::_Create, nullptr, 2, 0, nullptr),
1192
  JS_FS_END
1193
};
1194
#if defined(__clang__)
1195
#pragma clang diagnostic pop
1196
#endif
1197
1198
1199
static const Prefable<const JSFunctionSpec> sChromeStaticMethods[] = {
1200
  { nullptr, &sChromeStaticMethods_specs[0] },
1201
  { nullptr, nullptr }
1202
};
1203
1204
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1205
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1206
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1207
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1208
1209
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
1210
#if defined(__clang__)
1211
#pragma clang diagnostic push
1212
#pragma clang diagnostic ignored "-Wmissing-braces"
1213
#endif
1214
static const JSFunctionSpec sMethods_specs[] = {
1215
  JS_FNSPEC("subscribe", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&subscribe_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1216
  JS_FNSPEC("getSubscription", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&getSubscription_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1217
  JS_FNSPEC("permissionState", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&permissionState_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1218
  JS_FS_END
1219
};
1220
#if defined(__clang__)
1221
#pragma clang diagnostic pop
1222
#endif
1223
1224
1225
static const Prefable<const JSFunctionSpec> sMethods[] = {
1226
  { nullptr, &sMethods_specs[0] },
1227
  { nullptr, nullptr }
1228
};
1229
1230
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1231
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1232
static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1233
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1234
1235
1236
static uint16_t sNativeProperties_sortedPropertyIndices[3];
1237
static PropertyInfo sNativeProperties_propertyInfos[3];
1238
1239
static const NativePropertiesN<1> sNativeProperties = {
1240
  false, 0,
1241
  false, 0,
1242
  true,  0 /* sMethods */,
1243
  false, 0,
1244
  false, 0,
1245
  false, 0,
1246
  false, 0,
1247
  -1,
1248
  3,
1249
  sNativeProperties_sortedPropertyIndices,
1250
  {
1251
    { sMethods, &sNativeProperties_propertyInfos[0] }
1252
  }
1253
};
1254
static_assert(3 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
1255
    "We have a property info count that is oversized");
1256
1257
static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[1];
1258
static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[1];
1259
1260
static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
1261
  true,  0 /* sChromeStaticMethods */,
1262
  false, 0,
1263
  false, 0,
1264
  false, 0,
1265
  false, 0,
1266
  false, 0,
1267
  false, 0,
1268
  -1,
1269
  1,
1270
  sChromeOnlyNativeProperties_sortedPropertyIndices,
1271
  {
1272
    { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] }
1273
  }
1274
};
1275
static_assert(1 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
1276
    "We have a property info count that is oversized");
1277
1278
static bool
1279
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
1280
0
{
1281
0
  AUTO_PROFILER_LABEL_FAST("PushManagerImpl constructor", DOM, cx);
1282
0
1283
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
1284
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
1285
0
  if (!args.isConstructing()) {
1286
0
    // XXXbz wish I could get the name from the callee instead of
1287
0
    // Adding more relocations
1288
0
    return ThrowConstructorWithoutNew(cx, "PushManagerImpl");
1289
0
  }
1290
0
1291
0
  JS::Rooted<JSObject*> desiredProto(cx);
1292
0
  if (!GetDesiredProto(cx, args, &desiredProto)) {
1293
0
    return false;
1294
0
  }
1295
0
1296
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
1297
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "PushManagerImpl");
1298
0
  }
1299
0
  GlobalObject global(cx, obj);
1300
0
  if (global.Failed()) {
1301
0
    return false;
1302
0
  }
1303
0
1304
0
  bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1305
0
  binding_detail::FakeString arg0;
1306
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
1307
0
    return false;
1308
0
  }
1309
0
  Maybe<JSAutoRealm> ar;
1310
0
  if (objIsXray) {
1311
0
    obj = js::CheckedUnwrap(obj);
1312
0
    if (!obj) {
1313
0
      return false;
1314
0
    }
1315
0
    ar.emplace(cx, obj);
1316
0
    if (!JS_WrapObject(cx, &desiredProto)) {
1317
0
      return false;
1318
0
    }
1319
0
  }
1320
0
  FastErrorResult rv;
1321
0
  auto result(StrongOrRawPtr<mozilla::dom::PushManagerImpl>(mozilla::dom::PushManagerImpl::Constructor(global, cx, NonNullHelper(Constify(arg0)), rv, desiredProto)));
1322
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1323
0
    return false;
1324
0
  }
1325
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1326
0
  static_assert(!IsPointer<decltype(result)>::value,
1327
0
                "NewObject implies that we need to keep the object alive with a strong reference.");
1328
0
  if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
1329
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
1330
0
    return false;
1331
0
  }
1332
0
  return true;
1333
0
}
1334
1335
static const js::ClassOps sInterfaceObjectClassOps = {
1336
    nullptr,               /* addProperty */
1337
    nullptr,               /* delProperty */
1338
    nullptr,               /* enumerate */
1339
    nullptr,               /* newEnumerate */
1340
    nullptr,               /* resolve */
1341
    nullptr,               /* mayResolve */
1342
    nullptr,               /* finalize */
1343
    _constructor, /* call */
1344
    nullptr,               /* hasInstance */
1345
    _constructor, /* construct */
1346
    nullptr,               /* trace */
1347
};
1348
1349
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1350
  {
1351
    "Function",
1352
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1353
    &sInterfaceObjectClassOps,
1354
    JS_NULL_CLASS_SPEC,
1355
    JS_NULL_CLASS_EXT,
1356
    &sInterfaceObjectClassObjectOps
1357
  },
1358
  eInterface,
1359
  true,
1360
  prototypes::id::PushManagerImpl,
1361
  PrototypeTraits<prototypes::id::PushManagerImpl>::Depth,
1362
  sNativePropertyHooks,
1363
  "function PushManagerImpl() {\n    [native code]\n}",
1364
  JS::GetRealmFunctionPrototype
1365
};
1366
1367
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1368
  {
1369
    "PushManagerImplPrototype",
1370
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
1371
    JS_NULL_CLASS_OPS,
1372
    JS_NULL_CLASS_SPEC,
1373
    JS_NULL_CLASS_EXT,
1374
    JS_NULL_OBJECT_OPS
1375
  },
1376
  eInterfacePrototype,
1377
  false,
1378
  prototypes::id::PushManagerImpl,
1379
  PrototypeTraits<prototypes::id::PushManagerImpl>::Depth,
1380
  sNativePropertyHooks,
1381
  "[object PushManagerImplPrototype]",
1382
  JS::GetRealmObjectPrototype
1383
};
1384
1385
bool
1386
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
1387
0
{
1388
0
  return nsContentUtils::ThreadsafeIsSystemCaller(aCx);
1389
0
}
1390
1391
static const js::ClassOps sClassOps = {
1392
  _addProperty, /* addProperty */
1393
  nullptr,               /* delProperty */
1394
  nullptr,               /* enumerate */
1395
  nullptr, /* newEnumerate */
1396
  nullptr, /* resolve */
1397
  nullptr, /* mayResolve */
1398
  _finalize, /* finalize */
1399
  nullptr, /* call */
1400
  nullptr,               /* hasInstance */
1401
  nullptr,               /* construct */
1402
  nullptr, /* trace */
1403
};
1404
1405
static const js::ClassExtension sClassExtension = {
1406
  nullptr, /* weakmapKeyDelegateOp */
1407
  _objectMoved /* objectMovedOp */
1408
};
1409
1410
static const DOMJSClass sClass = {
1411
  { "PushManagerImpl",
1412
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
1413
    &sClassOps,
1414
    JS_NULL_CLASS_SPEC,
1415
    &sClassExtension,
1416
    JS_NULL_OBJECT_OPS
1417
  },
1418
  { prototypes::id::PushManagerImpl, 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 },
1419
  IsBaseOf<nsISupports, mozilla::dom::PushManagerImpl >::value,
1420
  sNativePropertyHooks,
1421
  FindAssociatedGlobalForNative<mozilla::dom::PushManagerImpl>::Get,
1422
  GetProtoObjectHandle,
1423
  GetCCParticipant<mozilla::dom::PushManagerImpl>::Get()
1424
};
1425
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1426
              "Must have the right minimal number of reserved slots.");
1427
static_assert(1 >= 1,
1428
              "Must have enough reserved slots.");
1429
1430
const JSClass*
1431
GetJSClass()
1432
0
{
1433
0
  return sClass.ToJSClass();
1434
0
}
1435
1436
bool
1437
Wrap(JSContext* aCx, mozilla::dom::PushManagerImpl* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1438
0
{
1439
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::PushManagerImpl>::value,
1440
0
                "Shouldn't have wrappercached things that are not refcounted.");
1441
0
  MOZ_ASSERT(static_cast<mozilla::dom::PushManagerImpl*>(aObject) ==
1442
0
             reinterpret_cast<mozilla::dom::PushManagerImpl*>(aObject),
1443
0
             "Multiple inheritance for mozilla::dom::PushManagerImpl is broken.");
1444
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1445
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1446
0
  MOZ_ASSERT(!aCache->GetWrapper(),
1447
0
             "You should probably not be using Wrap() directly; use "
1448
0
             "GetOrCreateDOMReflector instead");
1449
0
1450
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1451
0
             "nsISupports must be on our primary inheritance chain");
1452
0
1453
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1454
0
  if (!global) {
1455
0
    return false;
1456
0
  }
1457
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
1458
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
1459
0
1460
0
  // That might have ended up wrapping us already, due to the wonders
1461
0
  // of XBL.  Check for that, and bail out as needed.
1462
0
  aReflector.set(aCache->GetWrapper());
1463
0
  if (aReflector) {
1464
#ifdef DEBUG
1465
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1466
#endif // DEBUG
1467
    return true;
1468
0
  }
1469
0
1470
0
  JSAutoRealm ar(aCx, global);
1471
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1472
0
  if (!canonicalProto) {
1473
0
    return false;
1474
0
  }
1475
0
  JS::Rooted<JSObject*> proto(aCx);
1476
0
  if (aGivenProto) {
1477
0
    proto = aGivenProto;
1478
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
1479
0
    // coming in, we changed compartments to that of "parent" so may need
1480
0
    // to wrap the proto here.
1481
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1482
0
      if (!JS_WrapObject(aCx, &proto)) {
1483
0
        return false;
1484
0
      }
1485
0
    }
1486
0
  } else {
1487
0
    proto = canonicalProto;
1488
0
  }
1489
0
1490
0
  BindingJSObjectCreator<mozilla::dom::PushManagerImpl> creator(aCx);
1491
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1492
0
  if (!aReflector) {
1493
0
    return false;
1494
0
  }
1495
0
1496
0
  aCache->SetWrapper(aReflector);
1497
0
  creator.InitializationSucceeded();
1498
0
1499
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1500
0
             aCache->GetWrapperPreserveColor() == aReflector);
1501
0
  // If proto != canonicalProto, we have to preserve our wrapper;
1502
0
  // otherwise we won't be able to properly recreate it later, since
1503
0
  // we won't know what proto to use.  Note that we don't check
1504
0
  // aGivenProto here, since it's entirely possible (and even
1505
0
  // somewhat common) to have a non-null aGivenProto which is the
1506
0
  // same as canonicalProto.
1507
0
  if (proto != canonicalProto) {
1508
0
    PreserveWrapper(aObject);
1509
0
  }
1510
0
1511
0
  return true;
1512
0
}
1513
1514
const NativePropertyHooks sNativePropertyHooks[] = { {
1515
  nullptr,
1516
  nullptr,
1517
  nullptr,
1518
  { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
1519
  prototypes::id::PushManagerImpl,
1520
  constructors::id::PushManagerImpl,
1521
  nullptr,
1522
  &DefaultXrayExpandoObjectClass
1523
} };
1524
1525
void
1526
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1527
0
{
1528
0
  JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
1529
0
  if (!parentProto) {
1530
0
    return;
1531
0
  }
1532
0
1533
0
  JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
1534
0
  if (!constructorProto) {
1535
0
    return;
1536
0
  }
1537
0
1538
0
  static bool sIdsInited = false;
1539
0
  if (!sIdsInited && NS_IsMainThread()) {
1540
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
1541
0
      return;
1542
0
    }
1543
0
    if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
1544
0
      return;
1545
0
    }
1546
0
    sIdsInited = true;
1547
0
  }
1548
0
1549
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::PushManagerImpl);
1550
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::PushManagerImpl);
1551
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1552
0
                              &sPrototypeClass.mBase, protoCache,
1553
0
                              nullptr,
1554
0
                              constructorProto, &sInterfaceObjectClass.mBase, 1, nullptr,
1555
0
                              interfaceCache,
1556
0
                              sNativeProperties.Upcast(),
1557
0
                              sChromeOnlyNativeProperties.Upcast(),
1558
0
                              "PushManagerImpl", aDefineOnGlobal,
1559
0
                              nullptr,
1560
0
                              false);
1561
0
}
1562
1563
JSObject*
1564
GetConstructorObject(JSContext* aCx)
1565
0
{
1566
0
  return GetConstructorObjectHandle(aCx);
1567
0
}
1568
1569
} // namespace PushManagerImpl_Binding
1570
1571
1572
1573
already_AddRefed<Promise>
1574
PushManagerImplJSImpl::Subscribe(const PushSubscriptionOptionsInit& options, ErrorResult& aRv, JS::Realm* aRealm)
1575
0
{
1576
0
  CallSetup s(this, aRv, "PushManagerImpl.subscribe", eRethrowContentExceptions, aRealm, /* aIsJSImplementedWebIDL = */ true);
1577
0
  JSContext* cx = s.GetContext();
1578
0
  if (!cx) {
1579
0
    MOZ_ASSERT(aRv.Failed());
1580
0
    return nullptr;
1581
0
  }
1582
0
  JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
1583
0
  JS::AutoValueVector argv(cx);
1584
0
  if (!argv.resize(1)) {
1585
0
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
1586
0
    return nullptr;
1587
0
  }
1588
0
  unsigned argc = 1;
1589
0
1590
0
  do {
1591
0
    if (!options.ToObjectInternal(cx, argv[0])) {
1592
0
      aRv.Throw(NS_ERROR_UNEXPECTED);
1593
0
      return nullptr;
1594
0
    }
1595
0
    break;
1596
0
  } while (false);
1597
0
1598
0
  JS::Rooted<JS::Value> callable(cx);
1599
0
  PushManagerImplAtoms* atomsCache = GetAtomCache<PushManagerImplAtoms>(cx);
1600
0
  if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
1601
0
      !GetCallableProperty(cx, atomsCache->subscribe_id, &callable)) {
1602
0
    aRv.Throw(NS_ERROR_UNEXPECTED);
1603
0
    return nullptr;
1604
0
  }
1605
0
  JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
1606
0
  if (!JS::Call(cx, thisValue, callable,
1607
0
                JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
1608
0
    aRv.NoteJSContextException(cx);
1609
0
    return nullptr;
1610
0
  }
1611
0
  RefPtr<Promise> rvalDecl;
1612
0
  { // Scope for our GlobalObject, FastErrorResult, JSAutoRealm,
1613
0
    // etc.
1614
0
1615
0
    JS::Rooted<JSObject*> globalObj(cx);
1616
0
    if (!rval.isObject()) {
1617
0
      aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of PushManagerImpl.subscribe"));
1618
0
      return nullptr;
1619
0
    }
1620
0
    JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
1621
0
    if (!unwrappedVal) {
1622
0
      // A slight lie, but not much of one, for a dead object wrapper.
1623
0
      aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of PushManagerImpl.subscribe"));
1624
0
      return nullptr;
1625
0
    }
1626
0
    globalObj = JS::GetNonCCWObjectGlobal(unwrappedVal);
1627
0
    JSAutoRealm ar(cx, globalObj);
1628
0
    GlobalObject promiseGlobal(cx, globalObj);
1629
0
    if (promiseGlobal.Failed()) {
1630
0
      aRv.Throw(NS_ERROR_UNEXPECTED);
1631
0
      return nullptr;
1632
0
    }
1633
0
1634
0
    JS::Rooted<JS::Value> valueToResolve(cx, rval);
1635
0
    if (!JS_WrapValue(cx, &valueToResolve)) {
1636
0
      aRv.Throw(NS_ERROR_UNEXPECTED);
1637
0
      return nullptr;
1638
0
    }
1639
0
    binding_detail::FastErrorResult promiseRv;
1640
0
    nsCOMPtr<nsIGlobalObject> global =
1641
0
      do_QueryInterface(promiseGlobal.GetAsSupports());
1642
0
    if (!global) {
1643
0
      promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
1644
0
      MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
1645
0
      aRv.Throw(NS_ERROR_UNEXPECTED);
1646
0
      return nullptr;
1647
0
    }
1648
0
    rvalDecl = Promise::Resolve(global, cx, valueToResolve,
1649
0
                                    promiseRv);
1650
0
    if (promiseRv.MaybeSetPendingException(cx)) {
1651
0
      aRv.Throw(NS_ERROR_UNEXPECTED);
1652
0
      return nullptr;
1653
0
    }
1654
0
  }
1655
0
  return rvalDecl.forget();
1656
0
}
1657
1658
already_AddRefed<Promise>
1659
PushManagerImplJSImpl::GetSubscription(ErrorResult& aRv, JS::Realm* aRealm)
1660
0
{
1661
0
  CallSetup s(this, aRv, "PushManagerImpl.getSubscription", eRethrowContentExceptions, aRealm, /* aIsJSImplementedWebIDL = */ true);
1662
0
  JSContext* cx = s.GetContext();
1663
0
  if (!cx) {
1664
0
    MOZ_ASSERT(aRv.Failed());
1665
0
    return nullptr;
1666
0
  }
1667
0
  JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
1668
0
1669
0
  JS::Rooted<JS::Value> callable(cx);
1670
0
  PushManagerImplAtoms* atomsCache = GetAtomCache<PushManagerImplAtoms>(cx);
1671
0
  if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
1672
0
      !GetCallableProperty(cx, atomsCache->getSubscription_id, &callable)) {
1673
0
    aRv.Throw(NS_ERROR_UNEXPECTED);
1674
0
    return nullptr;
1675
0
  }
1676
0
  JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
1677
0
  if (!JS::Call(cx, thisValue, callable,
1678
0
                JS::HandleValueArray::empty(), &rval)) {
1679
0
    aRv.NoteJSContextException(cx);
1680
0
    return nullptr;
1681
0
  }
1682
0
  RefPtr<Promise> rvalDecl;
1683
0
  { // Scope for our GlobalObject, FastErrorResult, JSAutoRealm,
1684
0
    // etc.
1685
0
1686
0
    JS::Rooted<JSObject*> globalObj(cx);
1687
0
    if (!rval.isObject()) {
1688
0
      aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of PushManagerImpl.getSubscription"));
1689
0
      return nullptr;
1690
0
    }
1691
0
    JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
1692
0
    if (!unwrappedVal) {
1693
0
      // A slight lie, but not much of one, for a dead object wrapper.
1694
0
      aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of PushManagerImpl.getSubscription"));
1695
0
      return nullptr;
1696
0
    }
1697
0
    globalObj = JS::GetNonCCWObjectGlobal(unwrappedVal);
1698
0
    JSAutoRealm ar(cx, globalObj);
1699
0
    GlobalObject promiseGlobal(cx, globalObj);
1700
0
    if (promiseGlobal.Failed()) {
1701
0
      aRv.Throw(NS_ERROR_UNEXPECTED);
1702
0
      return nullptr;
1703
0
    }
1704
0
1705
0
    JS::Rooted<JS::Value> valueToResolve(cx, rval);
1706
0
    if (!JS_WrapValue(cx, &valueToResolve)) {
1707
0
      aRv.Throw(NS_ERROR_UNEXPECTED);
1708
0
      return nullptr;
1709
0
    }
1710
0
    binding_detail::FastErrorResult promiseRv;
1711
0
    nsCOMPtr<nsIGlobalObject> global =
1712
0
      do_QueryInterface(promiseGlobal.GetAsSupports());
1713
0
    if (!global) {
1714
0
      promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
1715
0
      MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
1716
0
      aRv.Throw(NS_ERROR_UNEXPECTED);
1717
0
      return nullptr;
1718
0
    }
1719
0
    rvalDecl = Promise::Resolve(global, cx, valueToResolve,
1720
0
                                    promiseRv);
1721
0
    if (promiseRv.MaybeSetPendingException(cx)) {
1722
0
      aRv.Throw(NS_ERROR_UNEXPECTED);
1723
0
      return nullptr;
1724
0
    }
1725
0
  }
1726
0
  return rvalDecl.forget();
1727
0
}
1728
1729
already_AddRefed<Promise>
1730
PushManagerImplJSImpl::PermissionState(const PushSubscriptionOptionsInit& options, ErrorResult& aRv, JS::Realm* aRealm)
1731
0
{
1732
0
  CallSetup s(this, aRv, "PushManagerImpl.permissionState", eRethrowContentExceptions, aRealm, /* aIsJSImplementedWebIDL = */ true);
1733
0
  JSContext* cx = s.GetContext();
1734
0
  if (!cx) {
1735
0
    MOZ_ASSERT(aRv.Failed());
1736
0
    return nullptr;
1737
0
  }
1738
0
  JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
1739
0
  JS::AutoValueVector argv(cx);
1740
0
  if (!argv.resize(1)) {
1741
0
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
1742
0
    return nullptr;
1743
0
  }
1744
0
  unsigned argc = 1;
1745
0
1746
0
  do {
1747
0
    if (!options.ToObjectInternal(cx, argv[0])) {
1748
0
      aRv.Throw(NS_ERROR_UNEXPECTED);
1749
0
      return nullptr;
1750
0
    }
1751
0
    break;
1752
0
  } while (false);
1753
0
1754
0
  JS::Rooted<JS::Value> callable(cx);
1755
0
  PushManagerImplAtoms* atomsCache = GetAtomCache<PushManagerImplAtoms>(cx);
1756
0
  if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
1757
0
      !GetCallableProperty(cx, atomsCache->permissionState_id, &callable)) {
1758
0
    aRv.Throw(NS_ERROR_UNEXPECTED);
1759
0
    return nullptr;
1760
0
  }
1761
0
  JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
1762
0
  if (!JS::Call(cx, thisValue, callable,
1763
0
                JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
1764
0
    aRv.NoteJSContextException(cx);
1765
0
    return nullptr;
1766
0
  }
1767
0
  RefPtr<Promise> rvalDecl;
1768
0
  { // Scope for our GlobalObject, FastErrorResult, JSAutoRealm,
1769
0
    // etc.
1770
0
1771
0
    JS::Rooted<JSObject*> globalObj(cx);
1772
0
    if (!rval.isObject()) {
1773
0
      aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of PushManagerImpl.permissionState"));
1774
0
      return nullptr;
1775
0
    }
1776
0
    JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
1777
0
    if (!unwrappedVal) {
1778
0
      // A slight lie, but not much of one, for a dead object wrapper.
1779
0
      aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of PushManagerImpl.permissionState"));
1780
0
      return nullptr;
1781
0
    }
1782
0
    globalObj = JS::GetNonCCWObjectGlobal(unwrappedVal);
1783
0
    JSAutoRealm ar(cx, globalObj);
1784
0
    GlobalObject promiseGlobal(cx, globalObj);
1785
0
    if (promiseGlobal.Failed()) {
1786
0
      aRv.Throw(NS_ERROR_UNEXPECTED);
1787
0
      return nullptr;
1788
0
    }
1789
0
1790
0
    JS::Rooted<JS::Value> valueToResolve(cx, rval);
1791
0
    if (!JS_WrapValue(cx, &valueToResolve)) {
1792
0
      aRv.Throw(NS_ERROR_UNEXPECTED);
1793
0
      return nullptr;
1794
0
    }
1795
0
    binding_detail::FastErrorResult promiseRv;
1796
0
    nsCOMPtr<nsIGlobalObject> global =
1797
0
      do_QueryInterface(promiseGlobal.GetAsSupports());
1798
0
    if (!global) {
1799
0
      promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
1800
0
      MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
1801
0
      aRv.Throw(NS_ERROR_UNEXPECTED);
1802
0
      return nullptr;
1803
0
    }
1804
0
    rvalDecl = Promise::Resolve(global, cx, valueToResolve,
1805
0
                                    promiseRv);
1806
0
    if (promiseRv.MaybeSetPendingException(cx)) {
1807
0
      aRv.Throw(NS_ERROR_UNEXPECTED);
1808
0
      return nullptr;
1809
0
    }
1810
0
  }
1811
0
  return rvalDecl.forget();
1812
0
}
1813
1814
void
1815
PushManagerImplJSImpl::__Init(const nsAString& scope, ErrorResult& aRv, JS::Realm* aRealm)
1816
0
{
1817
0
  CallSetup s(this, aRv, "__init", eRethrowContentExceptions, aRealm, /* aIsJSImplementedWebIDL = */ true);
1818
0
  JSContext* cx = s.GetContext();
1819
0
  if (!cx) {
1820
0
    MOZ_ASSERT(aRv.Failed());
1821
0
    return;
1822
0
  }
1823
0
  JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
1824
0
  JS::AutoValueVector argv(cx);
1825
0
  if (!argv.resize(1)) {
1826
0
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
1827
0
    return;
1828
0
  }
1829
0
  unsigned argc = 1;
1830
0
1831
0
  do {
1832
0
    nsString mutableStr(scope);
1833
0
    if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
1834
0
      aRv.Throw(NS_ERROR_UNEXPECTED);
1835
0
      return;
1836
0
    }
1837
0
    break;
1838
0
  } while (false);
1839
0
1840
0
  JS::Rooted<JS::Value> callable(cx);
1841
0
  PushManagerImplAtoms* atomsCache = GetAtomCache<PushManagerImplAtoms>(cx);
1842
0
  if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
1843
0
      !GetCallableProperty(cx, atomsCache->__init_id, &callable)) {
1844
0
    aRv.Throw(NS_ERROR_UNEXPECTED);
1845
0
    return;
1846
0
  }
1847
0
  JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
1848
0
  if (!JS::Call(cx, thisValue, callable,
1849
0
                JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
1850
0
    aRv.NoteJSContextException(cx);
1851
0
    return;
1852
0
  }
1853
0
}
1854
1855
bool
1856
PushManagerImplJSImpl::InitIds(JSContext* cx, PushManagerImplAtoms* atomsCache)
1857
0
{
1858
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1859
0
1860
0
  // Initialize these in reverse order so that any failure leaves the first one
1861
0
  // uninitialized.
1862
0
  if (!atomsCache->__init_id.init(cx, "__init") ||
1863
0
      !atomsCache->permissionState_id.init(cx, "permissionState") ||
1864
0
      !atomsCache->getSubscription_id.init(cx, "getSubscription") ||
1865
0
      !atomsCache->subscribe_id.init(cx, "subscribe")) {
1866
0
    return false;
1867
0
  }
1868
0
  return true;
1869
0
}
1870
1871
1872
1873
NS_IMPL_CYCLE_COLLECTION_CLASS(PushManagerImpl)
1874
0
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(PushManagerImpl)
1875
0
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mImpl)
1876
0
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
1877
0
  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
1878
0
  tmp->ClearWeakReferences();
1879
0
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
1880
0
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(PushManagerImpl)
1881
0
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImpl)
1882
0
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
1883
0
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
1884
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(PushManagerImpl)
1885
NS_IMPL_CYCLE_COLLECTING_ADDREF(PushManagerImpl)
1886
NS_IMPL_CYCLE_COLLECTING_RELEASE(PushManagerImpl)
1887
0
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PushManagerImpl)
1888
0
  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
1889
0
  NS_INTERFACE_MAP_ENTRY(nsISupports)
1890
0
  NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
1891
0
NS_INTERFACE_MAP_END
1892
1893
PushManagerImpl::PushManagerImpl(JS::Handle<JSObject*> aJSImplObject, JS::Handle<JSObject*> aJSImplGlobal, nsIGlobalObject* aParent)
1894
  : mImpl(new PushManagerImplJSImpl(nullptr, aJSImplObject, aJSImplGlobal, /* aIncumbentGlobal = */ nullptr)),
1895
    mParent(aParent)
1896
0
{
1897
0
}
1898
1899
1900
PushManagerImpl::~PushManagerImpl()
1901
0
{
1902
0
}
1903
1904
nsISupports*
1905
PushManagerImpl::GetParentObject() const
1906
0
{
1907
0
  return mParent;
1908
0
}
1909
1910
JSObject*
1911
PushManagerImpl::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
1912
0
{
1913
0
  JS::Rooted<JSObject*> obj(aCx, PushManagerImpl_Binding::Wrap(aCx, this, aGivenProto));
1914
0
  if (!obj) {
1915
0
    return nullptr;
1916
0
  }
1917
0
1918
0
  // Now define it on our chrome object
1919
0
  JSAutoRealm ar(aCx, mImpl->CallbackGlobalOrNull());
1920
0
  if (!JS_WrapObject(aCx, &obj)) {
1921
0
    return nullptr;
1922
0
  }
1923
0
  if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
1924
0
    return nullptr;
1925
0
  }
1926
0
  return obj;
1927
0
}
1928
1929
already_AddRefed<PushManagerImpl>
1930
PushManagerImpl::Constructor(const GlobalObject& global, JSContext* cx, const nsAString& scope, ErrorResult& aRv, JS::Handle<JSObject*> aGivenProto)
1931
0
{
1932
0
  JS::Rooted<JSObject*> jsImplObj(cx);
1933
0
  nsCOMPtr<nsIGlobalObject> globalHolder =
1934
0
    ConstructJSImplementation("@mozilla.org/push/PushManager;1", global, &jsImplObj, aRv);
1935
0
  if (aRv.Failed()) {
1936
0
    return nullptr;
1937
0
  }
1938
0
  // We should be getting the implementation object for the relevant
1939
0
  // contract here, which should never be a cross-compartment wrapper.
1940
0
  JS::Rooted<JSObject*> jsImplGlobal(cx, JS::GetNonCCWObjectGlobal(jsImplObj));
1941
0
  // Build the C++ implementation.
1942
0
  RefPtr<PushManagerImpl> impl = new PushManagerImpl(jsImplObj, jsImplGlobal, globalHolder);
1943
0
  // Wrap the object before calling __Init so that __DOM_IMPL__ is available.
1944
0
  JS::Rooted<JSObject*> scopeObj(cx, globalHolder->GetGlobalJSObject());
1945
0
  MOZ_ASSERT(js::IsObjectInContextCompartment(scopeObj, cx));
1946
0
  JS::Rooted<JS::Value> wrappedVal(cx);
1947
0
  if (!GetOrCreateDOMReflector(cx, impl, &wrappedVal, aGivenProto)) {
1948
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
1949
0
    aRv.Throw(NS_ERROR_UNEXPECTED);
1950
0
    return nullptr;
1951
0
  }
1952
0
  // Initialize the object with the constructor arguments.
1953
0
  impl->mImpl->__Init(scope, aRv, js::GetNonCCWObjectRealm(scopeObj));
1954
0
  if (aRv.Failed()) {
1955
0
    return nullptr;
1956
0
  }
1957
0
  return impl.forget();
1958
0
}
1959
1960
// Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
1961
already_AddRefed<Promise>
1962
PushManagerImpl::Subscribe(const PushSubscriptionOptionsInit& options, ErrorResult& aRv, JS::Realm* aRealm)
1963
0
{
1964
0
  return mImpl->Subscribe(options, aRv, aRealm);
1965
0
}
1966
1967
// Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
1968
already_AddRefed<Promise>
1969
PushManagerImpl::GetSubscription(ErrorResult& aRv, JS::Realm* aRealm)
1970
0
{
1971
0
  return mImpl->GetSubscription(aRv, aRealm);
1972
0
}
1973
1974
// Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
1975
already_AddRefed<Promise>
1976
PushManagerImpl::PermissionState(const PushSubscriptionOptionsInit& options, ErrorResult& aRv, JS::Realm* aRealm)
1977
0
{
1978
0
  return mImpl->PermissionState(options, aRv, aRealm);
1979
0
}
1980
1981
bool
1982
PushManagerImpl::_Create(JSContext* cx, unsigned argc, JS::Value* vp)
1983
0
{
1984
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
1985
0
  if (args.length() < 2) {
1986
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "PushManagerImpl._create");
1987
0
  }
1988
0
  if (!args[0].isObject()) {
1989
0
    return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of PushManagerImpl._create");
1990
0
  }
1991
0
  if (!args[1].isObject()) {
1992
0
    return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of PushManagerImpl._create");
1993
0
  }
1994
0
1995
0
  // GlobalObject will go through wrappers as needed for us, and
1996
0
  // is simpler than the right UnwrapArg incantation.
1997
0
  GlobalObject global(cx, &args[0].toObject());
1998
0
  if (global.Failed()) {
1999
0
    return false;
2000
0
  }
2001
0
  nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports());
2002
0
  MOZ_ASSERT(globalHolder);
2003
0
  JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
2004
0
  JS::Rooted<JSObject*> argGlobal(cx, JS::CurrentGlobalOrNull(cx));
2005
0
  RefPtr<PushManagerImpl> impl = new PushManagerImpl(arg, argGlobal, globalHolder);
2006
0
  MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
2007
0
  return GetOrCreateDOMReflector(cx, impl, args.rval());
2008
0
}
2009
2010
2011
} // namespace dom
2012
} // namespace mozilla