Coverage Report

Created: 2018-09-25 14:53

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