Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM RTCRtpReceiver.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "AtomList.h"
4 : #include "RTCRtpReceiverBinding.h"
5 : #include "WrapperFactory.h"
6 : #include "mozilla/OwningNonNull.h"
7 : #include "mozilla/Preferences.h"
8 : #include "mozilla/dom/BindingUtils.h"
9 : #include "mozilla/dom/DOMJSClass.h"
10 : #include "mozilla/dom/MediaStreamTrack.h"
11 : #include "mozilla/dom/NonRefcountedDOMObject.h"
12 : #include "mozilla/dom/Promise.h"
13 : #include "mozilla/dom/ToJSValue.h"
14 : #include "mozilla/dom/XrayExpandoClass.h"
15 : #include "nsContentUtils.h"
16 : #include "nsIGlobalObject.h"
17 :
18 : namespace mozilla {
19 : namespace dom {
20 :
21 : namespace RTCRtpReceiverBinding {
22 :
23 : static bool
24 0 : get_track(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCRtpReceiver* self, JSJitGetterCallArgs args)
25 : {
26 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
27 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
28 0 : if (objIsXray) {
29 0 : unwrappedObj.emplace(cx, obj);
30 : }
31 0 : if (objIsXray) {
32 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
33 0 : if (!unwrappedObj.ref()) {
34 0 : return false;
35 : }
36 : }
37 0 : binding_detail::FastErrorResult rv;
38 0 : auto result(StrongOrRawPtr<mozilla::dom::MediaStreamTrack>(self->GetTrack(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
39 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
40 0 : return false;
41 : }
42 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
43 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
44 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
45 0 : return false;
46 : }
47 0 : return true;
48 : }
49 :
50 : static const JSJitInfo track_getterinfo = {
51 : { (JSJitGetterOp)get_track },
52 : { prototypes::id::RTCRtpReceiver },
53 : { PrototypeTraits<prototypes::id::RTCRtpReceiver>::Depth },
54 : JSJitInfo::Getter,
55 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
56 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
57 : false, /* isInfallible. False in setters. */
58 : false, /* isMovable. Not relevant for setters. */
59 : false, /* isEliminatable. Not relevant for setters. */
60 : false, /* isAlwaysInSlot. Only relevant for getters. */
61 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
62 : false, /* isTypedMethod. Only relevant for methods. */
63 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
64 : };
65 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
66 : static_assert(0 < 1, "There is no slot for us");
67 :
68 : static bool
69 0 : getStats(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCRtpReceiver* self, const JSJitMethodCallArgs& args)
70 : {
71 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
72 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
73 0 : if (objIsXray) {
74 0 : unwrappedObj.emplace(cx, obj);
75 : }
76 0 : if (objIsXray) {
77 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
78 0 : if (!unwrappedObj.ref()) {
79 0 : return false;
80 : }
81 : }
82 0 : binding_detail::FastErrorResult rv;
83 0 : auto result(StrongOrRawPtr<Promise>(self->GetStats(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
84 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
85 0 : return false;
86 : }
87 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
88 0 : if (!ToJSValue(cx, result, args.rval())) {
89 0 : return false;
90 : }
91 0 : return true;
92 : }
93 :
94 : static bool
95 0 : getStats_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCRtpReceiver* self, const JSJitMethodCallArgs& args)
96 : {
97 : // Make sure to save the callee before someone maybe messes
98 : // with rval().
99 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
100 0 : bool ok = getStats(cx, obj, self, args);
101 0 : if (ok) {
102 0 : return true;
103 : }
104 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
105 0 : args.rval());
106 : }
107 :
108 : static const JSJitInfo getStats_methodinfo = {
109 : { (JSJitGetterOp)getStats_promiseWrapper },
110 : { prototypes::id::RTCRtpReceiver },
111 : { PrototypeTraits<prototypes::id::RTCRtpReceiver>::Depth },
112 : JSJitInfo::Method,
113 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
114 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
115 : false, /* isInfallible. False in setters. */
116 : false, /* isMovable. Not relevant for setters. */
117 : false, /* isEliminatable. Not relevant for setters. */
118 : false, /* isAlwaysInSlot. Only relevant for getters. */
119 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
120 : false, /* isTypedMethod. Only relevant for methods. */
121 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
122 : };
123 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
124 : static_assert(0 < 1, "There is no slot for us");
125 :
126 : static bool
127 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
128 : {
129 0 : mozilla::dom::RTCRtpReceiver* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::RTCRtpReceiver>(obj);
130 : // We don't want to preserve if we don't have a wrapper, and we
131 : // obviously can't preserve if we're not initialized.
132 0 : if (self && self->GetWrapperPreserveColor()) {
133 0 : PreserveWrapper(self);
134 : }
135 0 : return true;
136 : }
137 :
138 : static void
139 0 : _finalize(js::FreeOp* fop, JSObject* obj)
140 : {
141 0 : mozilla::dom::RTCRtpReceiver* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::RTCRtpReceiver>(obj);
142 0 : if (self) {
143 0 : ClearWrapper(self, self, obj);
144 0 : AddForDeferredFinalization<mozilla::dom::RTCRtpReceiver>(self);
145 : }
146 0 : }
147 :
148 : static void
149 0 : _objectMoved(JSObject* obj, const JSObject* old)
150 : {
151 0 : mozilla::dom::RTCRtpReceiver* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::RTCRtpReceiver>(obj);
152 0 : if (self) {
153 0 : UpdateWrapper(self, self, obj, old);
154 : }
155 0 : }
156 :
157 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
158 : #if defined(__clang__)
159 : #pragma clang diagnostic push
160 : #pragma clang diagnostic ignored "-Wmissing-braces"
161 : #endif
162 : static const JSFunctionSpec sChromeStaticMethods_specs[] = {
163 : JS_FNSPEC("_create", RTCRtpReceiver::_Create, nullptr, 2, 0, nullptr),
164 : JS_FS_END
165 : };
166 : #if defined(__clang__)
167 : #pragma clang diagnostic pop
168 : #endif
169 :
170 :
171 : // Can't be const because the pref-enabled boolean needs to be writable
172 : static Prefable<const JSFunctionSpec> sChromeStaticMethods[] = {
173 : { nullptr, &sChromeStaticMethods_specs[0] },
174 : { nullptr, nullptr }
175 : };
176 :
177 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
178 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
179 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
180 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
181 :
182 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
183 : #if defined(__clang__)
184 : #pragma clang diagnostic push
185 : #pragma clang diagnostic ignored "-Wmissing-braces"
186 : #endif
187 : static const JSFunctionSpec sMethods_specs[] = {
188 : JS_FNSPEC("getStats", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&getStats_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
189 : JS_FS_END
190 : };
191 : #if defined(__clang__)
192 : #pragma clang diagnostic pop
193 : #endif
194 :
195 :
196 : // Can't be const because the pref-enabled boolean needs to be writable
197 : static Prefable<const JSFunctionSpec> sMethods[] = {
198 : { nullptr, &sMethods_specs[0] },
199 : { nullptr, nullptr }
200 : };
201 :
202 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
203 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
204 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
205 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
206 :
207 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
208 : #if defined(__clang__)
209 : #pragma clang diagnostic push
210 : #pragma clang diagnostic ignored "-Wmissing-braces"
211 : #endif
212 : static const JSPropertySpec sAttributes_specs[] = {
213 : { "track", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &track_getterinfo, nullptr, nullptr },
214 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
215 : };
216 : #if defined(__clang__)
217 : #pragma clang diagnostic pop
218 : #endif
219 :
220 :
221 : // Can't be const because the pref-enabled boolean needs to be writable
222 : static Prefable<const JSPropertySpec> sAttributes[] = {
223 : { nullptr, &sAttributes_specs[0] },
224 : { nullptr, nullptr }
225 : };
226 :
227 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
228 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
229 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
230 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
231 :
232 :
233 : static uint16_t sNativeProperties_sortedPropertyIndices[2];
234 : static PropertyInfo sNativeProperties_propertyInfos[2];
235 :
236 : static const NativePropertiesN<2> sNativeProperties = {
237 : false, 0,
238 : false, 0,
239 : true, 0 /* sMethods */,
240 : true, 1 /* sAttributes */,
241 : false, 0,
242 : false, 0,
243 : false, 0,
244 : -1,
245 : 2,
246 : sNativeProperties_sortedPropertyIndices,
247 : {
248 : { sMethods, &sNativeProperties_propertyInfos[0] },
249 : { sAttributes, &sNativeProperties_propertyInfos[1] }
250 : }
251 : };
252 : static_assert(2 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
253 : "We have a property info count that is oversized");
254 :
255 : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[1];
256 : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[1];
257 :
258 : static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
259 : true, 0 /* sChromeStaticMethods */,
260 : false, 0,
261 : false, 0,
262 : false, 0,
263 : false, 0,
264 : false, 0,
265 : false, 0,
266 : -1,
267 : 1,
268 : sChromeOnlyNativeProperties_sortedPropertyIndices,
269 : {
270 : { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] }
271 : }
272 : };
273 : static_assert(1 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
274 : "We have a property info count that is oversized");
275 :
276 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
277 : {
278 : "Function",
279 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
280 : &sBoringInterfaceObjectClassClassOps,
281 : JS_NULL_CLASS_SPEC,
282 : JS_NULL_CLASS_EXT,
283 : &sInterfaceObjectClassObjectOps
284 : },
285 : eInterface,
286 : true,
287 : prototypes::id::RTCRtpReceiver,
288 : PrototypeTraits<prototypes::id::RTCRtpReceiver>::Depth,
289 : sNativePropertyHooks,
290 : "function RTCRtpReceiver() {\n [native code]\n}",
291 : JS::GetRealmFunctionPrototype
292 : };
293 :
294 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
295 : {
296 : "RTCRtpReceiverPrototype",
297 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
298 : JS_NULL_CLASS_OPS,
299 : JS_NULL_CLASS_SPEC,
300 : JS_NULL_CLASS_EXT,
301 : JS_NULL_OBJECT_OPS
302 : },
303 : eInterfacePrototype,
304 : false,
305 : prototypes::id::RTCRtpReceiver,
306 : PrototypeTraits<prototypes::id::RTCRtpReceiver>::Depth,
307 : sNativePropertyHooks,
308 : "[object RTCRtpReceiverPrototype]",
309 : JS::GetRealmObjectPrototype
310 : };
311 :
312 : bool
313 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
314 : {
315 : static bool sPrefValue;
316 : static bool sPrefCacheSetUp = false;
317 0 : if (!sPrefCacheSetUp) {
318 0 : sPrefCacheSetUp = true;
319 0 : Preferences::AddBoolVarCache(&sPrefValue, "media.peerconnection.enabled");
320 : }
321 :
322 0 : return sPrefValue;
323 : }
324 :
325 : JSObject*
326 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
327 : {
328 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
329 : }
330 :
331 : static const js::ClassOps sClassOps = {
332 : _addProperty, /* addProperty */
333 : nullptr, /* delProperty */
334 : nullptr, /* getProperty */
335 : nullptr, /* setProperty */
336 : nullptr, /* enumerate */
337 : nullptr, /* newEnumerate */
338 : nullptr, /* resolve */
339 : nullptr, /* mayResolve */
340 : _finalize, /* finalize */
341 : nullptr, /* call */
342 : nullptr, /* hasInstance */
343 : nullptr, /* construct */
344 : nullptr, /* trace */
345 : };
346 :
347 : static const js::ClassExtension sClassExtension = {
348 : nullptr, /* weakmapKeyDelegateOp */
349 : _objectMoved /* objectMovedOp */
350 : };
351 :
352 : static const DOMJSClass sClass = {
353 : { "RTCRtpReceiver",
354 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
355 : &sClassOps,
356 : JS_NULL_CLASS_SPEC,
357 : &sClassExtension,
358 : JS_NULL_OBJECT_OPS
359 : },
360 : { prototypes::id::RTCRtpReceiver, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
361 : IsBaseOf<nsISupports, mozilla::dom::RTCRtpReceiver >::value,
362 : sNativePropertyHooks,
363 : FindAssociatedGlobalForNative<mozilla::dom::RTCRtpReceiver>::Get,
364 : GetProtoObjectHandle,
365 : GetCCParticipant<mozilla::dom::RTCRtpReceiver>::Get()
366 : };
367 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
368 : "Must have the right minimal number of reserved slots.");
369 : static_assert(1 >= 1,
370 : "Must have enough reserved slots.");
371 :
372 : const JSClass*
373 0 : GetJSClass()
374 : {
375 0 : return sClass.ToJSClass();
376 : }
377 :
378 : bool
379 0 : Wrap(JSContext* aCx, mozilla::dom::RTCRtpReceiver* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
380 : {
381 : MOZ_ASSERT(static_cast<mozilla::dom::RTCRtpReceiver*>(aObject) ==
382 : reinterpret_cast<mozilla::dom::RTCRtpReceiver*>(aObject),
383 : "Multiple inheritance for mozilla::dom::RTCRtpReceiver is broken.");
384 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
385 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
386 0 : MOZ_ASSERT(!aCache->GetWrapper(),
387 : "You should probably not be using Wrap() directly; use "
388 : "GetOrCreateDOMReflector instead");
389 :
390 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
391 : "nsISupports must be on our primary inheritance chain");
392 :
393 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
394 0 : if (!global) {
395 0 : return false;
396 : }
397 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
398 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
399 :
400 : // That might have ended up wrapping us already, due to the wonders
401 : // of XBL. Check for that, and bail out as needed.
402 0 : aReflector.set(aCache->GetWrapper());
403 0 : if (aReflector) {
404 : #ifdef DEBUG
405 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
406 : #endif // DEBUG
407 0 : return true;
408 : }
409 :
410 0 : JSAutoCompartment ac(aCx, global);
411 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
412 0 : if (!canonicalProto) {
413 0 : return false;
414 : }
415 0 : JS::Rooted<JSObject*> proto(aCx);
416 0 : if (aGivenProto) {
417 0 : proto = aGivenProto;
418 : // Unfortunately, while aGivenProto was in the compartment of aCx
419 : // coming in, we changed compartments to that of "parent" so may need
420 : // to wrap the proto here.
421 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
422 0 : if (!JS_WrapObject(aCx, &proto)) {
423 0 : return false;
424 : }
425 : }
426 : } else {
427 0 : proto = canonicalProto;
428 : }
429 :
430 0 : BindingJSObjectCreator<mozilla::dom::RTCRtpReceiver> creator(aCx);
431 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
432 0 : if (!aReflector) {
433 0 : return false;
434 : }
435 :
436 0 : aCache->SetWrapper(aReflector);
437 0 : creator.InitializationSucceeded();
438 :
439 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
440 : aCache->GetWrapperPreserveColor() == aReflector);
441 : // If proto != canonicalProto, we have to preserve our wrapper;
442 : // otherwise we won't be able to properly recreate it later, since
443 : // we won't know what proto to use. Note that we don't check
444 : // aGivenProto here, since it's entirely possible (and even
445 : // somewhat common) to have a non-null aGivenProto which is the
446 : // same as canonicalProto.
447 0 : if (proto != canonicalProto) {
448 0 : PreserveWrapper(aObject);
449 : }
450 :
451 0 : return true;
452 : }
453 :
454 : const NativePropertyHooks sNativePropertyHooks[] = { {
455 : nullptr,
456 : nullptr,
457 : nullptr,
458 : { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
459 : prototypes::id::RTCRtpReceiver,
460 : constructors::id::RTCRtpReceiver,
461 : nullptr,
462 : &DefaultXrayExpandoObjectClass
463 : } };
464 :
465 : void
466 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
467 : {
468 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
469 0 : if (!parentProto) {
470 0 : return;
471 : }
472 :
473 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
474 0 : if (!constructorProto) {
475 0 : return;
476 : }
477 :
478 : static bool sIdsInited = false;
479 0 : if (!sIdsInited && NS_IsMainThread()) {
480 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
481 0 : return;
482 : }
483 0 : if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
484 0 : return;
485 : }
486 0 : sIdsInited = true;
487 : }
488 :
489 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::RTCRtpReceiver);
490 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::RTCRtpReceiver);
491 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
492 : &sPrototypeClass.mBase, protoCache,
493 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
494 : interfaceCache,
495 : sNativeProperties.Upcast(),
496 0 : nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
497 : "RTCRtpReceiver", aDefineOnGlobal,
498 : nullptr,
499 0 : false);
500 : }
501 :
502 : JS::Handle<JSObject*>
503 0 : GetProtoObjectHandle(JSContext* aCx)
504 : {
505 : /* Get the interface prototype object for this class. This will create the
506 : object as needed. */
507 0 : bool aDefineOnGlobal = true;
508 :
509 : /* Make sure our global is sane. Hopefully we can remove this sometime */
510 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
511 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
512 0 : return nullptr;
513 : }
514 :
515 : /* Check to see whether the interface objects are already installed */
516 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
517 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::RTCRtpReceiver)) {
518 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
519 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
520 : }
521 :
522 : /*
523 : * The object might _still_ be null, but that's OK.
524 : *
525 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
526 : * traced by TraceProtoAndIfaceCache() and its contents are never
527 : * changed after they have been set.
528 : *
529 : * Calling address() avoids the read read barrier that does gray
530 : * unmarking, but it's not possible for the object to be gray here.
531 : */
532 :
533 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::RTCRtpReceiver);
534 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
535 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
536 : }
537 :
538 : JS::Handle<JSObject*>
539 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
540 : {
541 : /* Get the interface object for this class. This will create the object as
542 : needed. */
543 :
544 : /* Make sure our global is sane. Hopefully we can remove this sometime */
545 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
546 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
547 0 : return nullptr;
548 : }
549 :
550 : /* Check to see whether the interface objects are already installed */
551 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
552 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::RTCRtpReceiver)) {
553 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
554 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
555 : }
556 :
557 : /*
558 : * The object might _still_ be null, but that's OK.
559 : *
560 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
561 : * traced by TraceProtoAndIfaceCache() and its contents are never
562 : * changed after they have been set.
563 : *
564 : * Calling address() avoids the read read barrier that does gray
565 : * unmarking, but it's not possible for the object to be gray here.
566 : */
567 :
568 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::RTCRtpReceiver);
569 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
570 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
571 : }
572 :
573 : JSObject*
574 0 : GetConstructorObject(JSContext* aCx)
575 : {
576 0 : return GetConstructorObjectHandle(aCx);
577 : }
578 :
579 : } // namespace RTCRtpReceiverBinding
580 :
581 :
582 :
583 : already_AddRefed<Promise>
584 0 : RTCRtpReceiverJSImpl::GetStats(ErrorResult& aRv, JSCompartment* aCompartment)
585 : {
586 0 : CallSetup s(this, aRv, "RTCRtpReceiver.getStats", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
587 0 : JSContext* cx = s.GetContext();
588 0 : if (!cx) {
589 0 : MOZ_ASSERT(aRv.Failed());
590 0 : return nullptr;
591 : }
592 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
593 :
594 0 : JS::Rooted<JS::Value> callable(cx);
595 0 : RTCRtpReceiverAtoms* atomsCache = GetAtomCache<RTCRtpReceiverAtoms>(cx);
596 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
597 0 : !GetCallableProperty(cx, atomsCache->getStats_id, &callable)) {
598 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
599 0 : return nullptr;
600 : }
601 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
602 0 : if (!JS::Call(cx, thisValue, callable,
603 0 : JS::HandleValueArray::empty(), &rval)) {
604 0 : aRv.NoteJSContextException(cx);
605 0 : return nullptr;
606 : }
607 0 : RefPtr<Promise> rvalDecl;
608 : { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
609 : // etc.
610 :
611 0 : JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
612 0 : if (!rval.isObject()) {
613 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of RTCRtpReceiver.getStats"));
614 0 : return nullptr;
615 : }
616 0 : JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
617 0 : if (!unwrappedVal) {
618 : // A slight lie, but not much of one, for a dead object wrapper.
619 0 : aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of RTCRtpReceiver.getStats"));
620 0 : return nullptr;
621 : }
622 0 : globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
623 0 : JSAutoCompartment ac(cx, globalObj);
624 0 : GlobalObject promiseGlobal(cx, globalObj);
625 0 : if (promiseGlobal.Failed()) {
626 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
627 0 : return nullptr;
628 : }
629 :
630 0 : JS::Rooted<JS::Value> valueToResolve(cx, rval);
631 0 : if (!JS_WrapValue(cx, &valueToResolve)) {
632 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
633 0 : return nullptr;
634 : }
635 0 : binding_detail::FastErrorResult promiseRv;
636 : nsCOMPtr<nsIGlobalObject> global =
637 0 : do_QueryInterface(promiseGlobal.GetAsSupports());
638 0 : if (!global) {
639 0 : promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
640 0 : MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
641 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
642 0 : return nullptr;
643 : }
644 0 : rvalDecl = Promise::Resolve(global, cx, valueToResolve,
645 0 : promiseRv);
646 0 : if (promiseRv.MaybeSetPendingException(cx)) {
647 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
648 0 : return nullptr;
649 : }
650 : }
651 0 : return rvalDecl.forget();
652 : }
653 :
654 : bool
655 0 : RTCRtpReceiverJSImpl::InitIds(JSContext* cx, RTCRtpReceiverAtoms* atomsCache)
656 : {
657 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
658 :
659 : // Initialize these in reverse order so that any failure leaves the first one
660 : // uninitialized.
661 0 : if (!atomsCache->getStats_id.init(cx, "getStats") ||
662 0 : !atomsCache->track_id.init(cx, "track")) {
663 0 : return false;
664 : }
665 0 : return true;
666 : }
667 :
668 :
669 : already_AddRefed<MediaStreamTrack>
670 0 : RTCRtpReceiverJSImpl::GetTrack(ErrorResult& aRv, JSCompartment* aCompartment)
671 : {
672 0 : CallSetup s(this, aRv, "RTCRtpReceiver.track", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
673 0 : JSContext* cx = s.GetContext();
674 0 : if (!cx) {
675 0 : MOZ_ASSERT(aRv.Failed());
676 0 : return nullptr;
677 : }
678 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
679 :
680 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
681 0 : RTCRtpReceiverAtoms* atomsCache = GetAtomCache<RTCRtpReceiverAtoms>(cx);
682 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
683 0 : !JS_GetPropertyById(cx, callback, atomsCache->track_id, &rval)) {
684 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
685 0 : return nullptr;
686 : }
687 0 : RefPtr<mozilla::dom::MediaStreamTrack> rvalDecl;
688 0 : if (rval.isObject()) {
689 : static_assert(IsRefcounted<mozilla::dom::MediaStreamTrack>::value, "We can only store refcounted classes.");{
690 0 : nsresult rv = UnwrapObject<prototypes::id::MediaStreamTrack, mozilla::dom::MediaStreamTrack>(rval, rvalDecl);
691 0 : if (NS_FAILED(rv)) {
692 0 : ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Return value of RTCRtpReceiver.track", "MediaStreamTrack");
693 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
694 0 : return nullptr;
695 : }
696 : }
697 : } else {
698 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of RTCRtpReceiver.track");
699 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
700 0 : return nullptr;
701 : }
702 0 : return rvalDecl.forget();
703 : }
704 :
705 :
706 : NS_IMPL_CYCLE_COLLECTION_CLASS(RTCRtpReceiver)
707 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(RTCRtpReceiver)
708 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mImpl)
709 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
710 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
711 0 : tmp->ClearWeakReferences();
712 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
713 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(RTCRtpReceiver)
714 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImpl)
715 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
716 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
717 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(RTCRtpReceiver)
718 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(RTCRtpReceiver)
719 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(RTCRtpReceiver)
720 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RTCRtpReceiver)
721 0 : NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
722 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
723 0 : NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
724 0 : NS_INTERFACE_MAP_END
725 :
726 0 : RTCRtpReceiver::RTCRtpReceiver(JS::Handle<JSObject*> aJSImplObject, nsIGlobalObject* aParent)
727 0 : : mImpl(new RTCRtpReceiverJSImpl(nullptr, aJSImplObject, /* aIncumbentGlobal = */ nullptr)),
728 0 : mParent(aParent)
729 : {
730 0 : }
731 :
732 :
733 0 : RTCRtpReceiver::~RTCRtpReceiver()
734 : {
735 0 : }
736 :
737 : nsISupports*
738 0 : RTCRtpReceiver::GetParentObject() const
739 : {
740 0 : return mParent;
741 : }
742 :
743 : JSObject*
744 0 : RTCRtpReceiver::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
745 : {
746 0 : JS::Rooted<JSObject*> obj(aCx, RTCRtpReceiverBinding::Wrap(aCx, this, aGivenProto));
747 0 : if (!obj) {
748 0 : return nullptr;
749 : }
750 :
751 : // Now define it on our chrome object
752 0 : JSAutoCompartment ac(aCx, mImpl->CallbackOrNull());
753 0 : if (!JS_WrapObject(aCx, &obj)) {
754 0 : return nullptr;
755 : }
756 0 : if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
757 0 : return nullptr;
758 : }
759 0 : return obj;
760 : }
761 :
762 : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
763 : already_AddRefed<MediaStreamTrack>
764 0 : RTCRtpReceiver::GetTrack(ErrorResult& aRv, JSCompartment* aCompartment) const
765 : {
766 0 : return mImpl->GetTrack(aRv, aCompartment);
767 : }
768 :
769 : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
770 : already_AddRefed<Promise>
771 0 : RTCRtpReceiver::GetStats(ErrorResult& aRv, JSCompartment* aCompartment)
772 : {
773 0 : return mImpl->GetStats(aRv, aCompartment);
774 : }
775 :
776 : bool
777 0 : RTCRtpReceiver::_Create(JSContext* cx, unsigned argc, JS::Value* vp)
778 : {
779 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
780 0 : if (args.length() < 2) {
781 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "RTCRtpReceiver._create");
782 : }
783 0 : if (!args[0].isObject()) {
784 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of RTCRtpReceiver._create");
785 : }
786 0 : if (!args[1].isObject()) {
787 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of RTCRtpReceiver._create");
788 : }
789 :
790 : // GlobalObject will go through wrappers as needed for us, and
791 : // is simpler than the right UnwrapArg incantation.
792 0 : GlobalObject global(cx, &args[0].toObject());
793 0 : if (global.Failed()) {
794 0 : return false;
795 : }
796 0 : nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports());
797 0 : MOZ_ASSERT(globalHolder);
798 0 : JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
799 0 : RefPtr<RTCRtpReceiver> impl = new RTCRtpReceiver(arg, globalHolder);
800 0 : MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
801 0 : return GetOrCreateDOMReflector(cx, impl, args.rval());
802 : }
803 :
804 :
805 : } // namespace dom
806 : } // namespace mozilla
|