Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/TrackEventBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM TrackEvent.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "AtomList.h"
4
#include "EventBinding.h"
5
#include "TrackEventBinding.h"
6
#include "WrapperFactory.h"
7
#include "mozilla/OwningNonNull.h"
8
#include "mozilla/dom/AudioTrack.h"
9
#include "mozilla/dom/BindingUtils.h"
10
#include "mozilla/dom/DOMJSClass.h"
11
#include "mozilla/dom/NonRefcountedDOMObject.h"
12
#include "mozilla/dom/Nullable.h"
13
#include "mozilla/dom/PrimitiveConversions.h"
14
#include "mozilla/dom/ScriptSettings.h"
15
#include "mozilla/dom/TextTrack.h"
16
#include "mozilla/dom/TrackEvent.h"
17
#include "mozilla/dom/UnionConversions.h"
18
#include "mozilla/dom/VideoTrack.h"
19
#include "mozilla/dom/XrayExpandoClass.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, OwningVideoTrackOrAudioTrackOrTextTrack& aUnion, const char* aName, uint32_t aFlags)
30
0
{
31
0
  if (aUnion.IsVideoTrack()) {
32
0
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsVideoTrack(), "mVideoTrack", aFlags);
33
0
  } else if (aUnion.IsAudioTrack()) {
34
0
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsAudioTrack(), "mAudioTrack", aFlags);
35
0
  } else if (aUnion.IsTextTrack()) {
36
0
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsTextTrack(), "mTextTrack", aFlags);
37
0
  }
38
0
}
39
40
41
void
42
ImplCycleCollectionUnlink(OwningVideoTrackOrAudioTrackOrTextTrack& aUnion)
43
0
{
44
0
  aUnion.Uninit();
45
0
}
46
47
48
bool
49
VideoTrackOrAudioTrackOrTextTrack::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 eVideoTrack: {
57
0
      if (!GetOrCreateDOMReflector(cx, mValue.mVideoTrack.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 eAudioTrack: {
65
0
      if (!GetOrCreateDOMReflector(cx, mValue.mAudioTrack.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 eTextTrack: {
73
0
      if (!GetOrCreateDOMReflector(cx, mValue.mTextTrack.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::VideoTrack>&
91
OwningVideoTrackOrAudioTrackOrTextTrack::RawSetAsVideoTrack()
92
0
{
93
0
  if (mType == eVideoTrack) {
94
0
    return mValue.mVideoTrack.Value();
95
0
  }
96
0
  MOZ_ASSERT(mType == eUninitialized);
97
0
  mType = eVideoTrack;
98
0
  return mValue.mVideoTrack.SetValue();
99
0
}
100
101
OwningNonNull<mozilla::dom::VideoTrack>&
102
OwningVideoTrackOrAudioTrackOrTextTrack::SetAsVideoTrack()
103
0
{
104
0
  if (mType == eVideoTrack) {
105
0
    return mValue.mVideoTrack.Value();
106
0
  }
107
0
  Uninit();
108
0
  mType = eVideoTrack;
109
0
  return mValue.mVideoTrack.SetValue();
110
0
}
111
112
bool
113
OwningVideoTrackOrAudioTrackOrTextTrack::TrySetToVideoTrack(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::VideoTrack>& memberSlot = RawSetAsVideoTrack();
118
0
    static_assert(IsRefcounted<mozilla::dom::VideoTrack>::value, "We can only store refcounted classes.");{
119
0
      nsresult rv = UnwrapObject<prototypes::id::VideoTrack, mozilla::dom::VideoTrack>(value, memberSlot);
120
0
      if (NS_FAILED(rv)) {
121
0
        DestroyVideoTrack();
122
0
        tryNext = true;
123
0
        return true;
124
0
      }
125
0
    }
126
0
  }
127
0
  return true;
128
0
}
129
130
void
131
OwningVideoTrackOrAudioTrackOrTextTrack::DestroyVideoTrack()
132
0
{
133
0
  MOZ_ASSERT(IsVideoTrack(), "Wrong type!");
134
0
  mValue.mVideoTrack.Destroy();
135
0
  mType = eUninitialized;
136
0
}
137
138
139
140
141
OwningNonNull<mozilla::dom::AudioTrack>&
142
OwningVideoTrackOrAudioTrackOrTextTrack::RawSetAsAudioTrack()
143
0
{
144
0
  if (mType == eAudioTrack) {
145
0
    return mValue.mAudioTrack.Value();
146
0
  }
147
0
  MOZ_ASSERT(mType == eUninitialized);
148
0
  mType = eAudioTrack;
149
0
  return mValue.mAudioTrack.SetValue();
150
0
}
151
152
OwningNonNull<mozilla::dom::AudioTrack>&
153
OwningVideoTrackOrAudioTrackOrTextTrack::SetAsAudioTrack()
154
0
{
155
0
  if (mType == eAudioTrack) {
156
0
    return mValue.mAudioTrack.Value();
157
0
  }
158
0
  Uninit();
159
0
  mType = eAudioTrack;
160
0
  return mValue.mAudioTrack.SetValue();
161
0
}
162
163
bool
164
OwningVideoTrackOrAudioTrackOrTextTrack::TrySetToAudioTrack(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::AudioTrack>& memberSlot = RawSetAsAudioTrack();
169
0
    static_assert(IsRefcounted<mozilla::dom::AudioTrack>::value, "We can only store refcounted classes.");{
170
0
      nsresult rv = UnwrapObject<prototypes::id::AudioTrack, mozilla::dom::AudioTrack>(value, memberSlot);
171
0
      if (NS_FAILED(rv)) {
172
0
        DestroyAudioTrack();
173
0
        tryNext = true;
174
0
        return true;
175
0
      }
176
0
    }
177
0
  }
178
0
  return true;
179
0
}
180
181
void
182
OwningVideoTrackOrAudioTrackOrTextTrack::DestroyAudioTrack()
183
0
{
184
0
  MOZ_ASSERT(IsAudioTrack(), "Wrong type!");
185
0
  mValue.mAudioTrack.Destroy();
186
0
  mType = eUninitialized;
187
0
}
188
189
190
191
192
OwningNonNull<mozilla::dom::TextTrack>&
193
OwningVideoTrackOrAudioTrackOrTextTrack::RawSetAsTextTrack()
194
0
{
195
0
  if (mType == eTextTrack) {
196
0
    return mValue.mTextTrack.Value();
197
0
  }
198
0
  MOZ_ASSERT(mType == eUninitialized);
199
0
  mType = eTextTrack;
200
0
  return mValue.mTextTrack.SetValue();
201
0
}
202
203
OwningNonNull<mozilla::dom::TextTrack>&
204
OwningVideoTrackOrAudioTrackOrTextTrack::SetAsTextTrack()
205
0
{
206
0
  if (mType == eTextTrack) {
207
0
    return mValue.mTextTrack.Value();
208
0
  }
209
0
  Uninit();
210
0
  mType = eTextTrack;
211
0
  return mValue.mTextTrack.SetValue();
212
0
}
213
214
bool
215
OwningVideoTrackOrAudioTrackOrTextTrack::TrySetToTextTrack(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::TextTrack>& memberSlot = RawSetAsTextTrack();
220
0
    static_assert(IsRefcounted<mozilla::dom::TextTrack>::value, "We can only store refcounted classes.");{
221
0
      nsresult rv = UnwrapObject<prototypes::id::TextTrack, mozilla::dom::TextTrack>(value, memberSlot);
222
0
      if (NS_FAILED(rv)) {
223
0
        DestroyTextTrack();
224
0
        tryNext = true;
225
0
        return true;
226
0
      }
227
0
    }
228
0
  }
229
0
  return true;
230
0
}
231
232
void
233
OwningVideoTrackOrAudioTrackOrTextTrack::DestroyTextTrack()
234
0
{
235
0
  MOZ_ASSERT(IsTextTrack(), "Wrong type!");
236
0
  mValue.mTextTrack.Destroy();
237
0
  mType = eUninitialized;
238
0
}
239
240
241
242
243
void
244
OwningVideoTrackOrAudioTrackOrTextTrack::Uninit()
245
{
246
  switch (mType) {
247
    case eUninitialized: {
248
      break;
249
    }
250
    case eVideoTrack: {
251
      DestroyVideoTrack();
252
      break;
253
    }
254
    case eAudioTrack: {
255
      DestroyAudioTrack();
256
      break;
257
    }
258
    case eTextTrack: {
259
      DestroyTextTrack();
260
      break;
261
    }
262
  }
263
}
264
265
bool
266
OwningVideoTrackOrAudioTrackOrTextTrack::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 eVideoTrack: {
274
0
      if (!GetOrCreateDOMReflector(cx, mValue.mVideoTrack.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 eAudioTrack: {
282
0
      if (!GetOrCreateDOMReflector(cx, mValue.mAudioTrack.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 eTextTrack: {
290
0
      if (!GetOrCreateDOMReflector(cx, mValue.mTextTrack.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
OwningVideoTrackOrAudioTrackOrTextTrack::TraceUnion(JSTracer* trc)
308
0
{
309
0
}
310
311
OwningVideoTrackOrAudioTrackOrTextTrack&
312
OwningVideoTrackOrAudioTrackOrTextTrack::operator=(const OwningVideoTrackOrAudioTrackOrTextTrack& 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 eVideoTrack: {
321
0
      SetAsVideoTrack() = aOther.GetAsVideoTrack();
322
0
      break;
323
0
    }
324
0
    case eAudioTrack: {
325
0
      SetAsAudioTrack() = aOther.GetAsAudioTrack();
326
0
      break;
327
0
    }
328
0
    case eTextTrack: {
329
0
      SetAsTextTrack() = aOther.GetAsTextTrack();
330
0
      break;
331
0
    }
332
0
  }
333
0
  return *this;
334
0
}
335
336
337
338
TrackEventInit::TrackEventInit()
339
  : EventInit(FastDictionaryInitializer())
340
0
{
341
0
  // Safe to pass a null context if we pass a null value
342
0
  Init(nullptr, JS::NullHandleValue);
343
0
}
344
345
346
347
bool
348
TrackEventInit::InitIds(JSContext* cx, TrackEventInitAtoms* 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->track_id.init(cx, "track")) {
355
0
    return false;
356
0
  }
357
0
  return true;
358
0
}
359
360
bool
361
TrackEventInit::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
362
0
{
363
0
  // Passing a null JSContext is OK only if we're initing from null,
364
0
  // Since in that case we will not have to do any property gets
365
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
366
0
  // checkers by static analysis tools
367
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
368
0
  TrackEventInitAtoms* atomsCache = nullptr;
369
0
  if (cx) {
370
0
    atomsCache = GetAtomCache<TrackEventInitAtoms>(cx);
371
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
372
0
      return false;
373
0
    }
374
0
  }
375
0
376
0
  // Per spec, we init the parent's members first
377
0
  if (!EventInit::Init(cx, val)) {
378
0
    return false;
379
0
  }
380
0
381
0
  bool isNull = val.isNullOrUndefined();
382
0
  // We only need these if !isNull, in which case we have |cx|.
383
0
  Maybe<JS::Rooted<JSObject *> > object;
384
0
  Maybe<JS::Rooted<JS::Value> > temp;
385
0
  if (!isNull) {
386
0
    MOZ_ASSERT(cx);
387
0
    object.emplace(cx, &val.toObject());
388
0
    temp.emplace(cx);
389
0
  }
390
0
  if (!isNull) {
391
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->track_id, temp.ptr())) {
392
0
      return false;
393
0
    }
394
0
  }
395
0
  if (!(!isNull && !temp->isUndefined()) || temp.ref().isNullOrUndefined()) {
396
0
    mTrack.SetNull();
397
0
  } else {
398
0
    {
399
0
      bool done = false, failed = false, tryNext;
400
0
      if (temp.ref().isObject()) {
401
0
        done = (failed = !mTrack.SetValue().TrySetToVideoTrack(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
402
0
               (failed = !mTrack.SetValue().TrySetToAudioTrack(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
403
0
               (failed = !mTrack.SetValue().TrySetToTextTrack(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext;
404
0
405
0
      }
406
0
      if (failed) {
407
0
        return false;
408
0
      }
409
0
      if (!done) {
410
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'track' member of TrackEventInit", "VideoTrack, AudioTrack, TextTrack");
411
0
        return false;
412
0
      }
413
0
    }
414
0
  }
415
0
  mIsAnyMemberPresent = true;
416
0
  return true;
417
0
}
418
419
bool
420
TrackEventInit::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
421
0
{
422
0
  TrackEventInitAtoms* atomsCache = GetAtomCache<TrackEventInitAtoms>(cx);
423
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
424
0
    return false;
425
0
  }
426
0
427
0
  // Per spec, we define the parent's members first
428
0
  if (!EventInit::ToObjectInternal(cx, rval)) {
429
0
    return false;
430
0
  }
431
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
432
0
433
0
  do {
434
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
435
0
    JS::Rooted<JS::Value> temp(cx);
436
0
    Nullable<OwningVideoTrackOrAudioTrackOrTextTrack > const & currentValue = mTrack;
437
0
    if (currentValue.IsNull()) {
438
0
      temp.setNull();
439
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->track_id, temp, JSPROP_ENUMERATE)) {
440
0
        return false;
441
0
      }
442
0
      break;
443
0
    }
444
0
    if (!currentValue.Value().ToJSVal(cx, obj, &temp)) {
445
0
      return false;
446
0
    }
447
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->track_id, temp, JSPROP_ENUMERATE)) {
448
0
      return false;
449
0
    }
450
0
    break;
451
0
  } while(false);
452
0
453
0
  return true;
454
0
}
455
456
void
457
TrackEventInit::TraceDictionary(JSTracer* trc)
458
0
{
459
0
  EventInit::TraceDictionary(trc);
460
0
}
461
462
463
464
TrackEventInit&
465
TrackEventInit::operator=(const TrackEventInit& aOther)
466
0
{
467
0
  EventInit::operator=(aOther);
468
0
  mTrack = aOther.mTrack;
469
0
  return *this;
470
0
}
471
472
namespace binding_detail {
473
} // namespace binding_detail
474
475
476
namespace TrackEvent_Binding {
477
478
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<Event_Binding::NativeType>::value,
479
              "Can't inherit from an interface with a different ownership model.");
480
481
MOZ_CAN_RUN_SCRIPT static bool
482
get_track(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TrackEvent* self, JSJitGetterCallArgs args)
483
0
{
484
0
  AUTO_PROFILER_LABEL_FAST("get TrackEvent.track", DOM, cx);
485
0
486
0
  Nullable<OwningVideoTrackOrAudioTrackOrTextTrack> result;
487
0
  self->GetTrack(result);
488
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
489
0
  if (result.IsNull()) {
490
0
    args.rval().setNull();
491
0
    return true;
492
0
  }
493
0
  if (!result.Value().ToJSVal(cx, obj, args.rval())) {
494
0
    return false;
495
0
  }
496
0
  return true;
497
0
}
498
499
static const JSJitInfo track_getterinfo = {
500
  { (JSJitGetterOp)get_track },
501
  { prototypes::id::TrackEvent },
502
  { PrototypeTraits<prototypes::id::TrackEvent>::Depth },
503
  JSJitInfo::Getter,
504
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
505
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
506
  false,  /* isInfallible. False in setters. */
507
  false,  /* isMovable.  Not relevant for setters. */
508
  false, /* isEliminatable.  Not relevant for setters. */
509
  false, /* isAlwaysInSlot.  Only relevant for getters. */
510
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
511
  false,  /* isTypedMethod.  Only relevant for methods. */
512
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
513
};
514
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
515
static_assert(0 < 1, "There is no slot for us");
516
517
MOZ_CAN_RUN_SCRIPT static bool
518
get_isTrusted(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TrackEvent* self, JSJitGetterCallArgs args)
519
0
{
520
0
  AUTO_PROFILER_LABEL_FAST("get TrackEvent.isTrusted", DOM, cx);
521
0
522
0
  bool result(self->IsTrusted());
523
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
524
0
  args.rval().setBoolean(result);
525
0
  return true;
526
0
}
527
528
static const JSJitInfo isTrusted_getterinfo = {
529
  { (JSJitGetterOp)get_isTrusted },
530
  { prototypes::id::TrackEvent },
531
  { PrototypeTraits<prototypes::id::TrackEvent>::Depth },
532
  JSJitInfo::Getter,
533
  JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
534
  JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
535
  true,  /* isInfallible. False in setters. */
536
  true,  /* isMovable.  Not relevant for setters. */
537
  true, /* isEliminatable.  Not relevant for setters. */
538
  false, /* isAlwaysInSlot.  Only relevant for getters. */
539
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
540
  false,  /* isTypedMethod.  Only relevant for methods. */
541
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
542
};
543
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
544
static_assert(0 < 1, "There is no slot for us");
545
546
static bool
547
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
548
0
{
549
0
  mozilla::dom::TrackEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TrackEvent>(obj);
550
0
  // We don't want to preserve if we don't have a wrapper, and we
551
0
  // obviously can't preserve if we're not initialized.
552
0
  if (self && self->GetWrapperPreserveColor()) {
553
0
    PreserveWrapper(self);
554
0
  }
555
0
  return true;
556
0
}
557
558
static void
559
_finalize(js::FreeOp* fop, JSObject* obj)
560
0
{
561
0
  mozilla::dom::TrackEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TrackEvent>(obj);
562
0
  if (self) {
563
0
    ClearWrapper(self, self, obj);
564
0
    AddForDeferredFinalization<mozilla::dom::TrackEvent>(self);
565
0
  }
566
0
}
567
568
static size_t
569
_objectMoved(JSObject* obj, JSObject* old)
570
0
{
571
0
  mozilla::dom::TrackEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TrackEvent>(obj);
572
0
  if (self) {
573
0
    UpdateWrapper(self, self, obj, old);
574
0
  }
575
0
576
0
  return 0;
577
0
}
578
579
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
580
#if defined(__clang__)
581
#pragma clang diagnostic push
582
#pragma clang diagnostic ignored "-Wmissing-braces"
583
#endif
584
static const JSPropertySpec sAttributes_specs[] = {
585
  { "track", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &track_getterinfo, nullptr, nullptr },
586
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
587
};
588
#if defined(__clang__)
589
#pragma clang diagnostic pop
590
#endif
591
592
593
static const Prefable<const JSPropertySpec> sAttributes[] = {
594
  { nullptr, &sAttributes_specs[0] },
595
  { nullptr, nullptr }
596
};
597
598
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
599
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
600
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
601
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
602
603
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
604
#if defined(__clang__)
605
#pragma clang diagnostic push
606
#pragma clang diagnostic ignored "-Wmissing-braces"
607
#endif
608
static const JSPropertySpec sUnforgeableAttributes_specs[] = {
609
  { "isTrusted", JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericGetter<NormalThisPolicy, ThrowExceptions>, &isTrusted_getterinfo, nullptr, nullptr },
610
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
611
};
612
#if defined(__clang__)
613
#pragma clang diagnostic pop
614
#endif
615
616
617
static const Prefable<const JSPropertySpec> sUnforgeableAttributes[] = {
618
  { nullptr, &sUnforgeableAttributes_specs[0] },
619
  { nullptr, nullptr }
620
};
621
622
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
623
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
624
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
625
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
626
627
628
static uint16_t sNativeProperties_sortedPropertyIndices[2];
629
static PropertyInfo sNativeProperties_propertyInfos[2];
630
631
static const NativePropertiesN<2> sNativeProperties = {
632
  false, 0,
633
  false, 0,
634
  false, 0,
635
  true,  0 /* sAttributes */,
636
  false, 0,
637
  true,  1 /* sUnforgeableAttributes */,
638
  false, 0,
639
  -1,
640
  2,
641
  sNativeProperties_sortedPropertyIndices,
642
  {
643
    { sAttributes, &sNativeProperties_propertyInfos[0] },
644
    { sUnforgeableAttributes, &sNativeProperties_propertyInfos[1] }
645
  }
646
};
647
static_assert(2 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
648
    "We have a property info count that is oversized");
649
650
static bool
651
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
652
0
{
653
0
  AUTO_PROFILER_LABEL_FAST("TrackEvent constructor", DOM, cx);
654
0
655
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
656
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
657
0
  if (!args.isConstructing()) {
658
0
    // XXXbz wish I could get the name from the callee instead of
659
0
    // Adding more relocations
660
0
    return ThrowConstructorWithoutNew(cx, "TrackEvent");
661
0
  }
662
0
663
0
  JS::Rooted<JSObject*> desiredProto(cx);
664
0
  if (!GetDesiredProto(cx, args, &desiredProto)) {
665
0
    return false;
666
0
  }
667
0
668
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
669
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TrackEvent");
670
0
  }
671
0
  GlobalObject global(cx, obj);
672
0
  if (global.Failed()) {
673
0
    return false;
674
0
  }
675
0
676
0
  bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
677
0
  binding_detail::FakeString arg0;
678
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
679
0
    return false;
680
0
  }
681
0
  binding_detail::FastTrackEventInit arg1;
682
0
  if (!arg1.Init(cx, (args.hasDefined(1)) ? args[1] : JS::NullHandleValue,  "Argument 2 of TrackEvent.constructor", false)) {
683
0
    return false;
684
0
  }
685
0
  Maybe<JSAutoRealm> ar;
686
0
  if (objIsXray) {
687
0
    obj = js::CheckedUnwrap(obj);
688
0
    if (!obj) {
689
0
      return false;
690
0
    }
691
0
    ar.emplace(cx, obj);
692
0
    if (!JS_WrapObject(cx, &desiredProto)) {
693
0
      return false;
694
0
    }
695
0
  }
696
0
  FastErrorResult rv;
697
0
  auto result(StrongOrRawPtr<mozilla::dom::TrackEvent>(mozilla::dom::TrackEvent::Constructor(global, NonNullHelper(Constify(arg0)), Constify(arg1), rv)));
698
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
699
0
    return false;
700
0
  }
701
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
702
0
  static_assert(!IsPointer<decltype(result)>::value,
703
0
                "NewObject implies that we need to keep the object alive with a strong reference.");
704
0
  if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
705
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
706
0
    return false;
707
0
  }
708
0
  return true;
709
0
}
710
711
static const js::ClassOps sInterfaceObjectClassOps = {
712
    nullptr,               /* addProperty */
713
    nullptr,               /* delProperty */
714
    nullptr,               /* enumerate */
715
    nullptr,               /* newEnumerate */
716
    nullptr,               /* resolve */
717
    nullptr,               /* mayResolve */
718
    nullptr,               /* finalize */
719
    _constructor, /* call */
720
    nullptr,               /* hasInstance */
721
    _constructor, /* construct */
722
    nullptr,               /* trace */
723
};
724
725
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
726
  {
727
    "Function",
728
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
729
    &sInterfaceObjectClassOps,
730
    JS_NULL_CLASS_SPEC,
731
    JS_NULL_CLASS_EXT,
732
    &sInterfaceObjectClassObjectOps
733
  },
734
  eInterface,
735
  true,
736
  prototypes::id::TrackEvent,
737
  PrototypeTraits<prototypes::id::TrackEvent>::Depth,
738
  sNativePropertyHooks,
739
  "function TrackEvent() {\n    [native code]\n}",
740
  Event_Binding::GetConstructorObject
741
};
742
743
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
744
  {
745
    "TrackEventPrototype",
746
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE + 1 /* slot for the JSObject holding the unforgeable properties */),
747
    JS_NULL_CLASS_OPS,
748
    JS_NULL_CLASS_SPEC,
749
    JS_NULL_CLASS_EXT,
750
    JS_NULL_OBJECT_OPS
751
  },
752
  eInterfacePrototype,
753
  false,
754
  prototypes::id::TrackEvent,
755
  PrototypeTraits<prototypes::id::TrackEvent>::Depth,
756
  sNativePropertyHooks,
757
  "[object TrackEventPrototype]",
758
  Event_Binding::GetProtoObject
759
};
760
761
static const js::ClassOps sClassOps = {
762
  _addProperty, /* addProperty */
763
  nullptr,               /* delProperty */
764
  nullptr,               /* enumerate */
765
  nullptr, /* newEnumerate */
766
  nullptr, /* resolve */
767
  nullptr, /* mayResolve */
768
  _finalize, /* finalize */
769
  nullptr, /* call */
770
  nullptr,               /* hasInstance */
771
  nullptr,               /* construct */
772
  nullptr, /* trace */
773
};
774
775
static const js::ClassExtension sClassExtension = {
776
  nullptr, /* weakmapKeyDelegateOp */
777
  _objectMoved /* objectMovedOp */
778
};
779
780
static const DOMJSClass sClass = {
781
  { "TrackEvent",
782
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_SKIP_NURSERY_FINALIZE,
783
    &sClassOps,
784
    JS_NULL_CLASS_SPEC,
785
    &sClassExtension,
786
    JS_NULL_OBJECT_OPS
787
  },
788
  { prototypes::id::Event, prototypes::id::TrackEvent, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
789
  IsBaseOf<nsISupports, mozilla::dom::TrackEvent >::value,
790
  sNativePropertyHooks,
791
  FindAssociatedGlobalForNative<mozilla::dom::TrackEvent>::Get,
792
  GetProtoObjectHandle,
793
  GetCCParticipant<mozilla::dom::TrackEvent>::Get()
794
};
795
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
796
              "Must have the right minimal number of reserved slots.");
797
static_assert(1 >= 1,
798
              "Must have enough reserved slots.");
799
800
const JSClass*
801
GetJSClass()
802
0
{
803
0
  return sClass.ToJSClass();
804
0
}
805
806
bool
807
Wrap(JSContext* aCx, mozilla::dom::TrackEvent* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
808
0
{
809
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::TrackEvent>::value,
810
0
                "Shouldn't have wrappercached things that are not refcounted.");
811
0
  MOZ_ASSERT(static_cast<mozilla::dom::TrackEvent*>(aObject) ==
812
0
             reinterpret_cast<mozilla::dom::TrackEvent*>(aObject),
813
0
             "Multiple inheritance for mozilla::dom::TrackEvent is broken.");
814
0
  MOZ_ASSERT(static_cast<mozilla::dom::Event*>(aObject) ==
815
0
             reinterpret_cast<mozilla::dom::Event*>(aObject),
816
0
             "Multiple inheritance for mozilla::dom::Event is broken.");
817
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
818
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
819
0
  MOZ_ASSERT(!aCache->GetWrapper(),
820
0
             "You should probably not be using Wrap() directly; use "
821
0
             "GetOrCreateDOMReflector instead");
822
0
823
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
824
0
             "nsISupports must be on our primary inheritance chain");
825
0
826
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
827
0
  if (!global) {
828
0
    return false;
829
0
  }
830
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
831
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
832
0
833
0
  // That might have ended up wrapping us already, due to the wonders
834
0
  // of XBL.  Check for that, and bail out as needed.
835
0
  aReflector.set(aCache->GetWrapper());
836
0
  if (aReflector) {
837
#ifdef DEBUG
838
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
839
#endif // DEBUG
840
    return true;
841
0
  }
842
0
843
0
  JSAutoRealm ar(aCx, global);
844
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
845
0
  if (!canonicalProto) {
846
0
    return false;
847
0
  }
848
0
  JS::Rooted<JSObject*> proto(aCx);
849
0
  if (aGivenProto) {
850
0
    proto = aGivenProto;
851
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
852
0
    // coming in, we changed compartments to that of "parent" so may need
853
0
    // to wrap the proto here.
854
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
855
0
      if (!JS_WrapObject(aCx, &proto)) {
856
0
        return false;
857
0
      }
858
0
    }
859
0
  } else {
860
0
    proto = canonicalProto;
861
0
  }
862
0
863
0
  BindingJSObjectCreator<mozilla::dom::TrackEvent> creator(aCx);
864
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
865
0
  if (!aReflector) {
866
0
    return false;
867
0
  }
868
0
869
0
  aCache->SetWrapper(aReflector);
870
0
871
0
  // Important: do unforgeable property setup after we have handed
872
0
  // over ownership of the C++ object to obj as needed, so that if
873
0
  // we fail and it ends up GCed it won't have problems in the
874
0
  // finalizer trying to drop its ownership of the C++ object.
875
0
  JS::Rooted<JSObject*> unforgeableHolder(aCx,
876
0
    &js::GetReservedSlot(canonicalProto, DOM_INTERFACE_PROTO_SLOTS_BASE).toObject());
877
0
  if (!JS_InitializePropertiesFromCompatibleNativeObject(aCx, aReflector, unforgeableHolder)) {
878
0
    aCache->ReleaseWrapper(aObject);
879
0
    aCache->ClearWrapper();
880
0
    return false;
881
0
  }
882
0
  creator.InitializationSucceeded();
883
0
884
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
885
0
             aCache->GetWrapperPreserveColor() == aReflector);
886
0
  // If proto != canonicalProto, we have to preserve our wrapper;
887
0
  // otherwise we won't be able to properly recreate it later, since
888
0
  // we won't know what proto to use.  Note that we don't check
889
0
  // aGivenProto here, since it's entirely possible (and even
890
0
  // somewhat common) to have a non-null aGivenProto which is the
891
0
  // same as canonicalProto.
892
0
  if (proto != canonicalProto) {
893
0
    PreserveWrapper(aObject);
894
0
  }
895
0
896
0
  return true;
897
0
}
898
899
const NativePropertyHooks sNativePropertyHooks[] = { {
900
  nullptr,
901
  nullptr,
902
  nullptr,
903
  { sNativeProperties.Upcast(), nullptr },
904
  prototypes::id::TrackEvent,
905
  constructors::id::TrackEvent,
906
  Event_Binding::sNativePropertyHooks,
907
  &DefaultXrayExpandoObjectClass
908
} };
909
910
void
911
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
912
0
{
913
0
  JS::Handle<JSObject*> parentProto(Event_Binding::GetProtoObjectHandle(aCx));
914
0
  if (!parentProto) {
915
0
    return;
916
0
  }
917
0
918
0
  JS::Handle<JSObject*> constructorProto(Event_Binding::GetConstructorObjectHandle(aCx));
919
0
  if (!constructorProto) {
920
0
    return;
921
0
  }
922
0
923
0
  static bool sIdsInited = false;
924
0
  if (!sIdsInited && NS_IsMainThread()) {
925
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
926
0
      return;
927
0
    }
928
0
    sIdsInited = true;
929
0
  }
930
0
931
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::TrackEvent);
932
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::TrackEvent);
933
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
934
0
                              &sPrototypeClass.mBase, protoCache,
935
0
                              nullptr,
936
0
                              constructorProto, &sInterfaceObjectClass.mBase, 1, nullptr,
937
0
                              interfaceCache,
938
0
                              sNativeProperties.Upcast(),
939
0
                              nullptr,
940
0
                              "TrackEvent", aDefineOnGlobal,
941
0
                              nullptr,
942
0
                              false);
943
0
944
0
  JS::Rooted<JSObject*> unforgeableHolder(aCx);
945
0
  {
946
0
    JS::Rooted<JSObject*> holderProto(aCx, *protoCache);
947
0
    unforgeableHolder = JS_NewObjectWithoutMetadata(aCx, sClass.ToJSClass(), holderProto);
948
0
    if (!unforgeableHolder) {
949
0
      *protoCache = nullptr;
950
0
      if (interfaceCache) {
951
0
        *interfaceCache = nullptr;
952
0
      }
953
0
      return;
954
0
    }
955
0
  }
956
0
957
0
  if (!DefineUnforgeableAttributes(aCx, unforgeableHolder, sUnforgeableAttributes)) {
958
0
    *protoCache = nullptr;
959
0
    if (interfaceCache) {
960
0
      *interfaceCache = nullptr;
961
0
    }
962
0
    return;
963
0
  }
964
0
965
0
  if (*protoCache) {
966
0
    js::SetReservedSlot(*protoCache, DOM_INTERFACE_PROTO_SLOTS_BASE,
967
0
                        JS::ObjectValue(*unforgeableHolder));
968
0
  }
969
0
}
970
971
JSObject*
972
GetConstructorObject(JSContext* aCx)
973
0
{
974
0
  return GetConstructorObjectHandle(aCx);
975
0
}
976
977
} // namespace TrackEvent_Binding
978
979
980
981
} // namespace dom
982
} // namespace mozilla