Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/AudioTrackListBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM AudioTrackList.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "AudioTrackListBinding.h"
4
#include "EventHandlerBinding.h"
5
#include "EventTargetBinding.h"
6
#include "WrapperFactory.h"
7
#include "mozilla/OwningNonNull.h"
8
#include "mozilla/Preferences.h"
9
#include "mozilla/dom/AudioTrack.h"
10
#include "mozilla/dom/AudioTrackList.h"
11
#include "mozilla/dom/BindingUtils.h"
12
#include "mozilla/dom/DOMJSClass.h"
13
#include "mozilla/dom/DOMJSProxyHandler.h"
14
#include "mozilla/dom/NonRefcountedDOMObject.h"
15
#include "mozilla/dom/Nullable.h"
16
#include "mozilla/dom/PrimitiveConversions.h"
17
#include "mozilla/dom/XrayExpandoClass.h"
18
19
namespace mozilla {
20
namespace dom {
21
22
namespace binding_detail {}; // Just to make sure it's known as a namespace
23
using namespace mozilla::dom::binding_detail;
24
25
26
namespace AudioTrackList_Binding {
27
28
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventTarget_Binding::NativeType>::value,
29
              "Can't inherit from an interface with a different ownership model.");
30
31
MOZ_CAN_RUN_SCRIPT static bool
32
get_length(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioTrackList* self, JSJitGetterCallArgs args)
33
0
{
34
0
  AUTO_PROFILER_LABEL_FAST("get AudioTrackList.length", DOM, cx);
35
0
36
0
  uint32_t result(self->Length());
37
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
38
0
  args.rval().setNumber(result);
39
0
  return true;
40
0
}
41
42
static const JSJitInfo length_getterinfo = {
43
  { (JSJitGetterOp)get_length },
44
  { prototypes::id::AudioTrackList },
45
  { PrototypeTraits<prototypes::id::AudioTrackList>::Depth },
46
  JSJitInfo::Getter,
47
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
48
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
49
  true,  /* isInfallible. False in setters. */
50
  false,  /* isMovable.  Not relevant for setters. */
51
  false, /* isEliminatable.  Not relevant for setters. */
52
  false, /* isAlwaysInSlot.  Only relevant for getters. */
53
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
54
  false,  /* isTypedMethod.  Only relevant for methods. */
55
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
56
};
57
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
58
static_assert(0 < 1, "There is no slot for us");
59
60
MOZ_CAN_RUN_SCRIPT static bool
61
getTrackById(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioTrackList* self, const JSJitMethodCallArgs& args)
62
0
{
63
0
  AUTO_PROFILER_LABEL_FAST("AudioTrackList.getTrackById", DOM, cx);
64
0
65
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
66
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "AudioTrackList.getTrackById");
67
0
  }
68
0
  binding_detail::FakeString arg0;
69
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
70
0
    return false;
71
0
  }
72
0
  auto result(StrongOrRawPtr<mozilla::dom::AudioTrack>(self->GetTrackById(NonNullHelper(Constify(arg0)))));
73
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
74
0
  if (!result) {
75
0
    args.rval().setNull();
76
0
    return true;
77
0
  }
78
0
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
79
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
80
0
    return false;
81
0
  }
82
0
  return true;
83
0
}
84
85
static const JSJitInfo getTrackById_methodinfo = {
86
  { (JSJitGetterOp)getTrackById },
87
  { prototypes::id::AudioTrackList },
88
  { PrototypeTraits<prototypes::id::AudioTrackList>::Depth },
89
  JSJitInfo::Method,
90
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
91
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
92
  false,  /* isInfallible. False in setters. */
93
  false,  /* isMovable.  Not relevant for setters. */
94
  false, /* isEliminatable.  Not relevant for setters. */
95
  false, /* isAlwaysInSlot.  Only relevant for getters. */
96
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
97
  false,  /* isTypedMethod.  Only relevant for methods. */
98
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
99
};
100
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
101
static_assert(0 < 1, "There is no slot for us");
102
103
MOZ_CAN_RUN_SCRIPT static bool
104
get_onchange(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioTrackList* self, JSJitGetterCallArgs args)
105
0
{
106
0
  AUTO_PROFILER_LABEL_FAST("get AudioTrackList.onchange", DOM, cx);
107
0
108
0
  RefPtr<EventHandlerNonNull> result(self->GetOnchange());
109
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
110
0
  if (result) {
111
0
    args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
112
0
    if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
113
0
      return false;
114
0
    }
115
0
    return true;
116
0
  } else {
117
0
    args.rval().setNull();
118
0
    return true;
119
0
  }
120
0
}
121
122
MOZ_CAN_RUN_SCRIPT static bool
123
set_onchange(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioTrackList* self, JSJitSetterCallArgs args)
124
0
{
125
0
  AUTO_PROFILER_LABEL_FAST("set AudioTrackList.onchange", DOM, cx);
126
0
127
0
  RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
128
0
  if (args[0].isObject()) {
129
0
    { // scope for tempRoot and tempGlobalRoot if needed
130
0
      arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
131
0
    }
132
0
  } else {
133
0
    arg0 = nullptr;
134
0
  }
135
0
  self->SetOnchange(Constify(arg0));
136
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
137
0
138
0
  return true;
139
0
}
140
141
static const JSJitInfo onchange_getterinfo = {
142
  { (JSJitGetterOp)get_onchange },
143
  { prototypes::id::AudioTrackList },
144
  { PrototypeTraits<prototypes::id::AudioTrackList>::Depth },
145
  JSJitInfo::Getter,
146
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
147
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
148
  false,  /* isInfallible. False in setters. */
149
  false,  /* isMovable.  Not relevant for setters. */
150
  false, /* isEliminatable.  Not relevant for setters. */
151
  false, /* isAlwaysInSlot.  Only relevant for getters. */
152
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
153
  false,  /* isTypedMethod.  Only relevant for methods. */
154
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
155
};
156
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
157
static_assert(0 < 1, "There is no slot for us");
158
static const JSJitInfo onchange_setterinfo = {
159
  { (JSJitGetterOp)set_onchange },
160
  { prototypes::id::AudioTrackList },
161
  { PrototypeTraits<prototypes::id::AudioTrackList>::Depth },
162
  JSJitInfo::Setter,
163
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
164
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
165
  false,  /* isInfallible. False in setters. */
166
  false,  /* isMovable.  Not relevant for setters. */
167
  false, /* isEliminatable.  Not relevant for setters. */
168
  false, /* isAlwaysInSlot.  Only relevant for getters. */
169
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
170
  false,  /* isTypedMethod.  Only relevant for methods. */
171
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
172
};
173
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
174
static_assert(0 < 1, "There is no slot for us");
175
176
MOZ_CAN_RUN_SCRIPT static bool
177
get_onaddtrack(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioTrackList* self, JSJitGetterCallArgs args)
178
0
{
179
0
  AUTO_PROFILER_LABEL_FAST("get AudioTrackList.onaddtrack", DOM, cx);
180
0
181
0
  RefPtr<EventHandlerNonNull> result(self->GetOnaddtrack());
182
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
183
0
  if (result) {
184
0
    args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
185
0
    if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
186
0
      return false;
187
0
    }
188
0
    return true;
189
0
  } else {
190
0
    args.rval().setNull();
191
0
    return true;
192
0
  }
193
0
}
194
195
MOZ_CAN_RUN_SCRIPT static bool
196
set_onaddtrack(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioTrackList* self, JSJitSetterCallArgs args)
197
0
{
198
0
  AUTO_PROFILER_LABEL_FAST("set AudioTrackList.onaddtrack", DOM, cx);
199
0
200
0
  RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
201
0
  if (args[0].isObject()) {
202
0
    { // scope for tempRoot and tempGlobalRoot if needed
203
0
      arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
204
0
    }
205
0
  } else {
206
0
    arg0 = nullptr;
207
0
  }
208
0
  self->SetOnaddtrack(Constify(arg0));
209
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
210
0
211
0
  return true;
212
0
}
213
214
static const JSJitInfo onaddtrack_getterinfo = {
215
  { (JSJitGetterOp)get_onaddtrack },
216
  { prototypes::id::AudioTrackList },
217
  { PrototypeTraits<prototypes::id::AudioTrackList>::Depth },
218
  JSJitInfo::Getter,
219
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
220
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
221
  false,  /* isInfallible. False in setters. */
222
  false,  /* isMovable.  Not relevant for setters. */
223
  false, /* isEliminatable.  Not relevant for setters. */
224
  false, /* isAlwaysInSlot.  Only relevant for getters. */
225
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
226
  false,  /* isTypedMethod.  Only relevant for methods. */
227
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
228
};
229
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
230
static_assert(0 < 1, "There is no slot for us");
231
static const JSJitInfo onaddtrack_setterinfo = {
232
  { (JSJitGetterOp)set_onaddtrack },
233
  { prototypes::id::AudioTrackList },
234
  { PrototypeTraits<prototypes::id::AudioTrackList>::Depth },
235
  JSJitInfo::Setter,
236
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
237
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
238
  false,  /* isInfallible. False in setters. */
239
  false,  /* isMovable.  Not relevant for setters. */
240
  false, /* isEliminatable.  Not relevant for setters. */
241
  false, /* isAlwaysInSlot.  Only relevant for getters. */
242
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
243
  false,  /* isTypedMethod.  Only relevant for methods. */
244
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
245
};
246
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
247
static_assert(0 < 1, "There is no slot for us");
248
249
MOZ_CAN_RUN_SCRIPT static bool
250
get_onremovetrack(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioTrackList* self, JSJitGetterCallArgs args)
251
0
{
252
0
  AUTO_PROFILER_LABEL_FAST("get AudioTrackList.onremovetrack", DOM, cx);
253
0
254
0
  RefPtr<EventHandlerNonNull> result(self->GetOnremovetrack());
255
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
256
0
  if (result) {
257
0
    args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
258
0
    if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
259
0
      return false;
260
0
    }
261
0
    return true;
262
0
  } else {
263
0
    args.rval().setNull();
264
0
    return true;
265
0
  }
266
0
}
267
268
MOZ_CAN_RUN_SCRIPT static bool
269
set_onremovetrack(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioTrackList* self, JSJitSetterCallArgs args)
270
0
{
271
0
  AUTO_PROFILER_LABEL_FAST("set AudioTrackList.onremovetrack", DOM, cx);
272
0
273
0
  RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
274
0
  if (args[0].isObject()) {
275
0
    { // scope for tempRoot and tempGlobalRoot if needed
276
0
      arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
277
0
    }
278
0
  } else {
279
0
    arg0 = nullptr;
280
0
  }
281
0
  self->SetOnremovetrack(Constify(arg0));
282
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
283
0
284
0
  return true;
285
0
}
286
287
static const JSJitInfo onremovetrack_getterinfo = {
288
  { (JSJitGetterOp)get_onremovetrack },
289
  { prototypes::id::AudioTrackList },
290
  { PrototypeTraits<prototypes::id::AudioTrackList>::Depth },
291
  JSJitInfo::Getter,
292
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
293
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
294
  false,  /* isInfallible. False in setters. */
295
  false,  /* isMovable.  Not relevant for setters. */
296
  false, /* isEliminatable.  Not relevant for setters. */
297
  false, /* isAlwaysInSlot.  Only relevant for getters. */
298
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
299
  false,  /* isTypedMethod.  Only relevant for methods. */
300
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
301
};
302
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
303
static_assert(0 < 1, "There is no slot for us");
304
static const JSJitInfo onremovetrack_setterinfo = {
305
  { (JSJitGetterOp)set_onremovetrack },
306
  { prototypes::id::AudioTrackList },
307
  { PrototypeTraits<prototypes::id::AudioTrackList>::Depth },
308
  JSJitInfo::Setter,
309
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
310
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
311
  false,  /* isInfallible. False in setters. */
312
  false,  /* isMovable.  Not relevant for setters. */
313
  false, /* isEliminatable.  Not relevant for setters. */
314
  false, /* isAlwaysInSlot.  Only relevant for getters. */
315
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
316
  false,  /* isTypedMethod.  Only relevant for methods. */
317
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
318
};
319
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
320
static_assert(0 < 1, "There is no slot for us");
321
322
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
323
#if defined(__clang__)
324
#pragma clang diagnostic push
325
#pragma clang diagnostic ignored "-Wmissing-braces"
326
#endif
327
static const JSFunctionSpec sMethods_specs[] = {
328
  JS_FNSPEC("getTrackById", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getTrackById_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
329
  JS_SYM_FNSPEC(iterator, nullptr, nullptr, 0, 0, "ArrayValues"),
330
  JS_FS_END
331
};
332
#if defined(__clang__)
333
#pragma clang diagnostic pop
334
#endif
335
336
337
static const Prefable<const JSFunctionSpec> sMethods[] = {
338
  { nullptr, &sMethods_specs[0] },
339
  { nullptr, nullptr }
340
};
341
342
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
343
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
344
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
345
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
346
347
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
348
#if defined(__clang__)
349
#pragma clang diagnostic push
350
#pragma clang diagnostic ignored "-Wmissing-braces"
351
#endif
352
static const JSPropertySpec sAttributes_specs[] = {
353
  { "length", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &length_getterinfo, nullptr, nullptr },
354
  { "onchange", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &onchange_getterinfo, GenericSetter<NormalThisPolicy>, &onchange_setterinfo },
355
  { "onaddtrack", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &onaddtrack_getterinfo, GenericSetter<NormalThisPolicy>, &onaddtrack_setterinfo },
356
  { "onremovetrack", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &onremovetrack_getterinfo, GenericSetter<NormalThisPolicy>, &onremovetrack_setterinfo },
357
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
358
};
359
#if defined(__clang__)
360
#pragma clang diagnostic pop
361
#endif
362
363
364
static const Prefable<const JSPropertySpec> sAttributes[] = {
365
  { nullptr, &sAttributes_specs[0] },
366
  { nullptr, nullptr }
367
};
368
369
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
370
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
371
static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
372
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
373
374
375
static uint16_t sNativeProperties_sortedPropertyIndices[6];
376
static PropertyInfo sNativeProperties_propertyInfos[6];
377
378
static const NativePropertiesN<2> sNativeProperties = {
379
  false, 0,
380
  false, 0,
381
  true,  0 /* sMethods */,
382
  true,  1 /* sAttributes */,
383
  false, 0,
384
  false, 0,
385
  false, 0,
386
  -1,
387
  6,
388
  sNativeProperties_sortedPropertyIndices,
389
  {
390
    { sMethods, &sNativeProperties_propertyInfos[0] },
391
    { sAttributes, &sNativeProperties_propertyInfos[2] }
392
  }
393
};
394
static_assert(6 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
395
    "We have a property info count that is oversized");
396
397
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
398
  {
399
    "Function",
400
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
401
    &sBoringInterfaceObjectClassClassOps,
402
    JS_NULL_CLASS_SPEC,
403
    JS_NULL_CLASS_EXT,
404
    &sInterfaceObjectClassObjectOps
405
  },
406
  eInterface,
407
  true,
408
  prototypes::id::AudioTrackList,
409
  PrototypeTraits<prototypes::id::AudioTrackList>::Depth,
410
  sNativePropertyHooks,
411
  "function AudioTrackList() {\n    [native code]\n}",
412
  EventTarget_Binding::GetConstructorObject
413
};
414
415
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
416
  {
417
    "AudioTrackListPrototype",
418
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
419
    JS_NULL_CLASS_OPS,
420
    JS_NULL_CLASS_SPEC,
421
    JS_NULL_CLASS_EXT,
422
    JS_NULL_OBJECT_OPS
423
  },
424
  eInterfacePrototype,
425
  false,
426
  prototypes::id::AudioTrackList,
427
  PrototypeTraits<prototypes::id::AudioTrackList>::Depth,
428
  sNativePropertyHooks,
429
  "[object AudioTrackListPrototype]",
430
  EventTarget_Binding::GetProtoObject
431
};
432
433
bool
434
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
435
0
{
436
0
  static bool sPrefValue;
437
0
  static bool sPrefCacheSetUp = false;
438
0
  if (!sPrefCacheSetUp) {
439
0
    sPrefCacheSetUp = true;
440
0
    Preferences::AddBoolVarCache(&sPrefValue, "media.track.enabled");
441
0
  }
442
0
443
0
  return sPrefValue;
444
0
}
445
446
static_assert(IsBaseOf<nsISupports, mozilla::dom::AudioTrackList >::value,
447
                  "We don't support non-nsISupports native classes for "
448
                  "proxy-based bindings yet");
449
450
451
class DOMProxyHandler : public mozilla::dom::DOMProxyHandler
452
{
453
public:
454
  explicit constexpr DOMProxyHandler()
455
0
  {
456
0
  }
457
458
  virtual bool
459
  getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
460
461
  virtual bool
462
  defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const override;
463
464
  using mozilla::dom::DOMProxyHandler::defineProperty;
465
466
  virtual bool
467
  ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const override;
468
469
  virtual bool
470
  hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const override;
471
472
  virtual bool
473
  get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
474
475
  virtual const char*
476
  className(JSContext* cx, JS::Handle<JSObject*> proxy) const override;
477
478
  virtual bool
479
  finalizeInBackground(const JS::Value& priv) const override;
480
481
  virtual void
482
  finalize(JSFreeOp* fop, JSObject* proxy) const override;
483
484
  static const DOMProxyHandler*
485
  getInstance();
486
487
  virtual bool
488
  delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const override;
489
490
  virtual bool
491
  getElements(JSContext* cx, JS::Handle<JSObject*> proxy, uint32_t begin, uint32_t end, js::ElementAdder* adder) const override;
492
493
  virtual size_t
494
  objectMoved(JSObject* obj, JSObject* old) const override;
495
};
496
497
MOZ_ALWAYS_INLINE bool
498
IsProxy(JSObject* obj)
499
0
{
500
0
  return js::IsProxy(obj) && js::GetProxyHandler(obj) == DOMProxyHandler::getInstance();
501
0
}
502
503
MOZ_ALWAYS_INLINE mozilla::dom::AudioTrackList*
504
UnwrapProxy(JSObject* obj)
505
0
{
506
0
  MOZ_ASSERT(js::IsProxy(obj));
507
0
  if (js::GetProxyHandler(obj) != DOMProxyHandler::getInstance()) {
508
0
    MOZ_ASSERT(xpc::WrapperFactory::IsXrayWrapper(obj));
509
0
    obj = js::UncheckedUnwrap(obj);
510
0
  }
511
0
  MOZ_ASSERT(IsProxy(obj));
512
0
  return static_cast<mozilla::dom::AudioTrackList*>(js::GetProxyReservedSlot(obj, DOM_OBJECT_SLOT).toPrivate());
513
0
}
514
515
bool
516
DOMProxyHandler::getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const
517
0
{
518
0
  bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
519
0
  uint32_t index = GetArrayIndexFromId(cx, id);
520
0
  if (IsArrayIndex(index)) {
521
0
    mozilla::dom::AudioTrackList* self = UnwrapProxy(proxy);
522
0
    bool found = false;
523
0
    auto result(StrongOrRawPtr<mozilla::dom::AudioTrack>(self->IndexedGetter(index, found)));
524
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
525
0
526
0
    if (found) {
527
0
      if (!GetOrCreateDOMReflector(cx, result, desc.value())) {
528
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
529
0
        return false;
530
0
      }
531
0
      FillPropertyDescriptor(desc, proxy, true);
532
0
      return true;
533
0
    }
534
0
  }
535
0
536
0
  JS::Rooted<JSObject*> expando(cx);
537
0
  if (!isXray && (expando = GetExpandoObject(proxy))) {
538
0
    if (!JS_GetOwnPropertyDescriptorById(cx, expando, id, desc)) {
539
0
      return false;
540
0
    }
541
0
    if (desc.object()) {
542
0
      // Pretend the property lives on the wrapper.
543
0
      desc.object().set(proxy);
544
0
      return true;
545
0
    }
546
0
  }
547
0
548
0
  desc.object().set(nullptr);
549
0
  return true;
550
0
}
551
552
bool
553
DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const
554
0
{
555
0
  if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {
556
0
    *defined = true;
557
0
    return opresult.failNoIndexedSetter();
558
0
  }
559
0
  return mozilla::dom::DOMProxyHandler::defineProperty(cx, proxy, id, desc, opresult, defined);
560
0
}
561
562
563
bool
564
DOMProxyHandler::ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const
565
0
{
566
0
  bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
567
0
568
0
  uint32_t length = UnwrapProxy(proxy)->Length();
569
0
  MOZ_ASSERT(int32_t(length) >= 0);
570
0
  for (int32_t i = 0; i < int32_t(length); ++i) {
571
0
    if (!props.append(INT_TO_JSID(i))) {
572
0
      return false;
573
0
    }
574
0
  }
575
0
576
0
  JS::Rooted<JSObject*> expando(cx);
577
0
  if (!isXray && (expando = DOMProxyHandler::GetExpandoObject(proxy)) &&
578
0
      !js::GetPropertyKeys(cx, expando, flags, &props)) {
579
0
    return false;
580
0
  }
581
0
582
0
  return true;
583
0
}
584
585
bool
586
DOMProxyHandler::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const
587
0
{
588
0
  MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
589
0
            "Should not have a XrayWrapper here");
590
0
591
0
  uint32_t index = GetArrayIndexFromId(cx, id);
592
0
  if (IsArrayIndex(index)) {
593
0
    bool found = false;
594
0
    mozilla::dom::AudioTrackList* self = UnwrapProxy(proxy);
595
0
    auto result(StrongOrRawPtr<mozilla::dom::AudioTrack>(self->IndexedGetter(index, found)));
596
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
597
0
    (void)result;
598
0
599
0
    *bp = found;
600
0
    return true;
601
0
  }
602
0
603
0
604
0
  JS::Rooted<JSObject*> expando(cx, GetExpandoObject(proxy));
605
0
  if (expando) {
606
0
    bool b = true;
607
0
    bool ok = JS_HasPropertyById(cx, expando, id, &b);
608
0
    *bp = !!b;
609
0
    if (!ok || *bp) {
610
0
      return ok;
611
0
    }
612
0
  }
613
0
614
0
  *bp = false;
615
0
  return true;
616
0
}
617
618
bool
619
DOMProxyHandler::get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const
620
0
{
621
0
  MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
622
0
              "Should not have a XrayWrapper here");
623
0
624
0
  uint32_t index = GetArrayIndexFromId(cx, id);
625
0
  if (IsArrayIndex(index)) {
626
0
    mozilla::dom::AudioTrackList* self = UnwrapProxy(proxy);
627
0
    bool found = false;
628
0
    auto result(StrongOrRawPtr<mozilla::dom::AudioTrack>(self->IndexedGetter(index, found)));
629
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
630
0
631
0
    if (found) {
632
0
      if (!GetOrCreateDOMReflector(cx, result, vp)) {
633
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
634
0
        return false;
635
0
      }
636
0
      return true;
637
0
    }
638
0
    // Even if we don't have this index, we don't forward the
639
0
    // get on to our expando object.
640
0
  } else {
641
0
    { // Scope for expando
642
0
      JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
643
0
      if (expando) {
644
0
        bool hasProp;
645
0
        if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
646
0
          return false;
647
0
        }
648
0
649
0
        if (hasProp) {
650
0
          // Forward the get to the expando object, but our receiver is whatever our
651
0
          // receiver is.
652
0
          return JS_ForwardGetPropertyTo(cx, expando, id, receiver, vp);
653
0
        }
654
0
      }
655
0
    }
656
0
  }
657
0
658
0
  bool foundOnPrototype;
659
0
  if (!GetPropertyOnPrototype(cx, proxy, receiver, id, &foundOnPrototype, vp)) {
660
0
    return false;
661
0
  }
662
0
663
0
  if (foundOnPrototype) {
664
0
    return true;
665
0
  }
666
0
667
0
  vp.setUndefined();
668
0
  return true;
669
0
}
670
671
const char*
672
DOMProxyHandler::className(JSContext* cx, JS::Handle<JSObject*> proxy) const
673
0
{
674
0
  return "AudioTrackList";
675
0
}
676
677
bool
678
DOMProxyHandler::finalizeInBackground(const JS::Value& priv) const
679
0
{
680
0
  return false;
681
0
}
682
683
void
684
DOMProxyHandler::finalize(JSFreeOp* fop, JSObject* proxy) const
685
0
{
686
0
  mozilla::dom::AudioTrackList* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AudioTrackList>(proxy);
687
0
  if (self) {
688
0
    ClearWrapper(self, self, proxy);
689
0
    AddForDeferredFinalization<mozilla::dom::AudioTrackList>(self);
690
0
  }
691
0
}
692
693
const DOMProxyHandler*
694
DOMProxyHandler::getInstance()
695
0
{
696
0
  static const DOMProxyHandler instance;
697
0
  return &instance;
698
0
}
699
700
bool
701
DOMProxyHandler::delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const
702
0
{
703
0
  MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
704
0
            "Should not have a XrayWrapper here");
705
0
706
0
  uint32_t index = GetArrayIndexFromId(cx, id);
707
0
  if (IsArrayIndex(index)) {
708
0
    bool deleteSucceeded;
709
0
    bool found = false;
710
0
    mozilla::dom::AudioTrackList* self = UnwrapProxy(proxy);
711
0
    auto result(StrongOrRawPtr<mozilla::dom::AudioTrack>(self->IndexedGetter(index, found)));
712
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
713
0
    (void)result;
714
0
    deleteSucceeded = !found;
715
0
    return deleteSucceeded ? opresult.succeed() : opresult.failCantDelete();
716
0
  }
717
0
718
0
  return dom::DOMProxyHandler::delete_(cx, proxy, id, opresult);
719
0
}
720
721
bool
722
DOMProxyHandler::getElements(JSContext* cx, JS::Handle<JSObject*> proxy, uint32_t begin, uint32_t end, js::ElementAdder* adder) const
723
0
{
724
0
  JS::Rooted<JS::Value> temp(cx);
725
0
  MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
726
0
             "Should not have a XrayWrapper here");
727
0
728
0
  mozilla::dom::AudioTrackList* self = UnwrapProxy(proxy);
729
0
  uint32_t length = self->Length();
730
0
  // Compute the end of the indices we'll get ourselves
731
0
  uint32_t ourEnd = std::max(begin, std::min(end, length));
732
0
733
0
  for (uint32_t index = begin; index < ourEnd; ++index) {
734
0
    bool found = false;
735
0
    auto result(StrongOrRawPtr<mozilla::dom::AudioTrack>(self->IndexedGetter(index, found)));
736
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
737
0
738
0
    MOZ_ASSERT(found);
739
0
    if (!GetOrCreateDOMReflector(cx, result, &temp)) {
740
0
      MOZ_ASSERT(JS_IsExceptionPending(cx));
741
0
      return false;
742
0
    }
743
0
    if (!adder->append(cx, temp)) return false;
744
0
    continue;
745
0
  }
746
0
747
0
  if (end > ourEnd) {
748
0
    JS::Rooted<JSObject*> proto(cx);
749
0
    if (!js::GetObjectProto(cx, proxy, &proto)) {
750
0
      return false;
751
0
    }
752
0
    return js::GetElementsWithAdder(cx, proto, proxy, ourEnd, end, adder);
753
0
  }
754
0
755
0
  return true;
756
0
}
757
758
size_t
759
DOMProxyHandler::objectMoved(JSObject* obj, JSObject* old) const
760
0
{
761
0
  mozilla::dom::AudioTrackList* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AudioTrackList>(obj);
762
0
  if (self) {
763
0
    UpdateWrapper(self, self, obj, old);
764
0
  }
765
0
766
0
  return 0;
767
0
}
768
769
static const DOMJSClass sClass = {
770
  PROXY_CLASS_DEF("AudioTrackList",
771
                  JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1)),
772
  { prototypes::id::EventTarget, prototypes::id::AudioTrackList, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
773
  IsBaseOf<nsISupports, mozilla::dom::AudioTrackList >::value,
774
  sNativePropertyHooks,
775
  FindAssociatedGlobalForNative<mozilla::dom::AudioTrackList>::Get,
776
  GetProtoObjectHandle,
777
  GetCCParticipant<mozilla::dom::AudioTrackList>::Get()
778
};
779
780
bool
781
Wrap(JSContext* aCx, mozilla::dom::AudioTrackList* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
782
0
{
783
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::AudioTrackList>::value,
784
0
                "Shouldn't have wrappercached things that are not refcounted.");
785
0
  MOZ_ASSERT(static_cast<mozilla::dom::AudioTrackList*>(aObject) ==
786
0
             reinterpret_cast<mozilla::dom::AudioTrackList*>(aObject),
787
0
             "Multiple inheritance for mozilla::dom::AudioTrackList is broken.");
788
0
  MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
789
0
             reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
790
0
             "Multiple inheritance for mozilla::dom::EventTarget is broken.");
791
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
792
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
793
0
  MOZ_ASSERT(!aCache->GetWrapper(),
794
0
             "You should probably not be using Wrap() directly; use "
795
0
             "GetOrCreateDOMReflector instead");
796
0
797
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
798
0
             "nsISupports must be on our primary inheritance chain");
799
0
800
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
801
0
  if (!global) {
802
0
    return false;
803
0
  }
804
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
805
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
806
0
807
0
  // That might have ended up wrapping us already, due to the wonders
808
0
  // of XBL.  Check for that, and bail out as needed.
809
0
  aReflector.set(aCache->GetWrapper());
810
0
  if (aReflector) {
811
#ifdef DEBUG
812
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
813
#endif // DEBUG
814
    return true;
815
0
  }
816
0
817
0
  JSAutoRealm ar(aCx, global);
818
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
819
0
  if (!canonicalProto) {
820
0
    return false;
821
0
  }
822
0
  JS::Rooted<JSObject*> proto(aCx);
823
0
  if (aGivenProto) {
824
0
    proto = aGivenProto;
825
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
826
0
    // coming in, we changed compartments to that of "parent" so may need
827
0
    // to wrap the proto here.
828
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
829
0
      if (!JS_WrapObject(aCx, &proto)) {
830
0
        return false;
831
0
      }
832
0
    }
833
0
  } else {
834
0
    proto = canonicalProto;
835
0
  }
836
0
837
0
  BindingJSObjectCreator<mozilla::dom::AudioTrackList> creator(aCx);
838
0
  creator.CreateProxyObject(aCx, &sClass.mBase, DOMProxyHandler::getInstance(),
839
0
                            proto, aObject, JS::UndefinedHandleValue, aReflector);
840
0
  if (!aReflector) {
841
0
    return false;
842
0
  }
843
0
844
0
  aCache->SetWrapper(aReflector);
845
0
  creator.InitializationSucceeded();
846
0
847
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
848
0
             aCache->GetWrapperPreserveColor() == aReflector);
849
0
  // If proto != canonicalProto, we have to preserve our wrapper;
850
0
  // otherwise we won't be able to properly recreate it later, since
851
0
  // we won't know what proto to use.  Note that we don't check
852
0
  // aGivenProto here, since it's entirely possible (and even
853
0
  // somewhat common) to have a non-null aGivenProto which is the
854
0
  // same as canonicalProto.
855
0
  if (proto != canonicalProto) {
856
0
    PreserveWrapper(aObject);
857
0
  }
858
0
859
0
  return true;
860
0
}
861
862
static bool
863
ResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::MutableHandle<JS::PropertyDescriptor> desc)
864
0
{
865
0
  return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc);
866
0
}
867
868
static bool
869
EnumerateOwnProperties(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::AutoIdVector& props)
870
0
{
871
0
  return js::GetProxyHandler(obj)->ownPropertyKeys(cx, wrapper, props);
872
0
}
873
874
const NativePropertyHooks sNativePropertyHooks[] = { {
875
  ResolveOwnProperty,
876
  EnumerateOwnProperties,
877
  nullptr,
878
  { sNativeProperties.Upcast(), nullptr },
879
  prototypes::id::AudioTrackList,
880
  constructors::id::AudioTrackList,
881
  EventTarget_Binding::sNativePropertyHooks,
882
  &DefaultXrayExpandoObjectClass
883
} };
884
885
void
886
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
887
0
{
888
0
  JS::Handle<JSObject*> parentProto(EventTarget_Binding::GetProtoObjectHandle(aCx));
889
0
  if (!parentProto) {
890
0
    return;
891
0
  }
892
0
893
0
  JS::Handle<JSObject*> constructorProto(EventTarget_Binding::GetConstructorObjectHandle(aCx));
894
0
  if (!constructorProto) {
895
0
    return;
896
0
  }
897
0
898
0
  static bool sIdsInited = false;
899
0
  if (!sIdsInited && NS_IsMainThread()) {
900
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
901
0
      return;
902
0
    }
903
0
    sIdsInited = true;
904
0
  }
905
0
906
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::AudioTrackList);
907
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::AudioTrackList);
908
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
909
0
                              &sPrototypeClass.mBase, protoCache,
910
0
                              nullptr,
911
0
                              constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
912
0
                              interfaceCache,
913
0
                              sNativeProperties.Upcast(),
914
0
                              nullptr,
915
0
                              "AudioTrackList", aDefineOnGlobal,
916
0
                              nullptr,
917
0
                              false);
918
0
}
919
920
JSObject*
921
GetConstructorObject(JSContext* aCx)
922
0
{
923
0
  return GetConstructorObjectHandle(aCx);
924
0
}
925
926
} // namespace AudioTrackList_Binding
927
928
929
930
} // namespace dom
931
} // namespace mozilla