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