Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/PushEventBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM PushEvent.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "AtomList.h"
4
#include "ExtendableEventBinding.h"
5
#include "PushEventBinding.h"
6
#include "ServiceWorkerEvents.h"
7
#include "WrapperFactory.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/ScriptSettings.h"
15
#include "mozilla/dom/UnionConversions.h"
16
#include "nsThreadUtils.h"
17
18
namespace mozilla {
19
namespace dom {
20
21
namespace binding_detail {}; // Just to make sure it's known as a namespace
22
using namespace mozilla::dom::binding_detail;
23
24
25
bool
26
ArrayBufferViewOrArrayBufferOrUSVString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
27
0
{
28
0
  switch (mType) {
29
0
    case eUninitialized: {
30
0
      return false;
31
0
      break;
32
0
    }
33
0
    case eArrayBufferView: {
34
0
      rval.setObject(*mValue.mArrayBufferView.Value().Obj());
35
0
      if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
36
0
        return false;
37
0
      }
38
0
      return true;
39
0
      break;
40
0
    }
41
0
    case eArrayBuffer: {
42
0
      rval.setObject(*mValue.mArrayBuffer.Value().Obj());
43
0
      if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
44
0
        return false;
45
0
      }
46
0
      return true;
47
0
      break;
48
0
    }
49
0
    case eUSVString: {
50
0
      if (!xpc::NonVoidStringToJsval(cx, mValue.mUSVString.Value(), rval)) {
51
0
        return false;
52
0
      }
53
0
      return true;
54
0
      break;
55
0
    }
56
0
    default: {
57
0
      return false;
58
0
      break;
59
0
    }
60
0
  }
61
0
62
0
  return false;
63
0
}
64
65
66
ArrayBufferView&
67
OwningArrayBufferViewOrArrayBufferOrUSVString::RawSetAsArrayBufferView()
68
0
{
69
0
  if (mType == eArrayBufferView) {
70
0
    return mValue.mArrayBufferView.Value();
71
0
  }
72
0
  MOZ_ASSERT(mType == eUninitialized);
73
0
  mType = eArrayBufferView;
74
0
  return mValue.mArrayBufferView.SetValue();
75
0
}
76
77
ArrayBufferView&
78
OwningArrayBufferViewOrArrayBufferOrUSVString::SetAsArrayBufferView()
79
0
{
80
0
  if (mType == eArrayBufferView) {
81
0
    return mValue.mArrayBufferView.Value();
82
0
  }
83
0
  Uninit();
84
0
  mType = eArrayBufferView;
85
0
  return mValue.mArrayBufferView.SetValue();
86
0
}
87
88
bool
89
OwningArrayBufferViewOrArrayBufferOrUSVString::TrySetToArrayBufferView(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
90
0
{
91
0
  tryNext = false;
92
0
  { // scope for memberSlot
93
0
    ArrayBufferView& memberSlot = RawSetAsArrayBufferView();
94
0
    if (!memberSlot.Init(&value.toObject())) {
95
0
      DestroyArrayBufferView();
96
0
      tryNext = true;
97
0
      return true;
98
0
    }
99
0
  }
100
0
  return true;
101
0
}
102
103
void
104
OwningArrayBufferViewOrArrayBufferOrUSVString::DestroyArrayBufferView()
105
0
{
106
0
  MOZ_ASSERT(IsArrayBufferView(), "Wrong type!");
107
0
  mValue.mArrayBufferView.Destroy();
108
0
  mType = eUninitialized;
109
0
}
110
111
112
113
114
ArrayBuffer&
115
OwningArrayBufferViewOrArrayBufferOrUSVString::RawSetAsArrayBuffer()
116
0
{
117
0
  if (mType == eArrayBuffer) {
118
0
    return mValue.mArrayBuffer.Value();
119
0
  }
120
0
  MOZ_ASSERT(mType == eUninitialized);
121
0
  mType = eArrayBuffer;
122
0
  return mValue.mArrayBuffer.SetValue();
123
0
}
124
125
ArrayBuffer&
126
OwningArrayBufferViewOrArrayBufferOrUSVString::SetAsArrayBuffer()
127
0
{
128
0
  if (mType == eArrayBuffer) {
129
0
    return mValue.mArrayBuffer.Value();
130
0
  }
131
0
  Uninit();
132
0
  mType = eArrayBuffer;
133
0
  return mValue.mArrayBuffer.SetValue();
134
0
}
135
136
bool
137
OwningArrayBufferViewOrArrayBufferOrUSVString::TrySetToArrayBuffer(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
138
0
{
139
0
  tryNext = false;
140
0
  { // scope for memberSlot
141
0
    ArrayBuffer& memberSlot = RawSetAsArrayBuffer();
142
0
    if (!memberSlot.Init(&value.toObject())) {
143
0
      DestroyArrayBuffer();
144
0
      tryNext = true;
145
0
      return true;
146
0
    }
147
0
  }
148
0
  return true;
149
0
}
150
151
void
152
OwningArrayBufferViewOrArrayBufferOrUSVString::DestroyArrayBuffer()
153
0
{
154
0
  MOZ_ASSERT(IsArrayBuffer(), "Wrong type!");
155
0
  mValue.mArrayBuffer.Destroy();
156
0
  mType = eUninitialized;
157
0
}
158
159
160
161
162
nsString&
163
OwningArrayBufferViewOrArrayBufferOrUSVString::RawSetAsUSVString()
164
0
{
165
0
  if (mType == eUSVString) {
166
0
    return mValue.mUSVString.Value();
167
0
  }
168
0
  MOZ_ASSERT(mType == eUninitialized);
169
0
  mType = eUSVString;
170
0
  return mValue.mUSVString.SetValue();
171
0
}
172
173
nsString&
174
OwningArrayBufferViewOrArrayBufferOrUSVString::SetAsUSVString()
175
0
{
176
0
  if (mType == eUSVString) {
177
0
    return mValue.mUSVString.Value();
178
0
  }
179
0
  Uninit();
180
0
  mType = eUSVString;
181
0
  return mValue.mUSVString.SetValue();
182
0
}
183
184
bool
185
OwningArrayBufferViewOrArrayBufferOrUSVString::TrySetToUSVString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
186
0
{
187
0
  tryNext = false;
188
0
  { // scope for memberSlot
189
0
    nsString& memberSlot = RawSetAsUSVString();
190
0
    if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
191
0
      return false;
192
0
    }
193
0
    NormalizeUSVString(memberSlot);
194
0
  }
195
0
  return true;
196
0
}
197
198
199
void
200
OwningArrayBufferViewOrArrayBufferOrUSVString::DestroyUSVString()
201
0
{
202
0
  MOZ_ASSERT(IsUSVString(), "Wrong type!");
203
0
  mValue.mUSVString.Destroy();
204
0
  mType = eUninitialized;
205
0
}
206
207
208
209
210
void
211
OwningArrayBufferViewOrArrayBufferOrUSVString::Uninit()
212
{
213
  switch (mType) {
214
    case eUninitialized: {
215
      break;
216
    }
217
    case eArrayBufferView: {
218
      DestroyArrayBufferView();
219
      break;
220
    }
221
    case eArrayBuffer: {
222
      DestroyArrayBuffer();
223
      break;
224
    }
225
    case eUSVString: {
226
      DestroyUSVString();
227
      break;
228
    }
229
  }
230
}
231
232
bool
233
OwningArrayBufferViewOrArrayBufferOrUSVString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
234
0
{
235
0
  switch (mType) {
236
0
    case eUninitialized: {
237
0
      return false;
238
0
      break;
239
0
    }
240
0
    case eArrayBufferView: {
241
0
      rval.setObject(*mValue.mArrayBufferView.Value().Obj());
242
0
      if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
243
0
        return false;
244
0
      }
245
0
      return true;
246
0
      break;
247
0
    }
248
0
    case eArrayBuffer: {
249
0
      rval.setObject(*mValue.mArrayBuffer.Value().Obj());
250
0
      if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
251
0
        return false;
252
0
      }
253
0
      return true;
254
0
      break;
255
0
    }
256
0
    case eUSVString: {
257
0
      if (!xpc::NonVoidStringToJsval(cx, mValue.mUSVString.Value(), rval)) {
258
0
        return false;
259
0
      }
260
0
      return true;
261
0
      break;
262
0
    }
263
0
    default: {
264
0
      return false;
265
0
      break;
266
0
    }
267
0
  }
268
0
269
0
  return false;
270
0
}
271
272
void
273
OwningArrayBufferViewOrArrayBufferOrUSVString::TraceUnion(JSTracer* trc)
274
{
275
  switch (mType) {
276
    case eArrayBufferView: {
277
      mValue.mArrayBufferView.Value().TraceSelf(trc);
278
      break;
279
    }
280
    case eArrayBuffer: {
281
      mValue.mArrayBuffer.Value().TraceSelf(trc);
282
      break;
283
    }
284
    default: {
285
      break;
286
    }
287
  }
288
}
289
290
291
292
PushEventInit::PushEventInit()
293
  : ExtendableEventInit(FastDictionaryInitializer())
294
0
{
295
0
  // Safe to pass a null context if we pass a null value
296
0
  Init(nullptr, JS::NullHandleValue);
297
0
}
298
299
300
bool
301
PushEventInit::InitIds(JSContext* cx, PushEventInitAtoms* atomsCache)
302
0
{
303
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
304
0
305
0
  // Initialize these in reverse order so that any failure leaves the first one
306
0
  // uninitialized.
307
0
  if (!atomsCache->data_id.init(cx, "data")) {
308
0
    return false;
309
0
  }
310
0
  return true;
311
0
}
312
313
bool
314
PushEventInit::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
315
0
{
316
0
  // Passing a null JSContext is OK only if we're initing from null,
317
0
  // Since in that case we will not have to do any property gets
318
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
319
0
  // checkers by static analysis tools
320
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
321
0
  PushEventInitAtoms* atomsCache = nullptr;
322
0
  if (cx) {
323
0
    atomsCache = GetAtomCache<PushEventInitAtoms>(cx);
324
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
325
0
      return false;
326
0
    }
327
0
  }
328
0
329
0
  // Per spec, we init the parent's members first
330
0
  if (!ExtendableEventInit::Init(cx, val)) {
331
0
    return false;
332
0
  }
333
0
334
0
  bool isNull = val.isNullOrUndefined();
335
0
  // We only need these if !isNull, in which case we have |cx|.
336
0
  Maybe<JS::Rooted<JSObject *> > object;
337
0
  Maybe<JS::Rooted<JS::Value> > temp;
338
0
  if (!isNull) {
339
0
    MOZ_ASSERT(cx);
340
0
    object.emplace(cx, &val.toObject());
341
0
    temp.emplace(cx);
342
0
  }
343
0
  if (!isNull) {
344
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->data_id, temp.ptr())) {
345
0
      return false;
346
0
    }
347
0
  }
348
0
  if (!isNull && !temp->isUndefined()) {
349
0
    mData.Construct();
350
0
    {
351
0
      bool done = false, failed = false, tryNext;
352
0
      if (temp.ref().isObject()) {
353
0
        done = (failed = !(mData.Value()).TrySetToArrayBufferView(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
354
0
               (failed = !(mData.Value()).TrySetToArrayBuffer(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext;
355
0
356
0
      }
357
0
      if (!done) {
358
0
        do {
359
0
          done = (failed = !(mData.Value()).TrySetToUSVString(cx, temp.ref(), tryNext)) || !tryNext;
360
0
          break;
361
0
        } while (false);
362
0
      }
363
0
      if (failed) {
364
0
        return false;
365
0
      }
366
0
      if (!done) {
367
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'data' member of PushEventInit", "ArrayBufferView, ArrayBuffer");
368
0
        return false;
369
0
      }
370
0
    }
371
0
    mIsAnyMemberPresent = true;
372
0
  }
373
0
  return true;
374
0
}
375
376
bool
377
PushEventInit::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
378
0
{
379
0
  PushEventInitAtoms* atomsCache = GetAtomCache<PushEventInitAtoms>(cx);
380
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
381
0
    return false;
382
0
  }
383
0
384
0
  // Per spec, we define the parent's members first
385
0
  if (!ExtendableEventInit::ToObjectInternal(cx, rval)) {
386
0
    return false;
387
0
  }
388
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
389
0
390
0
  if (mData.WasPassed()) {
391
0
    do {
392
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
393
0
      JS::Rooted<JS::Value> temp(cx);
394
0
      OwningArrayBufferViewOrArrayBufferOrUSVString const & currentValue = mData.InternalValue();
395
0
      if (!currentValue.ToJSVal(cx, obj, &temp)) {
396
0
        return false;
397
0
      }
398
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->data_id, temp, JSPROP_ENUMERATE)) {
399
0
        return false;
400
0
      }
401
0
      break;
402
0
    } while(false);
403
0
  }
404
0
405
0
  return true;
406
0
}
407
408
void
409
PushEventInit::TraceDictionary(JSTracer* trc)
410
0
{
411
0
  ExtendableEventInit::TraceDictionary(trc);
412
0
  if (mData.WasPassed()) {
413
0
    mData.Value().TraceUnion(trc);
414
0
  }
415
0
}
416
417
namespace binding_detail {
418
} // namespace binding_detail
419
420
421
namespace PushEvent_Binding {
422
423
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<ExtendableEvent_Binding::NativeType>::value,
424
              "Can't inherit from an interface with a different ownership model.");
425
426
MOZ_CAN_RUN_SCRIPT static bool
427
get_data(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PushEvent* self, JSJitGetterCallArgs args)
428
0
{
429
0
  AUTO_PROFILER_LABEL_FAST("get PushEvent.data", DOM, cx);
430
0
431
0
  auto result(StrongOrRawPtr<mozilla::dom::PushMessageData>(self->GetData()));
432
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
433
0
  if (!result) {
434
0
    args.rval().setNull();
435
0
    return true;
436
0
  }
437
0
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
438
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
439
0
    return false;
440
0
  }
441
0
  return true;
442
0
}
443
444
static const JSJitInfo data_getterinfo = {
445
  { (JSJitGetterOp)get_data },
446
  { prototypes::id::PushEvent },
447
  { PrototypeTraits<prototypes::id::PushEvent>::Depth },
448
  JSJitInfo::Getter,
449
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
450
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
451
  false,  /* isInfallible. False in setters. */
452
  false,  /* isMovable.  Not relevant for setters. */
453
  false, /* isEliminatable.  Not relevant for setters. */
454
  false, /* isAlwaysInSlot.  Only relevant for getters. */
455
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
456
  false,  /* isTypedMethod.  Only relevant for methods. */
457
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
458
};
459
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
460
static_assert(0 < 1, "There is no slot for us");
461
462
MOZ_CAN_RUN_SCRIPT static bool
463
get_isTrusted(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PushEvent* self, JSJitGetterCallArgs args)
464
0
{
465
0
  AUTO_PROFILER_LABEL_FAST("get PushEvent.isTrusted", DOM, cx);
466
0
467
0
  bool result(self->IsTrusted());
468
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
469
0
  args.rval().setBoolean(result);
470
0
  return true;
471
0
}
472
473
static const JSJitInfo isTrusted_getterinfo = {
474
  { (JSJitGetterOp)get_isTrusted },
475
  { prototypes::id::PushEvent },
476
  { PrototypeTraits<prototypes::id::PushEvent>::Depth },
477
  JSJitInfo::Getter,
478
  JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
479
  JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
480
  true,  /* isInfallible. False in setters. */
481
  true,  /* isMovable.  Not relevant for setters. */
482
  true, /* isEliminatable.  Not relevant for setters. */
483
  false, /* isAlwaysInSlot.  Only relevant for getters. */
484
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
485
  false,  /* isTypedMethod.  Only relevant for methods. */
486
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
487
};
488
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
489
static_assert(0 < 1, "There is no slot for us");
490
491
static bool
492
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
493
0
{
494
0
  mozilla::dom::PushEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PushEvent>(obj);
495
0
  // We don't want to preserve if we don't have a wrapper, and we
496
0
  // obviously can't preserve if we're not initialized.
497
0
  if (self && self->GetWrapperPreserveColor()) {
498
0
    PreserveWrapper(self);
499
0
  }
500
0
  return true;
501
0
}
502
503
static void
504
_finalize(js::FreeOp* fop, JSObject* obj)
505
0
{
506
0
  mozilla::dom::PushEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PushEvent>(obj);
507
0
  if (self) {
508
0
    ClearWrapper(self, self, obj);
509
0
    AddForDeferredFinalization<mozilla::dom::PushEvent>(self);
510
0
  }
511
0
}
512
513
static size_t
514
_objectMoved(JSObject* obj, JSObject* old)
515
0
{
516
0
  mozilla::dom::PushEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PushEvent>(obj);
517
0
  if (self) {
518
0
    UpdateWrapper(self, self, obj, old);
519
0
  }
520
0
521
0
  return 0;
522
0
}
523
524
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
525
#if defined(__clang__)
526
#pragma clang diagnostic push
527
#pragma clang diagnostic ignored "-Wmissing-braces"
528
#endif
529
static const JSPropertySpec sAttributes_specs[] = {
530
  { "data", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &data_getterinfo, nullptr, nullptr },
531
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
532
};
533
#if defined(__clang__)
534
#pragma clang diagnostic pop
535
#endif
536
537
538
static const Prefable<const JSPropertySpec> sAttributes[] = {
539
  { nullptr, &sAttributes_specs[0] },
540
  { nullptr, nullptr }
541
};
542
543
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
544
#if defined(__clang__)
545
#pragma clang diagnostic push
546
#pragma clang diagnostic ignored "-Wmissing-braces"
547
#endif
548
static const JSPropertySpec sUnforgeableAttributes_specs[] = {
549
  { "isTrusted", JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericGetter<NormalThisPolicy, ThrowExceptions>, &isTrusted_getterinfo, nullptr, nullptr },
550
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
551
};
552
#if defined(__clang__)
553
#pragma clang diagnostic pop
554
#endif
555
556
557
static const Prefable<const JSPropertySpec> sUnforgeableAttributes[] = {
558
  { nullptr, &sUnforgeableAttributes_specs[0] },
559
  { nullptr, nullptr }
560
};
561
562
563
static const NativePropertiesN<2> sNativeProperties = {
564
  false, 0,
565
  false, 0,
566
  false, 0,
567
  true,  0 /* sAttributes */,
568
  false, 0,
569
  true,  1 /* sUnforgeableAttributes */,
570
  false, 0,
571
  -1,
572
  0,
573
  nullptr,
574
  {
575
    { sAttributes, nullptr },
576
    { sUnforgeableAttributes, nullptr }
577
  }
578
};
579
580
static bool
581
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
582
0
{
583
0
  AUTO_PROFILER_LABEL_FAST("PushEvent constructor", DOM, cx);
584
0
585
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
586
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
587
0
  if (!args.isConstructing()) {
588
0
    // XXXbz wish I could get the name from the callee instead of
589
0
    // Adding more relocations
590
0
    return ThrowConstructorWithoutNew(cx, "PushEvent");
591
0
  }
592
0
593
0
  JS::Rooted<JSObject*> desiredProto(cx);
594
0
  if (!GetDesiredProto(cx, args, &desiredProto)) {
595
0
    return false;
596
0
  }
597
0
598
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
599
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "PushEvent");
600
0
  }
601
0
  GlobalObject global(cx, obj);
602
0
  if (global.Failed()) {
603
0
    return false;
604
0
  }
605
0
606
0
  bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
607
0
  binding_detail::FakeString arg0;
608
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
609
0
    return false;
610
0
  }
611
0
  RootedDictionary<binding_detail::FastPushEventInit> arg1(cx);
612
0
  if (!arg1.Init(cx, (args.hasDefined(1)) ? args[1] : JS::NullHandleValue,  "Argument 2 of PushEvent.constructor", false)) {
613
0
    return false;
614
0
  }
615
0
  Maybe<JSAutoRealm> ar;
616
0
  if (objIsXray) {
617
0
    obj = js::CheckedUnwrap(obj);
618
0
    if (!obj) {
619
0
      return false;
620
0
    }
621
0
    ar.emplace(cx, obj);
622
0
    if (!JS_WrapObject(cx, &desiredProto)) {
623
0
      return false;
624
0
    }
625
0
    if (arg1.mData.WasPassed()) {
626
0
      if (arg1.mData.Value().IsArrayBufferView()) {
627
0
        if (!arg1.mData.Value().GetAsArrayBufferView().WrapIntoNewCompartment(cx)) {
628
0
          return false;
629
0
        }
630
0
      }
631
0
      else if (arg1.mData.Value().IsArrayBuffer()) {
632
0
        if (!arg1.mData.Value().GetAsArrayBuffer().WrapIntoNewCompartment(cx)) {
633
0
          return false;
634
0
        }
635
0
      }
636
0
    }
637
0
  }
638
0
  FastErrorResult rv;
639
0
  auto result(StrongOrRawPtr<mozilla::dom::PushEvent>(mozilla::dom::PushEvent::Constructor(global, NonNullHelper(Constify(arg0)), Constify(arg1), rv)));
640
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
641
0
    return false;
642
0
  }
643
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
644
0
  static_assert(!IsPointer<decltype(result)>::value,
645
0
                "NewObject implies that we need to keep the object alive with a strong reference.");
646
0
  if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
647
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
648
0
    return false;
649
0
  }
650
0
  return true;
651
0
}
652
653
static const js::ClassOps sInterfaceObjectClassOps = {
654
    nullptr,               /* addProperty */
655
    nullptr,               /* delProperty */
656
    nullptr,               /* enumerate */
657
    nullptr,               /* newEnumerate */
658
    nullptr,               /* resolve */
659
    nullptr,               /* mayResolve */
660
    nullptr,               /* finalize */
661
    _constructor, /* call */
662
    nullptr,               /* hasInstance */
663
    _constructor, /* construct */
664
    nullptr,               /* trace */
665
};
666
667
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
668
  {
669
    "Function",
670
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
671
    &sInterfaceObjectClassOps,
672
    JS_NULL_CLASS_SPEC,
673
    JS_NULL_CLASS_EXT,
674
    &sInterfaceObjectClassObjectOps
675
  },
676
  eInterface,
677
  true,
678
  prototypes::id::PushEvent,
679
  PrototypeTraits<prototypes::id::PushEvent>::Depth,
680
  &sEmptyNativePropertyHooks,
681
  "function PushEvent() {\n    [native code]\n}",
682
  ExtendableEvent_Binding::GetConstructorObject
683
};
684
685
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
686
  {
687
    "PushEventPrototype",
688
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE + 1 /* slot for the JSObject holding the unforgeable properties */),
689
    JS_NULL_CLASS_OPS,
690
    JS_NULL_CLASS_SPEC,
691
    JS_NULL_CLASS_EXT,
692
    JS_NULL_OBJECT_OPS
693
  },
694
  eInterfacePrototype,
695
  false,
696
  prototypes::id::PushEvent,
697
  PrototypeTraits<prototypes::id::PushEvent>::Depth,
698
  &sEmptyNativePropertyHooks,
699
  "[object PushEventPrototype]",
700
  ExtendableEvent_Binding::GetProtoObject
701
};
702
703
bool
704
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
705
0
{
706
0
  MOZ_ASSERT(!NS_IsMainThread(), "Why did we even get called?");
707
0
708
0
  const char* name = js::GetObjectClass(aObj)->name;
709
0
  if (strcmp(name, "ServiceWorkerGlobalScope")) {
710
0
    return false;
711
0
  }
712
0
713
0
  return mozilla::dom::DOMPrefs::dom_push_enabled(aCx, aObj);
714
0
}
715
716
static const js::ClassOps sClassOps = {
717
  _addProperty, /* addProperty */
718
  nullptr,               /* delProperty */
719
  nullptr,               /* enumerate */
720
  nullptr, /* newEnumerate */
721
  nullptr, /* resolve */
722
  nullptr, /* mayResolve */
723
  _finalize, /* finalize */
724
  nullptr, /* call */
725
  nullptr,               /* hasInstance */
726
  nullptr,               /* construct */
727
  nullptr, /* trace */
728
};
729
730
static const js::ClassExtension sClassExtension = {
731
  nullptr, /* weakmapKeyDelegateOp */
732
  _objectMoved /* objectMovedOp */
733
};
734
735
static const DOMJSClass sClass = {
736
  { "PushEvent",
737
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_SKIP_NURSERY_FINALIZE,
738
    &sClassOps,
739
    JS_NULL_CLASS_SPEC,
740
    &sClassExtension,
741
    JS_NULL_OBJECT_OPS
742
  },
743
  { prototypes::id::Event, prototypes::id::ExtendableEvent, prototypes::id::PushEvent, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
744
  IsBaseOf<nsISupports, mozilla::dom::PushEvent >::value,
745
  &sEmptyNativePropertyHooks,
746
  FindAssociatedGlobalForNative<mozilla::dom::PushEvent>::Get,
747
  GetProtoObjectHandle,
748
  GetCCParticipant<mozilla::dom::PushEvent>::Get()
749
};
750
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
751
              "Must have the right minimal number of reserved slots.");
752
static_assert(1 >= 1,
753
              "Must have enough reserved slots.");
754
755
const JSClass*
756
GetJSClass()
757
0
{
758
0
  return sClass.ToJSClass();
759
0
}
760
761
bool
762
Wrap(JSContext* aCx, mozilla::dom::PushEvent* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
763
0
{
764
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::PushEvent>::value,
765
0
                "Shouldn't have wrappercached things that are not refcounted.");
766
0
  MOZ_ASSERT(static_cast<mozilla::dom::PushEvent*>(aObject) ==
767
0
             reinterpret_cast<mozilla::dom::PushEvent*>(aObject),
768
0
             "Multiple inheritance for mozilla::dom::PushEvent is broken.");
769
0
  MOZ_ASSERT(static_cast<mozilla::dom::ExtendableEvent*>(aObject) ==
770
0
             reinterpret_cast<mozilla::dom::ExtendableEvent*>(aObject),
771
0
             "Multiple inheritance for mozilla::dom::ExtendableEvent is broken.");
772
0
  MOZ_ASSERT(static_cast<mozilla::dom::Event*>(aObject) ==
773
0
             reinterpret_cast<mozilla::dom::Event*>(aObject),
774
0
             "Multiple inheritance for mozilla::dom::Event is broken.");
775
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
776
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
777
0
  MOZ_ASSERT(!aCache->GetWrapper(),
778
0
             "You should probably not be using Wrap() directly; use "
779
0
             "GetOrCreateDOMReflector instead");
780
0
781
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
782
0
             "nsISupports must be on our primary inheritance chain");
783
0
784
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
785
0
  if (!global) {
786
0
    return false;
787
0
  }
788
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
789
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
790
0
791
0
  // That might have ended up wrapping us already, due to the wonders
792
0
  // of XBL.  Check for that, and bail out as needed.
793
0
  aReflector.set(aCache->GetWrapper());
794
0
  if (aReflector) {
795
#ifdef DEBUG
796
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
797
#endif // DEBUG
798
    return true;
799
0
  }
800
0
801
0
  JSAutoRealm ar(aCx, global);
802
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
803
0
  if (!canonicalProto) {
804
0
    return false;
805
0
  }
806
0
  JS::Rooted<JSObject*> proto(aCx);
807
0
  if (aGivenProto) {
808
0
    proto = aGivenProto;
809
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
810
0
    // coming in, we changed compartments to that of "parent" so may need
811
0
    // to wrap the proto here.
812
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
813
0
      if (!JS_WrapObject(aCx, &proto)) {
814
0
        return false;
815
0
      }
816
0
    }
817
0
  } else {
818
0
    proto = canonicalProto;
819
0
  }
820
0
821
0
  BindingJSObjectCreator<mozilla::dom::PushEvent> creator(aCx);
822
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
823
0
  if (!aReflector) {
824
0
    return false;
825
0
  }
826
0
827
0
  aCache->SetWrapper(aReflector);
828
0
829
0
  // Important: do unforgeable property setup after we have handed
830
0
  // over ownership of the C++ object to obj as needed, so that if
831
0
  // we fail and it ends up GCed it won't have problems in the
832
0
  // finalizer trying to drop its ownership of the C++ object.
833
0
  JS::Rooted<JSObject*> unforgeableHolder(aCx,
834
0
    &js::GetReservedSlot(canonicalProto, DOM_INTERFACE_PROTO_SLOTS_BASE).toObject());
835
0
  if (!JS_InitializePropertiesFromCompatibleNativeObject(aCx, aReflector, unforgeableHolder)) {
836
0
    aCache->ReleaseWrapper(aObject);
837
0
    aCache->ClearWrapper();
838
0
    return false;
839
0
  }
840
0
  creator.InitializationSucceeded();
841
0
842
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
843
0
             aCache->GetWrapperPreserveColor() == aReflector);
844
0
  // If proto != canonicalProto, we have to preserve our wrapper;
845
0
  // otherwise we won't be able to properly recreate it later, since
846
0
  // we won't know what proto to use.  Note that we don't check
847
0
  // aGivenProto here, since it's entirely possible (and even
848
0
  // somewhat common) to have a non-null aGivenProto which is the
849
0
  // same as canonicalProto.
850
0
  if (proto != canonicalProto) {
851
0
    PreserveWrapper(aObject);
852
0
  }
853
0
854
0
  return true;
855
0
}
856
857
void
858
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
859
0
{
860
0
  JS::Handle<JSObject*> parentProto(ExtendableEvent_Binding::GetProtoObjectHandle(aCx));
861
0
  if (!parentProto) {
862
0
    return;
863
0
  }
864
0
865
0
  JS::Handle<JSObject*> constructorProto(ExtendableEvent_Binding::GetConstructorObjectHandle(aCx));
866
0
  if (!constructorProto) {
867
0
    return;
868
0
  }
869
0
870
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::PushEvent);
871
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::PushEvent);
872
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
873
0
                              &sPrototypeClass.mBase, protoCache,
874
0
                              nullptr,
875
0
                              constructorProto, &sInterfaceObjectClass.mBase, 1, nullptr,
876
0
                              interfaceCache,
877
0
                              sNativeProperties.Upcast(),
878
0
                              nullptr,
879
0
                              "PushEvent", aDefineOnGlobal,
880
0
                              nullptr,
881
0
                              false);
882
0
883
0
  JS::Rooted<JSObject*> unforgeableHolder(aCx);
884
0
  {
885
0
    JS::Rooted<JSObject*> holderProto(aCx, *protoCache);
886
0
    unforgeableHolder = JS_NewObjectWithoutMetadata(aCx, sClass.ToJSClass(), holderProto);
887
0
    if (!unforgeableHolder) {
888
0
      *protoCache = nullptr;
889
0
      if (interfaceCache) {
890
0
        *interfaceCache = nullptr;
891
0
      }
892
0
      return;
893
0
    }
894
0
  }
895
0
896
0
  if (!DefineUnforgeableAttributes(aCx, unforgeableHolder, sUnforgeableAttributes)) {
897
0
    *protoCache = nullptr;
898
0
    if (interfaceCache) {
899
0
      *interfaceCache = nullptr;
900
0
    }
901
0
    return;
902
0
  }
903
0
904
0
  if (*protoCache) {
905
0
    js::SetReservedSlot(*protoCache, DOM_INTERFACE_PROTO_SLOTS_BASE,
906
0
                        JS::ObjectValue(*unforgeableHolder));
907
0
  }
908
0
}
909
910
JSObject*
911
GetConstructorObject(JSContext* aCx)
912
0
{
913
0
  return GetConstructorObjectHandle(aCx);
914
0
}
915
916
} // namespace PushEvent_Binding
917
918
919
920
} // namespace dom
921
} // namespace mozilla