/work/obj-fuzz/dom/bindings/RTCRtpReceiverBinding.cpp
Line | Count | Source (jump to first uncovered line) |
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 "RTCRtpSourcesBinding.h" |
6 | | #include "RTCRtpTransceiverBinding.h" |
7 | | #include "WrapperFactory.h" |
8 | | #include "mozilla/OwningNonNull.h" |
9 | | #include "mozilla/Preferences.h" |
10 | | #include "mozilla/dom/BindingUtils.h" |
11 | | #include "mozilla/dom/DOMJSClass.h" |
12 | | #include "mozilla/dom/MediaStreamTrack.h" |
13 | | #include "mozilla/dom/NonRefcountedDOMObject.h" |
14 | | #include "mozilla/dom/PrimitiveConversions.h" |
15 | | #include "mozilla/dom/Promise.h" |
16 | | #include "mozilla/dom/ToJSValue.h" |
17 | | #include "mozilla/dom/XrayExpandoClass.h" |
18 | | #include "nsContentUtils.h" |
19 | | #include "nsIGlobalObject.h" |
20 | | |
21 | | namespace mozilla { |
22 | | namespace dom { |
23 | | |
24 | | namespace binding_detail {}; // Just to make sure it's known as a namespace |
25 | | using namespace mozilla::dom::binding_detail; |
26 | | |
27 | | |
28 | | namespace RTCRtpReceiver_Binding { |
29 | | |
30 | | MOZ_CAN_RUN_SCRIPT static bool |
31 | | get_track(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCRtpReceiver* self, JSJitGetterCallArgs args) |
32 | 0 | { |
33 | 0 | AUTO_PROFILER_LABEL_FAST("get RTCRtpReceiver.track", DOM, cx); |
34 | 0 |
|
35 | 0 | Maybe<JS::Rooted<JSObject*> > unwrappedObj; |
36 | 0 | bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj); |
37 | 0 | if (objIsXray) { |
38 | 0 | unwrappedObj.emplace(cx, obj); |
39 | 0 | } |
40 | 0 | if (objIsXray) { |
41 | 0 | unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref()); |
42 | 0 | if (!unwrappedObj.ref()) { |
43 | 0 | return false; |
44 | 0 | } |
45 | 0 | } |
46 | 0 | FastErrorResult rv; |
47 | 0 | auto result(StrongOrRawPtr<mozilla::dom::MediaStreamTrack>(self->GetTrack(rv, (unwrappedObj ? js::GetNonCCWObjectRealm(*unwrappedObj) : js::GetContextRealm(cx))))); |
48 | 0 | if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { |
49 | 0 | return false; |
50 | 0 | } |
51 | 0 | MOZ_ASSERT(!JS_IsExceptionPending(cx)); |
52 | 0 | if (!GetOrCreateDOMReflector(cx, result, args.rval())) { |
53 | 0 | MOZ_ASSERT(JS_IsExceptionPending(cx)); |
54 | 0 | return false; |
55 | 0 | } |
56 | 0 | return true; |
57 | 0 | } |
58 | | |
59 | | static const JSJitInfo track_getterinfo = { |
60 | | { (JSJitGetterOp)get_track }, |
61 | | { prototypes::id::RTCRtpReceiver }, |
62 | | { PrototypeTraits<prototypes::id::RTCRtpReceiver>::Depth }, |
63 | | JSJitInfo::Getter, |
64 | | JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ |
65 | | JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */ |
66 | | false, /* isInfallible. False in setters. */ |
67 | | false, /* isMovable. Not relevant for setters. */ |
68 | | false, /* isEliminatable. Not relevant for setters. */ |
69 | | false, /* isAlwaysInSlot. Only relevant for getters. */ |
70 | | false, /* isLazilyCachedInSlot. Only relevant for getters. */ |
71 | | false, /* isTypedMethod. Only relevant for methods. */ |
72 | | 0 /* Reserved slot index, if we're stored in a slot, else 0. */ |
73 | | }; |
74 | | static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); |
75 | | static_assert(0 < 1, "There is no slot for us"); |
76 | | |
77 | | MOZ_CAN_RUN_SCRIPT static bool |
78 | | getStats(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCRtpReceiver* self, const JSJitMethodCallArgs& args) |
79 | 0 | { |
80 | 0 | AUTO_PROFILER_LABEL_FAST("RTCRtpReceiver.getStats", DOM, cx); |
81 | 0 |
|
82 | 0 | Maybe<JS::Rooted<JSObject*> > unwrappedObj; |
83 | 0 | bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj); |
84 | 0 | if (objIsXray) { |
85 | 0 | unwrappedObj.emplace(cx, obj); |
86 | 0 | } |
87 | 0 | if (objIsXray) { |
88 | 0 | unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref()); |
89 | 0 | if (!unwrappedObj.ref()) { |
90 | 0 | return false; |
91 | 0 | } |
92 | 0 | } |
93 | 0 | FastErrorResult rv; |
94 | 0 | auto result(StrongOrRawPtr<Promise>(self->GetStats(rv, (unwrappedObj ? js::GetNonCCWObjectRealm(*unwrappedObj) : js::GetContextRealm(cx))))); |
95 | 0 | if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { |
96 | 0 | return false; |
97 | 0 | } |
98 | 0 | MOZ_ASSERT(!JS_IsExceptionPending(cx)); |
99 | 0 | if (!ToJSValue(cx, result, args.rval())) { |
100 | 0 | return false; |
101 | 0 | } |
102 | 0 | return true; |
103 | 0 | } |
104 | | |
105 | | MOZ_CAN_RUN_SCRIPT static bool |
106 | | getStats_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCRtpReceiver* self, const JSJitMethodCallArgs& args) |
107 | 0 | { |
108 | 0 | bool ok = getStats(cx, obj, self, args); |
109 | 0 | if (ok) { |
110 | 0 | return true; |
111 | 0 | } |
112 | 0 | return ConvertExceptionToPromise(cx, args.rval()); |
113 | 0 | } |
114 | | |
115 | | static const JSJitInfo getStats_methodinfo = { |
116 | | { (JSJitGetterOp)getStats_promiseWrapper }, |
117 | | { prototypes::id::RTCRtpReceiver }, |
118 | | { PrototypeTraits<prototypes::id::RTCRtpReceiver>::Depth }, |
119 | | JSJitInfo::Method, |
120 | | JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ |
121 | | JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */ |
122 | | false, /* isInfallible. False in setters. */ |
123 | | false, /* isMovable. Not relevant for setters. */ |
124 | | false, /* isEliminatable. Not relevant for setters. */ |
125 | | false, /* isAlwaysInSlot. Only relevant for getters. */ |
126 | | false, /* isLazilyCachedInSlot. Only relevant for getters. */ |
127 | | false, /* isTypedMethod. Only relevant for methods. */ |
128 | | 0 /* Reserved slot index, if we're stored in a slot, else 0. */ |
129 | | }; |
130 | | static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); |
131 | | static_assert(0 < 1, "There is no slot for us"); |
132 | | |
133 | | MOZ_CAN_RUN_SCRIPT static bool |
134 | | getContributingSources(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCRtpReceiver* self, const JSJitMethodCallArgs& args) |
135 | 0 | { |
136 | 0 | AUTO_PROFILER_LABEL_FAST("RTCRtpReceiver.getContributingSources", DOM, cx); |
137 | 0 |
|
138 | 0 | Maybe<JS::Rooted<JSObject*> > unwrappedObj; |
139 | 0 | bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj); |
140 | 0 | if (objIsXray) { |
141 | 0 | unwrappedObj.emplace(cx, obj); |
142 | 0 | } |
143 | 0 | if (objIsXray) { |
144 | 0 | unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref()); |
145 | 0 | if (!unwrappedObj.ref()) { |
146 | 0 | return false; |
147 | 0 | } |
148 | 0 | } |
149 | 0 | FastErrorResult rv; |
150 | 0 | nsTArray<RTCRtpContributingSource> result; |
151 | 0 | self->GetContributingSources(result, rv, (unwrappedObj ? js::GetNonCCWObjectRealm(*unwrappedObj) : js::GetContextRealm(cx))); |
152 | 0 | if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { |
153 | 0 | return false; |
154 | 0 | } |
155 | 0 | MOZ_ASSERT(!JS_IsExceptionPending(cx)); |
156 | 0 |
|
157 | 0 | uint32_t length = result.Length(); |
158 | 0 | JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length)); |
159 | 0 | if (!returnArray) { |
160 | 0 | return false; |
161 | 0 | } |
162 | 0 | // Scope for 'tmp' |
163 | 0 | { |
164 | 0 | JS::Rooted<JS::Value> tmp(cx); |
165 | 0 | for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) { |
166 | 0 | // Control block to let us common up the JS_DefineElement calls when there |
167 | 0 | // are different ways to succeed at wrapping the object. |
168 | 0 | do { |
169 | 0 | if (!result[sequenceIdx0].ToObjectInternal(cx, &tmp)) { |
170 | 0 | return false; |
171 | 0 | } |
172 | 0 | break; |
173 | 0 | } while (false); |
174 | 0 | if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp, |
175 | 0 | JSPROP_ENUMERATE)) { |
176 | 0 | return false; |
177 | 0 | } |
178 | 0 | } |
179 | 0 | } |
180 | 0 | args.rval().setObject(*returnArray); |
181 | 0 | return true; |
182 | 0 | } |
183 | | |
184 | | static const JSJitInfo getContributingSources_methodinfo = { |
185 | | { (JSJitGetterOp)getContributingSources }, |
186 | | { prototypes::id::RTCRtpReceiver }, |
187 | | { PrototypeTraits<prototypes::id::RTCRtpReceiver>::Depth }, |
188 | | JSJitInfo::Method, |
189 | | JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ |
190 | | JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */ |
191 | | false, /* isInfallible. False in setters. */ |
192 | | false, /* isMovable. Not relevant for setters. */ |
193 | | false, /* isEliminatable. Not relevant for setters. */ |
194 | | false, /* isAlwaysInSlot. Only relevant for getters. */ |
195 | | false, /* isLazilyCachedInSlot. Only relevant for getters. */ |
196 | | false, /* isTypedMethod. Only relevant for methods. */ |
197 | | 0 /* Reserved slot index, if we're stored in a slot, else 0. */ |
198 | | }; |
199 | | static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); |
200 | | static_assert(0 < 1, "There is no slot for us"); |
201 | | |
202 | | MOZ_CAN_RUN_SCRIPT static bool |
203 | | getSynchronizationSources(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCRtpReceiver* self, const JSJitMethodCallArgs& args) |
204 | 0 | { |
205 | 0 | AUTO_PROFILER_LABEL_FAST("RTCRtpReceiver.getSynchronizationSources", DOM, cx); |
206 | 0 |
|
207 | 0 | Maybe<JS::Rooted<JSObject*> > unwrappedObj; |
208 | 0 | bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj); |
209 | 0 | if (objIsXray) { |
210 | 0 | unwrappedObj.emplace(cx, obj); |
211 | 0 | } |
212 | 0 | if (objIsXray) { |
213 | 0 | unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref()); |
214 | 0 | if (!unwrappedObj.ref()) { |
215 | 0 | return false; |
216 | 0 | } |
217 | 0 | } |
218 | 0 | FastErrorResult rv; |
219 | 0 | nsTArray<RTCRtpSynchronizationSource> result; |
220 | 0 | self->GetSynchronizationSources(result, rv, (unwrappedObj ? js::GetNonCCWObjectRealm(*unwrappedObj) : js::GetContextRealm(cx))); |
221 | 0 | if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { |
222 | 0 | return false; |
223 | 0 | } |
224 | 0 | MOZ_ASSERT(!JS_IsExceptionPending(cx)); |
225 | 0 |
|
226 | 0 | uint32_t length = result.Length(); |
227 | 0 | JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length)); |
228 | 0 | if (!returnArray) { |
229 | 0 | return false; |
230 | 0 | } |
231 | 0 | // Scope for 'tmp' |
232 | 0 | { |
233 | 0 | JS::Rooted<JS::Value> tmp(cx); |
234 | 0 | for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) { |
235 | 0 | // Control block to let us common up the JS_DefineElement calls when there |
236 | 0 | // are different ways to succeed at wrapping the object. |
237 | 0 | do { |
238 | 0 | if (!result[sequenceIdx0].ToObjectInternal(cx, &tmp)) { |
239 | 0 | return false; |
240 | 0 | } |
241 | 0 | break; |
242 | 0 | } while (false); |
243 | 0 | if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp, |
244 | 0 | JSPROP_ENUMERATE)) { |
245 | 0 | return false; |
246 | 0 | } |
247 | 0 | } |
248 | 0 | } |
249 | 0 | args.rval().setObject(*returnArray); |
250 | 0 | return true; |
251 | 0 | } |
252 | | |
253 | | static const JSJitInfo getSynchronizationSources_methodinfo = { |
254 | | { (JSJitGetterOp)getSynchronizationSources }, |
255 | | { prototypes::id::RTCRtpReceiver }, |
256 | | { PrototypeTraits<prototypes::id::RTCRtpReceiver>::Depth }, |
257 | | JSJitInfo::Method, |
258 | | JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ |
259 | | JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */ |
260 | | false, /* isInfallible. False in setters. */ |
261 | | false, /* isMovable. Not relevant for setters. */ |
262 | | false, /* isEliminatable. Not relevant for setters. */ |
263 | | false, /* isAlwaysInSlot. Only relevant for getters. */ |
264 | | false, /* isLazilyCachedInSlot. Only relevant for getters. */ |
265 | | false, /* isTypedMethod. Only relevant for methods. */ |
266 | | 0 /* Reserved slot index, if we're stored in a slot, else 0. */ |
267 | | }; |
268 | | static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); |
269 | | static_assert(0 < 1, "There is no slot for us"); |
270 | | |
271 | | MOZ_CAN_RUN_SCRIPT static bool |
272 | | setStreamIds(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCRtpReceiver* self, const JSJitMethodCallArgs& args) |
273 | 0 | { |
274 | 0 | AUTO_PROFILER_LABEL_FAST("RTCRtpReceiver.setStreamIds", DOM, cx); |
275 | 0 |
|
276 | 0 | if (MOZ_UNLIKELY(args.length() < 1)) { |
277 | 0 | return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "RTCRtpReceiver.setStreamIds"); |
278 | 0 | } |
279 | 0 | Maybe<JS::Rooted<JSObject*> > unwrappedObj; |
280 | 0 | bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj); |
281 | 0 | if (objIsXray) { |
282 | 0 | unwrappedObj.emplace(cx, obj); |
283 | 0 | } |
284 | 0 | binding_detail::AutoSequence<nsString> arg0; |
285 | 0 | if (args[0].isObject()) { |
286 | 0 | JS::ForOfIterator iter(cx); |
287 | 0 | if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) { |
288 | 0 | return false; |
289 | 0 | } |
290 | 0 | if (!iter.valueIsIterable()) { |
291 | 0 | ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 1 of RTCRtpReceiver.setStreamIds"); |
292 | 0 | return false; |
293 | 0 | } |
294 | 0 | binding_detail::AutoSequence<nsString> &arr = arg0; |
295 | 0 | JS::Rooted<JS::Value> temp(cx); |
296 | 0 | while (true) { |
297 | 0 | bool done; |
298 | 0 | if (!iter.next(&temp, &done)) { |
299 | 0 | return false; |
300 | 0 | } |
301 | 0 | if (done) { |
302 | 0 | break; |
303 | 0 | } |
304 | 0 | nsString* slotPtr = arr.AppendElement(mozilla::fallible); |
305 | 0 | if (!slotPtr) { |
306 | 0 | JS_ReportOutOfMemory(cx); |
307 | 0 | return false; |
308 | 0 | } |
309 | 0 | nsString& slot = *slotPtr; |
310 | 0 | if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) { |
311 | 0 | return false; |
312 | 0 | } |
313 | 0 | } |
314 | 0 | } else { |
315 | 0 | ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 1 of RTCRtpReceiver.setStreamIds"); |
316 | 0 | return false; |
317 | 0 | } |
318 | 0 | if (objIsXray) { |
319 | 0 | unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref()); |
320 | 0 | if (!unwrappedObj.ref()) { |
321 | 0 | return false; |
322 | 0 | } |
323 | 0 | } |
324 | 0 | FastErrorResult rv; |
325 | 0 | self->SetStreamIds(Constify(arg0), rv, (unwrappedObj ? js::GetNonCCWObjectRealm(*unwrappedObj) : js::GetContextRealm(cx))); |
326 | 0 | if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { |
327 | 0 | return false; |
328 | 0 | } |
329 | 0 | MOZ_ASSERT(!JS_IsExceptionPending(cx)); |
330 | 0 | args.rval().setUndefined(); |
331 | 0 | return true; |
332 | 0 | } |
333 | | |
334 | | static const JSJitInfo setStreamIds_methodinfo = { |
335 | | { (JSJitGetterOp)setStreamIds }, |
336 | | { prototypes::id::RTCRtpReceiver }, |
337 | | { PrototypeTraits<prototypes::id::RTCRtpReceiver>::Depth }, |
338 | | JSJitInfo::Method, |
339 | | JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ |
340 | | JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */ |
341 | | false, /* isInfallible. False in setters. */ |
342 | | false, /* isMovable. Not relevant for setters. */ |
343 | | false, /* isEliminatable. Not relevant for setters. */ |
344 | | false, /* isAlwaysInSlot. Only relevant for getters. */ |
345 | | false, /* isLazilyCachedInSlot. Only relevant for getters. */ |
346 | | false, /* isTypedMethod. Only relevant for methods. */ |
347 | | 0 /* Reserved slot index, if we're stored in a slot, else 0. */ |
348 | | }; |
349 | | static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); |
350 | | static_assert(0 < 1, "There is no slot for us"); |
351 | | |
352 | | MOZ_CAN_RUN_SCRIPT static bool |
353 | | setRemoteSendBit(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCRtpReceiver* self, const JSJitMethodCallArgs& args) |
354 | 0 | { |
355 | 0 | AUTO_PROFILER_LABEL_FAST("RTCRtpReceiver.setRemoteSendBit", DOM, cx); |
356 | 0 |
|
357 | 0 | if (MOZ_UNLIKELY(args.length() < 1)) { |
358 | 0 | return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "RTCRtpReceiver.setRemoteSendBit"); |
359 | 0 | } |
360 | 0 | Maybe<JS::Rooted<JSObject*> > unwrappedObj; |
361 | 0 | bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj); |
362 | 0 | if (objIsXray) { |
363 | 0 | unwrappedObj.emplace(cx, obj); |
364 | 0 | } |
365 | 0 | bool arg0; |
366 | 0 | if (!ValueToPrimitive<bool, eDefault>(cx, args[0], &arg0)) { |
367 | 0 | return false; |
368 | 0 | } |
369 | 0 | if (objIsXray) { |
370 | 0 | unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref()); |
371 | 0 | if (!unwrappedObj.ref()) { |
372 | 0 | return false; |
373 | 0 | } |
374 | 0 | } |
375 | 0 | FastErrorResult rv; |
376 | 0 | self->SetRemoteSendBit(arg0, rv, (unwrappedObj ? js::GetNonCCWObjectRealm(*unwrappedObj) : js::GetContextRealm(cx))); |
377 | 0 | if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { |
378 | 0 | return false; |
379 | 0 | } |
380 | 0 | MOZ_ASSERT(!JS_IsExceptionPending(cx)); |
381 | 0 | args.rval().setUndefined(); |
382 | 0 | return true; |
383 | 0 | } |
384 | | |
385 | | static const JSJitInfo setRemoteSendBit_methodinfo = { |
386 | | { (JSJitGetterOp)setRemoteSendBit }, |
387 | | { prototypes::id::RTCRtpReceiver }, |
388 | | { PrototypeTraits<prototypes::id::RTCRtpReceiver>::Depth }, |
389 | | JSJitInfo::Method, |
390 | | JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ |
391 | | JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */ |
392 | | false, /* isInfallible. False in setters. */ |
393 | | false, /* isMovable. Not relevant for setters. */ |
394 | | false, /* isEliminatable. Not relevant for setters. */ |
395 | | false, /* isAlwaysInSlot. Only relevant for getters. */ |
396 | | false, /* isLazilyCachedInSlot. Only relevant for getters. */ |
397 | | false, /* isTypedMethod. Only relevant for methods. */ |
398 | | 0 /* Reserved slot index, if we're stored in a slot, else 0. */ |
399 | | }; |
400 | | static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); |
401 | | static_assert(0 < 1, "There is no slot for us"); |
402 | | |
403 | | MOZ_CAN_RUN_SCRIPT static bool |
404 | | processTrackAdditionsAndRemovals(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCRtpReceiver* self, const JSJitMethodCallArgs& args) |
405 | 0 | { |
406 | 0 | AUTO_PROFILER_LABEL_FAST("RTCRtpReceiver.processTrackAdditionsAndRemovals", DOM, cx); |
407 | 0 |
|
408 | 0 | if (MOZ_UNLIKELY(args.length() < 2)) { |
409 | 0 | return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "RTCRtpReceiver.processTrackAdditionsAndRemovals"); |
410 | 0 | } |
411 | 0 | Maybe<JS::Rooted<JSObject*> > unwrappedObj; |
412 | 0 | bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj); |
413 | 0 | if (objIsXray) { |
414 | 0 | unwrappedObj.emplace(cx, obj); |
415 | 0 | } |
416 | 0 | NonNull<mozilla::dom::RTCRtpTransceiver> arg0; |
417 | 0 | if (args[0].isObject()) { |
418 | 0 | { |
419 | 0 | nsresult rv = UnwrapObject<prototypes::id::RTCRtpTransceiver, mozilla::dom::RTCRtpTransceiver>(args[0], arg0); |
420 | 0 | if (NS_FAILED(rv)) { |
421 | 0 | ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of RTCRtpReceiver.processTrackAdditionsAndRemovals", "RTCRtpTransceiver"); |
422 | 0 | return false; |
423 | 0 | } |
424 | 0 | } |
425 | 0 | } else { |
426 | 0 | ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of RTCRtpReceiver.processTrackAdditionsAndRemovals"); |
427 | 0 | return false; |
428 | 0 | } |
429 | 0 | JS::Rooted<JSObject*> arg1(cx); |
430 | 0 | if (args[1].isObject()) { |
431 | 0 | #ifdef __clang__ |
432 | 0 | #pragma clang diagnostic push |
433 | 0 | #pragma clang diagnostic ignored "-Wunreachable-code" |
434 | 0 | #pragma clang diagnostic ignored "-Wunreachable-code-return" |
435 | 0 | #endif // __clang__ |
436 | 0 | if ((true) && !CallerSubsumes(args[1])) { |
437 | 0 | ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "argument 2 of RTCRtpReceiver.processTrackAdditionsAndRemovals"); |
438 | 0 | return false; |
439 | 0 | } |
440 | 0 | #ifdef __clang__ |
441 | 0 | #pragma clang diagnostic pop |
442 | 0 | #endif // __clang__ |
443 | 0 | arg1 = &args[1].toObject(); |
444 | 0 | } else { |
445 | 0 | ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of RTCRtpReceiver.processTrackAdditionsAndRemovals"); |
446 | 0 | return false; |
447 | 0 | } |
448 | 0 | if (objIsXray) { |
449 | 0 | unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref()); |
450 | 0 | if (!unwrappedObj.ref()) { |
451 | 0 | return false; |
452 | 0 | } |
453 | 0 | } |
454 | 0 | FastErrorResult rv; |
455 | 0 | self->ProcessTrackAdditionsAndRemovals(MOZ_KnownLive(NonNullHelper(arg0)), arg1, rv, (unwrappedObj ? js::GetNonCCWObjectRealm(*unwrappedObj) : js::GetContextRealm(cx))); |
456 | 0 | if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) { |
457 | 0 | return false; |
458 | 0 | } |
459 | 0 | MOZ_ASSERT(!JS_IsExceptionPending(cx)); |
460 | 0 | args.rval().setUndefined(); |
461 | 0 | return true; |
462 | 0 | } |
463 | | |
464 | | static const JSJitInfo processTrackAdditionsAndRemovals_methodinfo = { |
465 | | { (JSJitGetterOp)processTrackAdditionsAndRemovals }, |
466 | | { prototypes::id::RTCRtpReceiver }, |
467 | | { PrototypeTraits<prototypes::id::RTCRtpReceiver>::Depth }, |
468 | | JSJitInfo::Method, |
469 | | JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */ |
470 | | JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */ |
471 | | false, /* isInfallible. False in setters. */ |
472 | | false, /* isMovable. Not relevant for setters. */ |
473 | | false, /* isEliminatable. Not relevant for setters. */ |
474 | | false, /* isAlwaysInSlot. Only relevant for getters. */ |
475 | | false, /* isLazilyCachedInSlot. Only relevant for getters. */ |
476 | | false, /* isTypedMethod. Only relevant for methods. */ |
477 | | 0 /* Reserved slot index, if we're stored in a slot, else 0. */ |
478 | | }; |
479 | | static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit"); |
480 | | static_assert(0 < 1, "There is no slot for us"); |
481 | | |
482 | | static bool |
483 | | _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val) |
484 | 0 | { |
485 | 0 | mozilla::dom::RTCRtpReceiver* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::RTCRtpReceiver>(obj); |
486 | 0 | // We don't want to preserve if we don't have a wrapper, and we |
487 | 0 | // obviously can't preserve if we're not initialized. |
488 | 0 | if (self && self->GetWrapperPreserveColor()) { |
489 | 0 | PreserveWrapper(self); |
490 | 0 | } |
491 | 0 | return true; |
492 | 0 | } |
493 | | |
494 | | static void |
495 | | _finalize(js::FreeOp* fop, JSObject* obj) |
496 | 0 | { |
497 | 0 | mozilla::dom::RTCRtpReceiver* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::RTCRtpReceiver>(obj); |
498 | 0 | if (self) { |
499 | 0 | ClearWrapper(self, self, obj); |
500 | 0 | AddForDeferredFinalization<mozilla::dom::RTCRtpReceiver>(self); |
501 | 0 | } |
502 | 0 | } |
503 | | |
504 | | static size_t |
505 | | _objectMoved(JSObject* obj, JSObject* old) |
506 | 0 | { |
507 | 0 | mozilla::dom::RTCRtpReceiver* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::RTCRtpReceiver>(obj); |
508 | 0 | if (self) { |
509 | 0 | UpdateWrapper(self, self, obj, old); |
510 | 0 | } |
511 | 0 |
|
512 | 0 | return 0; |
513 | 0 | } |
514 | | |
515 | | // We deliberately use brace-elision to make Visual Studio produce better initalization code. |
516 | | #if defined(__clang__) |
517 | | #pragma clang diagnostic push |
518 | | #pragma clang diagnostic ignored "-Wmissing-braces" |
519 | | #endif |
520 | | static const JSFunctionSpec sChromeStaticMethods_specs[] = { |
521 | | JS_FNSPEC("_create", RTCRtpReceiver::_Create, nullptr, 2, 0, nullptr), |
522 | | JS_FS_END |
523 | | }; |
524 | | #if defined(__clang__) |
525 | | #pragma clang diagnostic pop |
526 | | #endif |
527 | | |
528 | | |
529 | | static const Prefable<const JSFunctionSpec> sChromeStaticMethods[] = { |
530 | | { nullptr, &sChromeStaticMethods_specs[0] }, |
531 | | { nullptr, nullptr } |
532 | | }; |
533 | | |
534 | | static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX, |
535 | | "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)"); |
536 | | static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX, |
537 | | "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)"); |
538 | | |
539 | | // We deliberately use brace-elision to make Visual Studio produce better initalization code. |
540 | | #if defined(__clang__) |
541 | | #pragma clang diagnostic push |
542 | | #pragma clang diagnostic ignored "-Wmissing-braces" |
543 | | #endif |
544 | | static const JSFunctionSpec sMethods_specs[] = { |
545 | | JS_FNSPEC("getStats", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&getStats_methodinfo), 0, JSPROP_ENUMERATE, nullptr), |
546 | | JS_FS_END, |
547 | | JS_FNSPEC("getContributingSources", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getContributingSources_methodinfo), 0, JSPROP_ENUMERATE, nullptr), |
548 | | JS_FNSPEC("getSynchronizationSources", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getSynchronizationSources_methodinfo), 0, JSPROP_ENUMERATE, nullptr), |
549 | | JS_FS_END |
550 | | }; |
551 | | #if defined(__clang__) |
552 | | #pragma clang diagnostic pop |
553 | | #endif |
554 | | |
555 | | // Can't be const because the pref-enabled boolean needs to be writable |
556 | | static PrefableDisablers sMethods_disablers2 = { |
557 | | true, false, 0, nullptr |
558 | | }; |
559 | | |
560 | | static const Prefable<const JSFunctionSpec> sMethods[] = { |
561 | | { nullptr, &sMethods_specs[0] }, |
562 | | { &sMethods_disablers2, &sMethods_specs[2] }, |
563 | | { nullptr, nullptr } |
564 | | }; |
565 | | |
566 | | static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX, |
567 | | "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)"); |
568 | | static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX, |
569 | | "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)"); |
570 | | |
571 | | // We deliberately use brace-elision to make Visual Studio produce better initalization code. |
572 | | #if defined(__clang__) |
573 | | #pragma clang diagnostic push |
574 | | #pragma clang diagnostic ignored "-Wmissing-braces" |
575 | | #endif |
576 | | static const JSFunctionSpec sChromeMethods_specs[] = { |
577 | | JS_FNSPEC("setStreamIds", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setStreamIds_methodinfo), 1, JSPROP_ENUMERATE, nullptr), |
578 | | JS_FNSPEC("setRemoteSendBit", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setRemoteSendBit_methodinfo), 1, JSPROP_ENUMERATE, nullptr), |
579 | | JS_FNSPEC("processTrackAdditionsAndRemovals", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&processTrackAdditionsAndRemovals_methodinfo), 2, JSPROP_ENUMERATE, nullptr), |
580 | | JS_FS_END |
581 | | }; |
582 | | #if defined(__clang__) |
583 | | #pragma clang diagnostic pop |
584 | | #endif |
585 | | |
586 | | |
587 | | static const Prefable<const JSFunctionSpec> sChromeMethods[] = { |
588 | | { nullptr, &sChromeMethods_specs[0] }, |
589 | | { nullptr, nullptr } |
590 | | }; |
591 | | |
592 | | static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX, |
593 | | "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)"); |
594 | | static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX, |
595 | | "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)"); |
596 | | |
597 | | // We deliberately use brace-elision to make Visual Studio produce better initalization code. |
598 | | #if defined(__clang__) |
599 | | #pragma clang diagnostic push |
600 | | #pragma clang diagnostic ignored "-Wmissing-braces" |
601 | | #endif |
602 | | static const JSPropertySpec sAttributes_specs[] = { |
603 | | { "track", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &track_getterinfo, nullptr, nullptr }, |
604 | | { nullptr, 0, nullptr, nullptr, nullptr, nullptr } |
605 | | }; |
606 | | #if defined(__clang__) |
607 | | #pragma clang diagnostic pop |
608 | | #endif |
609 | | |
610 | | |
611 | | static const Prefable<const JSPropertySpec> sAttributes[] = { |
612 | | { nullptr, &sAttributes_specs[0] }, |
613 | | { nullptr, nullptr } |
614 | | }; |
615 | | |
616 | | static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX, |
617 | | "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)"); |
618 | | static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX, |
619 | | "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)"); |
620 | | |
621 | | |
622 | | static uint16_t sNativeProperties_sortedPropertyIndices[4]; |
623 | | static PropertyInfo sNativeProperties_propertyInfos[4]; |
624 | | |
625 | | static const NativePropertiesN<2> sNativeProperties = { |
626 | | false, 0, |
627 | | false, 0, |
628 | | true, 0 /* sMethods */, |
629 | | true, 1 /* sAttributes */, |
630 | | false, 0, |
631 | | false, 0, |
632 | | false, 0, |
633 | | -1, |
634 | | 4, |
635 | | sNativeProperties_sortedPropertyIndices, |
636 | | { |
637 | | { sMethods, &sNativeProperties_propertyInfos[0] }, |
638 | | { sAttributes, &sNativeProperties_propertyInfos[3] } |
639 | | } |
640 | | }; |
641 | | static_assert(4 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount), |
642 | | "We have a property info count that is oversized"); |
643 | | |
644 | | static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[4]; |
645 | | static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[4]; |
646 | | |
647 | | static const NativePropertiesN<2> sChromeOnlyNativeProperties = { |
648 | | true, 0 /* sChromeStaticMethods */, |
649 | | false, 0, |
650 | | true, 1 /* sChromeMethods */, |
651 | | false, 0, |
652 | | false, 0, |
653 | | false, 0, |
654 | | false, 0, |
655 | | -1, |
656 | | 4, |
657 | | sChromeOnlyNativeProperties_sortedPropertyIndices, |
658 | | { |
659 | | { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] }, |
660 | | { sChromeMethods, &sChromeOnlyNativeProperties_propertyInfos[1] } |
661 | | } |
662 | | }; |
663 | | static_assert(4 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount), |
664 | | "We have a property info count that is oversized"); |
665 | | |
666 | | static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = { |
667 | | { |
668 | | "Function", |
669 | | JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE), |
670 | | &sBoringInterfaceObjectClassClassOps, |
671 | | JS_NULL_CLASS_SPEC, |
672 | | JS_NULL_CLASS_EXT, |
673 | | &sInterfaceObjectClassObjectOps |
674 | | }, |
675 | | eInterface, |
676 | | true, |
677 | | prototypes::id::RTCRtpReceiver, |
678 | | PrototypeTraits<prototypes::id::RTCRtpReceiver>::Depth, |
679 | | sNativePropertyHooks, |
680 | | "function RTCRtpReceiver() {\n [native code]\n}", |
681 | | JS::GetRealmFunctionPrototype |
682 | | }; |
683 | | |
684 | | static const DOMIfaceAndProtoJSClass sPrototypeClass = { |
685 | | { |
686 | | "RTCRtpReceiverPrototype", |
687 | | JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE), |
688 | | JS_NULL_CLASS_OPS, |
689 | | JS_NULL_CLASS_SPEC, |
690 | | JS_NULL_CLASS_EXT, |
691 | | JS_NULL_OBJECT_OPS |
692 | | }, |
693 | | eInterfacePrototype, |
694 | | false, |
695 | | prototypes::id::RTCRtpReceiver, |
696 | | PrototypeTraits<prototypes::id::RTCRtpReceiver>::Depth, |
697 | | sNativePropertyHooks, |
698 | | "[object RTCRtpReceiverPrototype]", |
699 | | JS::GetRealmObjectPrototype |
700 | | }; |
701 | | |
702 | | bool |
703 | | ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj) |
704 | 0 | { |
705 | 0 | static bool sPrefValue; |
706 | 0 | static bool sPrefCacheSetUp = false; |
707 | 0 | if (!sPrefCacheSetUp) { |
708 | 0 | sPrefCacheSetUp = true; |
709 | 0 | Preferences::AddBoolVarCache(&sPrefValue, "media.peerconnection.enabled"); |
710 | 0 | } |
711 | 0 |
|
712 | 0 | return sPrefValue; |
713 | 0 | } |
714 | | |
715 | | static const js::ClassOps sClassOps = { |
716 | | _addProperty, /* addProperty */ |
717 | | nullptr, /* delProperty */ |
718 | | nullptr, /* enumerate */ |
719 | | nullptr, /* newEnumerate */ |
720 | | nullptr, /* resolve */ |
721 | | nullptr, /* mayResolve */ |
722 | | _finalize, /* finalize */ |
723 | | nullptr, /* call */ |
724 | | nullptr, /* hasInstance */ |
725 | | nullptr, /* construct */ |
726 | | nullptr, /* trace */ |
727 | | }; |
728 | | |
729 | | static const js::ClassExtension sClassExtension = { |
730 | | nullptr, /* weakmapKeyDelegateOp */ |
731 | | _objectMoved /* objectMovedOp */ |
732 | | }; |
733 | | |
734 | | static const DOMJSClass sClass = { |
735 | | { "RTCRtpReceiver", |
736 | | JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1), |
737 | | &sClassOps, |
738 | | JS_NULL_CLASS_SPEC, |
739 | | &sClassExtension, |
740 | | JS_NULL_OBJECT_OPS |
741 | | }, |
742 | | { 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 }, |
743 | | IsBaseOf<nsISupports, mozilla::dom::RTCRtpReceiver >::value, |
744 | | sNativePropertyHooks, |
745 | | FindAssociatedGlobalForNative<mozilla::dom::RTCRtpReceiver>::Get, |
746 | | GetProtoObjectHandle, |
747 | | GetCCParticipant<mozilla::dom::RTCRtpReceiver>::Get() |
748 | | }; |
749 | | static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS, |
750 | | "Must have the right minimal number of reserved slots."); |
751 | | static_assert(1 >= 1, |
752 | | "Must have enough reserved slots."); |
753 | | |
754 | | const JSClass* |
755 | | GetJSClass() |
756 | 0 | { |
757 | 0 | return sClass.ToJSClass(); |
758 | 0 | } |
759 | | |
760 | | bool |
761 | | Wrap(JSContext* aCx, mozilla::dom::RTCRtpReceiver* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector) |
762 | 0 | { |
763 | 0 | static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::RTCRtpReceiver>::value, |
764 | 0 | "Shouldn't have wrappercached things that are not refcounted."); |
765 | 0 | MOZ_ASSERT(static_cast<mozilla::dom::RTCRtpReceiver*>(aObject) == |
766 | 0 | reinterpret_cast<mozilla::dom::RTCRtpReceiver*>(aObject), |
767 | 0 | "Multiple inheritance for mozilla::dom::RTCRtpReceiver is broken."); |
768 | 0 | MOZ_ASSERT(ToSupportsIsCorrect(aObject)); |
769 | 0 | MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx)); |
770 | 0 | MOZ_ASSERT(!aCache->GetWrapper(), |
771 | 0 | "You should probably not be using Wrap() directly; use " |
772 | 0 | "GetOrCreateDOMReflector instead"); |
773 | 0 |
|
774 | 0 | MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache), |
775 | 0 | "nsISupports must be on our primary inheritance chain"); |
776 | 0 |
|
777 | 0 | JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject())); |
778 | 0 | if (!global) { |
779 | 0 | return false; |
780 | 0 | } |
781 | 0 | MOZ_ASSERT(JS_IsGlobalObject(global)); |
782 | 0 | MOZ_ASSERT(JS::ObjectIsNotGray(global)); |
783 | 0 |
|
784 | 0 | // That might have ended up wrapping us already, due to the wonders |
785 | 0 | // of XBL. Check for that, and bail out as needed. |
786 | 0 | aReflector.set(aCache->GetWrapper()); |
787 | 0 | if (aReflector) { |
788 | | #ifdef DEBUG |
789 | | AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto); |
790 | | #endif // DEBUG |
791 | | return true; |
792 | 0 | } |
793 | 0 |
|
794 | 0 | JSAutoRealm ar(aCx, global); |
795 | 0 | JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx); |
796 | 0 | if (!canonicalProto) { |
797 | 0 | return false; |
798 | 0 | } |
799 | 0 | JS::Rooted<JSObject*> proto(aCx); |
800 | 0 | if (aGivenProto) { |
801 | 0 | proto = aGivenProto; |
802 | 0 | // Unfortunately, while aGivenProto was in the compartment of aCx |
803 | 0 | // coming in, we changed compartments to that of "parent" so may need |
804 | 0 | // to wrap the proto here. |
805 | 0 | if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) { |
806 | 0 | if (!JS_WrapObject(aCx, &proto)) { |
807 | 0 | return false; |
808 | 0 | } |
809 | 0 | } |
810 | 0 | } else { |
811 | 0 | proto = canonicalProto; |
812 | 0 | } |
813 | 0 |
|
814 | 0 | BindingJSObjectCreator<mozilla::dom::RTCRtpReceiver> creator(aCx); |
815 | 0 | creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector); |
816 | 0 | if (!aReflector) { |
817 | 0 | return false; |
818 | 0 | } |
819 | 0 | |
820 | 0 | aCache->SetWrapper(aReflector); |
821 | 0 | creator.InitializationSucceeded(); |
822 | 0 |
|
823 | 0 | MOZ_ASSERT(aCache->GetWrapperPreserveColor() && |
824 | 0 | aCache->GetWrapperPreserveColor() == aReflector); |
825 | 0 | // If proto != canonicalProto, we have to preserve our wrapper; |
826 | 0 | // otherwise we won't be able to properly recreate it later, since |
827 | 0 | // we won't know what proto to use. Note that we don't check |
828 | 0 | // aGivenProto here, since it's entirely possible (and even |
829 | 0 | // somewhat common) to have a non-null aGivenProto which is the |
830 | 0 | // same as canonicalProto. |
831 | 0 | if (proto != canonicalProto) { |
832 | 0 | PreserveWrapper(aObject); |
833 | 0 | } |
834 | 0 |
|
835 | 0 | return true; |
836 | 0 | } |
837 | | |
838 | | const NativePropertyHooks sNativePropertyHooks[] = { { |
839 | | nullptr, |
840 | | nullptr, |
841 | | nullptr, |
842 | | { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() }, |
843 | | prototypes::id::RTCRtpReceiver, |
844 | | constructors::id::RTCRtpReceiver, |
845 | | nullptr, |
846 | | &DefaultXrayExpandoObjectClass |
847 | | } }; |
848 | | |
849 | | void |
850 | | CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal) |
851 | 0 | { |
852 | 0 | JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx)); |
853 | 0 | if (!parentProto) { |
854 | 0 | return; |
855 | 0 | } |
856 | 0 | |
857 | 0 | JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx)); |
858 | 0 | if (!constructorProto) { |
859 | 0 | return; |
860 | 0 | } |
861 | 0 | |
862 | 0 | static bool sIdsInited = false; |
863 | 0 | if (!sIdsInited && NS_IsMainThread()) { |
864 | 0 | if (!InitIds(aCx, sNativeProperties.Upcast())) { |
865 | 0 | return; |
866 | 0 | } |
867 | 0 | if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) { |
868 | 0 | return; |
869 | 0 | } |
870 | 0 | sIdsInited = true; |
871 | 0 | } |
872 | 0 |
|
873 | 0 | static bool sPrefCachesInited = false; |
874 | 0 | if (!sPrefCachesInited && NS_IsMainThread()) { |
875 | 0 | sPrefCachesInited = true; |
876 | 0 | Preferences::AddBoolVarCache(&sMethods[1].disablers->enabled, "media.peerconnection.rtpsourcesapi.enabled"); |
877 | 0 | } |
878 | 0 |
|
879 | 0 | JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::RTCRtpReceiver); |
880 | 0 | JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::RTCRtpReceiver); |
881 | 0 | dom::CreateInterfaceObjects(aCx, aGlobal, parentProto, |
882 | 0 | &sPrototypeClass.mBase, protoCache, |
883 | 0 | nullptr, |
884 | 0 | constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr, |
885 | 0 | interfaceCache, |
886 | 0 | sNativeProperties.Upcast(), |
887 | 0 | sChromeOnlyNativeProperties.Upcast(), |
888 | 0 | "RTCRtpReceiver", aDefineOnGlobal, |
889 | 0 | nullptr, |
890 | 0 | false); |
891 | 0 | } |
892 | | |
893 | | JSObject* |
894 | | GetConstructorObject(JSContext* aCx) |
895 | 0 | { |
896 | 0 | return GetConstructorObjectHandle(aCx); |
897 | 0 | } |
898 | | |
899 | | } // namespace RTCRtpReceiver_Binding |
900 | | |
901 | | |
902 | | |
903 | | already_AddRefed<Promise> |
904 | | RTCRtpReceiverJSImpl::GetStats(ErrorResult& aRv, JS::Realm* aRealm) |
905 | 0 | { |
906 | 0 | CallSetup s(this, aRv, "RTCRtpReceiver.getStats", eRethrowContentExceptions, aRealm, /* aIsJSImplementedWebIDL = */ true); |
907 | 0 | JSContext* cx = s.GetContext(); |
908 | 0 | if (!cx) { |
909 | 0 | MOZ_ASSERT(aRv.Failed()); |
910 | 0 | return nullptr; |
911 | 0 | } |
912 | 0 | JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue()); |
913 | 0 |
|
914 | 0 | JS::Rooted<JS::Value> callable(cx); |
915 | 0 | RTCRtpReceiverAtoms* atomsCache = GetAtomCache<RTCRtpReceiverAtoms>(cx); |
916 | 0 | if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) || |
917 | 0 | !GetCallableProperty(cx, atomsCache->getStats_id, &callable)) { |
918 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
919 | 0 | return nullptr; |
920 | 0 | } |
921 | 0 | JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback)); |
922 | 0 | if (!JS::Call(cx, thisValue, callable, |
923 | 0 | JS::HandleValueArray::empty(), &rval)) { |
924 | 0 | aRv.NoteJSContextException(cx); |
925 | 0 | return nullptr; |
926 | 0 | } |
927 | 0 | RefPtr<Promise> rvalDecl; |
928 | 0 | { // Scope for our GlobalObject, FastErrorResult, JSAutoRealm, |
929 | 0 | // etc. |
930 | 0 |
|
931 | 0 | JS::Rooted<JSObject*> globalObj(cx); |
932 | 0 | if (!rval.isObject()) { |
933 | 0 | aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of RTCRtpReceiver.getStats")); |
934 | 0 | return nullptr; |
935 | 0 | } |
936 | 0 | JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject()); |
937 | 0 | if (!unwrappedVal) { |
938 | 0 | // A slight lie, but not much of one, for a dead object wrapper. |
939 | 0 | aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of RTCRtpReceiver.getStats")); |
940 | 0 | return nullptr; |
941 | 0 | } |
942 | 0 | globalObj = JS::GetNonCCWObjectGlobal(unwrappedVal); |
943 | 0 | JSAutoRealm ar(cx, globalObj); |
944 | 0 | GlobalObject promiseGlobal(cx, globalObj); |
945 | 0 | if (promiseGlobal.Failed()) { |
946 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
947 | 0 | return nullptr; |
948 | 0 | } |
949 | 0 | |
950 | 0 | JS::Rooted<JS::Value> valueToResolve(cx, rval); |
951 | 0 | if (!JS_WrapValue(cx, &valueToResolve)) { |
952 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
953 | 0 | return nullptr; |
954 | 0 | } |
955 | 0 | binding_detail::FastErrorResult promiseRv; |
956 | 0 | nsCOMPtr<nsIGlobalObject> global = |
957 | 0 | do_QueryInterface(promiseGlobal.GetAsSupports()); |
958 | 0 | if (!global) { |
959 | 0 | promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED); |
960 | 0 | MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx)); |
961 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
962 | 0 | return nullptr; |
963 | 0 | } |
964 | 0 | rvalDecl = Promise::Resolve(global, cx, valueToResolve, |
965 | 0 | promiseRv); |
966 | 0 | if (promiseRv.MaybeSetPendingException(cx)) { |
967 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
968 | 0 | return nullptr; |
969 | 0 | } |
970 | 0 | } |
971 | 0 | return rvalDecl.forget(); |
972 | 0 | } |
973 | | |
974 | | void |
975 | | RTCRtpReceiverJSImpl::GetContributingSources(nsTArray<RTCRtpContributingSource>& aRetVal, ErrorResult& aRv, JS::Realm* aRealm) |
976 | 0 | { |
977 | 0 | CallSetup s(this, aRv, "RTCRtpReceiver.getContributingSources", eRethrowContentExceptions, aRealm, /* aIsJSImplementedWebIDL = */ true); |
978 | 0 | JSContext* cx = s.GetContext(); |
979 | 0 | if (!cx) { |
980 | 0 | MOZ_ASSERT(aRv.Failed()); |
981 | 0 | return; |
982 | 0 | } |
983 | 0 | JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue()); |
984 | 0 |
|
985 | 0 | JS::Rooted<JS::Value> callable(cx); |
986 | 0 | RTCRtpReceiverAtoms* atomsCache = GetAtomCache<RTCRtpReceiverAtoms>(cx); |
987 | 0 | if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) || |
988 | 0 | !GetCallableProperty(cx, atomsCache->getContributingSources_id, &callable)) { |
989 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
990 | 0 | return; |
991 | 0 | } |
992 | 0 | JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback)); |
993 | 0 | if (!JS::Call(cx, thisValue, callable, |
994 | 0 | JS::HandleValueArray::empty(), &rval)) { |
995 | 0 | aRv.NoteJSContextException(cx); |
996 | 0 | return; |
997 | 0 | } |
998 | 0 | Sequence<RTCRtpContributingSource> rvalDecl; |
999 | 0 | if (rval.isObject()) { |
1000 | 0 | JS::ForOfIterator iter(cx); |
1001 | 0 | if (!iter.init(rval, JS::ForOfIterator::AllowNonIterable)) { |
1002 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1003 | 0 | return; |
1004 | 0 | } |
1005 | 0 | if (!iter.valueIsIterable()) { |
1006 | 0 | ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Return value of RTCRtpReceiver.getContributingSources"); |
1007 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1008 | 0 | return; |
1009 | 0 | } |
1010 | 0 | Sequence<RTCRtpContributingSource> &arr = rvalDecl; |
1011 | 0 | JS::Rooted<JS::Value> temp(cx); |
1012 | 0 | while (true) { |
1013 | 0 | bool done; |
1014 | 0 | if (!iter.next(&temp, &done)) { |
1015 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1016 | 0 | return; |
1017 | 0 | } |
1018 | 0 | if (done) { |
1019 | 0 | break; |
1020 | 0 | } |
1021 | 0 | RTCRtpContributingSource* slotPtr = arr.AppendElement(mozilla::fallible); |
1022 | 0 | if (!slotPtr) { |
1023 | 0 | JS_ReportOutOfMemory(cx); |
1024 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1025 | 0 | return; |
1026 | 0 | } |
1027 | 0 | RTCRtpContributingSource& slot = *slotPtr; |
1028 | 0 | if (!slot.Init(cx, temp, "Element of return value of RTCRtpReceiver.getContributingSources", false)) { |
1029 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1030 | 0 | return; |
1031 | 0 | } |
1032 | 0 | } |
1033 | 0 | } else { |
1034 | 0 | ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Return value of RTCRtpReceiver.getContributingSources"); |
1035 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1036 | 0 | return; |
1037 | 0 | } |
1038 | 0 | aRetVal.SwapElements(rvalDecl); |
1039 | 0 | } |
1040 | | |
1041 | | void |
1042 | | RTCRtpReceiverJSImpl::GetSynchronizationSources(nsTArray<RTCRtpSynchronizationSource>& aRetVal, ErrorResult& aRv, JS::Realm* aRealm) |
1043 | 0 | { |
1044 | 0 | CallSetup s(this, aRv, "RTCRtpReceiver.getSynchronizationSources", eRethrowContentExceptions, aRealm, /* aIsJSImplementedWebIDL = */ true); |
1045 | 0 | JSContext* cx = s.GetContext(); |
1046 | 0 | if (!cx) { |
1047 | 0 | MOZ_ASSERT(aRv.Failed()); |
1048 | 0 | return; |
1049 | 0 | } |
1050 | 0 | JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue()); |
1051 | 0 |
|
1052 | 0 | JS::Rooted<JS::Value> callable(cx); |
1053 | 0 | RTCRtpReceiverAtoms* atomsCache = GetAtomCache<RTCRtpReceiverAtoms>(cx); |
1054 | 0 | if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) || |
1055 | 0 | !GetCallableProperty(cx, atomsCache->getSynchronizationSources_id, &callable)) { |
1056 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1057 | 0 | return; |
1058 | 0 | } |
1059 | 0 | JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback)); |
1060 | 0 | if (!JS::Call(cx, thisValue, callable, |
1061 | 0 | JS::HandleValueArray::empty(), &rval)) { |
1062 | 0 | aRv.NoteJSContextException(cx); |
1063 | 0 | return; |
1064 | 0 | } |
1065 | 0 | Sequence<RTCRtpSynchronizationSource> rvalDecl; |
1066 | 0 | if (rval.isObject()) { |
1067 | 0 | JS::ForOfIterator iter(cx); |
1068 | 0 | if (!iter.init(rval, JS::ForOfIterator::AllowNonIterable)) { |
1069 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1070 | 0 | return; |
1071 | 0 | } |
1072 | 0 | if (!iter.valueIsIterable()) { |
1073 | 0 | ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Return value of RTCRtpReceiver.getSynchronizationSources"); |
1074 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1075 | 0 | return; |
1076 | 0 | } |
1077 | 0 | Sequence<RTCRtpSynchronizationSource> &arr = rvalDecl; |
1078 | 0 | JS::Rooted<JS::Value> temp(cx); |
1079 | 0 | while (true) { |
1080 | 0 | bool done; |
1081 | 0 | if (!iter.next(&temp, &done)) { |
1082 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1083 | 0 | return; |
1084 | 0 | } |
1085 | 0 | if (done) { |
1086 | 0 | break; |
1087 | 0 | } |
1088 | 0 | RTCRtpSynchronizationSource* slotPtr = arr.AppendElement(mozilla::fallible); |
1089 | 0 | if (!slotPtr) { |
1090 | 0 | JS_ReportOutOfMemory(cx); |
1091 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1092 | 0 | return; |
1093 | 0 | } |
1094 | 0 | RTCRtpSynchronizationSource& slot = *slotPtr; |
1095 | 0 | if (!slot.Init(cx, temp, "Element of return value of RTCRtpReceiver.getSynchronizationSources", false)) { |
1096 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1097 | 0 | return; |
1098 | 0 | } |
1099 | 0 | } |
1100 | 0 | } else { |
1101 | 0 | ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Return value of RTCRtpReceiver.getSynchronizationSources"); |
1102 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1103 | 0 | return; |
1104 | 0 | } |
1105 | 0 | aRetVal.SwapElements(rvalDecl); |
1106 | 0 | } |
1107 | | |
1108 | | void |
1109 | | RTCRtpReceiverJSImpl::SetStreamIds(const Sequence<nsString>& streamIds, ErrorResult& aRv, JS::Realm* aRealm) |
1110 | 0 | { |
1111 | 0 | CallSetup s(this, aRv, "RTCRtpReceiver.setStreamIds", eRethrowContentExceptions, aRealm, /* aIsJSImplementedWebIDL = */ true); |
1112 | 0 | JSContext* cx = s.GetContext(); |
1113 | 0 | if (!cx) { |
1114 | 0 | MOZ_ASSERT(aRv.Failed()); |
1115 | 0 | return; |
1116 | 0 | } |
1117 | 0 | JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue()); |
1118 | 0 | JS::AutoValueVector argv(cx); |
1119 | 0 | if (!argv.resize(1)) { |
1120 | 0 | aRv.Throw(NS_ERROR_OUT_OF_MEMORY); |
1121 | 0 | return; |
1122 | 0 | } |
1123 | 0 | unsigned argc = 1; |
1124 | 0 |
|
1125 | 0 | do { |
1126 | 0 |
|
1127 | 0 | uint32_t length = streamIds.Length(); |
1128 | 0 | JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length)); |
1129 | 0 | if (!returnArray) { |
1130 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1131 | 0 | return; |
1132 | 0 | } |
1133 | 0 | // Scope for 'tmp' |
1134 | 0 | { |
1135 | 0 | JS::Rooted<JS::Value> tmp(cx); |
1136 | 0 | for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) { |
1137 | 0 | // Control block to let us common up the JS_DefineElement calls when there |
1138 | 0 | // are different ways to succeed at wrapping the object. |
1139 | 0 | do { |
1140 | 0 | if (!xpc::NonVoidStringToJsval(cx, streamIds[sequenceIdx0], &tmp)) { |
1141 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1142 | 0 | return; |
1143 | 0 | } |
1144 | 0 | break; |
1145 | 0 | } while (false); |
1146 | 0 | if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp, |
1147 | 0 | JSPROP_ENUMERATE)) { |
1148 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1149 | 0 | return; |
1150 | 0 | } |
1151 | 0 | } |
1152 | 0 | } |
1153 | 0 | argv[0].setObject(*returnArray); |
1154 | 0 | break; |
1155 | 0 | } while (false); |
1156 | 0 |
|
1157 | 0 | JS::Rooted<JS::Value> callable(cx); |
1158 | 0 | RTCRtpReceiverAtoms* atomsCache = GetAtomCache<RTCRtpReceiverAtoms>(cx); |
1159 | 0 | if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) || |
1160 | 0 | !GetCallableProperty(cx, atomsCache->setStreamIds_id, &callable)) { |
1161 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1162 | 0 | return; |
1163 | 0 | } |
1164 | 0 | JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback)); |
1165 | 0 | if (!JS::Call(cx, thisValue, callable, |
1166 | 0 | JS::HandleValueArray::subarray(argv, 0, argc), &rval)) { |
1167 | 0 | aRv.NoteJSContextException(cx); |
1168 | 0 | return; |
1169 | 0 | } |
1170 | 0 | } |
1171 | | |
1172 | | void |
1173 | | RTCRtpReceiverJSImpl::SetRemoteSendBit(bool sendBit, ErrorResult& aRv, JS::Realm* aRealm) |
1174 | 0 | { |
1175 | 0 | CallSetup s(this, aRv, "RTCRtpReceiver.setRemoteSendBit", eRethrowContentExceptions, aRealm, /* aIsJSImplementedWebIDL = */ true); |
1176 | 0 | JSContext* cx = s.GetContext(); |
1177 | 0 | if (!cx) { |
1178 | 0 | MOZ_ASSERT(aRv.Failed()); |
1179 | 0 | return; |
1180 | 0 | } |
1181 | 0 | JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue()); |
1182 | 0 | JS::AutoValueVector argv(cx); |
1183 | 0 | if (!argv.resize(1)) { |
1184 | 0 | aRv.Throw(NS_ERROR_OUT_OF_MEMORY); |
1185 | 0 | return; |
1186 | 0 | } |
1187 | 0 | unsigned argc = 1; |
1188 | 0 |
|
1189 | 0 | do { |
1190 | 0 | argv[0].setBoolean(sendBit); |
1191 | 0 | break; |
1192 | 0 | } while (false); |
1193 | 0 |
|
1194 | 0 | JS::Rooted<JS::Value> callable(cx); |
1195 | 0 | RTCRtpReceiverAtoms* atomsCache = GetAtomCache<RTCRtpReceiverAtoms>(cx); |
1196 | 0 | if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) || |
1197 | 0 | !GetCallableProperty(cx, atomsCache->setRemoteSendBit_id, &callable)) { |
1198 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1199 | 0 | return; |
1200 | 0 | } |
1201 | 0 | JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback)); |
1202 | 0 | if (!JS::Call(cx, thisValue, callable, |
1203 | 0 | JS::HandleValueArray::subarray(argv, 0, argc), &rval)) { |
1204 | 0 | aRv.NoteJSContextException(cx); |
1205 | 0 | return; |
1206 | 0 | } |
1207 | 0 | } |
1208 | | |
1209 | | void |
1210 | | RTCRtpReceiverJSImpl::ProcessTrackAdditionsAndRemovals(RTCRtpTransceiver& transceiver, JS::Handle<JSObject*> postProcessing, ErrorResult& aRv, JS::Realm* aRealm) |
1211 | 0 | { |
1212 | 0 | CallSetup s(this, aRv, "RTCRtpReceiver.processTrackAdditionsAndRemovals", eRethrowContentExceptions, aRealm, /* aIsJSImplementedWebIDL = */ true); |
1213 | 0 | JSContext* cx = s.GetContext(); |
1214 | 0 | if (!cx) { |
1215 | 0 | MOZ_ASSERT(aRv.Failed()); |
1216 | 0 | return; |
1217 | 0 | } |
1218 | 0 | JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue()); |
1219 | 0 | JS::AutoValueVector argv(cx); |
1220 | 0 | if (!argv.resize(2)) { |
1221 | 0 | aRv.Throw(NS_ERROR_OUT_OF_MEMORY); |
1222 | 0 | return; |
1223 | 0 | } |
1224 | 0 | unsigned argc = 2; |
1225 | 0 |
|
1226 | 0 | do { |
1227 | 0 | JS::ExposeObjectToActiveJS(postProcessing); |
1228 | 0 | argv[1].setObject(*postProcessing); |
1229 | 0 | if (!MaybeWrapObjectValue(cx, argv[1])) { |
1230 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1231 | 0 | return; |
1232 | 0 | } |
1233 | 0 | break; |
1234 | 0 | } while (false); |
1235 | 0 |
|
1236 | 0 | do { |
1237 | 0 | if (!GetOrCreateDOMReflector(cx, transceiver, argv[0])) { |
1238 | 0 | MOZ_ASSERT(JS_IsExceptionPending(cx)); |
1239 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1240 | 0 | return; |
1241 | 0 | } |
1242 | 0 | break; |
1243 | 0 | } while (false); |
1244 | 0 |
|
1245 | 0 | JS::Rooted<JS::Value> callable(cx); |
1246 | 0 | RTCRtpReceiverAtoms* atomsCache = GetAtomCache<RTCRtpReceiverAtoms>(cx); |
1247 | 0 | if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) || |
1248 | 0 | !GetCallableProperty(cx, atomsCache->processTrackAdditionsAndRemovals_id, &callable)) { |
1249 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1250 | 0 | return; |
1251 | 0 | } |
1252 | 0 | JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback)); |
1253 | 0 | if (!JS::Call(cx, thisValue, callable, |
1254 | 0 | JS::HandleValueArray::subarray(argv, 0, argc), &rval)) { |
1255 | 0 | aRv.NoteJSContextException(cx); |
1256 | 0 | return; |
1257 | 0 | } |
1258 | 0 | } |
1259 | | |
1260 | | bool |
1261 | | RTCRtpReceiverJSImpl::InitIds(JSContext* cx, RTCRtpReceiverAtoms* atomsCache) |
1262 | 0 | { |
1263 | 0 | MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache)); |
1264 | 0 |
|
1265 | 0 | // Initialize these in reverse order so that any failure leaves the first one |
1266 | 0 | // uninitialized. |
1267 | 0 | if (!atomsCache->processTrackAdditionsAndRemovals_id.init(cx, "processTrackAdditionsAndRemovals") || |
1268 | 0 | !atomsCache->setRemoteSendBit_id.init(cx, "setRemoteSendBit") || |
1269 | 0 | !atomsCache->setStreamIds_id.init(cx, "setStreamIds") || |
1270 | 0 | !atomsCache->getSynchronizationSources_id.init(cx, "getSynchronizationSources") || |
1271 | 0 | !atomsCache->getContributingSources_id.init(cx, "getContributingSources") || |
1272 | 0 | !atomsCache->getStats_id.init(cx, "getStats") || |
1273 | 0 | !atomsCache->track_id.init(cx, "track")) { |
1274 | 0 | return false; |
1275 | 0 | } |
1276 | 0 | return true; |
1277 | 0 | } |
1278 | | |
1279 | | |
1280 | | already_AddRefed<MediaStreamTrack> |
1281 | | RTCRtpReceiverJSImpl::GetTrack(ErrorResult& aRv, JS::Realm* aRealm) |
1282 | 0 | { |
1283 | 0 | CallSetup s(this, aRv, "RTCRtpReceiver.track", eRethrowContentExceptions, aRealm, /* aIsJSImplementedWebIDL = */ true); |
1284 | 0 | JSContext* cx = s.GetContext(); |
1285 | 0 | if (!cx) { |
1286 | 0 | MOZ_ASSERT(aRv.Failed()); |
1287 | 0 | return nullptr; |
1288 | 0 | } |
1289 | 0 | JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue()); |
1290 | 0 |
|
1291 | 0 | JS::Rooted<JSObject *> callback(cx, mCallback); |
1292 | 0 | RTCRtpReceiverAtoms* atomsCache = GetAtomCache<RTCRtpReceiverAtoms>(cx); |
1293 | 0 | if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) || |
1294 | 0 | !JS_GetPropertyById(cx, callback, atomsCache->track_id, &rval)) { |
1295 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1296 | 0 | return nullptr; |
1297 | 0 | } |
1298 | 0 | RefPtr<mozilla::dom::MediaStreamTrack> rvalDecl; |
1299 | 0 | if (rval.isObject()) { |
1300 | 0 | static_assert(IsRefcounted<mozilla::dom::MediaStreamTrack>::value, "We can only store refcounted classes.");{ |
1301 | 0 | nsresult rv = UnwrapObject<prototypes::id::MediaStreamTrack, mozilla::dom::MediaStreamTrack>(rval, rvalDecl); |
1302 | 0 | if (NS_FAILED(rv)) { |
1303 | 0 | ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Return value of RTCRtpReceiver.track", "MediaStreamTrack"); |
1304 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1305 | 0 | return nullptr; |
1306 | 0 | } |
1307 | 0 | } |
1308 | 0 | } else { |
1309 | 0 | ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of RTCRtpReceiver.track"); |
1310 | 0 | aRv.Throw(NS_ERROR_UNEXPECTED); |
1311 | 0 | return nullptr; |
1312 | 0 | } |
1313 | 0 | return rvalDecl.forget(); |
1314 | 0 | } |
1315 | | |
1316 | | |
1317 | | NS_IMPL_CYCLE_COLLECTION_CLASS(RTCRtpReceiver) |
1318 | 0 | NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(RTCRtpReceiver) |
1319 | 0 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mImpl) |
1320 | 0 | NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent) |
1321 | 0 | NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER |
1322 | 0 | tmp->ClearWeakReferences(); |
1323 | 0 | NS_IMPL_CYCLE_COLLECTION_UNLINK_END |
1324 | 0 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(RTCRtpReceiver) |
1325 | 0 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImpl) |
1326 | 0 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent) |
1327 | 0 | NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END |
1328 | | NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(RTCRtpReceiver) |
1329 | | NS_IMPL_CYCLE_COLLECTING_ADDREF(RTCRtpReceiver) |
1330 | | NS_IMPL_CYCLE_COLLECTING_RELEASE(RTCRtpReceiver) |
1331 | 0 | NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RTCRtpReceiver) |
1332 | 0 | NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY |
1333 | 0 | NS_INTERFACE_MAP_ENTRY(nsISupports) |
1334 | 0 | NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) |
1335 | 0 | NS_INTERFACE_MAP_END |
1336 | | |
1337 | | RTCRtpReceiver::RTCRtpReceiver(JS::Handle<JSObject*> aJSImplObject, JS::Handle<JSObject*> aJSImplGlobal, nsIGlobalObject* aParent) |
1338 | | : mImpl(new RTCRtpReceiverJSImpl(nullptr, aJSImplObject, aJSImplGlobal, /* aIncumbentGlobal = */ nullptr)), |
1339 | | mParent(aParent) |
1340 | 0 | { |
1341 | 0 | } |
1342 | | |
1343 | | |
1344 | | RTCRtpReceiver::~RTCRtpReceiver() |
1345 | 0 | { |
1346 | 0 | } |
1347 | | |
1348 | | nsISupports* |
1349 | | RTCRtpReceiver::GetParentObject() const |
1350 | 0 | { |
1351 | 0 | return mParent; |
1352 | 0 | } |
1353 | | |
1354 | | JSObject* |
1355 | | RTCRtpReceiver::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) |
1356 | 0 | { |
1357 | 0 | JS::Rooted<JSObject*> obj(aCx, RTCRtpReceiver_Binding::Wrap(aCx, this, aGivenProto)); |
1358 | 0 | if (!obj) { |
1359 | 0 | return nullptr; |
1360 | 0 | } |
1361 | 0 | |
1362 | 0 | // Now define it on our chrome object |
1363 | 0 | JSAutoRealm ar(aCx, mImpl->CallbackGlobalOrNull()); |
1364 | 0 | if (!JS_WrapObject(aCx, &obj)) { |
1365 | 0 | return nullptr; |
1366 | 0 | } |
1367 | 0 | if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) { |
1368 | 0 | return nullptr; |
1369 | 0 | } |
1370 | 0 | return obj; |
1371 | 0 | } |
1372 | | |
1373 | | // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee). |
1374 | | already_AddRefed<MediaStreamTrack> |
1375 | | RTCRtpReceiver::GetTrack(ErrorResult& aRv, JS::Realm* aRealm) const |
1376 | 0 | { |
1377 | 0 | return mImpl->GetTrack(aRv, aRealm); |
1378 | 0 | } |
1379 | | |
1380 | | // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee). |
1381 | | already_AddRefed<Promise> |
1382 | | RTCRtpReceiver::GetStats(ErrorResult& aRv, JS::Realm* aRealm) |
1383 | 0 | { |
1384 | 0 | return mImpl->GetStats(aRv, aRealm); |
1385 | 0 | } |
1386 | | |
1387 | | void |
1388 | | RTCRtpReceiver::GetContributingSources(nsTArray<RTCRtpContributingSource>& aRetVal, ErrorResult& aRv, JS::Realm* aRealm) |
1389 | 0 | { |
1390 | 0 | return mImpl->GetContributingSources(aRetVal, aRv, aRealm); |
1391 | 0 | } |
1392 | | |
1393 | | void |
1394 | | RTCRtpReceiver::GetSynchronizationSources(nsTArray<RTCRtpSynchronizationSource>& aRetVal, ErrorResult& aRv, JS::Realm* aRealm) |
1395 | 0 | { |
1396 | 0 | return mImpl->GetSynchronizationSources(aRetVal, aRv, aRealm); |
1397 | 0 | } |
1398 | | |
1399 | | void |
1400 | | RTCRtpReceiver::SetStreamIds(const Sequence<nsString>& streamIds, ErrorResult& aRv, JS::Realm* aRealm) |
1401 | 0 | { |
1402 | 0 | return mImpl->SetStreamIds(streamIds, aRv, aRealm); |
1403 | 0 | } |
1404 | | |
1405 | | void |
1406 | | RTCRtpReceiver::SetRemoteSendBit(bool sendBit, ErrorResult& aRv, JS::Realm* aRealm) |
1407 | 0 | { |
1408 | 0 | return mImpl->SetRemoteSendBit(sendBit, aRv, aRealm); |
1409 | 0 | } |
1410 | | |
1411 | | void |
1412 | | RTCRtpReceiver::ProcessTrackAdditionsAndRemovals(RTCRtpTransceiver& transceiver, JS::Handle<JSObject*> postProcessing, ErrorResult& aRv, JS::Realm* aRealm) |
1413 | 0 | { |
1414 | 0 | return mImpl->ProcessTrackAdditionsAndRemovals(transceiver, postProcessing, aRv, aRealm); |
1415 | 0 | } |
1416 | | |
1417 | | bool |
1418 | | RTCRtpReceiver::_Create(JSContext* cx, unsigned argc, JS::Value* vp) |
1419 | 0 | { |
1420 | 0 | JS::CallArgs args = JS::CallArgsFromVp(argc, vp); |
1421 | 0 | if (args.length() < 2) { |
1422 | 0 | return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "RTCRtpReceiver._create"); |
1423 | 0 | } |
1424 | 0 | if (!args[0].isObject()) { |
1425 | 0 | return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of RTCRtpReceiver._create"); |
1426 | 0 | } |
1427 | 0 | if (!args[1].isObject()) { |
1428 | 0 | return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of RTCRtpReceiver._create"); |
1429 | 0 | } |
1430 | 0 | |
1431 | 0 | // GlobalObject will go through wrappers as needed for us, and |
1432 | 0 | // is simpler than the right UnwrapArg incantation. |
1433 | 0 | GlobalObject global(cx, &args[0].toObject()); |
1434 | 0 | if (global.Failed()) { |
1435 | 0 | return false; |
1436 | 0 | } |
1437 | 0 | nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports()); |
1438 | 0 | MOZ_ASSERT(globalHolder); |
1439 | 0 | JS::Rooted<JSObject*> arg(cx, &args[1].toObject()); |
1440 | 0 | JS::Rooted<JSObject*> argGlobal(cx, JS::CurrentGlobalOrNull(cx)); |
1441 | 0 | RefPtr<RTCRtpReceiver> impl = new RTCRtpReceiver(arg, argGlobal, globalHolder); |
1442 | 0 | MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx)); |
1443 | 0 | return GetOrCreateDOMReflector(cx, impl, args.rval()); |
1444 | 0 | } |
1445 | | |
1446 | | |
1447 | | } // namespace dom |
1448 | | } // namespace mozilla |