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