Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/AudioBufferSourceNodeBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM AudioBufferSourceNode.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "AtomList.h"
4
#include "AudioBufferSourceNodeBinding.h"
5
#include "AudioScheduledSourceNodeBinding.h"
6
#include "WrapperFactory.h"
7
#include "mozilla/FloatingPoint.h"
8
#include "mozilla/OwningNonNull.h"
9
#include "mozilla/Preferences.h"
10
#include "mozilla/dom/AudioBuffer.h"
11
#include "mozilla/dom/AudioBufferSourceNode.h"
12
#include "mozilla/dom/AudioContext.h"
13
#include "mozilla/dom/AudioParam.h"
14
#include "mozilla/dom/BindingUtils.h"
15
#include "mozilla/dom/DOMJSClass.h"
16
#include "mozilla/dom/NonRefcountedDOMObject.h"
17
#include "mozilla/dom/Nullable.h"
18
#include "mozilla/dom/PrimitiveConversions.h"
19
#include "mozilla/dom/ScriptSettings.h"
20
#include "mozilla/dom/XrayExpandoClass.h"
21
#include "nsContentUtils.h"
22
23
namespace mozilla {
24
namespace dom {
25
26
namespace binding_detail {}; // Just to make sure it's known as a namespace
27
using namespace mozilla::dom::binding_detail;
28
29
30
31
AudioBufferSourceOptions::AudioBufferSourceOptions()
32
0
{
33
0
  // Safe to pass a null context if we pass a null value
34
0
  Init(nullptr, JS::NullHandleValue);
35
0
}
36
37
38
39
bool
40
AudioBufferSourceOptions::InitIds(JSContext* cx, AudioBufferSourceOptionsAtoms* atomsCache)
41
0
{
42
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
43
0
44
0
  // Initialize these in reverse order so that any failure leaves the first one
45
0
  // uninitialized.
46
0
  if (!atomsCache->playbackRate_id.init(cx, "playbackRate") ||
47
0
      !atomsCache->loopStart_id.init(cx, "loopStart") ||
48
0
      !atomsCache->loopEnd_id.init(cx, "loopEnd") ||
49
0
      !atomsCache->loop_id.init(cx, "loop") ||
50
0
      !atomsCache->detune_id.init(cx, "detune") ||
51
0
      !atomsCache->buffer_id.init(cx, "buffer")) {
52
0
    return false;
53
0
  }
54
0
  return true;
55
0
}
56
57
bool
58
AudioBufferSourceOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
59
0
{
60
0
  // Passing a null JSContext is OK only if we're initing from null,
61
0
  // Since in that case we will not have to do any property gets
62
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
63
0
  // checkers by static analysis tools
64
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
65
0
  AudioBufferSourceOptionsAtoms* atomsCache = nullptr;
66
0
  if (cx) {
67
0
    atomsCache = GetAtomCache<AudioBufferSourceOptionsAtoms>(cx);
68
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
69
0
      return false;
70
0
    }
71
0
  }
72
0
73
0
  if (!IsConvertibleToDictionary(val)) {
74
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
75
0
  }
76
0
77
0
  bool isNull = val.isNullOrUndefined();
78
0
  // We only need these if !isNull, in which case we have |cx|.
79
0
  Maybe<JS::Rooted<JSObject *> > object;
80
0
  Maybe<JS::Rooted<JS::Value> > temp;
81
0
  if (!isNull) {
82
0
    MOZ_ASSERT(cx);
83
0
    object.emplace(cx, &val.toObject());
84
0
    temp.emplace(cx);
85
0
  }
86
0
  if (!isNull) {
87
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->buffer_id, temp.ptr())) {
88
0
      return false;
89
0
    }
90
0
  }
91
0
  if (!isNull && !temp->isUndefined()) {
92
0
    mBuffer.Construct();
93
0
    if (temp.ref().isObject()) {
94
0
      static_assert(IsRefcounted<mozilla::dom::AudioBuffer>::value, "We can only store refcounted classes.");{
95
0
        nsresult rv = UnwrapObject<prototypes::id::AudioBuffer, mozilla::dom::AudioBuffer>(temp.ptr(), (mBuffer.Value()));
96
0
        if (NS_FAILED(rv)) {
97
0
          ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "'buffer' member of AudioBufferSourceOptions", "AudioBuffer");
98
0
          return false;
99
0
        }
100
0
      }
101
0
    } else if (temp.ref().isNullOrUndefined()) {
102
0
      (mBuffer.Value()) = nullptr;
103
0
    } else {
104
0
      ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'buffer' member of AudioBufferSourceOptions");
105
0
      return false;
106
0
    }
107
0
    mIsAnyMemberPresent = true;
108
0
  }
109
0
110
0
  if (!isNull) {
111
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->detune_id, temp.ptr())) {
112
0
      return false;
113
0
    }
114
0
  }
115
0
  if (!isNull && !temp->isUndefined()) {
116
0
    if (!ValueToPrimitive<float, eDefault>(cx, temp.ref(), &mDetune)) {
117
0
      return false;
118
0
    } else if (!mozilla::IsFinite(mDetune)) {
119
0
      ThrowErrorMessage(cx, MSG_NOT_FINITE, "'detune' member of AudioBufferSourceOptions");
120
0
      return false;
121
0
    }
122
0
  } else {
123
0
    mDetune = 0.0F;
124
0
  }
125
0
  mIsAnyMemberPresent = true;
126
0
127
0
  if (!isNull) {
128
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->loop_id, temp.ptr())) {
129
0
      return false;
130
0
    }
131
0
  }
132
0
  if (!isNull && !temp->isUndefined()) {
133
0
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mLoop)) {
134
0
      return false;
135
0
    }
136
0
  } else {
137
0
    mLoop = false;
138
0
  }
139
0
  mIsAnyMemberPresent = true;
140
0
141
0
  if (!isNull) {
142
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->loopEnd_id, temp.ptr())) {
143
0
      return false;
144
0
    }
145
0
  }
146
0
  if (!isNull && !temp->isUndefined()) {
147
0
    if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &mLoopEnd)) {
148
0
      return false;
149
0
    } else if (!mozilla::IsFinite(mLoopEnd)) {
150
0
      ThrowErrorMessage(cx, MSG_NOT_FINITE, "'loopEnd' member of AudioBufferSourceOptions");
151
0
      return false;
152
0
    }
153
0
  } else {
154
0
    mLoopEnd = 0.0;
155
0
  }
156
0
  mIsAnyMemberPresent = true;
157
0
158
0
  if (!isNull) {
159
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->loopStart_id, temp.ptr())) {
160
0
      return false;
161
0
    }
162
0
  }
163
0
  if (!isNull && !temp->isUndefined()) {
164
0
    if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &mLoopStart)) {
165
0
      return false;
166
0
    } else if (!mozilla::IsFinite(mLoopStart)) {
167
0
      ThrowErrorMessage(cx, MSG_NOT_FINITE, "'loopStart' member of AudioBufferSourceOptions");
168
0
      return false;
169
0
    }
170
0
  } else {
171
0
    mLoopStart = 0.0;
172
0
  }
173
0
  mIsAnyMemberPresent = true;
174
0
175
0
  if (!isNull) {
176
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->playbackRate_id, temp.ptr())) {
177
0
      return false;
178
0
    }
179
0
  }
180
0
  if (!isNull && !temp->isUndefined()) {
181
0
    if (!ValueToPrimitive<float, eDefault>(cx, temp.ref(), &mPlaybackRate)) {
182
0
      return false;
183
0
    } else if (!mozilla::IsFinite(mPlaybackRate)) {
184
0
      ThrowErrorMessage(cx, MSG_NOT_FINITE, "'playbackRate' member of AudioBufferSourceOptions");
185
0
      return false;
186
0
    }
187
0
  } else {
188
0
    mPlaybackRate = 1.0F;
189
0
  }
190
0
  mIsAnyMemberPresent = true;
191
0
  return true;
192
0
}
193
194
bool
195
AudioBufferSourceOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
196
0
{
197
0
  AudioBufferSourceOptionsAtoms* atomsCache = GetAtomCache<AudioBufferSourceOptionsAtoms>(cx);
198
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
199
0
    return false;
200
0
  }
201
0
202
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
203
0
  if (!obj) {
204
0
    return false;
205
0
  }
206
0
  rval.set(JS::ObjectValue(*obj));
207
0
208
0
  if (mBuffer.WasPassed()) {
209
0
    do {
210
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
211
0
      JS::Rooted<JS::Value> temp(cx);
212
0
      RefPtr<mozilla::dom::AudioBuffer> const & currentValue = mBuffer.InternalValue();
213
0
      if (!currentValue) {
214
0
        temp.setNull();
215
0
        if (!JS_DefinePropertyById(cx, obj, atomsCache->buffer_id, temp, JSPROP_ENUMERATE)) {
216
0
          return false;
217
0
        }
218
0
        break;
219
0
      }
220
0
      if (!GetOrCreateDOMReflector(cx, currentValue, &temp)) {
221
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
222
0
        return false;
223
0
      }
224
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->buffer_id, temp, JSPROP_ENUMERATE)) {
225
0
        return false;
226
0
      }
227
0
      break;
228
0
    } while(false);
229
0
  }
230
0
231
0
  do {
232
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
233
0
    JS::Rooted<JS::Value> temp(cx);
234
0
    float const & currentValue = mDetune;
235
0
    temp.set(JS_NumberValue(double(currentValue)));
236
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->detune_id, temp, JSPROP_ENUMERATE)) {
237
0
      return false;
238
0
    }
239
0
    break;
240
0
  } while(false);
241
0
242
0
  do {
243
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
244
0
    JS::Rooted<JS::Value> temp(cx);
245
0
    bool const & currentValue = mLoop;
246
0
    temp.setBoolean(currentValue);
247
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->loop_id, temp, JSPROP_ENUMERATE)) {
248
0
      return false;
249
0
    }
250
0
    break;
251
0
  } while(false);
252
0
253
0
  do {
254
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
255
0
    JS::Rooted<JS::Value> temp(cx);
256
0
    double const & currentValue = mLoopEnd;
257
0
    temp.set(JS_NumberValue(double(currentValue)));
258
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->loopEnd_id, temp, JSPROP_ENUMERATE)) {
259
0
      return false;
260
0
    }
261
0
    break;
262
0
  } while(false);
263
0
264
0
  do {
265
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
266
0
    JS::Rooted<JS::Value> temp(cx);
267
0
    double const & currentValue = mLoopStart;
268
0
    temp.set(JS_NumberValue(double(currentValue)));
269
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->loopStart_id, temp, JSPROP_ENUMERATE)) {
270
0
      return false;
271
0
    }
272
0
    break;
273
0
  } while(false);
274
0
275
0
  do {
276
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
277
0
    JS::Rooted<JS::Value> temp(cx);
278
0
    float const & currentValue = mPlaybackRate;
279
0
    temp.set(JS_NumberValue(double(currentValue)));
280
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->playbackRate_id, temp, JSPROP_ENUMERATE)) {
281
0
      return false;
282
0
    }
283
0
    break;
284
0
  } while(false);
285
0
286
0
  return true;
287
0
}
288
289
void
290
AudioBufferSourceOptions::TraceDictionary(JSTracer* trc)
291
0
{
292
0
}
293
294
295
296
AudioBufferSourceOptions&
297
AudioBufferSourceOptions::operator=(const AudioBufferSourceOptions& aOther)
298
0
{
299
0
  DictionaryBase::operator=(aOther);
300
0
  mBuffer.Reset();
301
0
  if (aOther.mBuffer.WasPassed()) {
302
0
    mBuffer.Construct(aOther.mBuffer.Value());
303
0
  }
304
0
  mDetune = aOther.mDetune;
305
0
  mLoop = aOther.mLoop;
306
0
  mLoopEnd = aOther.mLoopEnd;
307
0
  mLoopStart = aOther.mLoopStart;
308
0
  mPlaybackRate = aOther.mPlaybackRate;
309
0
  return *this;
310
0
}
311
312
namespace binding_detail {
313
} // namespace binding_detail
314
315
316
namespace AudioBufferSourceNode_Binding {
317
318
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<AudioScheduledSourceNode_Binding::NativeType>::value,
319
              "Can't inherit from an interface with a different ownership model.");
320
321
MOZ_CAN_RUN_SCRIPT static bool
322
get_buffer(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioBufferSourceNode* self, JSJitGetterCallArgs args)
323
0
{
324
0
  AUTO_PROFILER_LABEL_FAST("get AudioBufferSourceNode.buffer", DOM, cx);
325
0
326
0
  auto result(StrongOrRawPtr<mozilla::dom::AudioBuffer>(self->GetBuffer(cx)));
327
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
328
0
  if (!result) {
329
0
    args.rval().setNull();
330
0
    return true;
331
0
  }
332
0
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
333
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
334
0
    return false;
335
0
  }
336
0
  return true;
337
0
}
338
339
MOZ_CAN_RUN_SCRIPT static bool
340
set_buffer(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioBufferSourceNode* self, JSJitSetterCallArgs args)
341
0
{
342
0
  AUTO_PROFILER_LABEL_FAST("set AudioBufferSourceNode.buffer", DOM, cx);
343
0
344
0
  mozilla::dom::AudioBuffer* arg0;
345
0
  if (args[0].isObject()) {
346
0
    {
347
0
      nsresult rv = UnwrapObject<prototypes::id::AudioBuffer, mozilla::dom::AudioBuffer>(args[0], arg0);
348
0
      if (NS_FAILED(rv)) {
349
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Value being assigned to AudioBufferSourceNode.buffer", "AudioBuffer");
350
0
        return false;
351
0
      }
352
0
    }
353
0
  } else if (args[0].isNullOrUndefined()) {
354
0
    arg0 = nullptr;
355
0
  } else {
356
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Value being assigned to AudioBufferSourceNode.buffer");
357
0
    return false;
358
0
  }
359
0
  self->SetBuffer(cx, MOZ_KnownLive(Constify(arg0)));
360
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
361
0
362
0
  return true;
363
0
}
364
365
static const JSJitInfo buffer_getterinfo = {
366
  { (JSJitGetterOp)get_buffer },
367
  { prototypes::id::AudioBufferSourceNode },
368
  { PrototypeTraits<prototypes::id::AudioBufferSourceNode>::Depth },
369
  JSJitInfo::Getter,
370
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
371
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
372
  false,  /* isInfallible. False in setters. */
373
  false,  /* isMovable.  Not relevant for setters. */
374
  false, /* isEliminatable.  Not relevant for setters. */
375
  false, /* isAlwaysInSlot.  Only relevant for getters. */
376
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
377
  false,  /* isTypedMethod.  Only relevant for methods. */
378
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
379
};
380
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
381
static_assert(0 < 1, "There is no slot for us");
382
static const JSJitInfo buffer_setterinfo = {
383
  { (JSJitGetterOp)set_buffer },
384
  { prototypes::id::AudioBufferSourceNode },
385
  { PrototypeTraits<prototypes::id::AudioBufferSourceNode>::Depth },
386
  JSJitInfo::Setter,
387
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
388
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
389
  false,  /* isInfallible. False in setters. */
390
  false,  /* isMovable.  Not relevant for setters. */
391
  false, /* isEliminatable.  Not relevant for setters. */
392
  false, /* isAlwaysInSlot.  Only relevant for getters. */
393
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
394
  false,  /* isTypedMethod.  Only relevant for methods. */
395
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
396
};
397
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
398
static_assert(0 < 1, "There is no slot for us");
399
400
MOZ_CAN_RUN_SCRIPT static bool
401
get_playbackRate(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioBufferSourceNode* self, JSJitGetterCallArgs args)
402
0
{
403
0
  AUTO_PROFILER_LABEL_FAST("get AudioBufferSourceNode.playbackRate", DOM, cx);
404
0
405
0
  auto result(StrongOrRawPtr<mozilla::dom::AudioParam>(self->PlaybackRate()));
406
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
407
0
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
408
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
409
0
    return false;
410
0
  }
411
0
  return true;
412
0
}
413
414
static const JSJitInfo playbackRate_getterinfo = {
415
  { (JSJitGetterOp)get_playbackRate },
416
  { prototypes::id::AudioBufferSourceNode },
417
  { PrototypeTraits<prototypes::id::AudioBufferSourceNode>::Depth },
418
  JSJitInfo::Getter,
419
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
420
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
421
  false,  /* isInfallible. False in setters. */
422
  false,  /* isMovable.  Not relevant for setters. */
423
  false, /* isEliminatable.  Not relevant for setters. */
424
  false, /* isAlwaysInSlot.  Only relevant for getters. */
425
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
426
  false,  /* isTypedMethod.  Only relevant for methods. */
427
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
428
};
429
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
430
static_assert(0 < 1, "There is no slot for us");
431
432
MOZ_CAN_RUN_SCRIPT static bool
433
get_detune(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioBufferSourceNode* self, JSJitGetterCallArgs args)
434
0
{
435
0
  AUTO_PROFILER_LABEL_FAST("get AudioBufferSourceNode.detune", DOM, cx);
436
0
437
0
  auto result(StrongOrRawPtr<mozilla::dom::AudioParam>(self->Detune()));
438
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
439
0
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
440
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
441
0
    return false;
442
0
  }
443
0
  return true;
444
0
}
445
446
static const JSJitInfo detune_getterinfo = {
447
  { (JSJitGetterOp)get_detune },
448
  { prototypes::id::AudioBufferSourceNode },
449
  { PrototypeTraits<prototypes::id::AudioBufferSourceNode>::Depth },
450
  JSJitInfo::Getter,
451
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
452
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
453
  false,  /* isInfallible. False in setters. */
454
  false,  /* isMovable.  Not relevant for setters. */
455
  false, /* isEliminatable.  Not relevant for setters. */
456
  false, /* isAlwaysInSlot.  Only relevant for getters. */
457
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
458
  false,  /* isTypedMethod.  Only relevant for methods. */
459
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
460
};
461
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
462
static_assert(0 < 1, "There is no slot for us");
463
464
MOZ_CAN_RUN_SCRIPT static bool
465
get_loop(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioBufferSourceNode* self, JSJitGetterCallArgs args)
466
0
{
467
0
  AUTO_PROFILER_LABEL_FAST("get AudioBufferSourceNode.loop", DOM, cx);
468
0
469
0
  bool result(self->Loop());
470
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
471
0
  args.rval().setBoolean(result);
472
0
  return true;
473
0
}
474
475
MOZ_CAN_RUN_SCRIPT static bool
476
set_loop(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioBufferSourceNode* self, JSJitSetterCallArgs args)
477
0
{
478
0
  AUTO_PROFILER_LABEL_FAST("set AudioBufferSourceNode.loop", DOM, cx);
479
0
480
0
  bool arg0;
481
0
  if (!ValueToPrimitive<bool, eDefault>(cx, args[0], &arg0)) {
482
0
    return false;
483
0
  }
484
0
  self->SetLoop(arg0);
485
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
486
0
487
0
  return true;
488
0
}
489
490
static const JSJitInfo loop_getterinfo = {
491
  { (JSJitGetterOp)get_loop },
492
  { prototypes::id::AudioBufferSourceNode },
493
  { PrototypeTraits<prototypes::id::AudioBufferSourceNode>::Depth },
494
  JSJitInfo::Getter,
495
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
496
  JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
497
  true,  /* isInfallible. False in setters. */
498
  false,  /* isMovable.  Not relevant for setters. */
499
  false, /* isEliminatable.  Not relevant for setters. */
500
  false, /* isAlwaysInSlot.  Only relevant for getters. */
501
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
502
  false,  /* isTypedMethod.  Only relevant for methods. */
503
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
504
};
505
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
506
static_assert(0 < 1, "There is no slot for us");
507
static const JSJitInfo loop_setterinfo = {
508
  { (JSJitGetterOp)set_loop },
509
  { prototypes::id::AudioBufferSourceNode },
510
  { PrototypeTraits<prototypes::id::AudioBufferSourceNode>::Depth },
511
  JSJitInfo::Setter,
512
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
513
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
514
  false,  /* isInfallible. False in setters. */
515
  false,  /* isMovable.  Not relevant for setters. */
516
  false, /* isEliminatable.  Not relevant for setters. */
517
  false, /* isAlwaysInSlot.  Only relevant for getters. */
518
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
519
  false,  /* isTypedMethod.  Only relevant for methods. */
520
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
521
};
522
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
523
static_assert(0 < 1, "There is no slot for us");
524
525
MOZ_CAN_RUN_SCRIPT static bool
526
get_loopStart(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioBufferSourceNode* self, JSJitGetterCallArgs args)
527
0
{
528
0
  AUTO_PROFILER_LABEL_FAST("get AudioBufferSourceNode.loopStart", DOM, cx);
529
0
530
0
  double result(self->LoopStart());
531
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
532
0
  args.rval().set(JS_NumberValue(double(result)));
533
0
  return true;
534
0
}
535
536
MOZ_CAN_RUN_SCRIPT static bool
537
set_loopStart(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioBufferSourceNode* self, JSJitSetterCallArgs args)
538
0
{
539
0
  AUTO_PROFILER_LABEL_FAST("set AudioBufferSourceNode.loopStart", DOM, cx);
540
0
541
0
  double arg0;
542
0
  if (!ValueToPrimitive<double, eDefault>(cx, args[0], &arg0)) {
543
0
    return false;
544
0
  } else if (!mozilla::IsFinite(arg0)) {
545
0
    ThrowErrorMessage(cx, MSG_NOT_FINITE, "Value being assigned to AudioBufferSourceNode.loopStart");
546
0
    return false;
547
0
  }
548
0
  self->SetLoopStart(arg0);
549
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
550
0
551
0
  return true;
552
0
}
553
554
static const JSJitInfo loopStart_getterinfo = {
555
  { (JSJitGetterOp)get_loopStart },
556
  { prototypes::id::AudioBufferSourceNode },
557
  { PrototypeTraits<prototypes::id::AudioBufferSourceNode>::Depth },
558
  JSJitInfo::Getter,
559
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
560
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
561
  true,  /* isInfallible. False in setters. */
562
  false,  /* isMovable.  Not relevant for setters. */
563
  false, /* isEliminatable.  Not relevant for setters. */
564
  false, /* isAlwaysInSlot.  Only relevant for getters. */
565
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
566
  false,  /* isTypedMethod.  Only relevant for methods. */
567
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
568
};
569
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
570
static_assert(0 < 1, "There is no slot for us");
571
static const JSJitInfo loopStart_setterinfo = {
572
  { (JSJitGetterOp)set_loopStart },
573
  { prototypes::id::AudioBufferSourceNode },
574
  { PrototypeTraits<prototypes::id::AudioBufferSourceNode>::Depth },
575
  JSJitInfo::Setter,
576
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
577
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
578
  false,  /* isInfallible. False in setters. */
579
  false,  /* isMovable.  Not relevant for setters. */
580
  false, /* isEliminatable.  Not relevant for setters. */
581
  false, /* isAlwaysInSlot.  Only relevant for getters. */
582
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
583
  false,  /* isTypedMethod.  Only relevant for methods. */
584
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
585
};
586
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
587
static_assert(0 < 1, "There is no slot for us");
588
589
MOZ_CAN_RUN_SCRIPT static bool
590
get_loopEnd(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioBufferSourceNode* self, JSJitGetterCallArgs args)
591
0
{
592
0
  AUTO_PROFILER_LABEL_FAST("get AudioBufferSourceNode.loopEnd", DOM, cx);
593
0
594
0
  double result(self->LoopEnd());
595
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
596
0
  args.rval().set(JS_NumberValue(double(result)));
597
0
  return true;
598
0
}
599
600
MOZ_CAN_RUN_SCRIPT static bool
601
set_loopEnd(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioBufferSourceNode* self, JSJitSetterCallArgs args)
602
0
{
603
0
  AUTO_PROFILER_LABEL_FAST("set AudioBufferSourceNode.loopEnd", DOM, cx);
604
0
605
0
  double arg0;
606
0
  if (!ValueToPrimitive<double, eDefault>(cx, args[0], &arg0)) {
607
0
    return false;
608
0
  } else if (!mozilla::IsFinite(arg0)) {
609
0
    ThrowErrorMessage(cx, MSG_NOT_FINITE, "Value being assigned to AudioBufferSourceNode.loopEnd");
610
0
    return false;
611
0
  }
612
0
  self->SetLoopEnd(arg0);
613
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
614
0
615
0
  return true;
616
0
}
617
618
static const JSJitInfo loopEnd_getterinfo = {
619
  { (JSJitGetterOp)get_loopEnd },
620
  { prototypes::id::AudioBufferSourceNode },
621
  { PrototypeTraits<prototypes::id::AudioBufferSourceNode>::Depth },
622
  JSJitInfo::Getter,
623
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
624
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
625
  true,  /* isInfallible. False in setters. */
626
  false,  /* isMovable.  Not relevant for setters. */
627
  false, /* isEliminatable.  Not relevant for setters. */
628
  false, /* isAlwaysInSlot.  Only relevant for getters. */
629
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
630
  false,  /* isTypedMethod.  Only relevant for methods. */
631
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
632
};
633
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
634
static_assert(0 < 1, "There is no slot for us");
635
static const JSJitInfo loopEnd_setterinfo = {
636
  { (JSJitGetterOp)set_loopEnd },
637
  { prototypes::id::AudioBufferSourceNode },
638
  { PrototypeTraits<prototypes::id::AudioBufferSourceNode>::Depth },
639
  JSJitInfo::Setter,
640
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
641
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
642
  false,  /* isInfallible. False in setters. */
643
  false,  /* isMovable.  Not relevant for setters. */
644
  false, /* isEliminatable.  Not relevant for setters. */
645
  false, /* isAlwaysInSlot.  Only relevant for getters. */
646
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
647
  false,  /* isTypedMethod.  Only relevant for methods. */
648
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
649
};
650
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
651
static_assert(0 < 1, "There is no slot for us");
652
653
MOZ_CAN_RUN_SCRIPT static bool
654
start(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioBufferSourceNode* self, const JSJitMethodCallArgs& args)
655
0
{
656
0
  AUTO_PROFILER_LABEL_FAST("AudioBufferSourceNode.start", DOM, cx);
657
0
658
0
  double arg0;
659
0
  if (args.hasDefined(0)) {
660
0
    if (!ValueToPrimitive<double, eDefault>(cx, args[0], &arg0)) {
661
0
      return false;
662
0
    } else if (!mozilla::IsFinite(arg0)) {
663
0
      ThrowErrorMessage(cx, MSG_NOT_FINITE, "Argument 1 of AudioBufferSourceNode.start");
664
0
      return false;
665
0
    }
666
0
  } else {
667
0
    arg0 = 0.0;
668
0
  }
669
0
  double arg1;
670
0
  if (args.hasDefined(1)) {
671
0
    if (!ValueToPrimitive<double, eDefault>(cx, args[1], &arg1)) {
672
0
      return false;
673
0
    } else if (!mozilla::IsFinite(arg1)) {
674
0
      ThrowErrorMessage(cx, MSG_NOT_FINITE, "Argument 2 of AudioBufferSourceNode.start");
675
0
      return false;
676
0
    }
677
0
  } else {
678
0
    arg1 = 0.0;
679
0
  }
680
0
  Optional<double> arg2;
681
0
  if (args.hasDefined(2)) {
682
0
    arg2.Construct();
683
0
    if (!ValueToPrimitive<double, eDefault>(cx, args[2], &arg2.Value())) {
684
0
      return false;
685
0
    } else if (!mozilla::IsFinite(arg2.Value())) {
686
0
      ThrowErrorMessage(cx, MSG_NOT_FINITE, "Argument 3 of AudioBufferSourceNode.start");
687
0
      return false;
688
0
    }
689
0
  }
690
0
  FastErrorResult rv;
691
0
  self->Start(arg0, arg1, Constify(arg2), rv);
692
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
693
0
    return false;
694
0
  }
695
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
696
0
  args.rval().setUndefined();
697
0
  return true;
698
0
}
699
700
static const JSJitInfo start_methodinfo = {
701
  { (JSJitGetterOp)start },
702
  { prototypes::id::AudioBufferSourceNode },
703
  { PrototypeTraits<prototypes::id::AudioBufferSourceNode>::Depth },
704
  JSJitInfo::Method,
705
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
706
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
707
  false,  /* isInfallible. False in setters. */
708
  false,  /* isMovable.  Not relevant for setters. */
709
  false, /* isEliminatable.  Not relevant for setters. */
710
  false, /* isAlwaysInSlot.  Only relevant for getters. */
711
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
712
  false,  /* isTypedMethod.  Only relevant for methods. */
713
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
714
};
715
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
716
static_assert(0 < 1, "There is no slot for us");
717
718
MOZ_CAN_RUN_SCRIPT static bool
719
get_passThrough(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioBufferSourceNode* self, JSJitGetterCallArgs args)
720
0
{
721
0
  AUTO_PROFILER_LABEL_FAST("get AudioBufferSourceNode.passThrough", DOM, cx);
722
0
723
0
  bool result(self->PassThrough());
724
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
725
0
  args.rval().setBoolean(result);
726
0
  return true;
727
0
}
728
729
MOZ_CAN_RUN_SCRIPT static bool
730
set_passThrough(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioBufferSourceNode* self, JSJitSetterCallArgs args)
731
0
{
732
0
  AUTO_PROFILER_LABEL_FAST("set AudioBufferSourceNode.passThrough", DOM, cx);
733
0
734
0
  bool arg0;
735
0
  if (!ValueToPrimitive<bool, eDefault>(cx, args[0], &arg0)) {
736
0
    return false;
737
0
  }
738
0
  self->SetPassThrough(arg0);
739
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
740
0
741
0
  return true;
742
0
}
743
744
static const JSJitInfo passThrough_getterinfo = {
745
  { (JSJitGetterOp)get_passThrough },
746
  { prototypes::id::AudioBufferSourceNode },
747
  { PrototypeTraits<prototypes::id::AudioBufferSourceNode>::Depth },
748
  JSJitInfo::Getter,
749
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
750
  JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
751
  true,  /* isInfallible. False in setters. */
752
  false,  /* isMovable.  Not relevant for setters. */
753
  false, /* isEliminatable.  Not relevant for setters. */
754
  false, /* isAlwaysInSlot.  Only relevant for getters. */
755
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
756
  false,  /* isTypedMethod.  Only relevant for methods. */
757
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
758
};
759
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
760
static_assert(0 < 1, "There is no slot for us");
761
static const JSJitInfo passThrough_setterinfo = {
762
  { (JSJitGetterOp)set_passThrough },
763
  { prototypes::id::AudioBufferSourceNode },
764
  { PrototypeTraits<prototypes::id::AudioBufferSourceNode>::Depth },
765
  JSJitInfo::Setter,
766
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
767
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
768
  false,  /* isInfallible. False in setters. */
769
  false,  /* isMovable.  Not relevant for setters. */
770
  false, /* isEliminatable.  Not relevant for setters. */
771
  false, /* isAlwaysInSlot.  Only relevant for getters. */
772
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
773
  false,  /* isTypedMethod.  Only relevant for methods. */
774
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
775
};
776
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
777
static_assert(0 < 1, "There is no slot for us");
778
779
static bool
780
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
781
0
{
782
0
  mozilla::dom::AudioBufferSourceNode* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AudioBufferSourceNode>(obj);
783
0
  // We don't want to preserve if we don't have a wrapper, and we
784
0
  // obviously can't preserve if we're not initialized.
785
0
  if (self && self->GetWrapperPreserveColor()) {
786
0
    PreserveWrapper(self);
787
0
  }
788
0
  return true;
789
0
}
790
791
static void
792
_finalize(js::FreeOp* fop, JSObject* obj)
793
0
{
794
0
  mozilla::dom::AudioBufferSourceNode* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AudioBufferSourceNode>(obj);
795
0
  if (self) {
796
0
    ClearWrapper(self, self, obj);
797
0
    AddForDeferredFinalization<mozilla::dom::AudioBufferSourceNode>(self);
798
0
  }
799
0
}
800
801
static size_t
802
_objectMoved(JSObject* obj, JSObject* old)
803
0
{
804
0
  mozilla::dom::AudioBufferSourceNode* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AudioBufferSourceNode>(obj);
805
0
  if (self) {
806
0
    UpdateWrapper(self, self, obj, old);
807
0
  }
808
0
809
0
  return 0;
810
0
}
811
812
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
813
#if defined(__clang__)
814
#pragma clang diagnostic push
815
#pragma clang diagnostic ignored "-Wmissing-braces"
816
#endif
817
static const JSFunctionSpec sMethods_specs[] = {
818
  JS_FNSPEC("start", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&start_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
819
  JS_FS_END
820
};
821
#if defined(__clang__)
822
#pragma clang diagnostic pop
823
#endif
824
825
826
static const Prefable<const JSFunctionSpec> sMethods[] = {
827
  { nullptr, &sMethods_specs[0] },
828
  { nullptr, nullptr }
829
};
830
831
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
832
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
833
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
834
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
835
836
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
837
#if defined(__clang__)
838
#pragma clang diagnostic push
839
#pragma clang diagnostic ignored "-Wmissing-braces"
840
#endif
841
static const JSPropertySpec sAttributes_specs[] = {
842
  { "buffer", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &buffer_getterinfo, GenericSetter<NormalThisPolicy>, &buffer_setterinfo },
843
  { "playbackRate", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &playbackRate_getterinfo, nullptr, nullptr },
844
  { "detune", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &detune_getterinfo, nullptr, nullptr },
845
  { "loop", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &loop_getterinfo, GenericSetter<NormalThisPolicy>, &loop_setterinfo },
846
  { "loopStart", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &loopStart_getterinfo, GenericSetter<NormalThisPolicy>, &loopStart_setterinfo },
847
  { "loopEnd", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &loopEnd_getterinfo, GenericSetter<NormalThisPolicy>, &loopEnd_setterinfo },
848
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
849
};
850
#if defined(__clang__)
851
#pragma clang diagnostic pop
852
#endif
853
854
855
static const Prefable<const JSPropertySpec> sAttributes[] = {
856
  { nullptr, &sAttributes_specs[0] },
857
  { nullptr, nullptr }
858
};
859
860
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
861
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
862
static_assert(6 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
863
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
864
865
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
866
#if defined(__clang__)
867
#pragma clang diagnostic push
868
#pragma clang diagnostic ignored "-Wmissing-braces"
869
#endif
870
static const JSPropertySpec sChromeAttributes_specs[] = {
871
  { "passThrough", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &passThrough_getterinfo, GenericSetter<NormalThisPolicy>, &passThrough_setterinfo },
872
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
873
};
874
#if defined(__clang__)
875
#pragma clang diagnostic pop
876
#endif
877
878
879
static const Prefable<const JSPropertySpec> sChromeAttributes[] = {
880
  { nullptr, &sChromeAttributes_specs[0] },
881
  { nullptr, nullptr }
882
};
883
884
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
885
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
886
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
887
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
888
889
890
static uint16_t sNativeProperties_sortedPropertyIndices[7];
891
static PropertyInfo sNativeProperties_propertyInfos[7];
892
893
static const NativePropertiesN<2> sNativeProperties = {
894
  false, 0,
895
  false, 0,
896
  true,  0 /* sMethods */,
897
  true,  1 /* sAttributes */,
898
  false, 0,
899
  false, 0,
900
  false, 0,
901
  -1,
902
  7,
903
  sNativeProperties_sortedPropertyIndices,
904
  {
905
    { sMethods, &sNativeProperties_propertyInfos[0] },
906
    { sAttributes, &sNativeProperties_propertyInfos[1] }
907
  }
908
};
909
static_assert(7 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
910
    "We have a property info count that is oversized");
911
912
static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[1];
913
static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[1];
914
915
static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
916
  false, 0,
917
  false, 0,
918
  false, 0,
919
  true,  0 /* sChromeAttributes */,
920
  false, 0,
921
  false, 0,
922
  false, 0,
923
  -1,
924
  1,
925
  sChromeOnlyNativeProperties_sortedPropertyIndices,
926
  {
927
    { sChromeAttributes, &sChromeOnlyNativeProperties_propertyInfos[0] }
928
  }
929
};
930
static_assert(1 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
931
    "We have a property info count that is oversized");
932
933
static bool
934
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
935
0
{
936
0
  AUTO_PROFILER_LABEL_FAST("AudioBufferSourceNode constructor", DOM, cx);
937
0
938
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
939
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
940
0
  if (!args.isConstructing()) {
941
0
    // XXXbz wish I could get the name from the callee instead of
942
0
    // Adding more relocations
943
0
    return ThrowConstructorWithoutNew(cx, "AudioBufferSourceNode");
944
0
  }
945
0
946
0
  JS::Rooted<JSObject*> desiredProto(cx);
947
0
  if (!GetDesiredProto(cx, args, &desiredProto)) {
948
0
    return false;
949
0
  }
950
0
951
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
952
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "AudioBufferSourceNode");
953
0
  }
954
0
  GlobalObject global(cx, obj);
955
0
  if (global.Failed()) {
956
0
    return false;
957
0
  }
958
0
959
0
  bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
960
0
  NonNull<mozilla::dom::AudioContext> arg0;
961
0
  if (args[0].isObject()) {
962
0
    {
963
0
      nsresult rv = UnwrapObject<prototypes::id::BaseAudioContext, mozilla::dom::AudioContext>(args[0], arg0);
964
0
      if (NS_FAILED(rv)) {
965
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of AudioBufferSourceNode.constructor", "BaseAudioContext");
966
0
        return false;
967
0
      }
968
0
    }
969
0
  } else {
970
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of AudioBufferSourceNode.constructor");
971
0
    return false;
972
0
  }
973
0
  binding_detail::FastAudioBufferSourceOptions arg1;
974
0
  if (!arg1.Init(cx, (args.hasDefined(1)) ? args[1] : JS::NullHandleValue,  "Argument 2 of AudioBufferSourceNode.constructor", false)) {
975
0
    return false;
976
0
  }
977
0
  Maybe<JSAutoRealm> ar;
978
0
  if (objIsXray) {
979
0
    obj = js::CheckedUnwrap(obj);
980
0
    if (!obj) {
981
0
      return false;
982
0
    }
983
0
    ar.emplace(cx, obj);
984
0
    if (!JS_WrapObject(cx, &desiredProto)) {
985
0
      return false;
986
0
    }
987
0
  }
988
0
  FastErrorResult rv;
989
0
  auto result(StrongOrRawPtr<mozilla::dom::AudioBufferSourceNode>(mozilla::dom::AudioBufferSourceNode::Constructor(global, MOZ_KnownLive(NonNullHelper(arg0)), Constify(arg1), rv)));
990
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
991
0
    return false;
992
0
  }
993
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
994
0
  static_assert(!IsPointer<decltype(result)>::value,
995
0
                "NewObject implies that we need to keep the object alive with a strong reference.");
996
0
  if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
997
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
998
0
    return false;
999
0
  }
1000
0
  return true;
1001
0
}
1002
1003
static const js::ClassOps sInterfaceObjectClassOps = {
1004
    nullptr,               /* addProperty */
1005
    nullptr,               /* delProperty */
1006
    nullptr,               /* enumerate */
1007
    nullptr,               /* newEnumerate */
1008
    nullptr,               /* resolve */
1009
    nullptr,               /* mayResolve */
1010
    nullptr,               /* finalize */
1011
    _constructor, /* call */
1012
    nullptr,               /* hasInstance */
1013
    _constructor, /* construct */
1014
    nullptr,               /* trace */
1015
};
1016
1017
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1018
  {
1019
    "Function",
1020
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1021
    &sInterfaceObjectClassOps,
1022
    JS_NULL_CLASS_SPEC,
1023
    JS_NULL_CLASS_EXT,
1024
    &sInterfaceObjectClassObjectOps
1025
  },
1026
  eInterface,
1027
  true,
1028
  prototypes::id::AudioBufferSourceNode,
1029
  PrototypeTraits<prototypes::id::AudioBufferSourceNode>::Depth,
1030
  sNativePropertyHooks,
1031
  "function AudioBufferSourceNode() {\n    [native code]\n}",
1032
  AudioScheduledSourceNode_Binding::GetConstructorObject
1033
};
1034
1035
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1036
  {
1037
    "AudioBufferSourceNodePrototype",
1038
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
1039
    JS_NULL_CLASS_OPS,
1040
    JS_NULL_CLASS_SPEC,
1041
    JS_NULL_CLASS_EXT,
1042
    JS_NULL_OBJECT_OPS
1043
  },
1044
  eInterfacePrototype,
1045
  false,
1046
  prototypes::id::AudioBufferSourceNode,
1047
  PrototypeTraits<prototypes::id::AudioBufferSourceNode>::Depth,
1048
  sNativePropertyHooks,
1049
  "[object AudioBufferSourceNodePrototype]",
1050
  AudioScheduledSourceNode_Binding::GetProtoObject
1051
};
1052
1053
bool
1054
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
1055
0
{
1056
0
  static bool sPrefValue;
1057
0
  static bool sPrefCacheSetUp = false;
1058
0
  if (!sPrefCacheSetUp) {
1059
0
    sPrefCacheSetUp = true;
1060
0
    Preferences::AddBoolVarCache(&sPrefValue, "dom.webaudio.enabled");
1061
0
  }
1062
0
1063
0
  return sPrefValue;
1064
0
}
1065
1066
static const js::ClassOps sClassOps = {
1067
  _addProperty, /* addProperty */
1068
  nullptr,               /* delProperty */
1069
  nullptr,               /* enumerate */
1070
  nullptr, /* newEnumerate */
1071
  nullptr, /* resolve */
1072
  nullptr, /* mayResolve */
1073
  _finalize, /* finalize */
1074
  nullptr, /* call */
1075
  nullptr,               /* hasInstance */
1076
  nullptr,               /* construct */
1077
  nullptr, /* trace */
1078
};
1079
1080
static const js::ClassExtension sClassExtension = {
1081
  nullptr, /* weakmapKeyDelegateOp */
1082
  _objectMoved /* objectMovedOp */
1083
};
1084
1085
static const DOMJSClass sClass = {
1086
  { "AudioBufferSourceNode",
1087
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
1088
    &sClassOps,
1089
    JS_NULL_CLASS_SPEC,
1090
    &sClassExtension,
1091
    JS_NULL_OBJECT_OPS
1092
  },
1093
  { prototypes::id::EventTarget, prototypes::id::AudioNode, prototypes::id::AudioScheduledSourceNode, prototypes::id::AudioBufferSourceNode, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
1094
  IsBaseOf<nsISupports, mozilla::dom::AudioBufferSourceNode >::value,
1095
  sNativePropertyHooks,
1096
  FindAssociatedGlobalForNative<mozilla::dom::AudioBufferSourceNode>::Get,
1097
  GetProtoObjectHandle,
1098
  GetCCParticipant<mozilla::dom::AudioBufferSourceNode>::Get()
1099
};
1100
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1101
              "Must have the right minimal number of reserved slots.");
1102
static_assert(1 >= 1,
1103
              "Must have enough reserved slots.");
1104
1105
const JSClass*
1106
GetJSClass()
1107
0
{
1108
0
  return sClass.ToJSClass();
1109
0
}
1110
1111
bool
1112
Wrap(JSContext* aCx, mozilla::dom::AudioBufferSourceNode* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1113
0
{
1114
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::AudioBufferSourceNode>::value,
1115
0
                "Shouldn't have wrappercached things that are not refcounted.");
1116
0
  MOZ_ASSERT(static_cast<mozilla::dom::AudioBufferSourceNode*>(aObject) ==
1117
0
             reinterpret_cast<mozilla::dom::AudioBufferSourceNode*>(aObject),
1118
0
             "Multiple inheritance for mozilla::dom::AudioBufferSourceNode is broken.");
1119
0
  MOZ_ASSERT(static_cast<mozilla::dom::AudioScheduledSourceNode*>(aObject) ==
1120
0
             reinterpret_cast<mozilla::dom::AudioScheduledSourceNode*>(aObject),
1121
0
             "Multiple inheritance for mozilla::dom::AudioScheduledSourceNode is broken.");
1122
0
  MOZ_ASSERT(static_cast<mozilla::dom::AudioNode*>(aObject) ==
1123
0
             reinterpret_cast<mozilla::dom::AudioNode*>(aObject),
1124
0
             "Multiple inheritance for mozilla::dom::AudioNode is broken.");
1125
0
  MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
1126
0
             reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
1127
0
             "Multiple inheritance for mozilla::dom::EventTarget is broken.");
1128
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1129
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1130
0
  MOZ_ASSERT(!aCache->GetWrapper(),
1131
0
             "You should probably not be using Wrap() directly; use "
1132
0
             "GetOrCreateDOMReflector instead");
1133
0
1134
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1135
0
             "nsISupports must be on our primary inheritance chain");
1136
0
1137
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1138
0
  if (!global) {
1139
0
    return false;
1140
0
  }
1141
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
1142
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
1143
0
1144
0
  // That might have ended up wrapping us already, due to the wonders
1145
0
  // of XBL.  Check for that, and bail out as needed.
1146
0
  aReflector.set(aCache->GetWrapper());
1147
0
  if (aReflector) {
1148
#ifdef DEBUG
1149
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1150
#endif // DEBUG
1151
    return true;
1152
0
  }
1153
0
1154
0
  JSAutoRealm ar(aCx, global);
1155
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1156
0
  if (!canonicalProto) {
1157
0
    return false;
1158
0
  }
1159
0
  JS::Rooted<JSObject*> proto(aCx);
1160
0
  if (aGivenProto) {
1161
0
    proto = aGivenProto;
1162
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
1163
0
    // coming in, we changed compartments to that of "parent" so may need
1164
0
    // to wrap the proto here.
1165
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1166
0
      if (!JS_WrapObject(aCx, &proto)) {
1167
0
        return false;
1168
0
      }
1169
0
    }
1170
0
  } else {
1171
0
    proto = canonicalProto;
1172
0
  }
1173
0
1174
0
  BindingJSObjectCreator<mozilla::dom::AudioBufferSourceNode> creator(aCx);
1175
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1176
0
  if (!aReflector) {
1177
0
    return false;
1178
0
  }
1179
0
1180
0
  aCache->SetWrapper(aReflector);
1181
0
  creator.InitializationSucceeded();
1182
0
1183
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1184
0
             aCache->GetWrapperPreserveColor() == aReflector);
1185
0
  // If proto != canonicalProto, we have to preserve our wrapper;
1186
0
  // otherwise we won't be able to properly recreate it later, since
1187
0
  // we won't know what proto to use.  Note that we don't check
1188
0
  // aGivenProto here, since it's entirely possible (and even
1189
0
  // somewhat common) to have a non-null aGivenProto which is the
1190
0
  // same as canonicalProto.
1191
0
  if (proto != canonicalProto) {
1192
0
    PreserveWrapper(aObject);
1193
0
  }
1194
0
1195
0
  return true;
1196
0
}
1197
1198
const NativePropertyHooks sNativePropertyHooks[] = { {
1199
  nullptr,
1200
  nullptr,
1201
  nullptr,
1202
  { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
1203
  prototypes::id::AudioBufferSourceNode,
1204
  constructors::id::AudioBufferSourceNode,
1205
  AudioScheduledSourceNode_Binding::sNativePropertyHooks,
1206
  &DefaultXrayExpandoObjectClass
1207
} };
1208
1209
void
1210
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1211
0
{
1212
0
  JS::Handle<JSObject*> parentProto(AudioScheduledSourceNode_Binding::GetProtoObjectHandle(aCx));
1213
0
  if (!parentProto) {
1214
0
    return;
1215
0
  }
1216
0
1217
0
  JS::Handle<JSObject*> constructorProto(AudioScheduledSourceNode_Binding::GetConstructorObjectHandle(aCx));
1218
0
  if (!constructorProto) {
1219
0
    return;
1220
0
  }
1221
0
1222
0
  static bool sIdsInited = false;
1223
0
  if (!sIdsInited && NS_IsMainThread()) {
1224
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
1225
0
      return;
1226
0
    }
1227
0
    if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
1228
0
      return;
1229
0
    }
1230
0
    sIdsInited = true;
1231
0
  }
1232
0
1233
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::AudioBufferSourceNode);
1234
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::AudioBufferSourceNode);
1235
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1236
0
                              &sPrototypeClass.mBase, protoCache,
1237
0
                              nullptr,
1238
0
                              constructorProto, &sInterfaceObjectClass.mBase, 1, nullptr,
1239
0
                              interfaceCache,
1240
0
                              sNativeProperties.Upcast(),
1241
0
                              sChromeOnlyNativeProperties.Upcast(),
1242
0
                              "AudioBufferSourceNode", aDefineOnGlobal,
1243
0
                              nullptr,
1244
0
                              false);
1245
0
}
1246
1247
JSObject*
1248
GetConstructorObject(JSContext* aCx)
1249
0
{
1250
0
  return GetConstructorObjectHandle(aCx);
1251
0
}
1252
1253
} // namespace AudioBufferSourceNode_Binding
1254
1255
1256
1257
} // namespace dom
1258
} // namespace mozilla