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