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