Coverage Report

Created: 2018-09-25 14:53

/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