Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/MessageEventBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM MessageEvent.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "AtomList.h"
4
#include "EventBinding.h"
5
#include "MessageEventBinding.h"
6
#include "WrapperFactory.h"
7
#include "XrayWrapper.h"
8
#include "mozilla/OwningNonNull.h"
9
#include "mozilla/dom/BindingUtils.h"
10
#include "mozilla/dom/DOMJSClass.h"
11
#include "mozilla/dom/MessageEvent.h"
12
#include "mozilla/dom/MessagePort.h"
13
#include "mozilla/dom/NonRefcountedDOMObject.h"
14
#include "mozilla/dom/Nullable.h"
15
#include "mozilla/dom/PrimitiveConversions.h"
16
#include "mozilla/dom/ScriptSettings.h"
17
#include "mozilla/dom/ServiceWorker.h"
18
#include "mozilla/dom/UnionConversions.h"
19
#include "mozilla/dom/XrayExpandoClass.h"
20
#include "nsPIDOMWindow.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
void
30
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningWindowProxyOrMessagePortOrServiceWorker& aUnion, const char* aName, uint32_t aFlags)
31
0
{
32
0
  if (aUnion.IsWindowProxy()) {
33
0
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsWindowProxy(), "mWindowProxy", aFlags);
34
0
  } else if (aUnion.IsMessagePort()) {
35
0
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsMessagePort(), "mMessagePort", aFlags);
36
0
  } else if (aUnion.IsServiceWorker()) {
37
0
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsServiceWorker(), "mServiceWorker", aFlags);
38
0
  }
39
0
}
40
41
42
void
43
ImplCycleCollectionUnlink(OwningWindowProxyOrMessagePortOrServiceWorker& aUnion)
44
0
{
45
0
  aUnion.Uninit();
46
0
}
47
48
49
bool
50
WindowProxyOrMessagePortOrServiceWorker::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
51
0
{
52
0
  switch (mType) {
53
0
    case eUninitialized: {
54
0
      return false;
55
0
      break;
56
0
    }
57
0
    case eWindowProxy: {
58
0
      if (!WrapObject(cx, mValue.mWindowProxy.Value(), rval)) {
59
0
        return false;
60
0
      }
61
0
      return true;
62
0
      break;
63
0
    }
64
0
    case eMessagePort: {
65
0
      if (!GetOrCreateDOMReflector(cx, mValue.mMessagePort.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 eServiceWorker: {
73
0
      if (!GetOrCreateDOMReflector(cx, mValue.mServiceWorker.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
RefPtr<nsPIDOMWindowOuter>&
91
OwningWindowProxyOrMessagePortOrServiceWorker::RawSetAsWindowProxy()
92
0
{
93
0
  if (mType == eWindowProxy) {
94
0
    return mValue.mWindowProxy.Value();
95
0
  }
96
0
  MOZ_ASSERT(mType == eUninitialized);
97
0
  mType = eWindowProxy;
98
0
  return mValue.mWindowProxy.SetValue();
99
0
}
100
101
RefPtr<nsPIDOMWindowOuter>&
102
OwningWindowProxyOrMessagePortOrServiceWorker::SetAsWindowProxy()
103
0
{
104
0
  if (mType == eWindowProxy) {
105
0
    return mValue.mWindowProxy.Value();
106
0
  }
107
0
  Uninit();
108
0
  mType = eWindowProxy;
109
0
  return mValue.mWindowProxy.SetValue();
110
0
}
111
112
bool
113
OwningWindowProxyOrMessagePortOrServiceWorker::TrySetToWindowProxy(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
114
0
{
115
0
  tryNext = false;
116
0
  { // scope for memberSlot
117
0
    RefPtr<nsPIDOMWindowOuter>& memberSlot = RawSetAsWindowProxy();
118
0
    static_assert(IsRefcounted<nsPIDOMWindowOuter>::value, "We can only store refcounted classes.");RefPtr<nsPIDOMWindowOuter> mWindowProxyHolder;
119
0
    JS::Rooted<JSObject*> source(cx, &value.toObject());
120
0
    if (NS_FAILED(UnwrapArg<nsPIDOMWindowOuter>(cx, source, getter_AddRefs(mWindowProxyHolder)))) {
121
0
      DestroyWindowProxy();
122
0
      tryNext = true;
123
0
      return true;
124
0
    }
125
0
    MOZ_ASSERT(mWindowProxyHolder);
126
0
    memberSlot = mWindowProxyHolder;
127
0
  }
128
0
  return true;
129
0
}
130
131
void
132
OwningWindowProxyOrMessagePortOrServiceWorker::DestroyWindowProxy()
133
0
{
134
0
  MOZ_ASSERT(IsWindowProxy(), "Wrong type!");
135
0
  mValue.mWindowProxy.Destroy();
136
0
  mType = eUninitialized;
137
0
}
138
139
140
141
142
OwningNonNull<mozilla::dom::MessagePort>&
143
OwningWindowProxyOrMessagePortOrServiceWorker::RawSetAsMessagePort()
144
0
{
145
0
  if (mType == eMessagePort) {
146
0
    return mValue.mMessagePort.Value();
147
0
  }
148
0
  MOZ_ASSERT(mType == eUninitialized);
149
0
  mType = eMessagePort;
150
0
  return mValue.mMessagePort.SetValue();
151
0
}
152
153
OwningNonNull<mozilla::dom::MessagePort>&
154
OwningWindowProxyOrMessagePortOrServiceWorker::SetAsMessagePort()
155
0
{
156
0
  if (mType == eMessagePort) {
157
0
    return mValue.mMessagePort.Value();
158
0
  }
159
0
  Uninit();
160
0
  mType = eMessagePort;
161
0
  return mValue.mMessagePort.SetValue();
162
0
}
163
164
bool
165
OwningWindowProxyOrMessagePortOrServiceWorker::TrySetToMessagePort(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
166
0
{
167
0
  tryNext = false;
168
0
  { // scope for memberSlot
169
0
    OwningNonNull<mozilla::dom::MessagePort>& memberSlot = RawSetAsMessagePort();
170
0
    static_assert(IsRefcounted<mozilla::dom::MessagePort>::value, "We can only store refcounted classes.");{
171
0
      nsresult rv = UnwrapObject<prototypes::id::MessagePort, mozilla::dom::MessagePort>(value, memberSlot);
172
0
      if (NS_FAILED(rv)) {
173
0
        DestroyMessagePort();
174
0
        tryNext = true;
175
0
        return true;
176
0
      }
177
0
    }
178
0
  }
179
0
  return true;
180
0
}
181
182
void
183
OwningWindowProxyOrMessagePortOrServiceWorker::DestroyMessagePort()
184
0
{
185
0
  MOZ_ASSERT(IsMessagePort(), "Wrong type!");
186
0
  mValue.mMessagePort.Destroy();
187
0
  mType = eUninitialized;
188
0
}
189
190
191
192
193
OwningNonNull<mozilla::dom::ServiceWorker>&
194
OwningWindowProxyOrMessagePortOrServiceWorker::RawSetAsServiceWorker()
195
0
{
196
0
  if (mType == eServiceWorker) {
197
0
    return mValue.mServiceWorker.Value();
198
0
  }
199
0
  MOZ_ASSERT(mType == eUninitialized);
200
0
  mType = eServiceWorker;
201
0
  return mValue.mServiceWorker.SetValue();
202
0
}
203
204
OwningNonNull<mozilla::dom::ServiceWorker>&
205
OwningWindowProxyOrMessagePortOrServiceWorker::SetAsServiceWorker()
206
0
{
207
0
  if (mType == eServiceWorker) {
208
0
    return mValue.mServiceWorker.Value();
209
0
  }
210
0
  Uninit();
211
0
  mType = eServiceWorker;
212
0
  return mValue.mServiceWorker.SetValue();
213
0
}
214
215
bool
216
OwningWindowProxyOrMessagePortOrServiceWorker::TrySetToServiceWorker(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
217
0
{
218
0
  tryNext = false;
219
0
  { // scope for memberSlot
220
0
    OwningNonNull<mozilla::dom::ServiceWorker>& memberSlot = RawSetAsServiceWorker();
221
0
    static_assert(IsRefcounted<mozilla::dom::ServiceWorker>::value, "We can only store refcounted classes.");{
222
0
      nsresult rv = UnwrapObject<prototypes::id::ServiceWorker, mozilla::dom::ServiceWorker>(value, memberSlot);
223
0
      if (NS_FAILED(rv)) {
224
0
        DestroyServiceWorker();
225
0
        tryNext = true;
226
0
        return true;
227
0
      }
228
0
    }
229
0
  }
230
0
  return true;
231
0
}
232
233
void
234
OwningWindowProxyOrMessagePortOrServiceWorker::DestroyServiceWorker()
235
0
{
236
0
  MOZ_ASSERT(IsServiceWorker(), "Wrong type!");
237
0
  mValue.mServiceWorker.Destroy();
238
0
  mType = eUninitialized;
239
0
}
240
241
242
243
244
void
245
OwningWindowProxyOrMessagePortOrServiceWorker::Uninit()
246
{
247
  switch (mType) {
248
    case eUninitialized: {
249
      break;
250
    }
251
    case eWindowProxy: {
252
      DestroyWindowProxy();
253
      break;
254
    }
255
    case eMessagePort: {
256
      DestroyMessagePort();
257
      break;
258
    }
259
    case eServiceWorker: {
260
      DestroyServiceWorker();
261
      break;
262
    }
263
  }
264
}
265
266
bool
267
OwningWindowProxyOrMessagePortOrServiceWorker::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
268
0
{
269
0
  switch (mType) {
270
0
    case eUninitialized: {
271
0
      return false;
272
0
      break;
273
0
    }
274
0
    case eWindowProxy: {
275
0
      if (!WrapObject(cx, mValue.mWindowProxy.Value(), rval)) {
276
0
        return false;
277
0
      }
278
0
      return true;
279
0
      break;
280
0
    }
281
0
    case eMessagePort: {
282
0
      if (!GetOrCreateDOMReflector(cx, mValue.mMessagePort.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 eServiceWorker: {
290
0
      if (!GetOrCreateDOMReflector(cx, mValue.mServiceWorker.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
OwningWindowProxyOrMessagePortOrServiceWorker::TraceUnion(JSTracer* trc)
308
0
{
309
0
}
310
311
OwningWindowProxyOrMessagePortOrServiceWorker&
312
OwningWindowProxyOrMessagePortOrServiceWorker::operator=(const OwningWindowProxyOrMessagePortOrServiceWorker& 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 eWindowProxy: {
321
0
      SetAsWindowProxy() = aOther.GetAsWindowProxy();
322
0
      break;
323
0
    }
324
0
    case eMessagePort: {
325
0
      SetAsMessagePort() = aOther.GetAsMessagePort();
326
0
      break;
327
0
    }
328
0
    case eServiceWorker: {
329
0
      SetAsServiceWorker() = aOther.GetAsServiceWorker();
330
0
      break;
331
0
    }
332
0
  }
333
0
  return *this;
334
0
}
335
336
337
338
MessageEventInit::MessageEventInit()
339
  : EventInit(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
MessageEventInit::InitIds(JSContext* cx, MessageEventInitAtoms* 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
MessageEventInit::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
  MessageEventInitAtoms* atomsCache = nullptr;
373
0
  if (cx) {
374
0
    atomsCache = GetAtomCache<MessageEventInitAtoms>(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 (!EventInit::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 MessageEventInit");
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 MessageEventInit");
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 MessageEventInit", "MessagePort");
484
0
              return false;
485
0
            }
486
0
          }
487
0
        } else {
488
0
          ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Element of 'ports' member of MessageEventInit");
489
0
          return false;
490
0
        }
491
0
      }
492
0
    } else {
493
0
      ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'ports' member of MessageEventInit");
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().TrySetToWindowProxy(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
513
0
               (failed = !mSource.SetValue().TrySetToMessagePort(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
514
0
               (failed = !mSource.SetValue().TrySetToServiceWorker(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 MessageEventInit", "WindowProxy, MessagePort, ServiceWorker");
522
0
        return false;
523
0
      }
524
0
    }
525
0
  }
526
0
  mIsAnyMemberPresent = true;
527
0
  return true;
528
0
}
529
530
bool
531
MessageEventInit::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
532
0
{
533
0
  MessageEventInitAtoms* atomsCache = GetAtomCache<MessageEventInitAtoms>(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 (!EventInit::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<OwningWindowProxyOrMessagePortOrServiceWorker > 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
MessageEventInit::TraceDictionary(JSTracer* trc)
646
0
{
647
0
  EventInit::TraceDictionary(trc);
648
0
  JS::UnsafeTraceRoot(trc, &mData, "MessageEventInit.mData");
649
0
}
650
651
652
653
namespace binding_detail {
654
} // namespace binding_detail
655
656
657
namespace MessageEvent_Binding {
658
659
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<Event_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::MessageEvent* self, JSJitGetterCallArgs args)
664
0
{
665
0
  AUTO_PROFILER_LABEL_FAST("get MessageEvent.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::MessageEvent },
685
  { PrototypeTraits<prototypes::id::MessageEvent>::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::MessageEvent* self, JSJitGetterCallArgs args)
702
0
{
703
0
  AUTO_PROFILER_LABEL_FAST("get MessageEvent.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::MessageEvent },
717
  { PrototypeTraits<prototypes::id::MessageEvent>::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::MessageEvent* self, JSJitGetterCallArgs args)
734
0
{
735
0
  AUTO_PROFILER_LABEL_FAST("get MessageEvent.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::MessageEvent },
749
  { PrototypeTraits<prototypes::id::MessageEvent>::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::MessageEvent* self, JSJitGetterCallArgs args)
766
0
{
767
0
  AUTO_PROFILER_LABEL_FAST("get MessageEvent.source", DOM, cx);
768
0
769
0
  Nullable<OwningWindowProxyOrMessagePortOrServiceWorker> 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::MessageEvent },
785
  { PrototypeTraits<prototypes::id::MessageEvent>::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::MessageEvent* self, JSJitGetterCallArgs args)
802
0
{
803
0
  AUTO_PROFILER_LABEL_FAST("get MessageEvent.ports", DOM, cx);
804
0
805
0
  // Have to either root across the getter call or reget after.
806
0
  bool isXray;
807
0
  JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
808
0
  if (!slotStorage) {
809
0
    return false;
810
0
  }
811
0
  const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 0) : (DOM_INSTANCE_RESERVED_SLOTS + 0);
812
0
  MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
813
0
  {
814
0
    // Scope for cachedVal
815
0
    JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
816
0
    if (!cachedVal.isUndefined()) {
817
0
      args.rval().set(cachedVal);
818
0
      // The cached value is in the compartment of slotStorage,
819
0
      // so wrap into the caller compartment as needed.
820
0
      if (MaybeWrapNonDOMObjectValue(cx, args.rval())) {
821
0
        return true;
822
0
      }
823
0
      return false;
824
0
    }
825
0
  }
826
0
827
0
  nsTArray<StrongPtrForMember<mozilla::dom::MessagePort>::Type> result;
828
0
  self->GetPorts(result);
829
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
830
0
  {
831
0
    JS::Rooted<JSObject*> conversionScope(cx, isXray ? JS::CurrentGlobalOrNull(cx) : slotStorage);
832
0
    JSAutoRealm ar(cx, conversionScope);
833
0
    do { // block we break out of when done wrapping
834
0
835
0
      uint32_t length = result.Length();
836
0
      JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
837
0
      if (!returnArray) {
838
0
        return false;
839
0
      }
840
0
      // Scope for 'tmp'
841
0
      {
842
0
        JS::Rooted<JS::Value> tmp(cx);
843
0
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
844
0
          // Control block to let us common up the JS_DefineElement calls when there
845
0
          // are different ways to succeed at wrapping the object.
846
0
          do {
847
0
            if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) {
848
0
              MOZ_ASSERT(JS_IsExceptionPending(cx));
849
0
              return false;
850
0
            }
851
0
            break;
852
0
          } while (false);
853
0
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
854
0
                                JSPROP_ENUMERATE)) {
855
0
            return false;
856
0
          }
857
0
        }
858
0
      }
859
0
      args.rval().setObject(*returnArray);
860
0
      break;
861
0
    } while (false);
862
0
    JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
863
0
    if (!JS_FreezeObject(cx, rvalObj)) {
864
0
      return false;
865
0
    }
866
0
  }
867
0
  { // And now store things in the realm of our slotStorage.
868
0
    JSAutoRealm ar(cx, slotStorage);
869
0
    // Make a copy so that we don't do unnecessary wrapping on args.rval().
870
0
    JS::Rooted<JS::Value> storedVal(cx, args.rval());
871
0
    if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
872
0
      return false;
873
0
    }
874
0
    js::SetReservedSlot(slotStorage, slotIndex, storedVal);
875
0
    if (!isXray) {
876
0
      // In the Xray case we don't need to do this, because getting the
877
0
      // expando object already preserved our wrapper.
878
0
      PreserveWrapper(self);
879
0
    }
880
0
  }
881
0
  // And now make sure args.rval() is in the caller realm.
882
0
  if (MaybeWrapNonDOMObjectValue(cx, args.rval())) {
883
0
    return true;
884
0
  }
885
0
  return false;
886
0
}
887
888
static const JSJitInfo ports_getterinfo = {
889
  { (JSJitGetterOp)get_ports },
890
  { prototypes::id::MessageEvent },
891
  { PrototypeTraits<prototypes::id::MessageEvent>::Depth },
892
  JSJitInfo::Getter,
893
  JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
894
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
895
  false,  /* isInfallible. False in setters. */
896
  true,  /* isMovable.  Not relevant for setters. */
897
  true, /* isEliminatable.  Not relevant for setters. */
898
  false, /* isAlwaysInSlot.  Only relevant for getters. */
899
  true, /* isLazilyCachedInSlot.  Only relevant for getters. */
900
  false,  /* isTypedMethod.  Only relevant for methods. */
901
  (DOM_INSTANCE_RESERVED_SLOTS + 0)   /* Reserved slot index, if we're stored in a slot, else 0. */
902
};
903
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit");
904
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 2, "There is no slot for us");
905
906
MOZ_CAN_RUN_SCRIPT static bool
907
initMessageEvent(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::MessageEvent* self, const JSJitMethodCallArgs& args)
908
0
{
909
0
  AUTO_PROFILER_LABEL_FAST("MessageEvent.initMessageEvent", DOM, cx);
910
0
911
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
912
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "MessageEvent.initMessageEvent");
913
0
  }
914
0
  binding_detail::FakeString arg0;
915
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
916
0
    return false;
917
0
  }
918
0
  bool arg1;
919
0
  if (args.hasDefined(1)) {
920
0
    if (!ValueToPrimitive<bool, eDefault>(cx, args[1], &arg1)) {
921
0
      return false;
922
0
    }
923
0
  } else {
924
0
    arg1 = false;
925
0
  }
926
0
  bool arg2;
927
0
  if (args.hasDefined(2)) {
928
0
    if (!ValueToPrimitive<bool, eDefault>(cx, args[2], &arg2)) {
929
0
      return false;
930
0
    }
931
0
  } else {
932
0
    arg2 = false;
933
0
  }
934
0
  JS::Rooted<JS::Value> arg3(cx);
935
0
  if (args.hasDefined(3)) {
936
0
    arg3 = args[3];
937
0
  } else {
938
0
    arg3 = JS::NullValue();
939
0
  }
940
0
  binding_detail::FakeString arg4;
941
0
  if (args.hasDefined(4)) {
942
0
    if (!ConvertJSValueToString(cx, args[4], eStringify, eStringify, arg4)) {
943
0
      return false;
944
0
    }
945
0
  } else {
946
0
    static const char16_t data[] = { 0 };
947
0
    arg4.Rebind(data, ArrayLength(data) - 1);
948
0
  }
949
0
  binding_detail::FakeString arg5;
950
0
  if (args.hasDefined(5)) {
951
0
    if (!ConvertJSValueToString(cx, args[5], eStringify, eStringify, arg5)) {
952
0
      return false;
953
0
    }
954
0
  } else {
955
0
    static const char16_t data[] = { 0 };
956
0
    arg5.Rebind(data, ArrayLength(data) - 1);
957
0
  }
958
0
  Nullable<WindowProxyOrMessagePortOrServiceWorker > arg6;
959
0
  Maybe<WindowProxyOrMessagePortOrServiceWorkerArgument> arg6_holder;
960
0
  if (!(args.hasDefined(6)) || args[6].isNullOrUndefined()) {
961
0
    arg6.SetNull();
962
0
  } else {
963
0
    arg6_holder.emplace(arg6.SetValue());
964
0
    {
965
0
      bool done = false, failed = false, tryNext;
966
0
      if (args[6].isObject()) {
967
0
        done = (failed = !arg6_holder.ref().TrySetToWindowProxy(cx, args[6], tryNext, false)) || !tryNext ||
968
0
               (failed = !arg6_holder.ref().TrySetToMessagePort(cx, args[6], tryNext, false)) || !tryNext ||
969
0
               (failed = !arg6_holder.ref().TrySetToServiceWorker(cx, args[6], tryNext, false)) || !tryNext;
970
0
971
0
      }
972
0
      if (failed) {
973
0
        return false;
974
0
      }
975
0
      if (!done) {
976
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 7 of MessageEvent.initMessageEvent", "WindowProxy, MessagePort, ServiceWorker");
977
0
        return false;
978
0
      }
979
0
    }
980
0
  }
981
0
  binding_detail::AutoSequence<OwningNonNull<mozilla::dom::MessagePort>> arg7;
982
0
  if (args.hasDefined(7)) {
983
0
    if (args[7].isObject()) {
984
0
      JS::ForOfIterator iter(cx);
985
0
      if (!iter.init(args[7], JS::ForOfIterator::AllowNonIterable)) {
986
0
        return false;
987
0
      }
988
0
      if (!iter.valueIsIterable()) {
989
0
        ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 8 of MessageEvent.initMessageEvent");
990
0
        return false;
991
0
      }
992
0
      binding_detail::AutoSequence<OwningNonNull<mozilla::dom::MessagePort>> &arr = arg7;
993
0
      JS::Rooted<JS::Value> temp(cx);
994
0
      while (true) {
995
0
        bool done;
996
0
        if (!iter.next(&temp, &done)) {
997
0
          return false;
998
0
        }
999
0
        if (done) {
1000
0
          break;
1001
0
        }
1002
0
        OwningNonNull<mozilla::dom::MessagePort>* slotPtr = arr.AppendElement(mozilla::fallible);
1003
0
        if (!slotPtr) {
1004
0
          JS_ReportOutOfMemory(cx);
1005
0
          return false;
1006
0
        }
1007
0
        OwningNonNull<mozilla::dom::MessagePort>& slot = *slotPtr;
1008
0
        if (temp.isObject()) {
1009
0
          static_assert(IsRefcounted<mozilla::dom::MessagePort>::value, "We can only store refcounted classes.");{
1010
0
            nsresult rv = UnwrapObject<prototypes::id::MessagePort, mozilla::dom::MessagePort>(&temp, slot);
1011
0
            if (NS_FAILED(rv)) {
1012
0
              ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Element of argument 8 of MessageEvent.initMessageEvent", "MessagePort");
1013
0
              return false;
1014
0
            }
1015
0
          }
1016
0
        } else {
1017
0
          ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Element of argument 8 of MessageEvent.initMessageEvent");
1018
0
          return false;
1019
0
        }
1020
0
      }
1021
0
    } else {
1022
0
      ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 8 of MessageEvent.initMessageEvent");
1023
0
      return false;
1024
0
    }
1025
0
  } else {
1026
0
    /* Array is already empty; nothing to do */
1027
0
  }
1028
0
  self->InitMessageEvent(cx, NonNullHelper(Constify(arg0)), arg1, arg2, arg3, NonNullHelper(Constify(arg4)), NonNullHelper(Constify(arg5)), Constify(arg6), Constify(arg7));
1029
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1030
0
  args.rval().setUndefined();
1031
0
  return true;
1032
0
}
1033
1034
static const JSJitInfo initMessageEvent_methodinfo = {
1035
  { (JSJitGetterOp)initMessageEvent },
1036
  { prototypes::id::MessageEvent },
1037
  { PrototypeTraits<prototypes::id::MessageEvent>::Depth },
1038
  JSJitInfo::Method,
1039
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
1040
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
1041
  false,  /* isInfallible. False in setters. */
1042
  false,  /* isMovable.  Not relevant for setters. */
1043
  false, /* isEliminatable.  Not relevant for setters. */
1044
  false, /* isAlwaysInSlot.  Only relevant for getters. */
1045
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
1046
  false,  /* isTypedMethod.  Only relevant for methods. */
1047
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
1048
};
1049
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1050
static_assert(0 < 2, "There is no slot for us");
1051
1052
MOZ_CAN_RUN_SCRIPT static bool
1053
get_isTrusted(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::MessageEvent* self, JSJitGetterCallArgs args)
1054
0
{
1055
0
  AUTO_PROFILER_LABEL_FAST("get MessageEvent.isTrusted", DOM, cx);
1056
0
1057
0
  bool result(self->IsTrusted());
1058
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1059
0
  args.rval().setBoolean(result);
1060
0
  return true;
1061
0
}
1062
1063
static const JSJitInfo isTrusted_getterinfo = {
1064
  { (JSJitGetterOp)get_isTrusted },
1065
  { prototypes::id::MessageEvent },
1066
  { PrototypeTraits<prototypes::id::MessageEvent>::Depth },
1067
  JSJitInfo::Getter,
1068
  JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
1069
  JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
1070
  true,  /* isInfallible. False in setters. */
1071
  true,  /* isMovable.  Not relevant for setters. */
1072
  true, /* isEliminatable.  Not relevant for setters. */
1073
  false, /* isAlwaysInSlot.  Only relevant for getters. */
1074
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
1075
  false,  /* isTypedMethod.  Only relevant for methods. */
1076
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
1077
};
1078
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1079
static_assert(0 < 2, "There is no slot for us");
1080
1081
static bool
1082
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
1083
0
{
1084
0
  mozilla::dom::MessageEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::MessageEvent>(obj);
1085
0
  // We don't want to preserve if we don't have a wrapper, and we
1086
0
  // obviously can't preserve if we're not initialized.
1087
0
  if (self && self->GetWrapperPreserveColor()) {
1088
0
    PreserveWrapper(self);
1089
0
  }
1090
0
  return true;
1091
0
}
1092
1093
static void
1094
_finalize(js::FreeOp* fop, JSObject* obj)
1095
0
{
1096
0
  mozilla::dom::MessageEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::MessageEvent>(obj);
1097
0
  if (self) {
1098
0
    ClearWrapper(self, self, obj);
1099
0
    AddForDeferredFinalization<mozilla::dom::MessageEvent>(self);
1100
0
  }
1101
0
}
1102
1103
static size_t
1104
_objectMoved(JSObject* obj, JSObject* old)
1105
0
{
1106
0
  mozilla::dom::MessageEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::MessageEvent>(obj);
1107
0
  if (self) {
1108
0
    UpdateWrapper(self, self, obj, old);
1109
0
  }
1110
0
1111
0
  return 0;
1112
0
}
1113
1114
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
1115
#if defined(__clang__)
1116
#pragma clang diagnostic push
1117
#pragma clang diagnostic ignored "-Wmissing-braces"
1118
#endif
1119
static const JSFunctionSpec sMethods_specs[] = {
1120
  JS_FNSPEC("initMessageEvent", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&initMessageEvent_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
1121
  JS_FS_END
1122
};
1123
#if defined(__clang__)
1124
#pragma clang diagnostic pop
1125
#endif
1126
1127
1128
static const Prefable<const JSFunctionSpec> sMethods[] = {
1129
  { nullptr, &sMethods_specs[0] },
1130
  { nullptr, nullptr }
1131
};
1132
1133
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1134
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1135
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1136
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1137
1138
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
1139
#if defined(__clang__)
1140
#pragma clang diagnostic push
1141
#pragma clang diagnostic ignored "-Wmissing-braces"
1142
#endif
1143
static const JSPropertySpec sAttributes_specs[] = {
1144
  { "data", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &data_getterinfo, nullptr, nullptr },
1145
  { "origin", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &origin_getterinfo, nullptr, nullptr },
1146
  { "lastEventId", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &lastEventId_getterinfo, nullptr, nullptr },
1147
  { "source", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &source_getterinfo, nullptr, nullptr },
1148
  { "ports", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &ports_getterinfo, nullptr, nullptr },
1149
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
1150
};
1151
#if defined(__clang__)
1152
#pragma clang diagnostic pop
1153
#endif
1154
1155
1156
static const Prefable<const JSPropertySpec> sAttributes[] = {
1157
  { nullptr, &sAttributes_specs[0] },
1158
  { nullptr, nullptr }
1159
};
1160
1161
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1162
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1163
static_assert(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1164
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1165
1166
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
1167
#if defined(__clang__)
1168
#pragma clang diagnostic push
1169
#pragma clang diagnostic ignored "-Wmissing-braces"
1170
#endif
1171
static const JSPropertySpec sUnforgeableAttributes_specs[] = {
1172
  { "isTrusted", JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericGetter<NormalThisPolicy, ThrowExceptions>, &isTrusted_getterinfo, nullptr, nullptr },
1173
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
1174
};
1175
#if defined(__clang__)
1176
#pragma clang diagnostic pop
1177
#endif
1178
1179
1180
static const Prefable<const JSPropertySpec> sUnforgeableAttributes[] = {
1181
  { nullptr, &sUnforgeableAttributes_specs[0] },
1182
  { nullptr, nullptr }
1183
};
1184
1185
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1186
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1187
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1188
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1189
1190
1191
static uint16_t sNativeProperties_sortedPropertyIndices[7];
1192
static PropertyInfo sNativeProperties_propertyInfos[7];
1193
1194
static const NativePropertiesN<3> sNativeProperties = {
1195
  false, 0,
1196
  false, 0,
1197
  true,  0 /* sMethods */,
1198
  true,  1 /* sAttributes */,
1199
  false, 0,
1200
  true,  2 /* sUnforgeableAttributes */,
1201
  false, 0,
1202
  -1,
1203
  7,
1204
  sNativeProperties_sortedPropertyIndices,
1205
  {
1206
    { sMethods, &sNativeProperties_propertyInfos[0] },
1207
    { sAttributes, &sNativeProperties_propertyInfos[1] },
1208
    { sUnforgeableAttributes, &sNativeProperties_propertyInfos[6] }
1209
  }
1210
};
1211
static_assert(7 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
1212
    "We have a property info count that is oversized");
1213
1214
static bool
1215
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
1216
0
{
1217
0
  AUTO_PROFILER_LABEL_FAST("MessageEvent constructor", DOM, cx);
1218
0
1219
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
1220
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
1221
0
  if (!args.isConstructing()) {
1222
0
    // XXXbz wish I could get the name from the callee instead of
1223
0
    // Adding more relocations
1224
0
    return ThrowConstructorWithoutNew(cx, "MessageEvent");
1225
0
  }
1226
0
1227
0
  JS::Rooted<JSObject*> desiredProto(cx);
1228
0
  if (!GetDesiredProto(cx, args, &desiredProto)) {
1229
0
    return false;
1230
0
  }
1231
0
1232
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
1233
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "MessageEvent");
1234
0
  }
1235
0
  GlobalObject global(cx, obj);
1236
0
  if (global.Failed()) {
1237
0
    return false;
1238
0
  }
1239
0
1240
0
  bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1241
0
  binding_detail::FakeString arg0;
1242
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
1243
0
    return false;
1244
0
  }
1245
0
  RootedDictionary<binding_detail::FastMessageEventInit> arg1(cx);
1246
0
  if (!arg1.Init(cx, (args.hasDefined(1)) ? args[1] : JS::NullHandleValue,  "Argument 2 of MessageEvent.constructor", false)) {
1247
0
    return false;
1248
0
  }
1249
0
  Maybe<JSAutoRealm> ar;
1250
0
  if (objIsXray) {
1251
0
    obj = js::CheckedUnwrap(obj);
1252
0
    if (!obj) {
1253
0
      return false;
1254
0
    }
1255
0
    ar.emplace(cx, obj);
1256
0
    if (!JS_WrapObject(cx, &desiredProto)) {
1257
0
      return false;
1258
0
    }
1259
0
    if (!JS_WrapValue(cx, JS::MutableHandle<JS::Value>::fromMarkedLocation(&arg1.mData))) {
1260
0
      return false;
1261
0
    }
1262
0
  }
1263
0
  FastErrorResult rv;
1264
0
  auto result(StrongOrRawPtr<mozilla::dom::MessageEvent>(mozilla::dom::MessageEvent::Constructor(global, NonNullHelper(Constify(arg0)), Constify(arg1), rv)));
1265
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1266
0
    return false;
1267
0
  }
1268
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1269
0
  static_assert(!IsPointer<decltype(result)>::value,
1270
0
                "NewObject implies that we need to keep the object alive with a strong reference.");
1271
0
  if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
1272
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
1273
0
    return false;
1274
0
  }
1275
0
  return true;
1276
0
}
1277
1278
static const js::ClassOps sInterfaceObjectClassOps = {
1279
    nullptr,               /* addProperty */
1280
    nullptr,               /* delProperty */
1281
    nullptr,               /* enumerate */
1282
    nullptr,               /* newEnumerate */
1283
    nullptr,               /* resolve */
1284
    nullptr,               /* mayResolve */
1285
    nullptr,               /* finalize */
1286
    _constructor, /* call */
1287
    nullptr,               /* hasInstance */
1288
    _constructor, /* construct */
1289
    nullptr,               /* trace */
1290
};
1291
1292
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1293
  {
1294
    "Function",
1295
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1296
    &sInterfaceObjectClassOps,
1297
    JS_NULL_CLASS_SPEC,
1298
    JS_NULL_CLASS_EXT,
1299
    &sInterfaceObjectClassObjectOps
1300
  },
1301
  eInterface,
1302
  true,
1303
  prototypes::id::MessageEvent,
1304
  PrototypeTraits<prototypes::id::MessageEvent>::Depth,
1305
  sNativePropertyHooks,
1306
  "function MessageEvent() {\n    [native code]\n}",
1307
  Event_Binding::GetConstructorObject
1308
};
1309
1310
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1311
  {
1312
    "MessageEventPrototype",
1313
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE + 1 /* slot for the JSObject holding the unforgeable properties */),
1314
    JS_NULL_CLASS_OPS,
1315
    JS_NULL_CLASS_SPEC,
1316
    JS_NULL_CLASS_EXT,
1317
    JS_NULL_OBJECT_OPS
1318
  },
1319
  eInterfacePrototype,
1320
  false,
1321
  prototypes::id::MessageEvent,
1322
  PrototypeTraits<prototypes::id::MessageEvent>::Depth,
1323
  sNativePropertyHooks,
1324
  "[object MessageEventPrototype]",
1325
  Event_Binding::GetProtoObject
1326
};
1327
1328
static const js::ClassOps sClassOps = {
1329
  _addProperty, /* addProperty */
1330
  nullptr,               /* delProperty */
1331
  nullptr,               /* enumerate */
1332
  nullptr, /* newEnumerate */
1333
  nullptr, /* resolve */
1334
  nullptr, /* mayResolve */
1335
  _finalize, /* finalize */
1336
  nullptr, /* call */
1337
  nullptr,               /* hasInstance */
1338
  nullptr,               /* construct */
1339
  nullptr, /* trace */
1340
};
1341
1342
static const js::ClassExtension sClassExtension = {
1343
  nullptr, /* weakmapKeyDelegateOp */
1344
  _objectMoved /* objectMovedOp */
1345
};
1346
1347
static const DOMJSClass sClass = {
1348
  { "MessageEvent",
1349
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_SKIP_NURSERY_FINALIZE,
1350
    &sClassOps,
1351
    JS_NULL_CLASS_SPEC,
1352
    &sClassExtension,
1353
    JS_NULL_OBJECT_OPS
1354
  },
1355
  { prototypes::id::Event, prototypes::id::MessageEvent, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
1356
  IsBaseOf<nsISupports, mozilla::dom::MessageEvent >::value,
1357
  sNativePropertyHooks,
1358
  FindAssociatedGlobalForNative<mozilla::dom::MessageEvent>::Get,
1359
  GetProtoObjectHandle,
1360
  GetCCParticipant<mozilla::dom::MessageEvent>::Get()
1361
};
1362
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1363
              "Must have the right minimal number of reserved slots.");
1364
static_assert(2 >= 2,
1365
              "Must have enough reserved slots.");
1366
1367
const JSClass*
1368
GetJSClass()
1369
0
{
1370
0
  return sClass.ToJSClass();
1371
0
}
1372
1373
bool
1374
Wrap(JSContext* aCx, mozilla::dom::MessageEvent* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1375
0
{
1376
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::MessageEvent>::value,
1377
0
                "Shouldn't have wrappercached things that are not refcounted.");
1378
0
  MOZ_ASSERT(static_cast<mozilla::dom::MessageEvent*>(aObject) ==
1379
0
             reinterpret_cast<mozilla::dom::MessageEvent*>(aObject),
1380
0
             "Multiple inheritance for mozilla::dom::MessageEvent is broken.");
1381
0
  MOZ_ASSERT(static_cast<mozilla::dom::Event*>(aObject) ==
1382
0
             reinterpret_cast<mozilla::dom::Event*>(aObject),
1383
0
             "Multiple inheritance for mozilla::dom::Event is broken.");
1384
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1385
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1386
0
  MOZ_ASSERT(!aCache->GetWrapper(),
1387
0
             "You should probably not be using Wrap() directly; use "
1388
0
             "GetOrCreateDOMReflector instead");
1389
0
1390
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1391
0
             "nsISupports must be on our primary inheritance chain");
1392
0
1393
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1394
0
  if (!global) {
1395
0
    return false;
1396
0
  }
1397
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
1398
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
1399
0
1400
0
  // That might have ended up wrapping us already, due to the wonders
1401
0
  // of XBL.  Check for that, and bail out as needed.
1402
0
  aReflector.set(aCache->GetWrapper());
1403
0
  if (aReflector) {
1404
#ifdef DEBUG
1405
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1406
#endif // DEBUG
1407
    return true;
1408
0
  }
1409
0
1410
0
  JSAutoRealm ar(aCx, global);
1411
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1412
0
  if (!canonicalProto) {
1413
0
    return false;
1414
0
  }
1415
0
  JS::Rooted<JSObject*> proto(aCx);
1416
0
  if (aGivenProto) {
1417
0
    proto = aGivenProto;
1418
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
1419
0
    // coming in, we changed compartments to that of "parent" so may need
1420
0
    // to wrap the proto here.
1421
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1422
0
      if (!JS_WrapObject(aCx, &proto)) {
1423
0
        return false;
1424
0
      }
1425
0
    }
1426
0
  } else {
1427
0
    proto = canonicalProto;
1428
0
  }
1429
0
1430
0
  BindingJSObjectCreator<mozilla::dom::MessageEvent> creator(aCx);
1431
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1432
0
  if (!aReflector) {
1433
0
    return false;
1434
0
  }
1435
0
1436
0
  aCache->SetWrapper(aReflector);
1437
0
1438
0
  // Important: do unforgeable property setup after we have handed
1439
0
  // over ownership of the C++ object to obj as needed, so that if
1440
0
  // we fail and it ends up GCed it won't have problems in the
1441
0
  // finalizer trying to drop its ownership of the C++ object.
1442
0
  JS::Rooted<JSObject*> unforgeableHolder(aCx,
1443
0
    &js::GetReservedSlot(canonicalProto, DOM_INTERFACE_PROTO_SLOTS_BASE).toObject());
1444
0
  if (!JS_InitializePropertiesFromCompatibleNativeObject(aCx, aReflector, unforgeableHolder)) {
1445
0
    aCache->ReleaseWrapper(aObject);
1446
0
    aCache->ClearWrapper();
1447
0
    return false;
1448
0
  }
1449
0
  creator.InitializationSucceeded();
1450
0
1451
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1452
0
             aCache->GetWrapperPreserveColor() == aReflector);
1453
0
  // If proto != canonicalProto, we have to preserve our wrapper;
1454
0
  // otherwise we won't be able to properly recreate it later, since
1455
0
  // we won't know what proto to use.  Note that we don't check
1456
0
  // aGivenProto here, since it's entirely possible (and even
1457
0
  // somewhat common) to have a non-null aGivenProto which is the
1458
0
  // same as canonicalProto.
1459
0
  if (proto != canonicalProto) {
1460
0
    PreserveWrapper(aObject);
1461
0
  }
1462
0
1463
0
  return true;
1464
0
}
1465
1466
// This may allocate too many slots, because we only really need
1467
// slots for our non-interface-typed members that we cache.  But
1468
// allocating slots only for those would make the slot index
1469
// computations much more complicated, so let's do this the simple
1470
// way for now.
1471
DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 1);
1472
1473
const NativePropertyHooks sNativePropertyHooks[] = { {
1474
  nullptr,
1475
  nullptr,
1476
  nullptr,
1477
  { sNativeProperties.Upcast(), nullptr },
1478
  prototypes::id::MessageEvent,
1479
  constructors::id::MessageEvent,
1480
  Event_Binding::sNativePropertyHooks,
1481
  &sXrayExpandoObjectClass
1482
} };
1483
1484
void
1485
ClearCachedPortsValue(mozilla::dom::MessageEvent* aObject)
1486
0
{
1487
0
  JSObject* obj;
1488
0
  obj = aObject->GetWrapper();
1489
0
  if (!obj) {
1490
0
    return;
1491
0
  }
1492
0
  js::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), JS::UndefinedValue());
1493
0
  xpc::ClearXrayExpandoSlots(obj, (xpc::JSSLOT_EXPANDO_COUNT + 0));
1494
0
}
1495
1496
void
1497
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1498
0
{
1499
0
  JS::Handle<JSObject*> parentProto(Event_Binding::GetProtoObjectHandle(aCx));
1500
0
  if (!parentProto) {
1501
0
    return;
1502
0
  }
1503
0
1504
0
  JS::Handle<JSObject*> constructorProto(Event_Binding::GetConstructorObjectHandle(aCx));
1505
0
  if (!constructorProto) {
1506
0
    return;
1507
0
  }
1508
0
1509
0
  static bool sIdsInited = false;
1510
0
  if (!sIdsInited && NS_IsMainThread()) {
1511
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
1512
0
      return;
1513
0
    }
1514
0
    sIdsInited = true;
1515
0
  }
1516
0
1517
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::MessageEvent);
1518
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::MessageEvent);
1519
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1520
0
                              &sPrototypeClass.mBase, protoCache,
1521
0
                              nullptr,
1522
0
                              constructorProto, &sInterfaceObjectClass.mBase, 1, nullptr,
1523
0
                              interfaceCache,
1524
0
                              sNativeProperties.Upcast(),
1525
0
                              nullptr,
1526
0
                              "MessageEvent", aDefineOnGlobal,
1527
0
                              nullptr,
1528
0
                              false);
1529
0
1530
0
  JS::Rooted<JSObject*> unforgeableHolder(aCx);
1531
0
  {
1532
0
    JS::Rooted<JSObject*> holderProto(aCx, *protoCache);
1533
0
    unforgeableHolder = JS_NewObjectWithoutMetadata(aCx, sClass.ToJSClass(), holderProto);
1534
0
    if (!unforgeableHolder) {
1535
0
      *protoCache = nullptr;
1536
0
      if (interfaceCache) {
1537
0
        *interfaceCache = nullptr;
1538
0
      }
1539
0
      return;
1540
0
    }
1541
0
  }
1542
0
1543
0
  if (!DefineUnforgeableAttributes(aCx, unforgeableHolder, sUnforgeableAttributes)) {
1544
0
    *protoCache = nullptr;
1545
0
    if (interfaceCache) {
1546
0
      *interfaceCache = nullptr;
1547
0
    }
1548
0
    return;
1549
0
  }
1550
0
1551
0
  if (*protoCache) {
1552
0
    js::SetReservedSlot(*protoCache, DOM_INTERFACE_PROTO_SLOTS_BASE,
1553
0
                        JS::ObjectValue(*unforgeableHolder));
1554
0
  }
1555
0
}
1556
1557
JSObject*
1558
GetConstructorObject(JSContext* aCx)
1559
0
{
1560
0
  return GetConstructorObjectHandle(aCx);
1561
0
}
1562
1563
} // namespace MessageEvent_Binding
1564
1565
1566
1567
} // namespace dom
1568
} // namespace mozilla