Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM WaveShaperNode.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "AtomList.h"
4 : #include "AudioNodeBinding.h"
5 : #include "WaveShaperNodeBinding.h"
6 : #include "WrapperFactory.h"
7 : #include "XrayWrapper.h"
8 : #include "jsapi.h"
9 : #include "jsfriendapi.h"
10 : #include "mozilla/FloatingPoint.h"
11 : #include "mozilla/OwningNonNull.h"
12 : #include "mozilla/Preferences.h"
13 : #include "mozilla/dom/AudioContext.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/SimpleGlobalObject.h"
21 : #include "mozilla/dom/TypedArray.h"
22 : #include "mozilla/dom/WaveShaperNode.h"
23 : #include "mozilla/dom/XrayExpandoClass.h"
24 : #include "nsContentUtils.h"
25 :
26 : namespace mozilla {
27 : namespace dom {
28 :
29 : namespace OverSampleTypeValues {
30 : extern const EnumEntry strings[4] = {
31 : {"none", 4},
32 : {"2x", 2},
33 : {"4x", 2},
34 : { nullptr, 0 }
35 : };
36 : } // namespace OverSampleTypeValues
37 :
38 : bool
39 0 : ToJSValue(JSContext* aCx, OverSampleType aArgument, JS::MutableHandle<JS::Value> aValue)
40 : {
41 0 : MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(OverSampleTypeValues::strings));
42 : JSString* resultStr =
43 0 : JS_NewStringCopyN(aCx, OverSampleTypeValues::strings[uint32_t(aArgument)].value,
44 0 : OverSampleTypeValues::strings[uint32_t(aArgument)].length);
45 0 : if (!resultStr) {
46 0 : return false;
47 : }
48 0 : aValue.setString(resultStr);
49 0 : return true;
50 : }
51 :
52 :
53 :
54 0 : WaveShaperOptions::WaveShaperOptions()
55 0 : : AudioNodeOptions(FastDictionaryInitializer())
56 : {
57 : // Safe to pass a null context if we pass a null value
58 0 : Init(nullptr, JS::NullHandleValue);
59 0 : }
60 :
61 :
62 :
63 : bool
64 0 : WaveShaperOptions::InitIds(JSContext* cx, WaveShaperOptionsAtoms* atomsCache)
65 : {
66 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
67 :
68 : // Initialize these in reverse order so that any failure leaves the first one
69 : // uninitialized.
70 0 : if (!atomsCache->oversample_id.init(cx, "oversample") ||
71 0 : !atomsCache->curve_id.init(cx, "curve")) {
72 0 : return false;
73 : }
74 0 : return true;
75 : }
76 :
77 : bool
78 0 : WaveShaperOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
79 : {
80 : // Passing a null JSContext is OK only if we're initing from null,
81 : // Since in that case we will not have to do any property gets
82 : // Also evaluate isNullOrUndefined in order to avoid false-positive
83 : // checkers by static analysis tools
84 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
85 0 : WaveShaperOptionsAtoms* atomsCache = nullptr;
86 0 : if (cx) {
87 0 : atomsCache = GetAtomCache<WaveShaperOptionsAtoms>(cx);
88 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
89 0 : return false;
90 : }
91 : }
92 :
93 : // Per spec, we init the parent's members first
94 0 : if (!AudioNodeOptions::Init(cx, val)) {
95 0 : return false;
96 : }
97 :
98 0 : bool isNull = val.isNullOrUndefined();
99 : // We only need these if !isNull, in which case we have |cx|.
100 0 : Maybe<JS::Rooted<JSObject *> > object;
101 0 : Maybe<JS::Rooted<JS::Value> > temp;
102 0 : if (!isNull) {
103 0 : MOZ_ASSERT(cx);
104 0 : object.emplace(cx, &val.toObject());
105 0 : temp.emplace(cx);
106 : }
107 0 : if (!isNull) {
108 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->curve_id, temp.ptr())) {
109 0 : return false;
110 : }
111 : }
112 0 : if (!isNull && !temp->isUndefined()) {
113 0 : mCurve.Construct();
114 0 : if (temp.ref().isObject()) {
115 0 : JS::ForOfIterator iter(cx);
116 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
117 0 : return false;
118 : }
119 0 : if (!iter.valueIsIterable()) {
120 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'curve' member of WaveShaperOptions");
121 0 : return false;
122 : }
123 0 : Sequence<float> &arr = (mCurve.Value());
124 0 : JS::Rooted<JS::Value> temp(cx);
125 : while (true) {
126 : bool done;
127 0 : if (!iter.next(&temp, &done)) {
128 0 : return false;
129 : }
130 0 : if (done) {
131 0 : break;
132 : }
133 0 : float* slotPtr = arr.AppendElement(mozilla::fallible);
134 0 : if (!slotPtr) {
135 0 : JS_ReportOutOfMemory(cx);
136 0 : return false;
137 : }
138 0 : float& slot = *slotPtr;
139 0 : if (!ValueToPrimitive<float, eDefault>(cx, temp, &slot)) {
140 0 : return false;
141 0 : } else if (!mozilla::IsFinite(slot)) {
142 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "Element of 'curve' member of WaveShaperOptions");
143 0 : return false;
144 : }
145 0 : }
146 : } else {
147 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'curve' member of WaveShaperOptions");
148 0 : return false;
149 : }
150 0 : mIsAnyMemberPresent = true;
151 : }
152 :
153 0 : if (!isNull) {
154 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->oversample_id, temp.ptr())) {
155 0 : return false;
156 : }
157 : }
158 0 : if (!isNull && !temp->isUndefined()) {
159 : {
160 : int index;
161 0 : if (!FindEnumStringIndex<true>(cx, temp.ref(), OverSampleTypeValues::strings, "OverSampleType", "'oversample' member of WaveShaperOptions", &index)) {
162 0 : return false;
163 : }
164 0 : MOZ_ASSERT(index >= 0);
165 0 : mOversample = static_cast<OverSampleType>(index);
166 : }
167 : } else {
168 0 : mOversample = OverSampleType::None;
169 : }
170 0 : mIsAnyMemberPresent = true;
171 0 : return true;
172 : }
173 :
174 : bool
175 0 : WaveShaperOptions::Init(const nsAString& aJSON)
176 : {
177 0 : AutoJSAPI jsapi;
178 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
179 0 : if (!cleanGlobal) {
180 0 : return false;
181 : }
182 0 : if (!jsapi.Init(cleanGlobal)) {
183 0 : return false;
184 : }
185 0 : JSContext* cx = jsapi.cx();
186 0 : JS::Rooted<JS::Value> json(cx);
187 0 : bool ok = ParseJSON(cx, aJSON, &json);
188 0 : NS_ENSURE_TRUE(ok, false);
189 0 : return Init(cx, json);
190 : }
191 :
192 : bool
193 0 : WaveShaperOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
194 : {
195 0 : WaveShaperOptionsAtoms* atomsCache = GetAtomCache<WaveShaperOptionsAtoms>(cx);
196 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
197 0 : return false;
198 : }
199 :
200 : // Per spec, we define the parent's members first
201 0 : if (!AudioNodeOptions::ToObjectInternal(cx, rval)) {
202 0 : return false;
203 : }
204 0 : JS::Rooted<JSObject*> obj(cx, &rval.toObject());
205 :
206 0 : if (mCurve.WasPassed()) {
207 : do {
208 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
209 0 : JS::Rooted<JS::Value> temp(cx);
210 0 : Sequence<float> const & currentValue = mCurve.InternalValue();
211 :
212 0 : uint32_t length = currentValue.Length();
213 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
214 0 : if (!returnArray) {
215 0 : return false;
216 : }
217 : // Scope for 'tmp'
218 : {
219 0 : JS::Rooted<JS::Value> tmp(cx);
220 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
221 : // Control block to let us common up the JS_DefineElement calls when there
222 : // are different ways to succeed at wrapping the object.
223 : do {
224 0 : tmp.set(JS_NumberValue(double(currentValue[sequenceIdx0])));
225 0 : break;
226 : } while (0);
227 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
228 : JSPROP_ENUMERATE)) {
229 0 : return false;
230 : }
231 : }
232 : }
233 0 : temp.setObject(*returnArray);
234 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->curve_id, temp, JSPROP_ENUMERATE)) {
235 0 : return false;
236 : }
237 0 : break;
238 : } while(0);
239 : }
240 :
241 : do {
242 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
243 0 : JS::Rooted<JS::Value> temp(cx);
244 0 : OverSampleType const & currentValue = mOversample;
245 0 : if (!ToJSValue(cx, currentValue, &temp)) {
246 0 : return false;
247 : }
248 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->oversample_id, temp, JSPROP_ENUMERATE)) {
249 0 : return false;
250 : }
251 0 : break;
252 : } while(0);
253 :
254 0 : return true;
255 : }
256 :
257 : bool
258 0 : WaveShaperOptions::ToJSON(nsAString& aJSON) const
259 : {
260 0 : AutoJSAPI jsapi;
261 0 : jsapi.Init();
262 0 : JSContext *cx = jsapi.cx();
263 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
264 : // because we'll only be creating objects, in ways that have no
265 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
266 : // which likewise guarantees no side-effects for the sorts of
267 : // things we will pass it.
268 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
269 0 : JS::Rooted<JS::Value> val(cx);
270 0 : if (!ToObjectInternal(cx, &val)) {
271 0 : return false;
272 : }
273 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
274 0 : return StringifyToJSON(cx, obj, aJSON);
275 : }
276 :
277 : void
278 0 : WaveShaperOptions::TraceDictionary(JSTracer* trc)
279 : {
280 0 : AudioNodeOptions::TraceDictionary(trc);
281 0 : }
282 :
283 : WaveShaperOptions&
284 0 : WaveShaperOptions::operator=(const WaveShaperOptions& aOther)
285 : {
286 0 : AudioNodeOptions::operator=(aOther);
287 0 : mCurve.Reset();
288 0 : if (aOther.mCurve.WasPassed()) {
289 0 : mCurve.Construct(aOther.mCurve.Value());
290 : }
291 0 : mOversample = aOther.mOversample;
292 0 : return *this;
293 : }
294 :
295 : namespace binding_detail {
296 : } // namespace binding_detail
297 :
298 :
299 : namespace WaveShaperNodeBinding {
300 :
301 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<AudioNodeBinding::NativeType>::value,
302 : "Can't inherit from an interface with a different ownership model.");
303 :
304 : static bool
305 0 : get_curve(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WaveShaperNode* self, JSJitGetterCallArgs args)
306 : {
307 : // Have to either root across the getter call or reget after.
308 : bool isXray;
309 0 : JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
310 0 : if (!slotStorage) {
311 0 : return false;
312 : }
313 0 : const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 0) : (DOM_INSTANCE_RESERVED_SLOTS + 0);
314 0 : MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
315 : {
316 : // Scope for cachedVal
317 0 : JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
318 0 : if (!cachedVal.isUndefined()) {
319 0 : args.rval().set(cachedVal);
320 : // The cached value is in the compartment of slotStorage,
321 : // so wrap into the caller compartment as needed.
322 0 : return MaybeWrapNonDOMObjectOrNullValue(cx, args.rval());
323 : }
324 : }
325 :
326 0 : JS::Rooted<JSObject*> result(cx);
327 0 : self->GetCurve(cx, &result);
328 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
329 : {
330 0 : JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
331 0 : JSAutoCompartment ac(cx, conversionScope);
332 : do { // block we break out of when done wrapping
333 0 : if (result) {
334 0 : JS::ExposeObjectToActiveJS(result);
335 : }
336 0 : args.rval().setObjectOrNull(result);
337 0 : if (!MaybeWrapNonDOMObjectOrNullValue(cx, args.rval())) {
338 0 : return false;
339 : }
340 0 : break;
341 : } while (0);
342 : }
343 : { // And now store things in the compartment of our slotStorage.
344 0 : JSAutoCompartment ac(cx, slotStorage);
345 : // Make a copy so that we don't do unnecessary wrapping on args.rval().
346 0 : JS::Rooted<JS::Value> storedVal(cx, args.rval());
347 0 : if (!MaybeWrapNonDOMObjectOrNullValue(cx, &storedVal)) {
348 0 : return false;
349 : }
350 0 : js::SetReservedSlot(slotStorage, slotIndex, storedVal);
351 0 : if (!isXray) {
352 : // In the Xray case we don't need to do this, because getting the
353 : // expando object already preserved our wrapper.
354 0 : PreserveWrapper(self);
355 : }
356 : }
357 : // And now make sure args.rval() is in the caller compartment
358 0 : return MaybeWrapNonDOMObjectOrNullValue(cx, args.rval());
359 : }
360 :
361 : static bool
362 0 : set_curve(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WaveShaperNode* self, JSJitSetterCallArgs args)
363 : {
364 0 : RootedTypedArray<Nullable<Float32Array>> arg0(cx);
365 0 : if (args[0].isObject()) {
366 0 : if (!arg0.SetValue().Init(&args[0].toObject())) {
367 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Value being assigned to WaveShaperNode.curve", "Float32ArrayOrNull");
368 0 : return false;
369 : }
370 0 : } else if (args[0].isNullOrUndefined()) {
371 0 : arg0.SetNull();
372 : } else {
373 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Value being assigned to WaveShaperNode.curve");
374 0 : return false;
375 : }
376 0 : binding_detail::FastErrorResult rv;
377 0 : self->SetCurve(Constify(arg0), rv);
378 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
379 0 : return false;
380 : }
381 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
382 :
383 0 : ClearCachedCurveValue(self);
384 0 : return true;
385 : }
386 :
387 : static const JSJitInfo curve_getterinfo = {
388 : { (JSJitGetterOp)get_curve },
389 : { prototypes::id::WaveShaperNode },
390 : { PrototypeTraits<prototypes::id::WaveShaperNode>::Depth },
391 : JSJitInfo::Getter,
392 : JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
393 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
394 : false, /* isInfallible. False in setters. */
395 : true, /* isMovable. Not relevant for setters. */
396 : true, /* isEliminatable. Not relevant for setters. */
397 : false, /* isAlwaysInSlot. Only relevant for getters. */
398 : true, /* isLazilyCachedInSlot. Only relevant for getters. */
399 : false, /* isTypedMethod. Only relevant for methods. */
400 : (DOM_INSTANCE_RESERVED_SLOTS + 0) /* Reserved slot index, if we're stored in a slot, else 0. */
401 : };
402 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit");
403 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 2, "There is no slot for us");
404 : static const JSJitInfo curve_setterinfo = {
405 : { (JSJitGetterOp)set_curve },
406 : { prototypes::id::WaveShaperNode },
407 : { PrototypeTraits<prototypes::id::WaveShaperNode>::Depth },
408 : JSJitInfo::Setter,
409 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
410 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
411 : false, /* isInfallible. False in setters. */
412 : false, /* isMovable. Not relevant for setters. */
413 : false, /* isEliminatable. Not relevant for setters. */
414 : false, /* isAlwaysInSlot. Only relevant for getters. */
415 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
416 : false, /* isTypedMethod. Only relevant for methods. */
417 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
418 : };
419 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
420 : static_assert(0 < 2, "There is no slot for us");
421 :
422 : static bool
423 0 : get_oversample(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WaveShaperNode* self, JSJitGetterCallArgs args)
424 : {
425 0 : OverSampleType result(self->Oversample());
426 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
427 0 : if (!ToJSValue(cx, result, args.rval())) {
428 0 : return false;
429 : }
430 0 : return true;
431 : }
432 :
433 : static bool
434 0 : set_oversample(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WaveShaperNode* self, JSJitSetterCallArgs args)
435 : {
436 : OverSampleType arg0;
437 : {
438 : int index;
439 0 : if (!FindEnumStringIndex<false>(cx, args[0], OverSampleTypeValues::strings, "OverSampleType", "Value being assigned to WaveShaperNode.oversample", &index)) {
440 0 : return false;
441 : }
442 0 : if (index < 0) {
443 0 : return true;
444 : }
445 0 : arg0 = static_cast<OverSampleType>(index);
446 : }
447 0 : self->SetOversample(arg0);
448 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
449 :
450 0 : return true;
451 : }
452 :
453 : static const JSJitInfo oversample_getterinfo = {
454 : { (JSJitGetterOp)get_oversample },
455 : { prototypes::id::WaveShaperNode },
456 : { PrototypeTraits<prototypes::id::WaveShaperNode>::Depth },
457 : JSJitInfo::Getter,
458 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
459 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
460 : false, /* isInfallible. False in setters. */
461 : false, /* isMovable. Not relevant for setters. */
462 : false, /* isEliminatable. Not relevant for setters. */
463 : false, /* isAlwaysInSlot. Only relevant for getters. */
464 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
465 : false, /* isTypedMethod. Only relevant for methods. */
466 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
467 : };
468 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
469 : static_assert(0 < 2, "There is no slot for us");
470 : static const JSJitInfo oversample_setterinfo = {
471 : { (JSJitGetterOp)set_oversample },
472 : { prototypes::id::WaveShaperNode },
473 : { PrototypeTraits<prototypes::id::WaveShaperNode>::Depth },
474 : JSJitInfo::Setter,
475 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
476 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
477 : false, /* isInfallible. False in setters. */
478 : false, /* isMovable. Not relevant for setters. */
479 : false, /* isEliminatable. Not relevant for setters. */
480 : false, /* isAlwaysInSlot. Only relevant for getters. */
481 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
482 : false, /* isTypedMethod. Only relevant for methods. */
483 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
484 : };
485 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
486 : static_assert(0 < 2, "There is no slot for us");
487 :
488 : static bool
489 0 : get_passThrough(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WaveShaperNode* self, JSJitGetterCallArgs args)
490 : {
491 0 : bool result(self->PassThrough());
492 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
493 0 : args.rval().setBoolean(result);
494 0 : return true;
495 : }
496 :
497 : static bool
498 0 : set_passThrough(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WaveShaperNode* self, JSJitSetterCallArgs args)
499 : {
500 : bool arg0;
501 0 : if (!ValueToPrimitive<bool, eDefault>(cx, args[0], &arg0)) {
502 0 : return false;
503 : }
504 0 : self->SetPassThrough(arg0);
505 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
506 :
507 0 : return true;
508 : }
509 :
510 : static const JSJitInfo passThrough_getterinfo = {
511 : { (JSJitGetterOp)get_passThrough },
512 : { prototypes::id::WaveShaperNode },
513 : { PrototypeTraits<prototypes::id::WaveShaperNode>::Depth },
514 : JSJitInfo::Getter,
515 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
516 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
517 : true, /* isInfallible. False in setters. */
518 : false, /* isMovable. Not relevant for setters. */
519 : false, /* isEliminatable. Not relevant for setters. */
520 : false, /* isAlwaysInSlot. Only relevant for getters. */
521 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
522 : false, /* isTypedMethod. Only relevant for methods. */
523 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
524 : };
525 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
526 : static_assert(0 < 2, "There is no slot for us");
527 : static const JSJitInfo passThrough_setterinfo = {
528 : { (JSJitGetterOp)set_passThrough },
529 : { prototypes::id::WaveShaperNode },
530 : { PrototypeTraits<prototypes::id::WaveShaperNode>::Depth },
531 : JSJitInfo::Setter,
532 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
533 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
534 : false, /* isInfallible. False in setters. */
535 : false, /* isMovable. Not relevant for setters. */
536 : false, /* isEliminatable. Not relevant for setters. */
537 : false, /* isAlwaysInSlot. Only relevant for getters. */
538 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
539 : false, /* isTypedMethod. Only relevant for methods. */
540 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
541 : };
542 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
543 : static_assert(0 < 2, "There is no slot for us");
544 :
545 : static bool
546 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
547 : {
548 0 : mozilla::dom::WaveShaperNode* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::WaveShaperNode>(obj);
549 : // We don't want to preserve if we don't have a wrapper, and we
550 : // obviously can't preserve if we're not initialized.
551 0 : if (self && self->GetWrapperPreserveColor()) {
552 0 : PreserveWrapper(self);
553 : }
554 0 : return true;
555 : }
556 :
557 : static void
558 0 : _finalize(js::FreeOp* fop, JSObject* obj)
559 : {
560 0 : mozilla::dom::WaveShaperNode* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::WaveShaperNode>(obj);
561 0 : if (self) {
562 0 : ClearWrapper(self, self, obj);
563 0 : AddForDeferredFinalization<mozilla::dom::WaveShaperNode>(self);
564 : }
565 0 : }
566 :
567 : static void
568 0 : _objectMoved(JSObject* obj, const JSObject* old)
569 : {
570 0 : mozilla::dom::WaveShaperNode* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::WaveShaperNode>(obj);
571 0 : if (self) {
572 0 : UpdateWrapper(self, self, obj, old);
573 : }
574 0 : }
575 :
576 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
577 : #if defined(__clang__)
578 : #pragma clang diagnostic push
579 : #pragma clang diagnostic ignored "-Wmissing-braces"
580 : #endif
581 : static const JSPropertySpec sAttributes_specs[] = {
582 : { "curve", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &curve_getterinfo, GenericBindingSetter, &curve_setterinfo },
583 : { "oversample", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &oversample_getterinfo, GenericBindingSetter, &oversample_setterinfo },
584 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
585 : };
586 : #if defined(__clang__)
587 : #pragma clang diagnostic pop
588 : #endif
589 :
590 :
591 : // Can't be const because the pref-enabled boolean needs to be writable
592 : static Prefable<const JSPropertySpec> sAttributes[] = {
593 : { nullptr, &sAttributes_specs[0] },
594 : { nullptr, nullptr }
595 : };
596 :
597 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
598 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
599 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
600 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
601 :
602 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
603 : #if defined(__clang__)
604 : #pragma clang diagnostic push
605 : #pragma clang diagnostic ignored "-Wmissing-braces"
606 : #endif
607 : static const JSPropertySpec sChromeAttributes_specs[] = {
608 : { "passThrough", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &passThrough_getterinfo, GenericBindingSetter, &passThrough_setterinfo },
609 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
610 : };
611 : #if defined(__clang__)
612 : #pragma clang diagnostic pop
613 : #endif
614 :
615 :
616 : // Can't be const because the pref-enabled boolean needs to be writable
617 : static Prefable<const JSPropertySpec> sChromeAttributes[] = {
618 : { nullptr, &sChromeAttributes_specs[0] },
619 : { nullptr, nullptr }
620 : };
621 :
622 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
623 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
624 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
625 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
626 :
627 :
628 : static uint16_t sNativeProperties_sortedPropertyIndices[2];
629 : static PropertyInfo sNativeProperties_propertyInfos[2];
630 :
631 : static const NativePropertiesN<1> sNativeProperties = {
632 : false, 0,
633 : false, 0,
634 : false, 0,
635 : true, 0 /* sAttributes */,
636 : false, 0,
637 : false, 0,
638 : false, 0,
639 : -1,
640 : 2,
641 : sNativeProperties_sortedPropertyIndices,
642 : {
643 : { sAttributes, &sNativeProperties_propertyInfos[0] }
644 : }
645 : };
646 : static_assert(2 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
647 : "We have a property info count that is oversized");
648 :
649 : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[1];
650 : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[1];
651 :
652 : static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
653 : false, 0,
654 : false, 0,
655 : false, 0,
656 : true, 0 /* sChromeAttributes */,
657 : false, 0,
658 : false, 0,
659 : false, 0,
660 : -1,
661 : 1,
662 : sChromeOnlyNativeProperties_sortedPropertyIndices,
663 : {
664 : { sChromeAttributes, &sChromeOnlyNativeProperties_propertyInfos[0] }
665 : }
666 : };
667 : static_assert(1 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
668 : "We have a property info count that is oversized");
669 :
670 : static bool
671 0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
672 : {
673 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
674 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
675 0 : if (!args.isConstructing()) {
676 : // XXXbz wish I could get the name from the callee instead of
677 : // Adding more relocations
678 0 : return ThrowConstructorWithoutNew(cx, "WaveShaperNode");
679 : }
680 :
681 0 : GlobalObject global(cx, obj);
682 0 : if (global.Failed()) {
683 0 : return false;
684 : }
685 :
686 0 : JS::Rooted<JSObject*> desiredProto(cx);
687 0 : if (!GetDesiredProto(cx, args, &desiredProto)) {
688 0 : return false;
689 : }
690 :
691 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
692 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "WaveShaperNode");
693 : }
694 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
695 0 : NonNull<mozilla::dom::AudioContext> arg0;
696 0 : if (args[0].isObject()) {
697 : {
698 0 : nsresult rv = UnwrapObject<prototypes::id::BaseAudioContext, mozilla::dom::AudioContext>(args[0], arg0);
699 0 : if (NS_FAILED(rv)) {
700 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of WaveShaperNode.constructor", "BaseAudioContext");
701 0 : return false;
702 : }
703 : }
704 : } else {
705 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of WaveShaperNode.constructor");
706 0 : return false;
707 : }
708 0 : binding_detail::FastWaveShaperOptions arg1;
709 0 : if (!arg1.Init(cx, (args.hasDefined(1)) ? args[1] : JS::NullHandleValue, "Argument 2 of WaveShaperNode.constructor", false)) {
710 0 : return false;
711 : }
712 0 : Maybe<JSAutoCompartment> ac;
713 0 : if (objIsXray) {
714 0 : obj = js::CheckedUnwrap(obj);
715 0 : if (!obj) {
716 0 : return false;
717 : }
718 0 : ac.emplace(cx, obj);
719 0 : if (!JS_WrapObject(cx, &desiredProto)) {
720 0 : return false;
721 : }
722 : }
723 0 : binding_detail::FastErrorResult rv;
724 0 : auto result(StrongOrRawPtr<mozilla::dom::WaveShaperNode>(mozilla::dom::WaveShaperNode::Constructor(global, NonNullHelper(arg0), Constify(arg1), rv)));
725 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
726 0 : return false;
727 : }
728 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
729 : static_assert(!IsPointer<decltype(result)>::value,
730 : "NewObject implies that we need to keep the object alive with a strong reference.");
731 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
732 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
733 0 : return false;
734 : }
735 0 : return true;
736 : }
737 :
738 : static const js::ClassOps sInterfaceObjectClassOps = {
739 : nullptr, /* addProperty */
740 : nullptr, /* delProperty */
741 : nullptr, /* getProperty */
742 : nullptr, /* setProperty */
743 : nullptr, /* enumerate */
744 : nullptr, /* newEnumerate */
745 : nullptr, /* resolve */
746 : nullptr, /* mayResolve */
747 : nullptr, /* finalize */
748 : _constructor, /* call */
749 : nullptr, /* hasInstance */
750 : _constructor, /* construct */
751 : nullptr, /* trace */
752 : };
753 :
754 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
755 : {
756 : "Function",
757 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
758 : &sInterfaceObjectClassOps,
759 : JS_NULL_CLASS_SPEC,
760 : JS_NULL_CLASS_EXT,
761 : &sInterfaceObjectClassObjectOps
762 : },
763 : eInterface,
764 : true,
765 : prototypes::id::WaveShaperNode,
766 : PrototypeTraits<prototypes::id::WaveShaperNode>::Depth,
767 : sNativePropertyHooks,
768 : "function WaveShaperNode() {\n [native code]\n}",
769 : AudioNodeBinding::GetConstructorObject
770 : };
771 :
772 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
773 : {
774 : "WaveShaperNodePrototype",
775 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
776 : JS_NULL_CLASS_OPS,
777 : JS_NULL_CLASS_SPEC,
778 : JS_NULL_CLASS_EXT,
779 : JS_NULL_OBJECT_OPS
780 : },
781 : eInterfacePrototype,
782 : false,
783 : prototypes::id::WaveShaperNode,
784 : PrototypeTraits<prototypes::id::WaveShaperNode>::Depth,
785 : sNativePropertyHooks,
786 : "[object WaveShaperNodePrototype]",
787 : AudioNodeBinding::GetProtoObject
788 : };
789 :
790 : bool
791 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
792 : {
793 : static bool sPrefValue;
794 : static bool sPrefCacheSetUp = false;
795 0 : if (!sPrefCacheSetUp) {
796 0 : sPrefCacheSetUp = true;
797 0 : Preferences::AddBoolVarCache(&sPrefValue, "dom.webaudio.enabled");
798 : }
799 :
800 0 : return sPrefValue;
801 : }
802 :
803 : JSObject*
804 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
805 : {
806 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
807 : }
808 :
809 : static const js::ClassOps sClassOps = {
810 : _addProperty, /* addProperty */
811 : nullptr, /* delProperty */
812 : nullptr, /* getProperty */
813 : nullptr, /* setProperty */
814 : nullptr, /* enumerate */
815 : nullptr, /* newEnumerate */
816 : nullptr, /* resolve */
817 : nullptr, /* mayResolve */
818 : _finalize, /* finalize */
819 : nullptr, /* call */
820 : nullptr, /* hasInstance */
821 : nullptr, /* construct */
822 : nullptr, /* trace */
823 : };
824 :
825 : static const js::ClassExtension sClassExtension = {
826 : nullptr, /* weakmapKeyDelegateOp */
827 : _objectMoved /* objectMovedOp */
828 : };
829 :
830 : static const DOMJSClass sClass = {
831 : { "WaveShaperNode",
832 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2),
833 : &sClassOps,
834 : JS_NULL_CLASS_SPEC,
835 : &sClassExtension,
836 : JS_NULL_OBJECT_OPS
837 : },
838 : { prototypes::id::EventTarget, prototypes::id::AudioNode, prototypes::id::WaveShaperNode, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
839 : IsBaseOf<nsISupports, mozilla::dom::WaveShaperNode >::value,
840 : sNativePropertyHooks,
841 : FindAssociatedGlobalForNative<mozilla::dom::WaveShaperNode>::Get,
842 : GetProtoObjectHandle,
843 : GetCCParticipant<mozilla::dom::WaveShaperNode>::Get()
844 : };
845 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
846 : "Must have the right minimal number of reserved slots.");
847 : static_assert(2 >= 2,
848 : "Must have enough reserved slots.");
849 :
850 : const JSClass*
851 0 : GetJSClass()
852 : {
853 0 : return sClass.ToJSClass();
854 : }
855 :
856 : bool
857 0 : Wrap(JSContext* aCx, mozilla::dom::WaveShaperNode* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
858 : {
859 : MOZ_ASSERT(static_cast<mozilla::dom::WaveShaperNode*>(aObject) ==
860 : reinterpret_cast<mozilla::dom::WaveShaperNode*>(aObject),
861 : "Multiple inheritance for mozilla::dom::WaveShaperNode is broken.");
862 : MOZ_ASSERT(static_cast<mozilla::dom::AudioNode*>(aObject) ==
863 : reinterpret_cast<mozilla::dom::AudioNode*>(aObject),
864 : "Multiple inheritance for mozilla::dom::AudioNode is broken.");
865 : MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
866 : reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
867 : "Multiple inheritance for mozilla::dom::EventTarget is broken.");
868 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
869 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
870 0 : MOZ_ASSERT(!aCache->GetWrapper(),
871 : "You should probably not be using Wrap() directly; use "
872 : "GetOrCreateDOMReflector instead");
873 :
874 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
875 : "nsISupports must be on our primary inheritance chain");
876 :
877 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
878 0 : if (!global) {
879 0 : return false;
880 : }
881 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
882 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
883 :
884 : // That might have ended up wrapping us already, due to the wonders
885 : // of XBL. Check for that, and bail out as needed.
886 0 : aReflector.set(aCache->GetWrapper());
887 0 : if (aReflector) {
888 : #ifdef DEBUG
889 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
890 : #endif // DEBUG
891 0 : return true;
892 : }
893 :
894 0 : JSAutoCompartment ac(aCx, global);
895 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
896 0 : if (!canonicalProto) {
897 0 : return false;
898 : }
899 0 : JS::Rooted<JSObject*> proto(aCx);
900 0 : if (aGivenProto) {
901 0 : proto = aGivenProto;
902 : // Unfortunately, while aGivenProto was in the compartment of aCx
903 : // coming in, we changed compartments to that of "parent" so may need
904 : // to wrap the proto here.
905 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
906 0 : if (!JS_WrapObject(aCx, &proto)) {
907 0 : return false;
908 : }
909 : }
910 : } else {
911 0 : proto = canonicalProto;
912 : }
913 :
914 0 : BindingJSObjectCreator<mozilla::dom::WaveShaperNode> creator(aCx);
915 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
916 0 : if (!aReflector) {
917 0 : return false;
918 : }
919 :
920 0 : aCache->SetWrapper(aReflector);
921 0 : creator.InitializationSucceeded();
922 :
923 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
924 : aCache->GetWrapperPreserveColor() == aReflector);
925 : // If proto != canonicalProto, we have to preserve our wrapper;
926 : // otherwise we won't be able to properly recreate it later, since
927 : // we won't know what proto to use. Note that we don't check
928 : // aGivenProto here, since it's entirely possible (and even
929 : // somewhat common) to have a non-null aGivenProto which is the
930 : // same as canonicalProto.
931 0 : if (proto != canonicalProto) {
932 0 : PreserveWrapper(aObject);
933 : }
934 :
935 0 : return true;
936 : }
937 :
938 : // This may allocate too many slots, because we only really need
939 : // slots for our non-interface-typed members that we cache. But
940 : // allocating slots only for those would make the slot index
941 : // computations much more complicated, so let's do this the simple
942 : // way for now.
943 : DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 1);
944 :
945 : const NativePropertyHooks sNativePropertyHooks[] = { {
946 : nullptr,
947 : nullptr,
948 : nullptr,
949 : { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
950 : prototypes::id::WaveShaperNode,
951 : constructors::id::WaveShaperNode,
952 : AudioNodeBinding::sNativePropertyHooks,
953 : &sXrayExpandoObjectClass
954 : } };
955 :
956 : void
957 0 : ClearCachedCurveValue(mozilla::dom::WaveShaperNode* aObject)
958 : {
959 : JSObject* obj;
960 0 : obj = aObject->GetWrapper();
961 0 : if (!obj) {
962 0 : return;
963 : }
964 0 : js::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), JS::UndefinedValue());
965 0 : xpc::ClearXrayExpandoSlots(obj, (xpc::JSSLOT_EXPANDO_COUNT + 0));
966 : }
967 :
968 : void
969 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
970 : {
971 0 : JS::Handle<JSObject*> parentProto(AudioNodeBinding::GetProtoObjectHandle(aCx));
972 0 : if (!parentProto) {
973 0 : return;
974 : }
975 :
976 0 : JS::Handle<JSObject*> constructorProto(AudioNodeBinding::GetConstructorObjectHandle(aCx));
977 0 : if (!constructorProto) {
978 0 : return;
979 : }
980 :
981 : static bool sIdsInited = false;
982 0 : if (!sIdsInited && NS_IsMainThread()) {
983 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
984 0 : return;
985 : }
986 0 : if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
987 0 : return;
988 : }
989 0 : sIdsInited = true;
990 : }
991 :
992 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::WaveShaperNode);
993 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::WaveShaperNode);
994 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
995 : &sPrototypeClass.mBase, protoCache,
996 : constructorProto, &sInterfaceObjectClass.mBase, 1, nullptr,
997 : interfaceCache,
998 : sNativeProperties.Upcast(),
999 0 : nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
1000 : "WaveShaperNode", aDefineOnGlobal,
1001 : nullptr,
1002 0 : false);
1003 : }
1004 :
1005 : JS::Handle<JSObject*>
1006 0 : GetProtoObjectHandle(JSContext* aCx)
1007 : {
1008 : /* Get the interface prototype object for this class. This will create the
1009 : object as needed. */
1010 0 : bool aDefineOnGlobal = true;
1011 :
1012 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1013 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1014 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1015 0 : return nullptr;
1016 : }
1017 :
1018 : /* Check to see whether the interface objects are already installed */
1019 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1020 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::WaveShaperNode)) {
1021 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1022 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1023 : }
1024 :
1025 : /*
1026 : * The object might _still_ be null, but that's OK.
1027 : *
1028 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1029 : * traced by TraceProtoAndIfaceCache() and its contents are never
1030 : * changed after they have been set.
1031 : *
1032 : * Calling address() avoids the read read barrier that does gray
1033 : * unmarking, but it's not possible for the object to be gray here.
1034 : */
1035 :
1036 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::WaveShaperNode);
1037 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1038 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1039 : }
1040 :
1041 : JS::Handle<JSObject*>
1042 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
1043 : {
1044 : /* Get the interface object for this class. This will create the object as
1045 : needed. */
1046 :
1047 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1048 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1049 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1050 0 : return nullptr;
1051 : }
1052 :
1053 : /* Check to see whether the interface objects are already installed */
1054 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1055 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::WaveShaperNode)) {
1056 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1057 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1058 : }
1059 :
1060 : /*
1061 : * The object might _still_ be null, but that's OK.
1062 : *
1063 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1064 : * traced by TraceProtoAndIfaceCache() and its contents are never
1065 : * changed after they have been set.
1066 : *
1067 : * Calling address() avoids the read read barrier that does gray
1068 : * unmarking, but it's not possible for the object to be gray here.
1069 : */
1070 :
1071 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::WaveShaperNode);
1072 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1073 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1074 : }
1075 :
1076 : JSObject*
1077 0 : GetConstructorObject(JSContext* aCx)
1078 : {
1079 0 : return GetConstructorObjectHandle(aCx);
1080 : }
1081 :
1082 : } // namespace WaveShaperNodeBinding
1083 :
1084 :
1085 :
1086 : } // namespace dom
1087 : } // namespace mozilla
|