Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM OfflineAudioContext.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "BaseAudioContextBinding.h"
4 : #include "EventHandlerBinding.h"
5 : #include "OfflineAudioContextBinding.h"
6 : #include "WrapperFactory.h"
7 : #include "mozilla/FloatingPoint.h"
8 : #include "mozilla/OwningNonNull.h"
9 : #include "mozilla/Preferences.h"
10 : #include "mozilla/dom/AudioContext.h"
11 : #include "mozilla/dom/BindingUtils.h"
12 : #include "mozilla/dom/DOMJSClass.h"
13 : #include "mozilla/dom/NonRefcountedDOMObject.h"
14 : #include "mozilla/dom/Nullable.h"
15 : #include "mozilla/dom/PrimitiveConversions.h"
16 : #include "mozilla/dom/Promise.h"
17 : #include "mozilla/dom/ToJSValue.h"
18 : #include "mozilla/dom/XrayExpandoClass.h"
19 :
20 : namespace mozilla {
21 : namespace dom {
22 :
23 : namespace OfflineAudioContextBinding {
24 :
25 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<BaseAudioContextBinding::NativeType>::value,
26 : "Can't inherit from an interface with a different ownership model.");
27 :
28 : static bool
29 0 : startRendering(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioContext* self, const JSJitMethodCallArgs& args)
30 : {
31 0 : binding_detail::FastErrorResult rv;
32 0 : auto result(StrongOrRawPtr<Promise>(self->StartRendering(rv)));
33 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
34 0 : return false;
35 : }
36 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
37 0 : if (!ToJSValue(cx, result, args.rval())) {
38 0 : return false;
39 : }
40 0 : return true;
41 : }
42 :
43 : static bool
44 0 : startRendering_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioContext* self, const JSJitMethodCallArgs& args)
45 : {
46 : // Make sure to save the callee before someone maybe messes
47 : // with rval().
48 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
49 0 : bool ok = startRendering(cx, obj, self, args);
50 0 : if (ok) {
51 0 : return true;
52 : }
53 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
54 0 : args.rval());
55 : }
56 :
57 : static const JSJitInfo startRendering_methodinfo = {
58 : { (JSJitGetterOp)startRendering_promiseWrapper },
59 : { prototypes::id::OfflineAudioContext },
60 : { PrototypeTraits<prototypes::id::OfflineAudioContext>::Depth },
61 : JSJitInfo::Method,
62 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
63 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
64 : false, /* isInfallible. False in setters. */
65 : false, /* isMovable. Not relevant for setters. */
66 : false, /* isEliminatable. Not relevant for setters. */
67 : false, /* isAlwaysInSlot. Only relevant for getters. */
68 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
69 : false, /* isTypedMethod. Only relevant for methods. */
70 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
71 : };
72 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
73 : static_assert(0 < 1, "There is no slot for us");
74 :
75 : static bool
76 0 : get_length(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioContext* self, JSJitGetterCallArgs args)
77 : {
78 0 : uint32_t result(self->Length());
79 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
80 0 : args.rval().setNumber(result);
81 0 : return true;
82 : }
83 :
84 : static const JSJitInfo length_getterinfo = {
85 : { (JSJitGetterOp)get_length },
86 : { prototypes::id::OfflineAudioContext },
87 : { PrototypeTraits<prototypes::id::OfflineAudioContext>::Depth },
88 : JSJitInfo::Getter,
89 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
90 : JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
91 : true, /* isInfallible. False in setters. */
92 : false, /* isMovable. Not relevant for setters. */
93 : false, /* isEliminatable. Not relevant for setters. */
94 : false, /* isAlwaysInSlot. Only relevant for getters. */
95 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
96 : false, /* isTypedMethod. Only relevant for methods. */
97 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
98 : };
99 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
100 : static_assert(0 < 1, "There is no slot for us");
101 :
102 : static bool
103 0 : get_oncomplete(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioContext* self, JSJitGetterCallArgs args)
104 : {
105 0 : RefPtr<EventHandlerNonNull> result(self->GetOncomplete());
106 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
107 0 : if (result) {
108 0 : args.rval().setObjectOrNull(GetCallbackFromCallbackObject(result));
109 0 : if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
110 0 : return false;
111 : }
112 0 : return true;
113 : } else {
114 0 : args.rval().setNull();
115 0 : return true;
116 : }
117 : }
118 :
119 : static bool
120 0 : set_oncomplete(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AudioContext* self, JSJitSetterCallArgs args)
121 : {
122 0 : RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
123 0 : if (args[0].isObject()) {
124 : { // scope for tempRoot
125 0 : JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
126 0 : arg0 = new binding_detail::FastEventHandlerNonNull(tempRoot);
127 : }
128 : } else {
129 0 : arg0 = nullptr;
130 : }
131 0 : self->SetOncomplete(Constify(arg0));
132 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
133 :
134 0 : return true;
135 : }
136 :
137 : static const JSJitInfo oncomplete_getterinfo = {
138 : { (JSJitGetterOp)get_oncomplete },
139 : { prototypes::id::OfflineAudioContext },
140 : { PrototypeTraits<prototypes::id::OfflineAudioContext>::Depth },
141 : JSJitInfo::Getter,
142 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
143 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
144 : false, /* isInfallible. False in setters. */
145 : false, /* isMovable. Not relevant for setters. */
146 : false, /* isEliminatable. Not relevant for setters. */
147 : false, /* isAlwaysInSlot. Only relevant for getters. */
148 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
149 : false, /* isTypedMethod. Only relevant for methods. */
150 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
151 : };
152 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
153 : static_assert(0 < 1, "There is no slot for us");
154 : static const JSJitInfo oncomplete_setterinfo = {
155 : { (JSJitGetterOp)set_oncomplete },
156 : { prototypes::id::OfflineAudioContext },
157 : { PrototypeTraits<prototypes::id::OfflineAudioContext>::Depth },
158 : JSJitInfo::Setter,
159 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
160 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
161 : false, /* isInfallible. False in setters. */
162 : false, /* isMovable. Not relevant for setters. */
163 : false, /* isEliminatable. Not relevant for setters. */
164 : false, /* isAlwaysInSlot. Only relevant for getters. */
165 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
166 : false, /* isTypedMethod. Only relevant for methods. */
167 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
168 : };
169 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
170 : static_assert(0 < 1, "There is no slot for us");
171 :
172 : static bool
173 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
174 : {
175 0 : mozilla::dom::AudioContext* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AudioContext>(obj);
176 : // We don't want to preserve if we don't have a wrapper, and we
177 : // obviously can't preserve if we're not initialized.
178 0 : if (self && self->GetWrapperPreserveColor()) {
179 0 : PreserveWrapper(self);
180 : }
181 0 : return true;
182 : }
183 :
184 : static void
185 0 : _finalize(js::FreeOp* fop, JSObject* obj)
186 : {
187 0 : mozilla::dom::AudioContext* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AudioContext>(obj);
188 0 : if (self) {
189 0 : ClearWrapper(self, self, obj);
190 0 : AddForDeferredFinalization<mozilla::dom::AudioContext>(self);
191 : }
192 0 : }
193 :
194 : static void
195 0 : _objectMoved(JSObject* obj, const JSObject* old)
196 : {
197 0 : mozilla::dom::AudioContext* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AudioContext>(obj);
198 0 : if (self) {
199 0 : UpdateWrapper(self, self, obj, old);
200 : }
201 0 : }
202 :
203 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
204 : #if defined(__clang__)
205 : #pragma clang diagnostic push
206 : #pragma clang diagnostic ignored "-Wmissing-braces"
207 : #endif
208 : static const JSFunctionSpec sMethods_specs[] = {
209 : JS_FNSPEC("startRendering", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&startRendering_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
210 : JS_FS_END
211 : };
212 : #if defined(__clang__)
213 : #pragma clang diagnostic pop
214 : #endif
215 :
216 :
217 : // Can't be const because the pref-enabled boolean needs to be writable
218 : static Prefable<const JSFunctionSpec> sMethods[] = {
219 : { nullptr, &sMethods_specs[0] },
220 : { nullptr, nullptr }
221 : };
222 :
223 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
224 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
225 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
226 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
227 :
228 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
229 : #if defined(__clang__)
230 : #pragma clang diagnostic push
231 : #pragma clang diagnostic ignored "-Wmissing-braces"
232 : #endif
233 : static const JSPropertySpec sAttributes_specs[] = {
234 : { "length", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &length_getterinfo, nullptr, nullptr },
235 : { "oncomplete", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &oncomplete_getterinfo, GenericBindingSetter, &oncomplete_setterinfo },
236 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
237 : };
238 : #if defined(__clang__)
239 : #pragma clang diagnostic pop
240 : #endif
241 :
242 :
243 : // Can't be const because the pref-enabled boolean needs to be writable
244 : static Prefable<const JSPropertySpec> sAttributes[] = {
245 : { nullptr, &sAttributes_specs[0] },
246 : { nullptr, nullptr }
247 : };
248 :
249 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
250 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
251 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
252 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
253 :
254 :
255 : static uint16_t sNativeProperties_sortedPropertyIndices[3];
256 : static PropertyInfo sNativeProperties_propertyInfos[3];
257 :
258 : static const NativePropertiesN<2> sNativeProperties = {
259 : false, 0,
260 : false, 0,
261 : true, 0 /* sMethods */,
262 : true, 1 /* sAttributes */,
263 : false, 0,
264 : false, 0,
265 : false, 0,
266 : -1,
267 : 3,
268 : sNativeProperties_sortedPropertyIndices,
269 : {
270 : { sMethods, &sNativeProperties_propertyInfos[0] },
271 : { sAttributes, &sNativeProperties_propertyInfos[1] }
272 : }
273 : };
274 : static_assert(3 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
275 : "We have a property info count that is oversized");
276 :
277 : static bool
278 0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
279 : {
280 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
281 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
282 0 : if (!args.isConstructing()) {
283 : // XXXbz wish I could get the name from the callee instead of
284 : // Adding more relocations
285 0 : return ThrowConstructorWithoutNew(cx, "OfflineAudioContext");
286 : }
287 :
288 0 : GlobalObject global(cx, obj);
289 0 : if (global.Failed()) {
290 0 : return false;
291 : }
292 :
293 0 : JS::Rooted<JSObject*> desiredProto(cx);
294 0 : if (!GetDesiredProto(cx, args, &desiredProto)) {
295 0 : return false;
296 : }
297 :
298 0 : if (MOZ_UNLIKELY(args.length() < 3)) {
299 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "OfflineAudioContext");
300 : }
301 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
302 : uint32_t arg0;
303 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[0], &arg0)) {
304 0 : return false;
305 : }
306 : uint32_t arg1;
307 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[1], &arg1)) {
308 0 : return false;
309 : }
310 : float arg2;
311 0 : if (!ValueToPrimitive<float, eDefault>(cx, args[2], &arg2)) {
312 0 : return false;
313 0 : } else if (!mozilla::IsFinite(arg2)) {
314 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "Argument 3 of OfflineAudioContext.constructor");
315 0 : return false;
316 : }
317 0 : Maybe<JSAutoCompartment> ac;
318 0 : if (objIsXray) {
319 0 : obj = js::CheckedUnwrap(obj);
320 0 : if (!obj) {
321 0 : return false;
322 : }
323 0 : ac.emplace(cx, obj);
324 0 : if (!JS_WrapObject(cx, &desiredProto)) {
325 0 : return false;
326 : }
327 : }
328 0 : binding_detail::FastErrorResult rv;
329 0 : auto result(StrongOrRawPtr<mozilla::dom::AudioContext>(mozilla::dom::AudioContext::Constructor(global, arg0, arg1, arg2, rv)));
330 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
331 0 : return false;
332 : }
333 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
334 : static_assert(!IsPointer<decltype(result)>::value,
335 : "NewObject implies that we need to keep the object alive with a strong reference.");
336 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
337 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
338 0 : return false;
339 : }
340 0 : return true;
341 : }
342 :
343 : static const js::ClassOps sInterfaceObjectClassOps = {
344 : nullptr, /* addProperty */
345 : nullptr, /* delProperty */
346 : nullptr, /* getProperty */
347 : nullptr, /* setProperty */
348 : nullptr, /* enumerate */
349 : nullptr, /* newEnumerate */
350 : nullptr, /* resolve */
351 : nullptr, /* mayResolve */
352 : nullptr, /* finalize */
353 : _constructor, /* call */
354 : nullptr, /* hasInstance */
355 : _constructor, /* construct */
356 : nullptr, /* trace */
357 : };
358 :
359 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
360 : {
361 : "Function",
362 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
363 : &sInterfaceObjectClassOps,
364 : JS_NULL_CLASS_SPEC,
365 : JS_NULL_CLASS_EXT,
366 : &sInterfaceObjectClassObjectOps
367 : },
368 : eInterface,
369 : true,
370 : prototypes::id::OfflineAudioContext,
371 : PrototypeTraits<prototypes::id::OfflineAudioContext>::Depth,
372 : sNativePropertyHooks,
373 : "function OfflineAudioContext() {\n [native code]\n}",
374 : BaseAudioContextBinding::GetConstructorObject
375 : };
376 :
377 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
378 : {
379 : "OfflineAudioContextPrototype",
380 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
381 : JS_NULL_CLASS_OPS,
382 : JS_NULL_CLASS_SPEC,
383 : JS_NULL_CLASS_EXT,
384 : JS_NULL_OBJECT_OPS
385 : },
386 : eInterfacePrototype,
387 : false,
388 : prototypes::id::OfflineAudioContext,
389 : PrototypeTraits<prototypes::id::OfflineAudioContext>::Depth,
390 : sNativePropertyHooks,
391 : "[object OfflineAudioContextPrototype]",
392 : BaseAudioContextBinding::GetProtoObject
393 : };
394 :
395 : bool
396 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
397 : {
398 : static bool sPrefValue;
399 : static bool sPrefCacheSetUp = false;
400 0 : if (!sPrefCacheSetUp) {
401 0 : sPrefCacheSetUp = true;
402 0 : Preferences::AddBoolVarCache(&sPrefValue, "dom.webaudio.enabled");
403 : }
404 :
405 0 : return sPrefValue;
406 : }
407 :
408 : JSObject*
409 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
410 : {
411 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
412 : }
413 :
414 : static const js::ClassOps sClassOps = {
415 : _addProperty, /* addProperty */
416 : nullptr, /* delProperty */
417 : nullptr, /* getProperty */
418 : nullptr, /* setProperty */
419 : nullptr, /* enumerate */
420 : nullptr, /* newEnumerate */
421 : nullptr, /* resolve */
422 : nullptr, /* mayResolve */
423 : _finalize, /* finalize */
424 : nullptr, /* call */
425 : nullptr, /* hasInstance */
426 : nullptr, /* construct */
427 : nullptr, /* trace */
428 : };
429 :
430 : static const js::ClassExtension sClassExtension = {
431 : nullptr, /* weakmapKeyDelegateOp */
432 : _objectMoved /* objectMovedOp */
433 : };
434 :
435 : static const DOMJSClass sClass = {
436 : { "OfflineAudioContext",
437 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
438 : &sClassOps,
439 : JS_NULL_CLASS_SPEC,
440 : &sClassExtension,
441 : JS_NULL_OBJECT_OPS
442 : },
443 : { prototypes::id::EventTarget, prototypes::id::BaseAudioContext, prototypes::id::OfflineAudioContext, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
444 : IsBaseOf<nsISupports, mozilla::dom::AudioContext >::value,
445 : sNativePropertyHooks,
446 : FindAssociatedGlobalForNative<mozilla::dom::AudioContext>::Get,
447 : GetProtoObjectHandle,
448 : GetCCParticipant<mozilla::dom::AudioContext>::Get()
449 : };
450 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
451 : "Must have the right minimal number of reserved slots.");
452 : static_assert(1 >= 1,
453 : "Must have enough reserved slots.");
454 :
455 : const JSClass*
456 0 : GetJSClass()
457 : {
458 0 : return sClass.ToJSClass();
459 : }
460 :
461 : bool
462 0 : Wrap(JSContext* aCx, mozilla::dom::AudioContext* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
463 : {
464 : MOZ_ASSERT(static_cast<mozilla::dom::AudioContext*>(aObject) ==
465 : reinterpret_cast<mozilla::dom::AudioContext*>(aObject),
466 : "Multiple inheritance for mozilla::dom::AudioContext is broken.");
467 : MOZ_ASSERT(static_cast<mozilla::dom::AudioContext*>(aObject) ==
468 : reinterpret_cast<mozilla::dom::AudioContext*>(aObject),
469 : "Multiple inheritance for mozilla::dom::AudioContext is broken.");
470 : MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
471 : reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
472 : "Multiple inheritance for mozilla::dom::EventTarget is broken.");
473 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
474 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
475 0 : MOZ_ASSERT(!aCache->GetWrapper(),
476 : "You should probably not be using Wrap() directly; use "
477 : "GetOrCreateDOMReflector instead");
478 :
479 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
480 : "nsISupports must be on our primary inheritance chain");
481 :
482 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
483 0 : if (!global) {
484 0 : return false;
485 : }
486 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
487 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
488 :
489 : // That might have ended up wrapping us already, due to the wonders
490 : // of XBL. Check for that, and bail out as needed.
491 0 : aReflector.set(aCache->GetWrapper());
492 0 : if (aReflector) {
493 : #ifdef DEBUG
494 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
495 : #endif // DEBUG
496 0 : return true;
497 : }
498 :
499 0 : JSAutoCompartment ac(aCx, global);
500 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
501 0 : if (!canonicalProto) {
502 0 : return false;
503 : }
504 0 : JS::Rooted<JSObject*> proto(aCx);
505 0 : if (aGivenProto) {
506 0 : proto = aGivenProto;
507 : // Unfortunately, while aGivenProto was in the compartment of aCx
508 : // coming in, we changed compartments to that of "parent" so may need
509 : // to wrap the proto here.
510 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
511 0 : if (!JS_WrapObject(aCx, &proto)) {
512 0 : return false;
513 : }
514 : }
515 : } else {
516 0 : proto = canonicalProto;
517 : }
518 :
519 0 : BindingJSObjectCreator<mozilla::dom::AudioContext> creator(aCx);
520 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
521 0 : if (!aReflector) {
522 0 : return false;
523 : }
524 :
525 0 : aCache->SetWrapper(aReflector);
526 0 : creator.InitializationSucceeded();
527 :
528 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
529 : aCache->GetWrapperPreserveColor() == aReflector);
530 : // If proto != canonicalProto, we have to preserve our wrapper;
531 : // otherwise we won't be able to properly recreate it later, since
532 : // we won't know what proto to use. Note that we don't check
533 : // aGivenProto here, since it's entirely possible (and even
534 : // somewhat common) to have a non-null aGivenProto which is the
535 : // same as canonicalProto.
536 0 : if (proto != canonicalProto) {
537 0 : PreserveWrapper(aObject);
538 : }
539 :
540 0 : return true;
541 : }
542 :
543 : const NativePropertyHooks sNativePropertyHooks[] = { {
544 : nullptr,
545 : nullptr,
546 : nullptr,
547 : { sNativeProperties.Upcast(), nullptr },
548 : prototypes::id::OfflineAudioContext,
549 : constructors::id::OfflineAudioContext,
550 : BaseAudioContextBinding::sNativePropertyHooks,
551 : &DefaultXrayExpandoObjectClass
552 : } };
553 :
554 : void
555 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
556 : {
557 0 : JS::Handle<JSObject*> parentProto(BaseAudioContextBinding::GetProtoObjectHandle(aCx));
558 0 : if (!parentProto) {
559 0 : return;
560 : }
561 :
562 0 : JS::Handle<JSObject*> constructorProto(BaseAudioContextBinding::GetConstructorObjectHandle(aCx));
563 0 : if (!constructorProto) {
564 0 : return;
565 : }
566 :
567 : static bool sIdsInited = false;
568 0 : if (!sIdsInited && NS_IsMainThread()) {
569 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
570 0 : return;
571 : }
572 0 : sIdsInited = true;
573 : }
574 :
575 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::OfflineAudioContext);
576 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::OfflineAudioContext);
577 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
578 : &sPrototypeClass.mBase, protoCache,
579 : constructorProto, &sInterfaceObjectClass.mBase, 3, nullptr,
580 : interfaceCache,
581 : sNativeProperties.Upcast(),
582 : nullptr,
583 : "OfflineAudioContext", aDefineOnGlobal,
584 : nullptr,
585 0 : false);
586 : }
587 :
588 : JS::Handle<JSObject*>
589 0 : GetProtoObjectHandle(JSContext* aCx)
590 : {
591 : /* Get the interface prototype object for this class. This will create the
592 : object as needed. */
593 0 : bool aDefineOnGlobal = true;
594 :
595 : /* Make sure our global is sane. Hopefully we can remove this sometime */
596 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
597 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
598 0 : return nullptr;
599 : }
600 :
601 : /* Check to see whether the interface objects are already installed */
602 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
603 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::OfflineAudioContext)) {
604 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
605 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
606 : }
607 :
608 : /*
609 : * The object might _still_ be null, but that's OK.
610 : *
611 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
612 : * traced by TraceProtoAndIfaceCache() and its contents are never
613 : * changed after they have been set.
614 : *
615 : * Calling address() avoids the read read barrier that does gray
616 : * unmarking, but it's not possible for the object to be gray here.
617 : */
618 :
619 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::OfflineAudioContext);
620 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
621 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
622 : }
623 :
624 : JS::Handle<JSObject*>
625 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
626 : {
627 : /* Get the interface object for this class. This will create the object as
628 : needed. */
629 :
630 : /* Make sure our global is sane. Hopefully we can remove this sometime */
631 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
632 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
633 0 : return nullptr;
634 : }
635 :
636 : /* Check to see whether the interface objects are already installed */
637 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
638 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::OfflineAudioContext)) {
639 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
640 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
641 : }
642 :
643 : /*
644 : * The object might _still_ be null, but that's OK.
645 : *
646 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
647 : * traced by TraceProtoAndIfaceCache() and its contents are never
648 : * changed after they have been set.
649 : *
650 : * Calling address() avoids the read read barrier that does gray
651 : * unmarking, but it's not possible for the object to be gray here.
652 : */
653 :
654 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::OfflineAudioContext);
655 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
656 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
657 : }
658 :
659 : JSObject*
660 0 : GetConstructorObject(JSContext* aCx)
661 : {
662 0 : return GetConstructorObjectHandle(aCx);
663 : }
664 :
665 : } // namespace OfflineAudioContextBinding
666 :
667 :
668 :
669 : } // namespace dom
670 : } // namespace mozilla
|