Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM MediaStream.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "AtomList.h"
4 : #include "DOMMediaStream.h"
5 : #include "EventHandlerBinding.h"
6 : #include "EventTargetBinding.h"
7 : #include "MediaStreamBinding.h"
8 : #include "WrapperFactory.h"
9 : #include "mozilla/FloatingPoint.h"
10 : #include "mozilla/OwningNonNull.h"
11 : #include "mozilla/dom/AudioStreamTrack.h"
12 : #include "mozilla/dom/BindingUtils.h"
13 : #include "mozilla/dom/DOMJSClass.h"
14 : #include "mozilla/dom/MediaStreamTrack.h"
15 : #include "mozilla/dom/NonRefcountedDOMObject.h"
16 : #include "mozilla/dom/Nullable.h"
17 : #include "mozilla/dom/PrimitiveConversions.h"
18 : #include "mozilla/dom/ScriptSettings.h"
19 : #include "mozilla/dom/SimpleGlobalObject.h"
20 : #include "mozilla/dom/UnionConversions.h"
21 : #include "mozilla/dom/VideoStreamTrack.h"
22 : #include "mozilla/dom/XrayExpandoClass.h"
23 :
24 : namespace mozilla {
25 : namespace dom {
26 :
27 : bool
28 0 : BooleanOrMediaTrackConstraints::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
29 : {
30 0 : switch (mType) {
31 : case eUninitialized: {
32 0 : return false;
33 : break;
34 : }
35 : case eBoolean: {
36 0 : rval.setBoolean(mValue.mBoolean.Value());
37 0 : return true;
38 : break;
39 : }
40 : case eMediaTrackConstraints: {
41 0 : if (!mValue.mMediaTrackConstraints.Value().ToObjectInternal(cx, rval)) {
42 0 : return false;
43 : }
44 0 : return true;
45 : break;
46 : }
47 : default: {
48 0 : return false;
49 : break;
50 : }
51 : }
52 :
53 : return false;
54 : }
55 :
56 :
57 : bool&
58 0 : OwningBooleanOrMediaTrackConstraints::RawSetAsBoolean()
59 : {
60 0 : if (mType == eBoolean) {
61 0 : return mValue.mBoolean.Value();
62 : }
63 0 : MOZ_ASSERT(mType == eUninitialized);
64 0 : mType = eBoolean;
65 0 : return mValue.mBoolean.SetValue();
66 : }
67 :
68 : bool&
69 0 : OwningBooleanOrMediaTrackConstraints::SetAsBoolean()
70 : {
71 0 : if (mType == eBoolean) {
72 0 : return mValue.mBoolean.Value();
73 : }
74 0 : Uninit();
75 0 : mType = eBoolean;
76 0 : return mValue.mBoolean.SetValue();
77 : }
78 :
79 : bool
80 0 : OwningBooleanOrMediaTrackConstraints::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
81 : {
82 0 : tryNext = false;
83 : { // scope for memberSlot
84 0 : bool& memberSlot = RawSetAsBoolean();
85 0 : if (!ValueToPrimitive<bool, eDefault>(cx, value, &memberSlot)) {
86 0 : return false;
87 : }
88 : }
89 0 : return true;
90 : }
91 :
92 : void
93 0 : OwningBooleanOrMediaTrackConstraints::DestroyBoolean()
94 : {
95 0 : MOZ_ASSERT(IsBoolean(), "Wrong type!");
96 0 : mValue.mBoolean.Destroy();
97 0 : mType = eUninitialized;
98 0 : }
99 :
100 :
101 :
102 :
103 : MediaTrackConstraints&
104 0 : OwningBooleanOrMediaTrackConstraints::RawSetAsMediaTrackConstraints()
105 : {
106 0 : if (mType == eMediaTrackConstraints) {
107 0 : return mValue.mMediaTrackConstraints.Value();
108 : }
109 0 : MOZ_ASSERT(mType == eUninitialized);
110 0 : mType = eMediaTrackConstraints;
111 0 : return mValue.mMediaTrackConstraints.SetValue();
112 : }
113 :
114 : MediaTrackConstraints&
115 0 : OwningBooleanOrMediaTrackConstraints::SetAsMediaTrackConstraints()
116 : {
117 0 : if (mType == eMediaTrackConstraints) {
118 0 : return mValue.mMediaTrackConstraints.Value();
119 : }
120 0 : Uninit();
121 0 : mType = eMediaTrackConstraints;
122 0 : return mValue.mMediaTrackConstraints.SetValue();
123 : }
124 :
125 : bool
126 0 : OwningBooleanOrMediaTrackConstraints::TrySetToMediaTrackConstraints(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
127 : {
128 0 : tryNext = false;
129 : { // scope for memberSlot
130 0 : MediaTrackConstraints& memberSlot = RawSetAsMediaTrackConstraints();
131 0 : if (!IsConvertibleToDictionary(value)) {
132 0 : DestroyMediaTrackConstraints();
133 0 : tryNext = true;
134 0 : return true;
135 : }
136 0 : if (!memberSlot.Init(cx, value, "Member of BooleanOrMediaTrackConstraints", passedToJSImpl)) {
137 0 : return false;
138 : }
139 : }
140 0 : return true;
141 : }
142 :
143 : void
144 0 : OwningBooleanOrMediaTrackConstraints::DestroyMediaTrackConstraints()
145 : {
146 0 : MOZ_ASSERT(IsMediaTrackConstraints(), "Wrong type!");
147 0 : mValue.mMediaTrackConstraints.Destroy();
148 0 : mType = eUninitialized;
149 0 : }
150 :
151 :
152 :
153 :
154 : void
155 0 : OwningBooleanOrMediaTrackConstraints::Uninit()
156 : {
157 0 : switch (mType) {
158 : case eUninitialized: {
159 0 : break;
160 : }
161 : case eBoolean: {
162 0 : DestroyBoolean();
163 0 : break;
164 : }
165 : case eMediaTrackConstraints: {
166 0 : DestroyMediaTrackConstraints();
167 0 : break;
168 : }
169 : }
170 0 : }
171 :
172 : bool
173 0 : OwningBooleanOrMediaTrackConstraints::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
174 : {
175 0 : switch (mType) {
176 : case eUninitialized: {
177 0 : return false;
178 : break;
179 : }
180 : case eBoolean: {
181 0 : rval.setBoolean(mValue.mBoolean.Value());
182 0 : return true;
183 : break;
184 : }
185 : case eMediaTrackConstraints: {
186 0 : if (!mValue.mMediaTrackConstraints.Value().ToObjectInternal(cx, rval)) {
187 0 : return false;
188 : }
189 0 : return true;
190 : break;
191 : }
192 : default: {
193 0 : return false;
194 : break;
195 : }
196 : }
197 :
198 : return false;
199 : }
200 :
201 : void
202 0 : OwningBooleanOrMediaTrackConstraints::TraceUnion(JSTracer* trc)
203 : {
204 0 : }
205 :
206 : OwningBooleanOrMediaTrackConstraints&
207 0 : OwningBooleanOrMediaTrackConstraints::operator=(const OwningBooleanOrMediaTrackConstraints& aOther)
208 : {
209 0 : switch (aOther.mType) {
210 : case eUninitialized: {
211 0 : MOZ_ASSERT(mType == eUninitialized,
212 : "We need to destroy ourselves?");
213 0 : break;
214 : }
215 : case eBoolean: {
216 0 : SetAsBoolean() = aOther.GetAsBoolean();
217 0 : break;
218 : }
219 : case eMediaTrackConstraints: {
220 0 : SetAsMediaTrackConstraints() = aOther.GetAsMediaTrackConstraints();
221 0 : break;
222 : }
223 : }
224 0 : return *this;
225 : }
226 :
227 :
228 :
229 0 : MediaStreamConstraints::MediaStreamConstraints()
230 : {
231 : // Safe to pass a null context if we pass a null value
232 0 : Init(nullptr, JS::NullHandleValue);
233 0 : }
234 :
235 :
236 :
237 : bool
238 0 : MediaStreamConstraints::InitIds(JSContext* cx, MediaStreamConstraintsAtoms* atomsCache)
239 : {
240 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
241 :
242 : // Initialize these in reverse order so that any failure leaves the first one
243 : // uninitialized.
244 0 : if (!atomsCache->video_id.init(cx, "video") ||
245 0 : !atomsCache->picture_id.init(cx, "picture") ||
246 0 : !atomsCache->peerIdentity_id.init(cx, "peerIdentity") ||
247 0 : !atomsCache->fake_id.init(cx, "fake") ||
248 0 : !atomsCache->audio_id.init(cx, "audio")) {
249 0 : return false;
250 : }
251 0 : return true;
252 : }
253 :
254 : bool
255 0 : MediaStreamConstraints::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
256 : {
257 : // Passing a null JSContext is OK only if we're initing from null,
258 : // Since in that case we will not have to do any property gets
259 : // Also evaluate isNullOrUndefined in order to avoid false-positive
260 : // checkers by static analysis tools
261 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
262 0 : MediaStreamConstraintsAtoms* atomsCache = nullptr;
263 0 : if (cx) {
264 0 : atomsCache = GetAtomCache<MediaStreamConstraintsAtoms>(cx);
265 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
266 0 : return false;
267 : }
268 : }
269 :
270 0 : if (!IsConvertibleToDictionary(val)) {
271 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
272 : }
273 :
274 0 : bool isNull = val.isNullOrUndefined();
275 : // We only need these if !isNull, in which case we have |cx|.
276 0 : Maybe<JS::Rooted<JSObject *> > object;
277 0 : Maybe<JS::Rooted<JS::Value> > temp;
278 0 : if (!isNull) {
279 0 : MOZ_ASSERT(cx);
280 0 : object.emplace(cx, &val.toObject());
281 0 : temp.emplace(cx);
282 : }
283 0 : if (!isNull) {
284 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->audio_id, temp.ptr())) {
285 0 : return false;
286 : }
287 : }
288 0 : mAudio.Uninit();
289 0 : if (!(!isNull && !temp->isUndefined())) {
290 0 : mAudio.RawSetAsBoolean() = false;
291 : } else {
292 : {
293 0 : bool done = false, failed = false, tryNext;
294 0 : if (!done) {
295 0 : done = (failed = !mAudio.TrySetToMediaTrackConstraints(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext;
296 : }
297 0 : if (!done) {
298 : do {
299 0 : done = (failed = !mAudio.TrySetToBoolean(cx, temp.ref(), tryNext)) || !tryNext;
300 0 : break;
301 : } while (0);
302 : }
303 0 : if (failed) {
304 0 : return false;
305 : }
306 0 : if (!done) {
307 0 : ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'audio' member of MediaStreamConstraints", "MediaTrackConstraints");
308 0 : return false;
309 : }
310 : }
311 : }
312 0 : mIsAnyMemberPresent = true;
313 :
314 0 : if (!isNull) {
315 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->fake_id, temp.ptr())) {
316 0 : return false;
317 : }
318 : }
319 0 : if (!isNull && !temp->isUndefined()) {
320 0 : mFake.Construct();
321 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &(mFake.Value()))) {
322 0 : return false;
323 : }
324 0 : mIsAnyMemberPresent = true;
325 : }
326 :
327 0 : if (!isNull) {
328 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->peerIdentity_id, temp.ptr())) {
329 0 : return false;
330 : }
331 : }
332 0 : if (!isNull && !temp->isUndefined()) {
333 0 : if (!ConvertJSValueToString(cx, temp.ref(), eNull, eNull, mPeerIdentity)) {
334 0 : return false;
335 : }
336 : } else {
337 0 : mPeerIdentity.SetIsVoid(true);
338 : }
339 0 : mIsAnyMemberPresent = true;
340 :
341 0 : if (!isNull) {
342 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->picture_id, temp.ptr())) {
343 0 : return false;
344 : }
345 : }
346 0 : if (!isNull && !temp->isUndefined()) {
347 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mPicture)) {
348 0 : return false;
349 : }
350 : } else {
351 0 : mPicture = false;
352 : }
353 0 : mIsAnyMemberPresent = true;
354 :
355 0 : if (!isNull) {
356 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->video_id, temp.ptr())) {
357 0 : return false;
358 : }
359 : }
360 0 : mVideo.Uninit();
361 0 : if (!(!isNull && !temp->isUndefined())) {
362 0 : mVideo.RawSetAsBoolean() = false;
363 : } else {
364 : {
365 0 : bool done = false, failed = false, tryNext;
366 0 : if (!done) {
367 0 : done = (failed = !mVideo.TrySetToMediaTrackConstraints(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext;
368 : }
369 0 : if (!done) {
370 : do {
371 0 : done = (failed = !mVideo.TrySetToBoolean(cx, temp.ref(), tryNext)) || !tryNext;
372 0 : break;
373 : } while (0);
374 : }
375 0 : if (failed) {
376 0 : return false;
377 : }
378 0 : if (!done) {
379 0 : ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'video' member of MediaStreamConstraints", "MediaTrackConstraints");
380 0 : return false;
381 : }
382 : }
383 : }
384 0 : mIsAnyMemberPresent = true;
385 0 : return true;
386 : }
387 :
388 : bool
389 0 : MediaStreamConstraints::Init(const nsAString& aJSON)
390 : {
391 0 : AutoJSAPI jsapi;
392 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
393 0 : if (!cleanGlobal) {
394 0 : return false;
395 : }
396 0 : if (!jsapi.Init(cleanGlobal)) {
397 0 : return false;
398 : }
399 0 : JSContext* cx = jsapi.cx();
400 0 : JS::Rooted<JS::Value> json(cx);
401 0 : bool ok = ParseJSON(cx, aJSON, &json);
402 0 : NS_ENSURE_TRUE(ok, false);
403 0 : return Init(cx, json);
404 : }
405 :
406 : bool
407 0 : MediaStreamConstraints::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
408 : {
409 0 : MediaStreamConstraintsAtoms* atomsCache = GetAtomCache<MediaStreamConstraintsAtoms>(cx);
410 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
411 0 : return false;
412 : }
413 :
414 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
415 0 : if (!obj) {
416 0 : return false;
417 : }
418 0 : rval.set(JS::ObjectValue(*obj));
419 :
420 : do {
421 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
422 0 : JS::Rooted<JS::Value> temp(cx);
423 0 : OwningBooleanOrMediaTrackConstraints const & currentValue = mAudio;
424 0 : if (!currentValue.ToJSVal(cx, obj, &temp)) {
425 0 : return false;
426 : }
427 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->audio_id, temp, JSPROP_ENUMERATE)) {
428 0 : return false;
429 : }
430 0 : break;
431 : } while(0);
432 :
433 0 : if (mFake.WasPassed()) {
434 : do {
435 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
436 0 : JS::Rooted<JS::Value> temp(cx);
437 0 : bool const & currentValue = mFake.InternalValue();
438 0 : temp.setBoolean(currentValue);
439 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->fake_id, temp, JSPROP_ENUMERATE)) {
440 0 : return false;
441 : }
442 0 : break;
443 : } while(0);
444 : }
445 :
446 : do {
447 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
448 0 : JS::Rooted<JS::Value> temp(cx);
449 0 : nsString const & currentValue = mPeerIdentity;
450 0 : if (!xpc::StringToJsval(cx, currentValue, &temp)) {
451 0 : return false;
452 : }
453 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->peerIdentity_id, temp, JSPROP_ENUMERATE)) {
454 0 : return false;
455 : }
456 0 : break;
457 : } while(0);
458 :
459 : do {
460 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
461 0 : JS::Rooted<JS::Value> temp(cx);
462 0 : bool const & currentValue = mPicture;
463 0 : temp.setBoolean(currentValue);
464 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->picture_id, temp, JSPROP_ENUMERATE)) {
465 0 : return false;
466 : }
467 0 : break;
468 : } while(0);
469 :
470 : do {
471 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
472 0 : JS::Rooted<JS::Value> temp(cx);
473 0 : OwningBooleanOrMediaTrackConstraints const & currentValue = mVideo;
474 0 : if (!currentValue.ToJSVal(cx, obj, &temp)) {
475 0 : return false;
476 : }
477 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->video_id, temp, JSPROP_ENUMERATE)) {
478 0 : return false;
479 : }
480 0 : break;
481 : } while(0);
482 :
483 0 : return true;
484 : }
485 :
486 : bool
487 0 : MediaStreamConstraints::ToJSON(nsAString& aJSON) const
488 : {
489 0 : AutoJSAPI jsapi;
490 0 : jsapi.Init();
491 0 : JSContext *cx = jsapi.cx();
492 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
493 : // because we'll only be creating objects, in ways that have no
494 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
495 : // which likewise guarantees no side-effects for the sorts of
496 : // things we will pass it.
497 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
498 0 : JS::Rooted<JS::Value> val(cx);
499 0 : if (!ToObjectInternal(cx, &val)) {
500 0 : return false;
501 : }
502 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
503 0 : return StringifyToJSON(cx, obj, aJSON);
504 : }
505 :
506 : void
507 0 : MediaStreamConstraints::TraceDictionary(JSTracer* trc)
508 : {
509 0 : }
510 :
511 : MediaStreamConstraints&
512 0 : MediaStreamConstraints::operator=(const MediaStreamConstraints& aOther)
513 : {
514 0 : mAudio = aOther.mAudio;
515 0 : mFake.Reset();
516 0 : if (aOther.mFake.WasPassed()) {
517 0 : mFake.Construct(aOther.mFake.Value());
518 : }
519 0 : mPeerIdentity = aOther.mPeerIdentity;
520 0 : mPicture = aOther.mPicture;
521 0 : mVideo = aOther.mVideo;
522 0 : return *this;
523 : }
524 :
525 : namespace binding_detail {
526 : } // namespace binding_detail
527 :
528 :
529 : namespace MediaStreamBinding {
530 :
531 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventTargetBinding::NativeType>::value,
532 : "Can't inherit from an interface with a different ownership model.");
533 :
534 : static bool
535 0 : get_id(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::DOMMediaStream* self, JSJitGetterCallArgs args)
536 : {
537 0 : DOMString result;
538 0 : self->GetId(result);
539 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
540 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
541 0 : return false;
542 : }
543 0 : return true;
544 : }
545 :
546 : static const JSJitInfo id_getterinfo = {
547 : { (JSJitGetterOp)get_id },
548 : { prototypes::id::MediaStream },
549 : { PrototypeTraits<prototypes::id::MediaStream>::Depth },
550 : JSJitInfo::Getter,
551 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
552 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
553 : false, /* isInfallible. False in setters. */
554 : false, /* isMovable. Not relevant for setters. */
555 : false, /* isEliminatable. Not relevant for setters. */
556 : false, /* isAlwaysInSlot. Only relevant for getters. */
557 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
558 : false, /* isTypedMethod. Only relevant for methods. */
559 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
560 : };
561 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
562 : static_assert(0 < 1, "There is no slot for us");
563 :
564 : static bool
565 0 : getAudioTracks(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::DOMMediaStream* self, const JSJitMethodCallArgs& args)
566 : {
567 0 : nsTArray<StrongPtrForMember<mozilla::dom::AudioStreamTrack>::Type> result;
568 0 : self->GetAudioTracks(result);
569 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
570 :
571 0 : uint32_t length = result.Length();
572 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
573 0 : if (!returnArray) {
574 0 : return false;
575 : }
576 : // Scope for 'tmp'
577 : {
578 0 : JS::Rooted<JS::Value> tmp(cx);
579 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
580 : // Control block to let us common up the JS_DefineElement calls when there
581 : // are different ways to succeed at wrapping the object.
582 : do {
583 0 : if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) {
584 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
585 0 : return false;
586 : }
587 0 : break;
588 : } while (0);
589 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
590 : JSPROP_ENUMERATE)) {
591 0 : return false;
592 : }
593 : }
594 : }
595 0 : args.rval().setObject(*returnArray);
596 0 : return true;
597 : }
598 :
599 : static const JSJitInfo getAudioTracks_methodinfo = {
600 : { (JSJitGetterOp)getAudioTracks },
601 : { prototypes::id::MediaStream },
602 : { PrototypeTraits<prototypes::id::MediaStream>::Depth },
603 : JSJitInfo::Method,
604 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
605 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
606 : false, /* isInfallible. False in setters. */
607 : false, /* isMovable. Not relevant for setters. */
608 : false, /* isEliminatable. Not relevant for setters. */
609 : false, /* isAlwaysInSlot. Only relevant for getters. */
610 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
611 : false, /* isTypedMethod. Only relevant for methods. */
612 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
613 : };
614 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
615 : static_assert(0 < 1, "There is no slot for us");
616 :
617 : static bool
618 0 : getVideoTracks(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::DOMMediaStream* self, const JSJitMethodCallArgs& args)
619 : {
620 0 : nsTArray<StrongPtrForMember<mozilla::dom::VideoStreamTrack>::Type> result;
621 0 : self->GetVideoTracks(result);
622 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
623 :
624 0 : uint32_t length = result.Length();
625 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
626 0 : if (!returnArray) {
627 0 : return false;
628 : }
629 : // Scope for 'tmp'
630 : {
631 0 : JS::Rooted<JS::Value> tmp(cx);
632 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
633 : // Control block to let us common up the JS_DefineElement calls when there
634 : // are different ways to succeed at wrapping the object.
635 : do {
636 0 : if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) {
637 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
638 0 : return false;
639 : }
640 0 : break;
641 : } while (0);
642 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
643 : JSPROP_ENUMERATE)) {
644 0 : return false;
645 : }
646 : }
647 : }
648 0 : args.rval().setObject(*returnArray);
649 0 : return true;
650 : }
651 :
652 : static const JSJitInfo getVideoTracks_methodinfo = {
653 : { (JSJitGetterOp)getVideoTracks },
654 : { prototypes::id::MediaStream },
655 : { PrototypeTraits<prototypes::id::MediaStream>::Depth },
656 : JSJitInfo::Method,
657 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
658 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
659 : false, /* isInfallible. False in setters. */
660 : false, /* isMovable. Not relevant for setters. */
661 : false, /* isEliminatable. Not relevant for setters. */
662 : false, /* isAlwaysInSlot. Only relevant for getters. */
663 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
664 : false, /* isTypedMethod. Only relevant for methods. */
665 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
666 : };
667 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
668 : static_assert(0 < 1, "There is no slot for us");
669 :
670 : static bool
671 0 : getTracks(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::DOMMediaStream* self, const JSJitMethodCallArgs& args)
672 : {
673 0 : nsTArray<StrongPtrForMember<mozilla::dom::MediaStreamTrack>::Type> result;
674 0 : self->GetTracks(result);
675 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
676 :
677 0 : uint32_t length = result.Length();
678 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
679 0 : if (!returnArray) {
680 0 : return false;
681 : }
682 : // Scope for 'tmp'
683 : {
684 0 : JS::Rooted<JS::Value> tmp(cx);
685 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
686 : // Control block to let us common up the JS_DefineElement calls when there
687 : // are different ways to succeed at wrapping the object.
688 : do {
689 0 : if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) {
690 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
691 0 : return false;
692 : }
693 0 : break;
694 : } while (0);
695 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
696 : JSPROP_ENUMERATE)) {
697 0 : return false;
698 : }
699 : }
700 : }
701 0 : args.rval().setObject(*returnArray);
702 0 : return true;
703 : }
704 :
705 : static const JSJitInfo getTracks_methodinfo = {
706 : { (JSJitGetterOp)getTracks },
707 : { prototypes::id::MediaStream },
708 : { PrototypeTraits<prototypes::id::MediaStream>::Depth },
709 : JSJitInfo::Method,
710 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
711 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
712 : false, /* isInfallible. False in setters. */
713 : false, /* isMovable. Not relevant for setters. */
714 : false, /* isEliminatable. Not relevant for setters. */
715 : false, /* isAlwaysInSlot. Only relevant for getters. */
716 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
717 : false, /* isTypedMethod. Only relevant for methods. */
718 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
719 : };
720 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
721 : static_assert(0 < 1, "There is no slot for us");
722 :
723 : static bool
724 0 : getTrackById(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::DOMMediaStream* self, const JSJitMethodCallArgs& args)
725 : {
726 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
727 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "MediaStream.getTrackById");
728 : }
729 0 : binding_detail::FakeString arg0;
730 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
731 0 : return false;
732 : }
733 0 : auto result(StrongOrRawPtr<mozilla::dom::MediaStreamTrack>(self->GetTrackById(NonNullHelper(Constify(arg0)))));
734 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
735 0 : if (!result) {
736 0 : args.rval().setNull();
737 0 : return true;
738 : }
739 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
740 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
741 0 : return false;
742 : }
743 0 : return true;
744 : }
745 :
746 : static const JSJitInfo getTrackById_methodinfo = {
747 : { (JSJitGetterOp)getTrackById },
748 : { prototypes::id::MediaStream },
749 : { PrototypeTraits<prototypes::id::MediaStream>::Depth },
750 : JSJitInfo::Method,
751 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
752 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
753 : false, /* isInfallible. False in setters. */
754 : false, /* isMovable. Not relevant for setters. */
755 : false, /* isEliminatable. Not relevant for setters. */
756 : false, /* isAlwaysInSlot. Only relevant for getters. */
757 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
758 : false, /* isTypedMethod. Only relevant for methods. */
759 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
760 : };
761 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
762 : static_assert(0 < 1, "There is no slot for us");
763 :
764 : static bool
765 0 : addTrack(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::DOMMediaStream* self, const JSJitMethodCallArgs& args)
766 : {
767 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
768 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "MediaStream.addTrack");
769 : }
770 0 : NonNull<mozilla::dom::MediaStreamTrack> arg0;
771 0 : if (args[0].isObject()) {
772 : {
773 0 : nsresult rv = UnwrapObject<prototypes::id::MediaStreamTrack, mozilla::dom::MediaStreamTrack>(args[0], arg0);
774 0 : if (NS_FAILED(rv)) {
775 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of MediaStream.addTrack", "MediaStreamTrack");
776 0 : return false;
777 : }
778 : }
779 : } else {
780 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of MediaStream.addTrack");
781 0 : return false;
782 : }
783 0 : self->AddTrack(NonNullHelper(arg0));
784 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
785 0 : args.rval().setUndefined();
786 0 : return true;
787 : }
788 :
789 : static const JSJitInfo addTrack_methodinfo = {
790 : { (JSJitGetterOp)addTrack },
791 : { prototypes::id::MediaStream },
792 : { PrototypeTraits<prototypes::id::MediaStream>::Depth },
793 : JSJitInfo::Method,
794 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
795 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
796 : false, /* isInfallible. False in setters. */
797 : false, /* isMovable. Not relevant for setters. */
798 : false, /* isEliminatable. Not relevant for setters. */
799 : false, /* isAlwaysInSlot. Only relevant for getters. */
800 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
801 : false, /* isTypedMethod. Only relevant for methods. */
802 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
803 : };
804 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
805 : static_assert(0 < 1, "There is no slot for us");
806 :
807 : static bool
808 0 : removeTrack(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::DOMMediaStream* self, const JSJitMethodCallArgs& args)
809 : {
810 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
811 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "MediaStream.removeTrack");
812 : }
813 0 : NonNull<mozilla::dom::MediaStreamTrack> arg0;
814 0 : if (args[0].isObject()) {
815 : {
816 0 : nsresult rv = UnwrapObject<prototypes::id::MediaStreamTrack, mozilla::dom::MediaStreamTrack>(args[0], arg0);
817 0 : if (NS_FAILED(rv)) {
818 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of MediaStream.removeTrack", "MediaStreamTrack");
819 0 : return false;
820 : }
821 : }
822 : } else {
823 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of MediaStream.removeTrack");
824 0 : return false;
825 : }
826 0 : self->RemoveTrack(NonNullHelper(arg0));
827 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
828 0 : args.rval().setUndefined();
829 0 : return true;
830 : }
831 :
832 : static const JSJitInfo removeTrack_methodinfo = {
833 : { (JSJitGetterOp)removeTrack },
834 : { prototypes::id::MediaStream },
835 : { PrototypeTraits<prototypes::id::MediaStream>::Depth },
836 : JSJitInfo::Method,
837 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
838 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
839 : false, /* isInfallible. False in setters. */
840 : false, /* isMovable. Not relevant for setters. */
841 : false, /* isEliminatable. Not relevant for setters. */
842 : false, /* isAlwaysInSlot. Only relevant for getters. */
843 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
844 : false, /* isTypedMethod. Only relevant for methods. */
845 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
846 : };
847 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
848 : static_assert(0 < 1, "There is no slot for us");
849 :
850 : static bool
851 0 : clone(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::DOMMediaStream* self, const JSJitMethodCallArgs& args)
852 : {
853 0 : auto result(StrongOrRawPtr<mozilla::DOMMediaStream>(self->Clone()));
854 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
855 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
856 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
857 0 : return false;
858 : }
859 0 : return true;
860 : }
861 :
862 : static const JSJitInfo clone_methodinfo = {
863 : { (JSJitGetterOp)clone },
864 : { prototypes::id::MediaStream },
865 : { PrototypeTraits<prototypes::id::MediaStream>::Depth },
866 : JSJitInfo::Method,
867 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
868 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
869 : false, /* isInfallible. False in setters. */
870 : false, /* isMovable. Not relevant for setters. */
871 : false, /* isEliminatable. Not relevant for setters. */
872 : false, /* isAlwaysInSlot. Only relevant for getters. */
873 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
874 : false, /* isTypedMethod. Only relevant for methods. */
875 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
876 : };
877 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
878 : static_assert(0 < 1, "There is no slot for us");
879 :
880 : static bool
881 0 : get_active(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::DOMMediaStream* self, JSJitGetterCallArgs args)
882 : {
883 0 : bool result(self->Active());
884 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
885 0 : args.rval().setBoolean(result);
886 0 : return true;
887 : }
888 :
889 : static const JSJitInfo active_getterinfo = {
890 : { (JSJitGetterOp)get_active },
891 : { prototypes::id::MediaStream },
892 : { PrototypeTraits<prototypes::id::MediaStream>::Depth },
893 : JSJitInfo::Getter,
894 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
895 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
896 : true, /* isInfallible. False in setters. */
897 : false, /* isMovable. Not relevant for setters. */
898 : false, /* isEliminatable. Not relevant for setters. */
899 : false, /* isAlwaysInSlot. Only relevant for getters. */
900 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
901 : false, /* isTypedMethod. Only relevant for methods. */
902 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
903 : };
904 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
905 : static_assert(0 < 1, "There is no slot for us");
906 :
907 : static bool
908 0 : get_onaddtrack(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::DOMMediaStream* self, JSJitGetterCallArgs args)
909 : {
910 0 : RefPtr<EventHandlerNonNull> result(self->GetOnaddtrack());
911 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
912 0 : if (result) {
913 0 : args.rval().setObjectOrNull(GetCallbackFromCallbackObject(result));
914 0 : if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
915 0 : return false;
916 : }
917 0 : return true;
918 : } else {
919 0 : args.rval().setNull();
920 0 : return true;
921 : }
922 : }
923 :
924 : static bool
925 0 : set_onaddtrack(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::DOMMediaStream* self, JSJitSetterCallArgs args)
926 : {
927 0 : RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
928 0 : if (args[0].isObject()) {
929 : { // scope for tempRoot
930 0 : JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
931 0 : arg0 = new binding_detail::FastEventHandlerNonNull(tempRoot);
932 : }
933 : } else {
934 0 : arg0 = nullptr;
935 : }
936 0 : self->SetOnaddtrack(Constify(arg0));
937 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
938 :
939 0 : return true;
940 : }
941 :
942 : static const JSJitInfo onaddtrack_getterinfo = {
943 : { (JSJitGetterOp)get_onaddtrack },
944 : { prototypes::id::MediaStream },
945 : { PrototypeTraits<prototypes::id::MediaStream>::Depth },
946 : JSJitInfo::Getter,
947 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
948 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
949 : false, /* isInfallible. False in setters. */
950 : false, /* isMovable. Not relevant for setters. */
951 : false, /* isEliminatable. Not relevant for setters. */
952 : false, /* isAlwaysInSlot. Only relevant for getters. */
953 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
954 : false, /* isTypedMethod. Only relevant for methods. */
955 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
956 : };
957 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
958 : static_assert(0 < 1, "There is no slot for us");
959 : static const JSJitInfo onaddtrack_setterinfo = {
960 : { (JSJitGetterOp)set_onaddtrack },
961 : { prototypes::id::MediaStream },
962 : { PrototypeTraits<prototypes::id::MediaStream>::Depth },
963 : JSJitInfo::Setter,
964 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
965 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
966 : false, /* isInfallible. False in setters. */
967 : false, /* isMovable. Not relevant for setters. */
968 : false, /* isEliminatable. Not relevant for setters. */
969 : false, /* isAlwaysInSlot. Only relevant for getters. */
970 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
971 : false, /* isTypedMethod. Only relevant for methods. */
972 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
973 : };
974 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
975 : static_assert(0 < 1, "There is no slot for us");
976 :
977 : static bool
978 0 : get_currentTime(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::DOMMediaStream* self, JSJitGetterCallArgs args)
979 : {
980 0 : double result(self->CurrentTime());
981 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
982 0 : args.rval().set(JS_NumberValue(double(result)));
983 0 : return true;
984 : }
985 :
986 : static const JSJitInfo currentTime_getterinfo = {
987 : { (JSJitGetterOp)get_currentTime },
988 : { prototypes::id::MediaStream },
989 : { PrototypeTraits<prototypes::id::MediaStream>::Depth },
990 : JSJitInfo::Getter,
991 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
992 : JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
993 : true, /* isInfallible. False in setters. */
994 : false, /* isMovable. Not relevant for setters. */
995 : false, /* isEliminatable. Not relevant for setters. */
996 : false, /* isAlwaysInSlot. Only relevant for getters. */
997 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
998 : false, /* isTypedMethod. Only relevant for methods. */
999 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1000 : };
1001 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1002 : static_assert(0 < 1, "There is no slot for us");
1003 :
1004 : static bool
1005 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
1006 : {
1007 0 : mozilla::DOMMediaStream* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::DOMMediaStream>(obj);
1008 : // We don't want to preserve if we don't have a wrapper, and we
1009 : // obviously can't preserve if we're not initialized.
1010 0 : if (self && self->GetWrapperPreserveColor()) {
1011 0 : PreserveWrapper(self);
1012 : }
1013 0 : return true;
1014 : }
1015 :
1016 : static void
1017 0 : _finalize(js::FreeOp* fop, JSObject* obj)
1018 : {
1019 0 : mozilla::DOMMediaStream* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::DOMMediaStream>(obj);
1020 0 : if (self) {
1021 0 : ClearWrapper(self, self, obj);
1022 0 : AddForDeferredFinalization<mozilla::DOMMediaStream>(self);
1023 : }
1024 0 : }
1025 :
1026 : static void
1027 0 : _objectMoved(JSObject* obj, const JSObject* old)
1028 : {
1029 0 : mozilla::DOMMediaStream* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::DOMMediaStream>(obj);
1030 0 : if (self) {
1031 0 : UpdateWrapper(self, self, obj, old);
1032 : }
1033 0 : }
1034 :
1035 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1036 : #if defined(__clang__)
1037 : #pragma clang diagnostic push
1038 : #pragma clang diagnostic ignored "-Wmissing-braces"
1039 : #endif
1040 : static const JSFunctionSpec sMethods_specs[] = {
1041 : JS_FNSPEC("getAudioTracks", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&getAudioTracks_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1042 : JS_FNSPEC("getVideoTracks", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&getVideoTracks_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1043 : JS_FNSPEC("getTracks", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&getTracks_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1044 : JS_FNSPEC("getTrackById", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&getTrackById_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
1045 : JS_FNSPEC("addTrack", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&addTrack_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
1046 : JS_FNSPEC("removeTrack", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&removeTrack_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
1047 : JS_FNSPEC("clone", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&clone_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1048 : JS_FS_END
1049 : };
1050 : #if defined(__clang__)
1051 : #pragma clang diagnostic pop
1052 : #endif
1053 :
1054 :
1055 : // Can't be const because the pref-enabled boolean needs to be writable
1056 : static Prefable<const JSFunctionSpec> sMethods[] = {
1057 : { nullptr, &sMethods_specs[0] },
1058 : { nullptr, nullptr }
1059 : };
1060 :
1061 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1062 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1063 : static_assert(7 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1064 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1065 :
1066 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1067 : #if defined(__clang__)
1068 : #pragma clang diagnostic push
1069 : #pragma clang diagnostic ignored "-Wmissing-braces"
1070 : #endif
1071 : static const JSPropertySpec sAttributes_specs[] = {
1072 : { "id", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &id_getterinfo, nullptr, nullptr },
1073 : { "active", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &active_getterinfo, nullptr, nullptr },
1074 : { "onaddtrack", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &onaddtrack_getterinfo, GenericBindingSetter, &onaddtrack_setterinfo },
1075 : { "currentTime", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, ¤tTime_getterinfo, nullptr, nullptr },
1076 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
1077 : };
1078 : #if defined(__clang__)
1079 : #pragma clang diagnostic pop
1080 : #endif
1081 :
1082 :
1083 : // Can't be const because the pref-enabled boolean needs to be writable
1084 : static Prefable<const JSPropertySpec> sAttributes[] = {
1085 : { nullptr, &sAttributes_specs[0] },
1086 : { nullptr, nullptr }
1087 : };
1088 :
1089 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1090 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1091 : static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1092 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1093 :
1094 :
1095 : static uint16_t sNativeProperties_sortedPropertyIndices[11];
1096 : static PropertyInfo sNativeProperties_propertyInfos[11];
1097 :
1098 : static const NativePropertiesN<2> sNativeProperties = {
1099 : false, 0,
1100 : false, 0,
1101 : true, 0 /* sMethods */,
1102 : true, 1 /* sAttributes */,
1103 : false, 0,
1104 : false, 0,
1105 : false, 0,
1106 : -1,
1107 : 11,
1108 : sNativeProperties_sortedPropertyIndices,
1109 : {
1110 : { sMethods, &sNativeProperties_propertyInfos[0] },
1111 : { sAttributes, &sNativeProperties_propertyInfos[7] }
1112 : }
1113 : };
1114 : static_assert(11 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
1115 : "We have a property info count that is oversized");
1116 :
1117 : static bool
1118 0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
1119 : {
1120 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
1121 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
1122 0 : if (!args.isConstructing()) {
1123 : // XXXbz wish I could get the name from the callee instead of
1124 : // Adding more relocations
1125 0 : return ThrowConstructorWithoutNew(cx, "MediaStream");
1126 : }
1127 :
1128 0 : GlobalObject global(cx, obj);
1129 0 : if (global.Failed()) {
1130 0 : return false;
1131 : }
1132 :
1133 0 : JS::Rooted<JSObject*> desiredProto(cx);
1134 0 : if (!GetDesiredProto(cx, args, &desiredProto)) {
1135 0 : return false;
1136 : }
1137 :
1138 0 : unsigned argcount = std::min(args.length(), 1u);
1139 0 : switch (argcount) {
1140 : case 0: {
1141 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1142 0 : Maybe<JSAutoCompartment> ac;
1143 0 : if (objIsXray) {
1144 0 : obj = js::CheckedUnwrap(obj);
1145 0 : if (!obj) {
1146 0 : return false;
1147 : }
1148 0 : ac.emplace(cx, obj);
1149 0 : if (!JS_WrapObject(cx, &desiredProto)) {
1150 0 : return false;
1151 : }
1152 : }
1153 0 : binding_detail::FastErrorResult rv;
1154 0 : auto result(StrongOrRawPtr<mozilla::DOMMediaStream>(mozilla::DOMMediaStream::Constructor(global, rv)));
1155 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1156 0 : return false;
1157 : }
1158 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1159 : static_assert(!IsPointer<decltype(result)>::value,
1160 : "NewObject implies that we need to keep the object alive with a strong reference.");
1161 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
1162 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
1163 0 : return false;
1164 : }
1165 0 : return true;
1166 : break;
1167 : }
1168 : case 1: {
1169 0 : if (args[0].isObject()) {
1170 : do {
1171 0 : NonNull<mozilla::DOMMediaStream> arg0;
1172 : {
1173 0 : nsresult rv = UnwrapObject<prototypes::id::MediaStream, mozilla::DOMMediaStream>(args[0], arg0);
1174 0 : if (NS_FAILED(rv)) {
1175 0 : break;
1176 : }
1177 : }
1178 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1179 0 : Maybe<JSAutoCompartment> ac;
1180 0 : if (objIsXray) {
1181 0 : obj = js::CheckedUnwrap(obj);
1182 0 : if (!obj) {
1183 0 : return false;
1184 : }
1185 0 : ac.emplace(cx, obj);
1186 0 : if (!JS_WrapObject(cx, &desiredProto)) {
1187 0 : return false;
1188 : }
1189 : }
1190 0 : binding_detail::FastErrorResult rv;
1191 0 : auto result(StrongOrRawPtr<mozilla::DOMMediaStream>(mozilla::DOMMediaStream::Constructor(global, NonNullHelper(arg0), rv)));
1192 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1193 0 : return false;
1194 : }
1195 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1196 : static_assert(!IsPointer<decltype(result)>::value,
1197 : "NewObject implies that we need to keep the object alive with a strong reference.");
1198 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
1199 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
1200 0 : return false;
1201 : }
1202 0 : return true;
1203 : } while (0);
1204 : do {
1205 0 : binding_detail::AutoSequence<OwningNonNull<mozilla::dom::MediaStreamTrack>> arg0;
1206 0 : JS::ForOfIterator iter(cx);
1207 0 : if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) {
1208 0 : return false;
1209 : }
1210 0 : if (!iter.valueIsIterable()) {
1211 0 : break;
1212 : }
1213 0 : binding_detail::AutoSequence<OwningNonNull<mozilla::dom::MediaStreamTrack>> &arr = arg0;
1214 0 : JS::Rooted<JS::Value> temp(cx);
1215 : while (true) {
1216 : bool done;
1217 0 : if (!iter.next(&temp, &done)) {
1218 0 : return false;
1219 : }
1220 0 : if (done) {
1221 0 : break;
1222 : }
1223 0 : OwningNonNull<mozilla::dom::MediaStreamTrack>* slotPtr = arr.AppendElement(mozilla::fallible);
1224 0 : if (!slotPtr) {
1225 0 : JS_ReportOutOfMemory(cx);
1226 0 : return false;
1227 : }
1228 0 : OwningNonNull<mozilla::dom::MediaStreamTrack>& slot = *slotPtr;
1229 0 : if (temp.isObject()) {
1230 : static_assert(IsRefcounted<mozilla::dom::MediaStreamTrack>::value, "We can only store refcounted classes.");{
1231 0 : nsresult rv = UnwrapObject<prototypes::id::MediaStreamTrack, mozilla::dom::MediaStreamTrack>(&temp, slot);
1232 0 : if (NS_FAILED(rv)) {
1233 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Element of argument 1 of MediaStream", "MediaStreamTrack");
1234 0 : return false;
1235 : }
1236 : }
1237 : } else {
1238 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Element of argument 1 of MediaStream");
1239 0 : return false;
1240 : }
1241 0 : }
1242 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1243 0 : Maybe<JSAutoCompartment> ac;
1244 0 : if (objIsXray) {
1245 0 : obj = js::CheckedUnwrap(obj);
1246 0 : if (!obj) {
1247 0 : return false;
1248 : }
1249 0 : ac.emplace(cx, obj);
1250 0 : if (!JS_WrapObject(cx, &desiredProto)) {
1251 0 : return false;
1252 : }
1253 : }
1254 0 : binding_detail::FastErrorResult rv;
1255 0 : auto result(StrongOrRawPtr<mozilla::DOMMediaStream>(mozilla::DOMMediaStream::Constructor(global, Constify(arg0), rv)));
1256 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1257 0 : return false;
1258 : }
1259 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1260 : static_assert(!IsPointer<decltype(result)>::value,
1261 : "NewObject implies that we need to keep the object alive with a strong reference.");
1262 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
1263 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
1264 0 : return false;
1265 : }
1266 0 : return true;
1267 : } while (0);
1268 : }
1269 0 : return ThrowErrorMessage(cx, MSG_OVERLOAD_RESOLUTION_FAILED, "1", "1", "MediaStream");
1270 : break;
1271 : }
1272 : default: {
1273 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "MediaStream");
1274 : break;
1275 : }
1276 : }
1277 : MOZ_CRASH("We have an always-returning default case");
1278 : return false;
1279 : }
1280 :
1281 : static const js::ClassOps sInterfaceObjectClassOps = {
1282 : nullptr, /* addProperty */
1283 : nullptr, /* delProperty */
1284 : nullptr, /* getProperty */
1285 : nullptr, /* setProperty */
1286 : nullptr, /* enumerate */
1287 : nullptr, /* newEnumerate */
1288 : nullptr, /* resolve */
1289 : nullptr, /* mayResolve */
1290 : nullptr, /* finalize */
1291 : _constructor, /* call */
1292 : nullptr, /* hasInstance */
1293 : _constructor, /* construct */
1294 : nullptr, /* trace */
1295 : };
1296 :
1297 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1298 : {
1299 : "Function",
1300 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1301 : &sInterfaceObjectClassOps,
1302 : JS_NULL_CLASS_SPEC,
1303 : JS_NULL_CLASS_EXT,
1304 : &sInterfaceObjectClassObjectOps
1305 : },
1306 : eInterface,
1307 : true,
1308 : prototypes::id::MediaStream,
1309 : PrototypeTraits<prototypes::id::MediaStream>::Depth,
1310 : sNativePropertyHooks,
1311 : "function MediaStream() {\n [native code]\n}",
1312 : EventTargetBinding::GetConstructorObject
1313 : };
1314 :
1315 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1316 : {
1317 : "MediaStreamPrototype",
1318 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
1319 : JS_NULL_CLASS_OPS,
1320 : JS_NULL_CLASS_SPEC,
1321 : JS_NULL_CLASS_EXT,
1322 : JS_NULL_OBJECT_OPS
1323 : },
1324 : eInterfacePrototype,
1325 : false,
1326 : prototypes::id::MediaStream,
1327 : PrototypeTraits<prototypes::id::MediaStream>::Depth,
1328 : sNativePropertyHooks,
1329 : "[object MediaStreamPrototype]",
1330 : EventTargetBinding::GetProtoObject
1331 : };
1332 :
1333 : JSObject*
1334 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
1335 : {
1336 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
1337 : }
1338 :
1339 : static const js::ClassOps sClassOps = {
1340 : _addProperty, /* addProperty */
1341 : nullptr, /* delProperty */
1342 : nullptr, /* getProperty */
1343 : nullptr, /* setProperty */
1344 : nullptr, /* enumerate */
1345 : nullptr, /* newEnumerate */
1346 : nullptr, /* resolve */
1347 : nullptr, /* mayResolve */
1348 : _finalize, /* finalize */
1349 : nullptr, /* call */
1350 : nullptr, /* hasInstance */
1351 : nullptr, /* construct */
1352 : nullptr, /* trace */
1353 : };
1354 :
1355 : static const js::ClassExtension sClassExtension = {
1356 : nullptr, /* weakmapKeyDelegateOp */
1357 : _objectMoved /* objectMovedOp */
1358 : };
1359 :
1360 : static const DOMJSClass sClass = {
1361 : { "MediaStream",
1362 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
1363 : &sClassOps,
1364 : JS_NULL_CLASS_SPEC,
1365 : &sClassExtension,
1366 : JS_NULL_OBJECT_OPS
1367 : },
1368 : { prototypes::id::EventTarget, prototypes::id::MediaStream, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
1369 : IsBaseOf<nsISupports, mozilla::DOMMediaStream >::value,
1370 : sNativePropertyHooks,
1371 : FindAssociatedGlobalForNative<mozilla::DOMMediaStream>::Get,
1372 : GetProtoObjectHandle,
1373 : GetCCParticipant<mozilla::DOMMediaStream>::Get()
1374 : };
1375 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1376 : "Must have the right minimal number of reserved slots.");
1377 : static_assert(1 >= 1,
1378 : "Must have enough reserved slots.");
1379 :
1380 : const JSClass*
1381 0 : GetJSClass()
1382 : {
1383 0 : return sClass.ToJSClass();
1384 : }
1385 :
1386 : bool
1387 0 : Wrap(JSContext* aCx, mozilla::DOMMediaStream* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1388 : {
1389 : MOZ_ASSERT(static_cast<mozilla::DOMMediaStream*>(aObject) ==
1390 : reinterpret_cast<mozilla::DOMMediaStream*>(aObject),
1391 : "Multiple inheritance for mozilla::DOMMediaStream is broken.");
1392 : MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
1393 : reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
1394 : "Multiple inheritance for mozilla::dom::EventTarget is broken.");
1395 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1396 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1397 0 : MOZ_ASSERT(!aCache->GetWrapper(),
1398 : "You should probably not be using Wrap() directly; use "
1399 : "GetOrCreateDOMReflector instead");
1400 :
1401 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1402 : "nsISupports must be on our primary inheritance chain");
1403 :
1404 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1405 0 : if (!global) {
1406 0 : return false;
1407 : }
1408 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
1409 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
1410 :
1411 : // That might have ended up wrapping us already, due to the wonders
1412 : // of XBL. Check for that, and bail out as needed.
1413 0 : aReflector.set(aCache->GetWrapper());
1414 0 : if (aReflector) {
1415 : #ifdef DEBUG
1416 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1417 : #endif // DEBUG
1418 0 : return true;
1419 : }
1420 :
1421 0 : JSAutoCompartment ac(aCx, global);
1422 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1423 0 : if (!canonicalProto) {
1424 0 : return false;
1425 : }
1426 0 : JS::Rooted<JSObject*> proto(aCx);
1427 0 : if (aGivenProto) {
1428 0 : proto = aGivenProto;
1429 : // Unfortunately, while aGivenProto was in the compartment of aCx
1430 : // coming in, we changed compartments to that of "parent" so may need
1431 : // to wrap the proto here.
1432 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1433 0 : if (!JS_WrapObject(aCx, &proto)) {
1434 0 : return false;
1435 : }
1436 : }
1437 : } else {
1438 0 : proto = canonicalProto;
1439 : }
1440 :
1441 0 : BindingJSObjectCreator<mozilla::DOMMediaStream> creator(aCx);
1442 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1443 0 : if (!aReflector) {
1444 0 : return false;
1445 : }
1446 :
1447 0 : aCache->SetWrapper(aReflector);
1448 0 : creator.InitializationSucceeded();
1449 :
1450 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1451 : aCache->GetWrapperPreserveColor() == aReflector);
1452 : // If proto != canonicalProto, we have to preserve our wrapper;
1453 : // otherwise we won't be able to properly recreate it later, since
1454 : // we won't know what proto to use. Note that we don't check
1455 : // aGivenProto here, since it's entirely possible (and even
1456 : // somewhat common) to have a non-null aGivenProto which is the
1457 : // same as canonicalProto.
1458 0 : if (proto != canonicalProto) {
1459 0 : PreserveWrapper(aObject);
1460 : }
1461 :
1462 0 : return true;
1463 : }
1464 :
1465 : const NativePropertyHooks sNativePropertyHooks[] = { {
1466 : nullptr,
1467 : nullptr,
1468 : nullptr,
1469 : { sNativeProperties.Upcast(), nullptr },
1470 : prototypes::id::MediaStream,
1471 : constructors::id::MediaStream,
1472 : EventTargetBinding::sNativePropertyHooks,
1473 : &DefaultXrayExpandoObjectClass
1474 : } };
1475 :
1476 : void
1477 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1478 : {
1479 0 : JS::Handle<JSObject*> parentProto(EventTargetBinding::GetProtoObjectHandle(aCx));
1480 0 : if (!parentProto) {
1481 0 : return;
1482 : }
1483 :
1484 0 : JS::Handle<JSObject*> constructorProto(EventTargetBinding::GetConstructorObjectHandle(aCx));
1485 0 : if (!constructorProto) {
1486 0 : return;
1487 : }
1488 :
1489 : static bool sIdsInited = false;
1490 0 : if (!sIdsInited && NS_IsMainThread()) {
1491 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
1492 0 : return;
1493 : }
1494 0 : sIdsInited = true;
1495 : }
1496 :
1497 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::MediaStream);
1498 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::MediaStream);
1499 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1500 : &sPrototypeClass.mBase, protoCache,
1501 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1502 : interfaceCache,
1503 : sNativeProperties.Upcast(),
1504 : nullptr,
1505 : "MediaStream", aDefineOnGlobal,
1506 : nullptr,
1507 0 : false);
1508 : }
1509 :
1510 : JS::Handle<JSObject*>
1511 0 : GetProtoObjectHandle(JSContext* aCx)
1512 : {
1513 : /* Get the interface prototype object for this class. This will create the
1514 : object as needed. */
1515 0 : bool aDefineOnGlobal = true;
1516 :
1517 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1518 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1519 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1520 0 : return nullptr;
1521 : }
1522 :
1523 : /* Check to see whether the interface objects are already installed */
1524 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1525 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::MediaStream)) {
1526 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1527 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1528 : }
1529 :
1530 : /*
1531 : * The object might _still_ be null, but that's OK.
1532 : *
1533 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1534 : * traced by TraceProtoAndIfaceCache() and its contents are never
1535 : * changed after they have been set.
1536 : *
1537 : * Calling address() avoids the read read barrier that does gray
1538 : * unmarking, but it's not possible for the object to be gray here.
1539 : */
1540 :
1541 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::MediaStream);
1542 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1543 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1544 : }
1545 :
1546 : JSObject*
1547 0 : GetProtoObject(JSContext* aCx)
1548 : {
1549 0 : return GetProtoObjectHandle(aCx);
1550 : }
1551 :
1552 : JS::Handle<JSObject*>
1553 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
1554 : {
1555 : /* Get the interface object for this class. This will create the object as
1556 : needed. */
1557 :
1558 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1559 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1560 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1561 0 : return nullptr;
1562 : }
1563 :
1564 : /* Check to see whether the interface objects are already installed */
1565 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1566 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::MediaStream)) {
1567 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1568 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1569 : }
1570 :
1571 : /*
1572 : * The object might _still_ be null, but that's OK.
1573 : *
1574 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1575 : * traced by TraceProtoAndIfaceCache() and its contents are never
1576 : * changed after they have been set.
1577 : *
1578 : * Calling address() avoids the read read barrier that does gray
1579 : * unmarking, but it's not possible for the object to be gray here.
1580 : */
1581 :
1582 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::MediaStream);
1583 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1584 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1585 : }
1586 :
1587 : JSObject*
1588 0 : GetConstructorObject(JSContext* aCx)
1589 : {
1590 0 : return GetConstructorObjectHandle(aCx);
1591 : }
1592 :
1593 : } // namespace MediaStreamBinding
1594 :
1595 :
1596 :
1597 : } // namespace dom
1598 : } // namespace mozilla
|