Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/ExtendableMessageEventBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM ExtendableMessageEvent.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "AtomList.h"
4
#include "ExtendableEventBinding.h"
5
#include "ExtendableMessageEventBinding.h"
6
#include "WrapperFactory.h"
7
#include "mozilla/OwningNonNull.h"
8
#include "mozilla/dom/BindingUtils.h"
9
#include "mozilla/dom/Client.h"
10
#include "mozilla/dom/DOMJSClass.h"
11
#include "mozilla/dom/MessagePort.h"
12
#include "mozilla/dom/NonRefcountedDOMObject.h"
13
#include "mozilla/dom/Nullable.h"
14
#include "mozilla/dom/PrimitiveConversions.h"
15
#include "mozilla/dom/ScriptSettings.h"
16
#include "mozilla/dom/ServiceWorker.h"
17
#include "mozilla/dom/ServiceWorkerEvents.h"
18
#include "mozilla/dom/UnionConversions.h"
19
#include "nsThreadUtils.h"
20
21
namespace mozilla {
22
namespace dom {
23
24
namespace binding_detail {}; // Just to make sure it's known as a namespace
25
using namespace mozilla::dom::binding_detail;
26
27
28
void
29
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningClientOrServiceWorkerOrMessagePort& aUnion, const char* aName, uint32_t aFlags)
30
0
{
31
0
  if (aUnion.IsClient()) {
32
0
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsClient(), "mClient", aFlags);
33
0
  } else if (aUnion.IsServiceWorker()) {
34
0
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsServiceWorker(), "mServiceWorker", aFlags);
35
0
  } else if (aUnion.IsMessagePort()) {
36
0
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsMessagePort(), "mMessagePort", aFlags);
37
0
  }
38
0
}
39
40
41
void
42
ImplCycleCollectionUnlink(OwningClientOrServiceWorkerOrMessagePort& aUnion)
43
0
{
44
0
  aUnion.Uninit();
45
0
}
46
47
48
bool
49
ClientOrServiceWorkerOrMessagePort::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
50
0
{
51
0
  switch (mType) {
52
0
    case eUninitialized: {
53
0
      return false;
54
0
      break;
55
0
    }
56
0
    case eClient: {
57
0
      if (!GetOrCreateDOMReflector(cx, mValue.mClient.Value(), rval)) {
58
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
59
0
        return false;
60
0
      }
61
0
      return true;
62
0
      break;
63
0
    }
64
0
    case eServiceWorker: {
65
0
      if (!GetOrCreateDOMReflector(cx, mValue.mServiceWorker.Value(), rval)) {
66
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
67
0
        return false;
68
0
      }
69
0
      return true;
70
0
      break;
71
0
    }
72
0
    case eMessagePort: {
73
0
      if (!GetOrCreateDOMReflector(cx, mValue.mMessagePort.Value(), rval)) {
74
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
75
0
        return false;
76
0
      }
77
0
      return true;
78
0
      break;
79
0
    }
80
0
    default: {
81
0
      return false;
82
0
      break;
83
0
    }
84
0
  }
85
0
86
0
  return false;
87
0
}
88
89
90
OwningNonNull<mozilla::dom::Client>&
91
OwningClientOrServiceWorkerOrMessagePort::RawSetAsClient()
92
0
{
93
0
  if (mType == eClient) {
94
0
    return mValue.mClient.Value();
95
0
  }
96
0
  MOZ_ASSERT(mType == eUninitialized);
97
0
  mType = eClient;
98
0
  return mValue.mClient.SetValue();
99
0
}
100
101
OwningNonNull<mozilla::dom::Client>&
102
OwningClientOrServiceWorkerOrMessagePort::SetAsClient()
103
0
{
104
0
  if (mType == eClient) {
105
0
    return mValue.mClient.Value();
106
0
  }
107
0
  Uninit();
108
0
  mType = eClient;
109
0
  return mValue.mClient.SetValue();
110
0
}
111
112
bool
113
OwningClientOrServiceWorkerOrMessagePort::TrySetToClient(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
114
0
{
115
0
  tryNext = false;
116
0
  { // scope for memberSlot
117
0
    OwningNonNull<mozilla::dom::Client>& memberSlot = RawSetAsClient();
118
0
    static_assert(IsRefcounted<mozilla::dom::Client>::value, "We can only store refcounted classes.");{
119
0
      nsresult rv = UnwrapObject<prototypes::id::Client, mozilla::dom::Client>(value, memberSlot);
120
0
      if (NS_FAILED(rv)) {
121
0
        DestroyClient();
122
0
        tryNext = true;
123
0
        return true;
124
0
      }
125
0
    }
126
0
  }
127
0
  return true;
128
0
}
129
130
void
131
OwningClientOrServiceWorkerOrMessagePort::DestroyClient()
132
0
{
133
0
  MOZ_ASSERT(IsClient(), "Wrong type!");
134
0
  mValue.mClient.Destroy();
135
0
  mType = eUninitialized;
136
0
}
137
138
139
140
141
OwningNonNull<mozilla::dom::ServiceWorker>&
142
OwningClientOrServiceWorkerOrMessagePort::RawSetAsServiceWorker()
143
0
{
144
0
  if (mType == eServiceWorker) {
145
0
    return mValue.mServiceWorker.Value();
146
0
  }
147
0
  MOZ_ASSERT(mType == eUninitialized);
148
0
  mType = eServiceWorker;
149
0
  return mValue.mServiceWorker.SetValue();
150
0
}
151
152
OwningNonNull<mozilla::dom::ServiceWorker>&
153
OwningClientOrServiceWorkerOrMessagePort::SetAsServiceWorker()
154
0
{
155
0
  if (mType == eServiceWorker) {
156
0
    return mValue.mServiceWorker.Value();
157
0
  }
158
0
  Uninit();
159
0
  mType = eServiceWorker;
160
0
  return mValue.mServiceWorker.SetValue();
161
0
}
162
163
bool
164
OwningClientOrServiceWorkerOrMessagePort::TrySetToServiceWorker(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
165
0
{
166
0
  tryNext = false;
167
0
  { // scope for memberSlot
168
0
    OwningNonNull<mozilla::dom::ServiceWorker>& memberSlot = RawSetAsServiceWorker();
169
0
    static_assert(IsRefcounted<mozilla::dom::ServiceWorker>::value, "We can only store refcounted classes.");{
170
0
      nsresult rv = UnwrapObject<prototypes::id::ServiceWorker, mozilla::dom::ServiceWorker>(value, memberSlot);
171
0
      if (NS_FAILED(rv)) {
172
0
        DestroyServiceWorker();
173
0
        tryNext = true;
174
0
        return true;
175
0
      }
176
0
    }
177
0
  }
178
0
  return true;
179
0
}
180
181
void
182
OwningClientOrServiceWorkerOrMessagePort::DestroyServiceWorker()
183
0
{
184
0
  MOZ_ASSERT(IsServiceWorker(), "Wrong type!");
185
0
  mValue.mServiceWorker.Destroy();
186
0
  mType = eUninitialized;
187
0
}
188
189
190
191
192
OwningNonNull<mozilla::dom::MessagePort>&
193
OwningClientOrServiceWorkerOrMessagePort::RawSetAsMessagePort()
194
0
{
195
0
  if (mType == eMessagePort) {
196
0
    return mValue.mMessagePort.Value();
197
0
  }
198
0
  MOZ_ASSERT(mType == eUninitialized);
199
0
  mType = eMessagePort;
200
0
  return mValue.mMessagePort.SetValue();
201
0
}
202
203
OwningNonNull<mozilla::dom::MessagePort>&
204
OwningClientOrServiceWorkerOrMessagePort::SetAsMessagePort()
205
0
{
206
0
  if (mType == eMessagePort) {
207
0
    return mValue.mMessagePort.Value();
208
0
  }
209
0
  Uninit();
210
0
  mType = eMessagePort;
211
0
  return mValue.mMessagePort.SetValue();
212
0
}
213
214
bool
215
OwningClientOrServiceWorkerOrMessagePort::TrySetToMessagePort(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
216
0
{
217
0
  tryNext = false;
218
0
  { // scope for memberSlot
219
0
    OwningNonNull<mozilla::dom::MessagePort>& memberSlot = RawSetAsMessagePort();
220
0
    static_assert(IsRefcounted<mozilla::dom::MessagePort>::value, "We can only store refcounted classes.");{
221
0
      nsresult rv = UnwrapObject<prototypes::id::MessagePort, mozilla::dom::MessagePort>(value, memberSlot);
222
0
      if (NS_FAILED(rv)) {
223
0
        DestroyMessagePort();
224
0
        tryNext = true;
225
0
        return true;
226
0
      }
227
0
    }
228
0
  }
229
0
  return true;
230
0
}
231
232
void
233
OwningClientOrServiceWorkerOrMessagePort::DestroyMessagePort()
234
0
{
235
0
  MOZ_ASSERT(IsMessagePort(), "Wrong type!");
236
0
  mValue.mMessagePort.Destroy();
237
0
  mType = eUninitialized;
238
0
}
239
240
241
242
243
void
244
OwningClientOrServiceWorkerOrMessagePort::Uninit()
245
{
246
  switch (mType) {
247
    case eUninitialized: {
248
      break;
249
    }
250
    case eClient: {
251
      DestroyClient();
252
      break;
253
    }
254
    case eServiceWorker: {
255
      DestroyServiceWorker();
256
      break;
257
    }
258
    case eMessagePort: {
259
      DestroyMessagePort();
260
      break;
261
    }
262
  }
263
}
264
265
bool
266
OwningClientOrServiceWorkerOrMessagePort::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
267
0
{
268
0
  switch (mType) {
269
0
    case eUninitialized: {
270
0
      return false;
271
0
      break;
272
0
    }
273
0
    case eClient: {
274
0
      if (!GetOrCreateDOMReflector(cx, mValue.mClient.Value(), rval)) {
275
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
276
0
        return false;
277
0
      }
278
0
      return true;
279
0
      break;
280
0
    }
281
0
    case eServiceWorker: {
282
0
      if (!GetOrCreateDOMReflector(cx, mValue.mServiceWorker.Value(), rval)) {
283
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
284
0
        return false;
285
0
      }
286
0
      return true;
287
0
      break;
288
0
    }
289
0
    case eMessagePort: {
290
0
      if (!GetOrCreateDOMReflector(cx, mValue.mMessagePort.Value(), rval)) {
291
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
292
0
        return false;
293
0
      }
294
0
      return true;
295
0
      break;
296
0
    }
297
0
    default: {
298
0
      return false;
299
0
      break;
300
0
    }
301
0
  }
302
0
303
0
  return false;
304
0
}
305
306
void
307
OwningClientOrServiceWorkerOrMessagePort::TraceUnion(JSTracer* trc)
308
0
{
309
0
}
310
311
OwningClientOrServiceWorkerOrMessagePort&
312
OwningClientOrServiceWorkerOrMessagePort::operator=(const OwningClientOrServiceWorkerOrMessagePort& aOther)
313
0
{
314
0
  switch (aOther.mType) {
315
0
    case eUninitialized: {
316
0
      MOZ_ASSERT(mType == eUninitialized,
317
0
                 "We need to destroy ourselves?");
318
0
      break;
319
0
    }
320
0
    case eClient: {
321
0
      SetAsClient() = aOther.GetAsClient();
322
0
      break;
323
0
    }
324
0
    case eServiceWorker: {
325
0
      SetAsServiceWorker() = aOther.GetAsServiceWorker();
326
0
      break;
327
0
    }
328
0
    case eMessagePort: {
329
0
      SetAsMessagePort() = aOther.GetAsMessagePort();
330
0
      break;
331
0
    }
332
0
  }
333
0
  return *this;
334
0
}
335
336
337
338
ExtendableMessageEventInit::ExtendableMessageEventInit()
339
  : ExtendableEventInit(FastDictionaryInitializer()),
340
    mData(JS::UndefinedValue())
341
0
{
342
0
  // Safe to pass a null context if we pass a null value
343
0
  Init(nullptr, JS::NullHandleValue);
344
0
}
345
346
347
bool
348
ExtendableMessageEventInit::InitIds(JSContext* cx, ExtendableMessageEventInitAtoms* atomsCache)
349
0
{
350
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
351
0
352
0
  // Initialize these in reverse order so that any failure leaves the first one
353
0
  // uninitialized.
354
0
  if (!atomsCache->source_id.init(cx, "source") ||
355
0
      !atomsCache->ports_id.init(cx, "ports") ||
356
0
      !atomsCache->origin_id.init(cx, "origin") ||
357
0
      !atomsCache->lastEventId_id.init(cx, "lastEventId") ||
358
0
      !atomsCache->data_id.init(cx, "data")) {
359
0
    return false;
360
0
  }
361
0
  return true;
362
0
}
363
364
bool
365
ExtendableMessageEventInit::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
366
0
{
367
0
  // Passing a null JSContext is OK only if we're initing from null,
368
0
  // Since in that case we will not have to do any property gets
369
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
370
0
  // checkers by static analysis tools
371
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
372
0
  ExtendableMessageEventInitAtoms* atomsCache = nullptr;
373
0
  if (cx) {
374
0
    atomsCache = GetAtomCache<ExtendableMessageEventInitAtoms>(cx);
375
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
376
0
      return false;
377
0
    }
378
0
  }
379
0
380
0
  // Per spec, we init the parent's members first
381
0
  if (!ExtendableEventInit::Init(cx, val)) {
382
0
    return false;
383
0
  }
384
0
385
0
  bool isNull = val.isNullOrUndefined();
386
0
  // We only need these if !isNull, in which case we have |cx|.
387
0
  Maybe<JS::Rooted<JSObject *> > object;
388
0
  Maybe<JS::Rooted<JS::Value> > temp;
389
0
  if (!isNull) {
390
0
    MOZ_ASSERT(cx);
391
0
    object.emplace(cx, &val.toObject());
392
0
    temp.emplace(cx);
393
0
  }
394
0
  if (!isNull) {
395
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->data_id, temp.ptr())) {
396
0
      return false;
397
0
    }
398
0
  }
399
0
  if (!isNull && !temp->isUndefined()) {
400
0
#ifdef __clang__
401
0
#pragma clang diagnostic push
402
0
#pragma clang diagnostic ignored "-Wunreachable-code"
403
0
#pragma clang diagnostic ignored "-Wunreachable-code-return"
404
0
#endif // __clang__
405
0
    if ((passedToJSImpl) && !CallerSubsumes(temp.ref())) {
406
0
      ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "'data' member of ExtendableMessageEventInit");
407
0
      return false;
408
0
    }
409
0
#ifdef __clang__
410
0
#pragma clang diagnostic pop
411
0
#endif // __clang__
412
0
    mData = temp.ref();
413
0
  } else {
414
0
    mData = JS::NullValue();
415
0
  }
416
0
  mIsAnyMemberPresent = true;
417
0
418
0
  if (!isNull) {
419
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->lastEventId_id, temp.ptr())) {
420
0
      return false;
421
0
    }
422
0
  }
423
0
  if (!isNull && !temp->isUndefined()) {
424
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mLastEventId)) {
425
0
      return false;
426
0
    }
427
0
  } else {
428
0
    static const char16_t data[] = { 0 };
429
0
    mLastEventId.Rebind(data, ArrayLength(data) - 1);
430
0
  }
431
0
  mIsAnyMemberPresent = true;
432
0
433
0
  if (!isNull) {
434
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->origin_id, temp.ptr())) {
435
0
      return false;
436
0
    }
437
0
  }
438
0
  if (!isNull && !temp->isUndefined()) {
439
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mOrigin)) {
440
0
      return false;
441
0
    }
442
0
  } else {
443
0
    static const char16_t data[] = { 0 };
444
0
    mOrigin.Rebind(data, ArrayLength(data) - 1);
445
0
  }
446
0
  mIsAnyMemberPresent = true;
447
0
448
0
  if (!isNull) {
449
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->ports_id, temp.ptr())) {
450
0
      return false;
451
0
    }
452
0
  }
453
0
  if (!isNull && !temp->isUndefined()) {
454
0
    if (temp.ref().isObject()) {
455
0
      JS::ForOfIterator iter(cx);
456
0
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
457
0
        return false;
458
0
      }
459
0
      if (!iter.valueIsIterable()) {
460
0
        ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'ports' member of ExtendableMessageEventInit");
461
0
        return false;
462
0
      }
463
0
      Sequence<OwningNonNull<mozilla::dom::MessagePort>> &arr = mPorts;
464
0
      JS::Rooted<JS::Value> temp(cx);
465
0
      while (true) {
466
0
        bool done;
467
0
        if (!iter.next(&temp, &done)) {
468
0
          return false;
469
0
        }
470
0
        if (done) {
471
0
          break;
472
0
        }
473
0
        OwningNonNull<mozilla::dom::MessagePort>* slotPtr = arr.AppendElement(mozilla::fallible);
474
0
        if (!slotPtr) {
475
0
          JS_ReportOutOfMemory(cx);
476
0
          return false;
477
0
        }
478
0
        OwningNonNull<mozilla::dom::MessagePort>& slot = *slotPtr;
479
0
        if (temp.isObject()) {
480
0
          static_assert(IsRefcounted<mozilla::dom::MessagePort>::value, "We can only store refcounted classes.");{
481
0
            nsresult rv = UnwrapObject<prototypes::id::MessagePort, mozilla::dom::MessagePort>(&temp, slot);
482
0
            if (NS_FAILED(rv)) {
483
0
              ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Element of 'ports' member of ExtendableMessageEventInit", "MessagePort");
484
0
              return false;
485
0
            }
486
0
          }
487
0
        } else {
488
0
          ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Element of 'ports' member of ExtendableMessageEventInit");
489
0
          return false;
490
0
        }
491
0
      }
492
0
    } else {
493
0
      ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'ports' member of ExtendableMessageEventInit");
494
0
      return false;
495
0
    }
496
0
  } else {
497
0
    /* Array is already empty; nothing to do */
498
0
  }
499
0
  mIsAnyMemberPresent = true;
500
0
501
0
  if (!isNull) {
502
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->source_id, temp.ptr())) {
503
0
      return false;
504
0
    }
505
0
  }
506
0
  if (!(!isNull && !temp->isUndefined()) || temp.ref().isNullOrUndefined()) {
507
0
    mSource.SetNull();
508
0
  } else {
509
0
    {
510
0
      bool done = false, failed = false, tryNext;
511
0
      if (temp.ref().isObject()) {
512
0
        done = (failed = !mSource.SetValue().TrySetToClient(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
513
0
               (failed = !mSource.SetValue().TrySetToServiceWorker(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
514
0
               (failed = !mSource.SetValue().TrySetToMessagePort(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext;
515
0
516
0
      }
517
0
      if (failed) {
518
0
        return false;
519
0
      }
520
0
      if (!done) {
521
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'source' member of ExtendableMessageEventInit", "Client, ServiceWorker, MessagePort");
522
0
        return false;
523
0
      }
524
0
    }
525
0
  }
526
0
  mIsAnyMemberPresent = true;
527
0
  return true;
528
0
}
529
530
bool
531
ExtendableMessageEventInit::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
532
0
{
533
0
  ExtendableMessageEventInitAtoms* atomsCache = GetAtomCache<ExtendableMessageEventInitAtoms>(cx);
534
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
535
0
    return false;
536
0
  }
537
0
538
0
  // Per spec, we define the parent's members first
539
0
  if (!ExtendableEventInit::ToObjectInternal(cx, rval)) {
540
0
    return false;
541
0
  }
542
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
543
0
544
0
  do {
545
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
546
0
    JS::Rooted<JS::Value> temp(cx);
547
0
    JS::Value const & currentValue = mData;
548
0
    JS::ExposeValueToActiveJS(currentValue);
549
0
    temp.set(currentValue);
550
0
    if (!MaybeWrapValue(cx, &temp)) {
551
0
      return false;
552
0
    }
553
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->data_id, temp, JSPROP_ENUMERATE)) {
554
0
      return false;
555
0
    }
556
0
    break;
557
0
  } while(false);
558
0
559
0
  do {
560
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
561
0
    JS::Rooted<JS::Value> temp(cx);
562
0
    nsString const & currentValue = mLastEventId;
563
0
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
564
0
      return false;
565
0
    }
566
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->lastEventId_id, temp, JSPROP_ENUMERATE)) {
567
0
      return false;
568
0
    }
569
0
    break;
570
0
  } while(false);
571
0
572
0
  do {
573
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
574
0
    JS::Rooted<JS::Value> temp(cx);
575
0
    nsString const & currentValue = mOrigin;
576
0
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
577
0
      return false;
578
0
    }
579
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->origin_id, temp, JSPROP_ENUMERATE)) {
580
0
      return false;
581
0
    }
582
0
    break;
583
0
  } while(false);
584
0
585
0
  do {
586
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
587
0
    JS::Rooted<JS::Value> temp(cx);
588
0
    Sequence<OwningNonNull<mozilla::dom::MessagePort>> const & currentValue = mPorts;
589
0
590
0
    uint32_t length = currentValue.Length();
591
0
    JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
592
0
    if (!returnArray) {
593
0
      return false;
594
0
    }
595
0
    // Scope for 'tmp'
596
0
    {
597
0
      JS::Rooted<JS::Value> tmp(cx);
598
0
      for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
599
0
        // Control block to let us common up the JS_DefineElement calls when there
600
0
        // are different ways to succeed at wrapping the object.
601
0
        do {
602
0
          if (!GetOrCreateDOMReflector(cx, currentValue[sequenceIdx0], &tmp)) {
603
0
            MOZ_ASSERT(JS_IsExceptionPending(cx));
604
0
            return false;
605
0
          }
606
0
          break;
607
0
        } while (false);
608
0
        if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
609
0
                              JSPROP_ENUMERATE)) {
610
0
          return false;
611
0
        }
612
0
      }
613
0
    }
614
0
    temp.setObject(*returnArray);
615
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->ports_id, temp, JSPROP_ENUMERATE)) {
616
0
      return false;
617
0
    }
618
0
    break;
619
0
  } while(false);
620
0
621
0
  do {
622
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
623
0
    JS::Rooted<JS::Value> temp(cx);
624
0
    Nullable<OwningClientOrServiceWorkerOrMessagePort > const & currentValue = mSource;
625
0
    if (currentValue.IsNull()) {
626
0
      temp.setNull();
627
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->source_id, temp, JSPROP_ENUMERATE)) {
628
0
        return false;
629
0
      }
630
0
      break;
631
0
    }
632
0
    if (!currentValue.Value().ToJSVal(cx, obj, &temp)) {
633
0
      return false;
634
0
    }
635
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->source_id, temp, JSPROP_ENUMERATE)) {
636
0
      return false;
637
0
    }
638
0
    break;
639
0
  } while(false);
640
0
641
0
  return true;
642
0
}
643
644
void
645
ExtendableMessageEventInit::TraceDictionary(JSTracer* trc)
646
0
{
647
0
  ExtendableEventInit::TraceDictionary(trc);
648
0
  JS::UnsafeTraceRoot(trc, &mData, "ExtendableMessageEventInit.mData");
649
0
}
650
651
652
653
namespace binding_detail {
654
} // namespace binding_detail
655
656
657
namespace ExtendableMessageEvent_Binding {
658
659
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<ExtendableEvent_Binding::NativeType>::value,
660
              "Can't inherit from an interface with a different ownership model.");
661
662
MOZ_CAN_RUN_SCRIPT static bool
663
get_data(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ExtendableMessageEvent* self, JSJitGetterCallArgs args)
664
0
{
665
0
  AUTO_PROFILER_LABEL_FAST("get ExtendableMessageEvent.data", DOM, cx);
666
0
667
0
  FastErrorResult rv;
668
0
  JS::Rooted<JS::Value> result(cx);
669
0
  self->GetData(cx, &result, rv);
670
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
671
0
    return false;
672
0
  }
673
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
674
0
  JS::ExposeValueToActiveJS(result);
675
0
  args.rval().set(result);
676
0
  if (!MaybeWrapValue(cx, args.rval())) {
677
0
    return false;
678
0
  }
679
0
  return true;
680
0
}
681
682
static const JSJitInfo data_getterinfo = {
683
  { (JSJitGetterOp)get_data },
684
  { prototypes::id::ExtendableMessageEvent },
685
  { PrototypeTraits<prototypes::id::ExtendableMessageEvent>::Depth },
686
  JSJitInfo::Getter,
687
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
688
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
689
  false,  /* isInfallible. False in setters. */
690
  false,  /* isMovable.  Not relevant for setters. */
691
  false, /* isEliminatable.  Not relevant for setters. */
692
  false, /* isAlwaysInSlot.  Only relevant for getters. */
693
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
694
  false,  /* isTypedMethod.  Only relevant for methods. */
695
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
696
};
697
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
698
static_assert(0 < 2, "There is no slot for us");
699
700
MOZ_CAN_RUN_SCRIPT static bool
701
get_origin(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ExtendableMessageEvent* self, JSJitGetterCallArgs args)
702
0
{
703
0
  AUTO_PROFILER_LABEL_FAST("get ExtendableMessageEvent.origin", DOM, cx);
704
0
705
0
  DOMString result;
706
0
  self->GetOrigin(result);
707
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
708
0
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
709
0
    return false;
710
0
  }
711
0
  return true;
712
0
}
713
714
static const JSJitInfo origin_getterinfo = {
715
  { (JSJitGetterOp)get_origin },
716
  { prototypes::id::ExtendableMessageEvent },
717
  { PrototypeTraits<prototypes::id::ExtendableMessageEvent>::Depth },
718
  JSJitInfo::Getter,
719
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
720
  JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
721
  false,  /* isInfallible. False in setters. */
722
  false,  /* isMovable.  Not relevant for setters. */
723
  false, /* isEliminatable.  Not relevant for setters. */
724
  false, /* isAlwaysInSlot.  Only relevant for getters. */
725
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
726
  false,  /* isTypedMethod.  Only relevant for methods. */
727
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
728
};
729
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
730
static_assert(0 < 2, "There is no slot for us");
731
732
MOZ_CAN_RUN_SCRIPT static bool
733
get_lastEventId(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ExtendableMessageEvent* self, JSJitGetterCallArgs args)
734
0
{
735
0
  AUTO_PROFILER_LABEL_FAST("get ExtendableMessageEvent.lastEventId", DOM, cx);
736
0
737
0
  DOMString result;
738
0
  self->GetLastEventId(result);
739
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
740
0
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
741
0
    return false;
742
0
  }
743
0
  return true;
744
0
}
745
746
static const JSJitInfo lastEventId_getterinfo = {
747
  { (JSJitGetterOp)get_lastEventId },
748
  { prototypes::id::ExtendableMessageEvent },
749
  { PrototypeTraits<prototypes::id::ExtendableMessageEvent>::Depth },
750
  JSJitInfo::Getter,
751
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
752
  JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
753
  false,  /* isInfallible. False in setters. */
754
  false,  /* isMovable.  Not relevant for setters. */
755
  false, /* isEliminatable.  Not relevant for setters. */
756
  false, /* isAlwaysInSlot.  Only relevant for getters. */
757
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
758
  false,  /* isTypedMethod.  Only relevant for methods. */
759
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
760
};
761
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
762
static_assert(0 < 2, "There is no slot for us");
763
764
MOZ_CAN_RUN_SCRIPT static bool
765
get_source(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ExtendableMessageEvent* self, JSJitGetterCallArgs args)
766
0
{
767
0
  AUTO_PROFILER_LABEL_FAST("get ExtendableMessageEvent.source", DOM, cx);
768
0
769
0
  Nullable<OwningClientOrServiceWorkerOrMessagePort> result;
770
0
  self->GetSource(result);
771
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
772
0
  if (result.IsNull()) {
773
0
    args.rval().setNull();
774
0
    return true;
775
0
  }
776
0
  if (!result.Value().ToJSVal(cx, obj, args.rval())) {
777
0
    return false;
778
0
  }
779
0
  return true;
780
0
}
781
782
static const JSJitInfo source_getterinfo = {
783
  { (JSJitGetterOp)get_source },
784
  { prototypes::id::ExtendableMessageEvent },
785
  { PrototypeTraits<prototypes::id::ExtendableMessageEvent>::Depth },
786
  JSJitInfo::Getter,
787
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
788
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
789
  false,  /* isInfallible. False in setters. */
790
  false,  /* isMovable.  Not relevant for setters. */
791
  false, /* isEliminatable.  Not relevant for setters. */
792
  false, /* isAlwaysInSlot.  Only relevant for getters. */
793
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
794
  false,  /* isTypedMethod.  Only relevant for methods. */
795
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
796
};
797
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
798
static_assert(0 < 2, "There is no slot for us");
799
800
MOZ_CAN_RUN_SCRIPT static bool
801
get_ports(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ExtendableMessageEvent* self, JSJitGetterCallArgs args)
802
0
{
803
0
  AUTO_PROFILER_LABEL_FAST("get ExtendableMessageEvent.ports", DOM, cx);
804
0
805
0
  // Have to either root across the getter call or reget after.
806
0
  JS::Rooted<JSObject*> slotStorage(cx, js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false));
807
0
  MOZ_ASSERT(IsDOMObject(slotStorage));
808
0
  const size_t slotIndex = (DOM_INSTANCE_RESERVED_SLOTS + 0);
809
0
  MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
810
0
  {
811
0
    // Scope for cachedVal
812
0
    JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
813
0
    if (!cachedVal.isUndefined()) {
814
0
      args.rval().set(cachedVal);
815
0
      // The cached value is in the compartment of slotStorage,
816
0
      // so wrap into the caller compartment as needed.
817
0
      if (MaybeWrapNonDOMObjectValue(cx, args.rval())) {
818
0
        return true;
819
0
      }
820
0
      return false;
821
0
    }
822
0
  }
823
0
824
0
  nsTArray<StrongPtrForMember<mozilla::dom::MessagePort>::Type> result;
825
0
  self->GetPorts(result);
826
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
827
0
  {
828
0
    JS::Rooted<JSObject*> conversionScope(cx, slotStorage);
829
0
    JSAutoRealm ar(cx, conversionScope);
830
0
    do { // block we break out of when done wrapping
831
0
832
0
      uint32_t length = result.Length();
833
0
      JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
834
0
      if (!returnArray) {
835
0
        return false;
836
0
      }
837
0
      // Scope for 'tmp'
838
0
      {
839
0
        JS::Rooted<JS::Value> tmp(cx);
840
0
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
841
0
          // Control block to let us common up the JS_DefineElement calls when there
842
0
          // are different ways to succeed at wrapping the object.
843
0
          do {
844
0
            if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) {
845
0
              MOZ_ASSERT(JS_IsExceptionPending(cx));
846
0
              return false;
847
0
            }
848
0
            break;
849
0
          } while (false);
850
0
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
851
0
                                JSPROP_ENUMERATE)) {
852
0
            return false;
853
0
          }
854
0
        }
855
0
      }
856
0
      args.rval().setObject(*returnArray);
857
0
      break;
858
0
    } while (false);
859
0
    JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
860
0
    if (!JS_FreezeObject(cx, rvalObj)) {
861
0
      return false;
862
0
    }
863
0
  }
864
0
  { // And now store things in the realm of our slotStorage.
865
0
    JSAutoRealm ar(cx, slotStorage);
866
0
    // Make a copy so that we don't do unnecessary wrapping on args.rval().
867
0
    JS::Rooted<JS::Value> storedVal(cx, args.rval());
868
0
    if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
869
0
      return false;
870
0
    }
871
0
    js::SetReservedSlot(slotStorage, slotIndex, storedVal);
872
0
    PreserveWrapper(self);
873
0
  }
874
0
  // And now make sure args.rval() is in the caller realm.
875
0
  if (MaybeWrapNonDOMObjectValue(cx, args.rval())) {
876
0
    return true;
877
0
  }
878
0
  return false;
879
0
}
880
881
static const JSJitInfo ports_getterinfo = {
882
  { (JSJitGetterOp)get_ports },
883
  { prototypes::id::ExtendableMessageEvent },
884
  { PrototypeTraits<prototypes::id::ExtendableMessageEvent>::Depth },
885
  JSJitInfo::Getter,
886
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
887
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
888
  false,  /* isInfallible. False in setters. */
889
  true,  /* isMovable.  Not relevant for setters. */
890
  true, /* isEliminatable.  Not relevant for setters. */
891
  false, /* isAlwaysInSlot.  Only relevant for getters. */
892
  true, /* isLazilyCachedInSlot.  Only relevant for getters. */
893
  false,  /* isTypedMethod.  Only relevant for methods. */
894
  (DOM_INSTANCE_RESERVED_SLOTS + 0)   /* Reserved slot index, if we're stored in a slot, else 0. */
895
};
896
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit");
897
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 2, "There is no slot for us");
898
899
MOZ_CAN_RUN_SCRIPT static bool
900
get_isTrusted(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ExtendableMessageEvent* self, JSJitGetterCallArgs args)
901
0
{
902
0
  AUTO_PROFILER_LABEL_FAST("get ExtendableMessageEvent.isTrusted", DOM, cx);
903
0
904
0
  bool result(self->IsTrusted());
905
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
906
0
  args.rval().setBoolean(result);
907
0
  return true;
908
0
}
909
910
static const JSJitInfo isTrusted_getterinfo = {
911
  { (JSJitGetterOp)get_isTrusted },
912
  { prototypes::id::ExtendableMessageEvent },
913
  { PrototypeTraits<prototypes::id::ExtendableMessageEvent>::Depth },
914
  JSJitInfo::Getter,
915
  JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
916
  JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
917
  true,  /* isInfallible. False in setters. */
918
  true,  /* isMovable.  Not relevant for setters. */
919
  true, /* isEliminatable.  Not relevant for setters. */
920
  false, /* isAlwaysInSlot.  Only relevant for getters. */
921
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
922
  false,  /* isTypedMethod.  Only relevant for methods. */
923
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
924
};
925
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
926
static_assert(0 < 2, "There is no slot for us");
927
928
static bool
929
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
930
0
{
931
0
  mozilla::dom::ExtendableMessageEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::ExtendableMessageEvent>(obj);
932
0
  // We don't want to preserve if we don't have a wrapper, and we
933
0
  // obviously can't preserve if we're not initialized.
934
0
  if (self && self->GetWrapperPreserveColor()) {
935
0
    PreserveWrapper(self);
936
0
  }
937
0
  return true;
938
0
}
939
940
static void
941
_finalize(js::FreeOp* fop, JSObject* obj)
942
0
{
943
0
  mozilla::dom::ExtendableMessageEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::ExtendableMessageEvent>(obj);
944
0
  if (self) {
945
0
    ClearWrapper(self, self, obj);
946
0
    AddForDeferredFinalization<mozilla::dom::ExtendableMessageEvent>(self);
947
0
  }
948
0
}
949
950
static size_t
951
_objectMoved(JSObject* obj, JSObject* old)
952
0
{
953
0
  mozilla::dom::ExtendableMessageEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::ExtendableMessageEvent>(obj);
954
0
  if (self) {
955
0
    UpdateWrapper(self, self, obj, old);
956
0
  }
957
0
958
0
  return 0;
959
0
}
960
961
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
962
#if defined(__clang__)
963
#pragma clang diagnostic push
964
#pragma clang diagnostic ignored "-Wmissing-braces"
965
#endif
966
static const JSPropertySpec sAttributes_specs[] = {
967
  { "data", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &data_getterinfo, nullptr, nullptr },
968
  { "origin", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &origin_getterinfo, nullptr, nullptr },
969
  { "lastEventId", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &lastEventId_getterinfo, nullptr, nullptr },
970
  { "source", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &source_getterinfo, nullptr, nullptr },
971
  { "ports", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &ports_getterinfo, nullptr, nullptr },
972
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
973
};
974
#if defined(__clang__)
975
#pragma clang diagnostic pop
976
#endif
977
978
979
static const Prefable<const JSPropertySpec> sAttributes[] = {
980
  { nullptr, &sAttributes_specs[0] },
981
  { nullptr, nullptr }
982
};
983
984
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
985
#if defined(__clang__)
986
#pragma clang diagnostic push
987
#pragma clang diagnostic ignored "-Wmissing-braces"
988
#endif
989
static const JSPropertySpec sUnforgeableAttributes_specs[] = {
990
  { "isTrusted", JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericGetter<NormalThisPolicy, ThrowExceptions>, &isTrusted_getterinfo, nullptr, nullptr },
991
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
992
};
993
#if defined(__clang__)
994
#pragma clang diagnostic pop
995
#endif
996
997
998
static const Prefable<const JSPropertySpec> sUnforgeableAttributes[] = {
999
  { nullptr, &sUnforgeableAttributes_specs[0] },
1000
  { nullptr, nullptr }
1001
};
1002
1003
1004
static const NativePropertiesN<2> sNativeProperties = {
1005
  false, 0,
1006
  false, 0,
1007
  false, 0,
1008
  true,  0 /* sAttributes */,
1009
  false, 0,
1010
  true,  1 /* sUnforgeableAttributes */,
1011
  false, 0,
1012
  -1,
1013
  0,
1014
  nullptr,
1015
  {
1016
    { sAttributes, nullptr },
1017
    { sUnforgeableAttributes, nullptr }
1018
  }
1019
};
1020
1021
static bool
1022
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
1023
0
{
1024
0
  AUTO_PROFILER_LABEL_FAST("ExtendableMessageEvent constructor", DOM, cx);
1025
0
1026
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
1027
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
1028
0
  if (!args.isConstructing()) {
1029
0
    // XXXbz wish I could get the name from the callee instead of
1030
0
    // Adding more relocations
1031
0
    return ThrowConstructorWithoutNew(cx, "ExtendableMessageEvent");
1032
0
  }
1033
0
1034
0
  JS::Rooted<JSObject*> desiredProto(cx);
1035
0
  if (!GetDesiredProto(cx, args, &desiredProto)) {
1036
0
    return false;
1037
0
  }
1038
0
1039
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
1040
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ExtendableMessageEvent");
1041
0
  }
1042
0
  GlobalObject global(cx, obj);
1043
0
  if (global.Failed()) {
1044
0
    return false;
1045
0
  }
1046
0
1047
0
  bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1048
0
  binding_detail::FakeString arg0;
1049
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
1050
0
    return false;
1051
0
  }
1052
0
  RootedDictionary<binding_detail::FastExtendableMessageEventInit> arg1(cx);
1053
0
  if (!arg1.Init(cx, (args.hasDefined(1)) ? args[1] : JS::NullHandleValue,  "Argument 2 of ExtendableMessageEvent.constructor", false)) {
1054
0
    return false;
1055
0
  }
1056
0
  Maybe<JSAutoRealm> ar;
1057
0
  if (objIsXray) {
1058
0
    obj = js::CheckedUnwrap(obj);
1059
0
    if (!obj) {
1060
0
      return false;
1061
0
    }
1062
0
    ar.emplace(cx, obj);
1063
0
    if (!JS_WrapObject(cx, &desiredProto)) {
1064
0
      return false;
1065
0
    }
1066
0
    if (!JS_WrapValue(cx, JS::MutableHandle<JS::Value>::fromMarkedLocation(&arg1.mData))) {
1067
0
      return false;
1068
0
    }
1069
0
  }
1070
0
  FastErrorResult rv;
1071
0
  auto result(StrongOrRawPtr<mozilla::dom::ExtendableMessageEvent>(mozilla::dom::ExtendableMessageEvent::Constructor(global, NonNullHelper(Constify(arg0)), Constify(arg1), rv)));
1072
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1073
0
    return false;
1074
0
  }
1075
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1076
0
  static_assert(!IsPointer<decltype(result)>::value,
1077
0
                "NewObject implies that we need to keep the object alive with a strong reference.");
1078
0
  if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
1079
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
1080
0
    return false;
1081
0
  }
1082
0
  return true;
1083
0
}
1084
1085
static const js::ClassOps sInterfaceObjectClassOps = {
1086
    nullptr,               /* addProperty */
1087
    nullptr,               /* delProperty */
1088
    nullptr,               /* enumerate */
1089
    nullptr,               /* newEnumerate */
1090
    nullptr,               /* resolve */
1091
    nullptr,               /* mayResolve */
1092
    nullptr,               /* finalize */
1093
    _constructor, /* call */
1094
    nullptr,               /* hasInstance */
1095
    _constructor, /* construct */
1096
    nullptr,               /* trace */
1097
};
1098
1099
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1100
  {
1101
    "Function",
1102
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1103
    &sInterfaceObjectClassOps,
1104
    JS_NULL_CLASS_SPEC,
1105
    JS_NULL_CLASS_EXT,
1106
    &sInterfaceObjectClassObjectOps
1107
  },
1108
  eInterface,
1109
  true,
1110
  prototypes::id::ExtendableMessageEvent,
1111
  PrototypeTraits<prototypes::id::ExtendableMessageEvent>::Depth,
1112
  &sEmptyNativePropertyHooks,
1113
  "function ExtendableMessageEvent() {\n    [native code]\n}",
1114
  ExtendableEvent_Binding::GetConstructorObject
1115
};
1116
1117
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1118
  {
1119
    "ExtendableMessageEventPrototype",
1120
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE + 1 /* slot for the JSObject holding the unforgeable properties */),
1121
    JS_NULL_CLASS_OPS,
1122
    JS_NULL_CLASS_SPEC,
1123
    JS_NULL_CLASS_EXT,
1124
    JS_NULL_OBJECT_OPS
1125
  },
1126
  eInterfacePrototype,
1127
  false,
1128
  prototypes::id::ExtendableMessageEvent,
1129
  PrototypeTraits<prototypes::id::ExtendableMessageEvent>::Depth,
1130
  &sEmptyNativePropertyHooks,
1131
  "[object ExtendableMessageEventPrototype]",
1132
  ExtendableEvent_Binding::GetProtoObject
1133
};
1134
1135
bool
1136
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
1137
0
{
1138
0
  MOZ_ASSERT(!NS_IsMainThread(), "Why did we even get called?");
1139
0
1140
0
  const char* name = js::GetObjectClass(aObj)->name;
1141
0
  if (strcmp(name, "ServiceWorkerGlobalScope")) {
1142
0
    return false;
1143
0
  }
1144
0
1145
0
  return true;
1146
0
}
1147
1148
static const js::ClassOps sClassOps = {
1149
  _addProperty, /* addProperty */
1150
  nullptr,               /* delProperty */
1151
  nullptr,               /* enumerate */
1152
  nullptr, /* newEnumerate */
1153
  nullptr, /* resolve */
1154
  nullptr, /* mayResolve */
1155
  _finalize, /* finalize */
1156
  nullptr, /* call */
1157
  nullptr,               /* hasInstance */
1158
  nullptr,               /* construct */
1159
  nullptr, /* trace */
1160
};
1161
1162
static const js::ClassExtension sClassExtension = {
1163
  nullptr, /* weakmapKeyDelegateOp */
1164
  _objectMoved /* objectMovedOp */
1165
};
1166
1167
static const DOMJSClass sClass = {
1168
  { "ExtendableMessageEvent",
1169
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_SKIP_NURSERY_FINALIZE,
1170
    &sClassOps,
1171
    JS_NULL_CLASS_SPEC,
1172
    &sClassExtension,
1173
    JS_NULL_OBJECT_OPS
1174
  },
1175
  { prototypes::id::Event, prototypes::id::ExtendableEvent, prototypes::id::ExtendableMessageEvent, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
1176
  IsBaseOf<nsISupports, mozilla::dom::ExtendableMessageEvent >::value,
1177
  &sEmptyNativePropertyHooks,
1178
  FindAssociatedGlobalForNative<mozilla::dom::ExtendableMessageEvent>::Get,
1179
  GetProtoObjectHandle,
1180
  GetCCParticipant<mozilla::dom::ExtendableMessageEvent>::Get()
1181
};
1182
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1183
              "Must have the right minimal number of reserved slots.");
1184
static_assert(2 >= 2,
1185
              "Must have enough reserved slots.");
1186
1187
const JSClass*
1188
GetJSClass()
1189
0
{
1190
0
  return sClass.ToJSClass();
1191
0
}
1192
1193
bool
1194
Wrap(JSContext* aCx, mozilla::dom::ExtendableMessageEvent* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1195
0
{
1196
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::ExtendableMessageEvent>::value,
1197
0
                "Shouldn't have wrappercached things that are not refcounted.");
1198
0
  MOZ_ASSERT(static_cast<mozilla::dom::ExtendableMessageEvent*>(aObject) ==
1199
0
             reinterpret_cast<mozilla::dom::ExtendableMessageEvent*>(aObject),
1200
0
             "Multiple inheritance for mozilla::dom::ExtendableMessageEvent is broken.");
1201
0
  MOZ_ASSERT(static_cast<mozilla::dom::ExtendableEvent*>(aObject) ==
1202
0
             reinterpret_cast<mozilla::dom::ExtendableEvent*>(aObject),
1203
0
             "Multiple inheritance for mozilla::dom::ExtendableEvent is broken.");
1204
0
  MOZ_ASSERT(static_cast<mozilla::dom::Event*>(aObject) ==
1205
0
             reinterpret_cast<mozilla::dom::Event*>(aObject),
1206
0
             "Multiple inheritance for mozilla::dom::Event is broken.");
1207
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1208
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1209
0
  MOZ_ASSERT(!aCache->GetWrapper(),
1210
0
             "You should probably not be using Wrap() directly; use "
1211
0
             "GetOrCreateDOMReflector instead");
1212
0
1213
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1214
0
             "nsISupports must be on our primary inheritance chain");
1215
0
1216
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1217
0
  if (!global) {
1218
0
    return false;
1219
0
  }
1220
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
1221
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
1222
0
1223
0
  // That might have ended up wrapping us already, due to the wonders
1224
0
  // of XBL.  Check for that, and bail out as needed.
1225
0
  aReflector.set(aCache->GetWrapper());
1226
0
  if (aReflector) {
1227
#ifdef DEBUG
1228
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1229
#endif // DEBUG
1230
    return true;
1231
0
  }
1232
0
1233
0
  JSAutoRealm ar(aCx, global);
1234
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1235
0
  if (!canonicalProto) {
1236
0
    return false;
1237
0
  }
1238
0
  JS::Rooted<JSObject*> proto(aCx);
1239
0
  if (aGivenProto) {
1240
0
    proto = aGivenProto;
1241
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
1242
0
    // coming in, we changed compartments to that of "parent" so may need
1243
0
    // to wrap the proto here.
1244
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1245
0
      if (!JS_WrapObject(aCx, &proto)) {
1246
0
        return false;
1247
0
      }
1248
0
    }
1249
0
  } else {
1250
0
    proto = canonicalProto;
1251
0
  }
1252
0
1253
0
  BindingJSObjectCreator<mozilla::dom::ExtendableMessageEvent> creator(aCx);
1254
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1255
0
  if (!aReflector) {
1256
0
    return false;
1257
0
  }
1258
0
1259
0
  aCache->SetWrapper(aReflector);
1260
0
1261
0
  // Important: do unforgeable property setup after we have handed
1262
0
  // over ownership of the C++ object to obj as needed, so that if
1263
0
  // we fail and it ends up GCed it won't have problems in the
1264
0
  // finalizer trying to drop its ownership of the C++ object.
1265
0
  JS::Rooted<JSObject*> unforgeableHolder(aCx,
1266
0
    &js::GetReservedSlot(canonicalProto, DOM_INTERFACE_PROTO_SLOTS_BASE).toObject());
1267
0
  if (!JS_InitializePropertiesFromCompatibleNativeObject(aCx, aReflector, unforgeableHolder)) {
1268
0
    aCache->ReleaseWrapper(aObject);
1269
0
    aCache->ClearWrapper();
1270
0
    return false;
1271
0
  }
1272
0
  creator.InitializationSucceeded();
1273
0
1274
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1275
0
             aCache->GetWrapperPreserveColor() == aReflector);
1276
0
  // If proto != canonicalProto, we have to preserve our wrapper;
1277
0
  // otherwise we won't be able to properly recreate it later, since
1278
0
  // we won't know what proto to use.  Note that we don't check
1279
0
  // aGivenProto here, since it's entirely possible (and even
1280
0
  // somewhat common) to have a non-null aGivenProto which is the
1281
0
  // same as canonicalProto.
1282
0
  if (proto != canonicalProto) {
1283
0
    PreserveWrapper(aObject);
1284
0
  }
1285
0
1286
0
  return true;
1287
0
}
1288
1289
void
1290
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1291
0
{
1292
0
  JS::Handle<JSObject*> parentProto(ExtendableEvent_Binding::GetProtoObjectHandle(aCx));
1293
0
  if (!parentProto) {
1294
0
    return;
1295
0
  }
1296
0
1297
0
  JS::Handle<JSObject*> constructorProto(ExtendableEvent_Binding::GetConstructorObjectHandle(aCx));
1298
0
  if (!constructorProto) {
1299
0
    return;
1300
0
  }
1301
0
1302
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::ExtendableMessageEvent);
1303
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::ExtendableMessageEvent);
1304
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1305
0
                              &sPrototypeClass.mBase, protoCache,
1306
0
                              nullptr,
1307
0
                              constructorProto, &sInterfaceObjectClass.mBase, 1, nullptr,
1308
0
                              interfaceCache,
1309
0
                              sNativeProperties.Upcast(),
1310
0
                              nullptr,
1311
0
                              "ExtendableMessageEvent", aDefineOnGlobal,
1312
0
                              nullptr,
1313
0
                              false);
1314
0
1315
0
  JS::Rooted<JSObject*> unforgeableHolder(aCx);
1316
0
  {
1317
0
    JS::Rooted<JSObject*> holderProto(aCx, *protoCache);
1318
0
    unforgeableHolder = JS_NewObjectWithoutMetadata(aCx, sClass.ToJSClass(), holderProto);
1319
0
    if (!unforgeableHolder) {
1320
0
      *protoCache = nullptr;
1321
0
      if (interfaceCache) {
1322
0
        *interfaceCache = nullptr;
1323
0
      }
1324
0
      return;
1325
0
    }
1326
0
  }
1327
0
1328
0
  if (!DefineUnforgeableAttributes(aCx, unforgeableHolder, sUnforgeableAttributes)) {
1329
0
    *protoCache = nullptr;
1330
0
    if (interfaceCache) {
1331
0
      *interfaceCache = nullptr;
1332
0
    }
1333
0
    return;
1334
0
  }
1335
0
1336
0
  if (*protoCache) {
1337
0
    js::SetReservedSlot(*protoCache, DOM_INTERFACE_PROTO_SLOTS_BASE,
1338
0
                        JS::ObjectValue(*unforgeableHolder));
1339
0
  }
1340
0
}
1341
1342
JSObject*
1343
GetConstructorObject(JSContext* aCx)
1344
0
{
1345
0
  return GetConstructorObjectHandle(aCx);
1346
0
}
1347
1348
} // namespace ExtendableMessageEvent_Binding
1349
1350
1351
1352
} // namespace dom
1353
} // namespace mozilla