Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM RTCStatsReport.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "AtomList.h"
4 : #include "RTCStatsReportBinding.h"
5 : #include "WrapperFactory.h"
6 : #include "XrayWrapper.h"
7 : #include "jsapi.h"
8 : #include "mozilla/FloatingPoint.h"
9 : #include "mozilla/OwningNonNull.h"
10 : #include "mozilla/Preferences.h"
11 : #include "mozilla/dom/BindingUtils.h"
12 : #include "mozilla/dom/DOMJSClass.h"
13 : #include "mozilla/dom/NonRefcountedDOMObject.h"
14 : #include "mozilla/dom/PrimitiveConversions.h"
15 : #include "mozilla/dom/ScriptSettings.h"
16 : #include "mozilla/dom/SimpleGlobalObject.h"
17 : #include "mozilla/dom/ToJSValue.h"
18 : #include "mozilla/dom/XrayExpandoClass.h"
19 : #include "nsContentUtils.h"
20 : #include "nsIGlobalObject.h"
21 :
22 : namespace mozilla {
23 : namespace dom {
24 :
25 : namespace RTCStatsTypeValues {
26 : extern const EnumEntry strings[10] = {
27 : {"inbound-rtp", 11},
28 : {"outbound-rtp", 12},
29 : {"csrc", 4},
30 : {"session", 7},
31 : {"track", 5},
32 : {"transport", 9},
33 : {"candidate-pair", 14},
34 : {"local-candidate", 15},
35 : {"remote-candidate", 16},
36 : { nullptr, 0 }
37 : };
38 : } // namespace RTCStatsTypeValues
39 :
40 : bool
41 0 : ToJSValue(JSContext* aCx, RTCStatsType aArgument, JS::MutableHandle<JS::Value> aValue)
42 : {
43 0 : MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(RTCStatsTypeValues::strings));
44 : JSString* resultStr =
45 0 : JS_NewStringCopyN(aCx, RTCStatsTypeValues::strings[uint32_t(aArgument)].value,
46 0 : RTCStatsTypeValues::strings[uint32_t(aArgument)].length);
47 0 : if (!resultStr) {
48 0 : return false;
49 : }
50 0 : aValue.setString(resultStr);
51 0 : return true;
52 : }
53 :
54 :
55 : namespace RTCStatsIceCandidatePairStateValues {
56 : extern const EnumEntry strings[7] = {
57 : {"frozen", 6},
58 : {"waiting", 7},
59 : {"inprogress", 10},
60 : {"failed", 6},
61 : {"succeeded", 9},
62 : {"cancelled", 9},
63 : { nullptr, 0 }
64 : };
65 : } // namespace RTCStatsIceCandidatePairStateValues
66 :
67 : bool
68 0 : ToJSValue(JSContext* aCx, RTCStatsIceCandidatePairState aArgument, JS::MutableHandle<JS::Value> aValue)
69 : {
70 0 : MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(RTCStatsIceCandidatePairStateValues::strings));
71 : JSString* resultStr =
72 0 : JS_NewStringCopyN(aCx, RTCStatsIceCandidatePairStateValues::strings[uint32_t(aArgument)].value,
73 0 : RTCStatsIceCandidatePairStateValues::strings[uint32_t(aArgument)].length);
74 0 : if (!resultStr) {
75 0 : return false;
76 : }
77 0 : aValue.setString(resultStr);
78 0 : return true;
79 : }
80 :
81 :
82 : namespace RTCStatsIceCandidateTypeValues {
83 : extern const EnumEntry strings[5] = {
84 : {"host", 4},
85 : {"serverreflexive", 15},
86 : {"peerreflexive", 13},
87 : {"relayed", 7},
88 : { nullptr, 0 }
89 : };
90 : } // namespace RTCStatsIceCandidateTypeValues
91 :
92 : bool
93 0 : ToJSValue(JSContext* aCx, RTCStatsIceCandidateType aArgument, JS::MutableHandle<JS::Value> aValue)
94 : {
95 0 : MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(RTCStatsIceCandidateTypeValues::strings));
96 : JSString* resultStr =
97 0 : JS_NewStringCopyN(aCx, RTCStatsIceCandidateTypeValues::strings[uint32_t(aArgument)].value,
98 0 : RTCStatsIceCandidateTypeValues::strings[uint32_t(aArgument)].length);
99 0 : if (!resultStr) {
100 0 : return false;
101 : }
102 0 : aValue.setString(resultStr);
103 0 : return true;
104 : }
105 :
106 :
107 :
108 0 : RTCStats::RTCStats()
109 : {
110 : // Safe to pass a null context if we pass a null value
111 0 : Init(nullptr, JS::NullHandleValue);
112 0 : }
113 :
114 :
115 :
116 : bool
117 0 : RTCStats::InitIds(JSContext* cx, RTCStatsAtoms* atomsCache)
118 : {
119 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
120 :
121 : // Initialize these in reverse order so that any failure leaves the first one
122 : // uninitialized.
123 0 : if (!atomsCache->type_id.init(cx, "type") ||
124 0 : !atomsCache->timestamp_id.init(cx, "timestamp") ||
125 0 : !atomsCache->id_id.init(cx, "id")) {
126 0 : return false;
127 : }
128 0 : return true;
129 : }
130 :
131 : bool
132 0 : RTCStats::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
133 : {
134 : // Passing a null JSContext is OK only if we're initing from null,
135 : // Since in that case we will not have to do any property gets
136 : // Also evaluate isNullOrUndefined in order to avoid false-positive
137 : // checkers by static analysis tools
138 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
139 0 : RTCStatsAtoms* atomsCache = nullptr;
140 0 : if (cx) {
141 0 : atomsCache = GetAtomCache<RTCStatsAtoms>(cx);
142 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
143 0 : return false;
144 : }
145 : }
146 :
147 0 : if (!IsConvertibleToDictionary(val)) {
148 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
149 : }
150 :
151 0 : bool isNull = val.isNullOrUndefined();
152 : // We only need these if !isNull, in which case we have |cx|.
153 0 : Maybe<JS::Rooted<JSObject *> > object;
154 0 : Maybe<JS::Rooted<JS::Value> > temp;
155 0 : if (!isNull) {
156 0 : MOZ_ASSERT(cx);
157 0 : object.emplace(cx, &val.toObject());
158 0 : temp.emplace(cx);
159 : }
160 0 : if (!isNull) {
161 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->id_id, temp.ptr())) {
162 0 : return false;
163 : }
164 : }
165 0 : if (!isNull && !temp->isUndefined()) {
166 0 : mId.Construct();
167 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mId.Value()))) {
168 0 : return false;
169 : }
170 0 : mIsAnyMemberPresent = true;
171 : }
172 :
173 0 : if (!isNull) {
174 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->timestamp_id, temp.ptr())) {
175 0 : return false;
176 : }
177 : }
178 0 : if (!isNull && !temp->isUndefined()) {
179 0 : mTimestamp.Construct();
180 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &(mTimestamp.Value()))) {
181 0 : return false;
182 0 : } else if (!mozilla::IsFinite((mTimestamp.Value()))) {
183 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'timestamp' member of RTCStats");
184 0 : return false;
185 : }
186 0 : mIsAnyMemberPresent = true;
187 : }
188 :
189 0 : if (!isNull) {
190 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->type_id, temp.ptr())) {
191 0 : return false;
192 : }
193 : }
194 0 : if (!isNull && !temp->isUndefined()) {
195 0 : mType.Construct();
196 : {
197 : int index;
198 0 : if (!FindEnumStringIndex<true>(cx, temp.ref(), RTCStatsTypeValues::strings, "RTCStatsType", "'type' member of RTCStats", &index)) {
199 0 : return false;
200 : }
201 0 : MOZ_ASSERT(index >= 0);
202 0 : (mType.Value()) = static_cast<RTCStatsType>(index);
203 : }
204 0 : mIsAnyMemberPresent = true;
205 : }
206 0 : return true;
207 : }
208 :
209 : bool
210 0 : RTCStats::Init(const nsAString& aJSON)
211 : {
212 0 : AutoJSAPI jsapi;
213 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
214 0 : if (!cleanGlobal) {
215 0 : return false;
216 : }
217 0 : if (!jsapi.Init(cleanGlobal)) {
218 0 : return false;
219 : }
220 0 : JSContext* cx = jsapi.cx();
221 0 : JS::Rooted<JS::Value> json(cx);
222 0 : bool ok = ParseJSON(cx, aJSON, &json);
223 0 : NS_ENSURE_TRUE(ok, false);
224 0 : return Init(cx, json);
225 : }
226 :
227 : bool
228 0 : RTCStats::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
229 : {
230 0 : RTCStatsAtoms* atomsCache = GetAtomCache<RTCStatsAtoms>(cx);
231 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
232 0 : return false;
233 : }
234 :
235 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
236 0 : if (!obj) {
237 0 : return false;
238 : }
239 0 : rval.set(JS::ObjectValue(*obj));
240 :
241 0 : if (mId.WasPassed()) {
242 : do {
243 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
244 0 : JS::Rooted<JS::Value> temp(cx);
245 0 : nsString const & currentValue = mId.InternalValue();
246 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
247 0 : return false;
248 : }
249 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->id_id, temp, JSPROP_ENUMERATE)) {
250 0 : return false;
251 : }
252 0 : break;
253 : } while(0);
254 : }
255 :
256 0 : if (mTimestamp.WasPassed()) {
257 : do {
258 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
259 0 : JS::Rooted<JS::Value> temp(cx);
260 0 : double const & currentValue = mTimestamp.InternalValue();
261 0 : temp.set(JS_NumberValue(double(currentValue)));
262 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->timestamp_id, temp, JSPROP_ENUMERATE)) {
263 0 : return false;
264 : }
265 0 : break;
266 : } while(0);
267 : }
268 :
269 0 : if (mType.WasPassed()) {
270 : do {
271 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
272 0 : JS::Rooted<JS::Value> temp(cx);
273 0 : RTCStatsType const & currentValue = mType.InternalValue();
274 0 : if (!ToJSValue(cx, currentValue, &temp)) {
275 0 : return false;
276 : }
277 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->type_id, temp, JSPROP_ENUMERATE)) {
278 0 : return false;
279 : }
280 0 : break;
281 : } while(0);
282 : }
283 :
284 0 : return true;
285 : }
286 :
287 : bool
288 0 : RTCStats::ToJSON(nsAString& aJSON) const
289 : {
290 0 : AutoJSAPI jsapi;
291 0 : jsapi.Init();
292 0 : JSContext *cx = jsapi.cx();
293 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
294 : // because we'll only be creating objects, in ways that have no
295 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
296 : // which likewise guarantees no side-effects for the sorts of
297 : // things we will pass it.
298 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
299 0 : JS::Rooted<JS::Value> val(cx);
300 0 : if (!ToObjectInternal(cx, &val)) {
301 0 : return false;
302 : }
303 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
304 0 : return StringifyToJSON(cx, obj, aJSON);
305 : }
306 :
307 : void
308 0 : RTCStats::TraceDictionary(JSTracer* trc)
309 : {
310 0 : }
311 :
312 : RTCStats&
313 0 : RTCStats::operator=(const RTCStats& aOther)
314 : {
315 0 : mId.Reset();
316 0 : if (aOther.mId.WasPassed()) {
317 0 : mId.Construct(aOther.mId.Value());
318 : }
319 0 : mTimestamp.Reset();
320 0 : if (aOther.mTimestamp.WasPassed()) {
321 0 : mTimestamp.Construct(aOther.mTimestamp.Value());
322 : }
323 0 : mType.Reset();
324 0 : if (aOther.mType.WasPassed()) {
325 0 : mType.Construct(aOther.mType.Value());
326 : }
327 0 : return *this;
328 : }
329 :
330 : namespace binding_detail {
331 : } // namespace binding_detail
332 :
333 :
334 :
335 0 : RTCCodecStats::RTCCodecStats()
336 0 : : RTCStats(FastDictionaryInitializer())
337 : {
338 : // Safe to pass a null context if we pass a null value
339 0 : Init(nullptr, JS::NullHandleValue);
340 0 : }
341 :
342 :
343 :
344 : bool
345 0 : RTCCodecStats::InitIds(JSContext* cx, RTCCodecStatsAtoms* atomsCache)
346 : {
347 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
348 :
349 : // Initialize these in reverse order so that any failure leaves the first one
350 : // uninitialized.
351 0 : if (!atomsCache->payloadType_id.init(cx, "payloadType") ||
352 0 : !atomsCache->parameters_id.init(cx, "parameters") ||
353 0 : !atomsCache->codec_id.init(cx, "codec") ||
354 0 : !atomsCache->clockRate_id.init(cx, "clockRate") ||
355 0 : !atomsCache->channels_id.init(cx, "channels")) {
356 0 : return false;
357 : }
358 0 : return true;
359 : }
360 :
361 : bool
362 0 : RTCCodecStats::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
363 : {
364 : // Passing a null JSContext is OK only if we're initing from null,
365 : // Since in that case we will not have to do any property gets
366 : // Also evaluate isNullOrUndefined in order to avoid false-positive
367 : // checkers by static analysis tools
368 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
369 0 : RTCCodecStatsAtoms* atomsCache = nullptr;
370 0 : if (cx) {
371 0 : atomsCache = GetAtomCache<RTCCodecStatsAtoms>(cx);
372 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
373 0 : return false;
374 : }
375 : }
376 :
377 : // Per spec, we init the parent's members first
378 0 : if (!RTCStats::Init(cx, val)) {
379 0 : return false;
380 : }
381 :
382 0 : bool isNull = val.isNullOrUndefined();
383 : // We only need these if !isNull, in which case we have |cx|.
384 0 : Maybe<JS::Rooted<JSObject *> > object;
385 0 : Maybe<JS::Rooted<JS::Value> > temp;
386 0 : if (!isNull) {
387 0 : MOZ_ASSERT(cx);
388 0 : object.emplace(cx, &val.toObject());
389 0 : temp.emplace(cx);
390 : }
391 0 : if (!isNull) {
392 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->channels_id, temp.ptr())) {
393 0 : return false;
394 : }
395 : }
396 0 : if (!isNull && !temp->isUndefined()) {
397 0 : mChannels.Construct();
398 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mChannels.Value()))) {
399 0 : return false;
400 : }
401 0 : mIsAnyMemberPresent = true;
402 : }
403 :
404 0 : if (!isNull) {
405 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->clockRate_id, temp.ptr())) {
406 0 : return false;
407 : }
408 : }
409 0 : if (!isNull && !temp->isUndefined()) {
410 0 : mClockRate.Construct();
411 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mClockRate.Value()))) {
412 0 : return false;
413 : }
414 0 : mIsAnyMemberPresent = true;
415 : }
416 :
417 0 : if (!isNull) {
418 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->codec_id, temp.ptr())) {
419 0 : return false;
420 : }
421 : }
422 0 : if (!isNull && !temp->isUndefined()) {
423 0 : mCodec.Construct();
424 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mCodec.Value()))) {
425 0 : return false;
426 : }
427 0 : mIsAnyMemberPresent = true;
428 : }
429 :
430 0 : if (!isNull) {
431 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->parameters_id, temp.ptr())) {
432 0 : return false;
433 : }
434 : }
435 0 : if (!isNull && !temp->isUndefined()) {
436 0 : mParameters.Construct();
437 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mParameters.Value()))) {
438 0 : return false;
439 : }
440 0 : mIsAnyMemberPresent = true;
441 : }
442 :
443 0 : if (!isNull) {
444 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->payloadType_id, temp.ptr())) {
445 0 : return false;
446 : }
447 : }
448 0 : if (!isNull && !temp->isUndefined()) {
449 0 : mPayloadType.Construct();
450 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mPayloadType.Value()))) {
451 0 : return false;
452 : }
453 0 : mIsAnyMemberPresent = true;
454 : }
455 0 : return true;
456 : }
457 :
458 : bool
459 0 : RTCCodecStats::Init(const nsAString& aJSON)
460 : {
461 0 : AutoJSAPI jsapi;
462 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
463 0 : if (!cleanGlobal) {
464 0 : return false;
465 : }
466 0 : if (!jsapi.Init(cleanGlobal)) {
467 0 : return false;
468 : }
469 0 : JSContext* cx = jsapi.cx();
470 0 : JS::Rooted<JS::Value> json(cx);
471 0 : bool ok = ParseJSON(cx, aJSON, &json);
472 0 : NS_ENSURE_TRUE(ok, false);
473 0 : return Init(cx, json);
474 : }
475 :
476 : bool
477 0 : RTCCodecStats::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
478 : {
479 0 : RTCCodecStatsAtoms* atomsCache = GetAtomCache<RTCCodecStatsAtoms>(cx);
480 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
481 0 : return false;
482 : }
483 :
484 : // Per spec, we define the parent's members first
485 0 : if (!RTCStats::ToObjectInternal(cx, rval)) {
486 0 : return false;
487 : }
488 0 : JS::Rooted<JSObject*> obj(cx, &rval.toObject());
489 :
490 0 : if (mChannels.WasPassed()) {
491 : do {
492 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
493 0 : JS::Rooted<JS::Value> temp(cx);
494 0 : uint32_t const & currentValue = mChannels.InternalValue();
495 0 : temp.setNumber(currentValue);
496 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->channels_id, temp, JSPROP_ENUMERATE)) {
497 0 : return false;
498 : }
499 0 : break;
500 : } while(0);
501 : }
502 :
503 0 : if (mClockRate.WasPassed()) {
504 : do {
505 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
506 0 : JS::Rooted<JS::Value> temp(cx);
507 0 : uint32_t const & currentValue = mClockRate.InternalValue();
508 0 : temp.setNumber(currentValue);
509 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->clockRate_id, temp, JSPROP_ENUMERATE)) {
510 0 : return false;
511 : }
512 0 : break;
513 : } while(0);
514 : }
515 :
516 0 : if (mCodec.WasPassed()) {
517 : do {
518 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
519 0 : JS::Rooted<JS::Value> temp(cx);
520 0 : nsString const & currentValue = mCodec.InternalValue();
521 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
522 0 : return false;
523 : }
524 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->codec_id, temp, JSPROP_ENUMERATE)) {
525 0 : return false;
526 : }
527 0 : break;
528 : } while(0);
529 : }
530 :
531 0 : if (mParameters.WasPassed()) {
532 : do {
533 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
534 0 : JS::Rooted<JS::Value> temp(cx);
535 0 : nsString const & currentValue = mParameters.InternalValue();
536 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
537 0 : return false;
538 : }
539 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->parameters_id, temp, JSPROP_ENUMERATE)) {
540 0 : return false;
541 : }
542 0 : break;
543 : } while(0);
544 : }
545 :
546 0 : if (mPayloadType.WasPassed()) {
547 : do {
548 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
549 0 : JS::Rooted<JS::Value> temp(cx);
550 0 : uint32_t const & currentValue = mPayloadType.InternalValue();
551 0 : temp.setNumber(currentValue);
552 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->payloadType_id, temp, JSPROP_ENUMERATE)) {
553 0 : return false;
554 : }
555 0 : break;
556 : } while(0);
557 : }
558 :
559 0 : return true;
560 : }
561 :
562 : bool
563 0 : RTCCodecStats::ToJSON(nsAString& aJSON) const
564 : {
565 0 : AutoJSAPI jsapi;
566 0 : jsapi.Init();
567 0 : JSContext *cx = jsapi.cx();
568 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
569 : // because we'll only be creating objects, in ways that have no
570 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
571 : // which likewise guarantees no side-effects for the sorts of
572 : // things we will pass it.
573 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
574 0 : JS::Rooted<JS::Value> val(cx);
575 0 : if (!ToObjectInternal(cx, &val)) {
576 0 : return false;
577 : }
578 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
579 0 : return StringifyToJSON(cx, obj, aJSON);
580 : }
581 :
582 : void
583 0 : RTCCodecStats::TraceDictionary(JSTracer* trc)
584 : {
585 0 : RTCStats::TraceDictionary(trc);
586 0 : }
587 :
588 : RTCCodecStats&
589 0 : RTCCodecStats::operator=(const RTCCodecStats& aOther)
590 : {
591 0 : RTCStats::operator=(aOther);
592 0 : mChannels.Reset();
593 0 : if (aOther.mChannels.WasPassed()) {
594 0 : mChannels.Construct(aOther.mChannels.Value());
595 : }
596 0 : mClockRate.Reset();
597 0 : if (aOther.mClockRate.WasPassed()) {
598 0 : mClockRate.Construct(aOther.mClockRate.Value());
599 : }
600 0 : mCodec.Reset();
601 0 : if (aOther.mCodec.WasPassed()) {
602 0 : mCodec.Construct(aOther.mCodec.Value());
603 : }
604 0 : mParameters.Reset();
605 0 : if (aOther.mParameters.WasPassed()) {
606 0 : mParameters.Construct(aOther.mParameters.Value());
607 : }
608 0 : mPayloadType.Reset();
609 0 : if (aOther.mPayloadType.WasPassed()) {
610 0 : mPayloadType.Construct(aOther.mPayloadType.Value());
611 : }
612 0 : return *this;
613 : }
614 :
615 : namespace binding_detail {
616 : } // namespace binding_detail
617 :
618 :
619 :
620 0 : RTCIceCandidatePairStats::RTCIceCandidatePairStats()
621 0 : : RTCStats(FastDictionaryInitializer())
622 : {
623 : // Safe to pass a null context if we pass a null value
624 0 : Init(nullptr, JS::NullHandleValue);
625 0 : }
626 :
627 :
628 :
629 : bool
630 0 : RTCIceCandidatePairStats::InitIds(JSContext* cx, RTCIceCandidatePairStatsAtoms* atomsCache)
631 : {
632 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
633 :
634 : // Initialize these in reverse order so that any failure leaves the first one
635 : // uninitialized.
636 0 : if (!atomsCache->writable_id.init(cx, "writable") ||
637 0 : !atomsCache->transportId_id.init(cx, "transportId") ||
638 0 : !atomsCache->state_id.init(cx, "state") ||
639 0 : !atomsCache->selected_id.init(cx, "selected") ||
640 0 : !atomsCache->remoteCandidateId_id.init(cx, "remoteCandidateId") ||
641 0 : !atomsCache->readable_id.init(cx, "readable") ||
642 0 : !atomsCache->priority_id.init(cx, "priority") ||
643 0 : !atomsCache->nominated_id.init(cx, "nominated") ||
644 0 : !atomsCache->localCandidateId_id.init(cx, "localCandidateId") ||
645 0 : !atomsCache->lastPacketSentTimestamp_id.init(cx, "lastPacketSentTimestamp") ||
646 0 : !atomsCache->lastPacketReceivedTimestamp_id.init(cx, "lastPacketReceivedTimestamp") ||
647 0 : !atomsCache->bytesSent_id.init(cx, "bytesSent") ||
648 0 : !atomsCache->bytesReceived_id.init(cx, "bytesReceived")) {
649 0 : return false;
650 : }
651 0 : return true;
652 : }
653 :
654 : bool
655 0 : RTCIceCandidatePairStats::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
656 : {
657 : // Passing a null JSContext is OK only if we're initing from null,
658 : // Since in that case we will not have to do any property gets
659 : // Also evaluate isNullOrUndefined in order to avoid false-positive
660 : // checkers by static analysis tools
661 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
662 0 : RTCIceCandidatePairStatsAtoms* atomsCache = nullptr;
663 0 : if (cx) {
664 0 : atomsCache = GetAtomCache<RTCIceCandidatePairStatsAtoms>(cx);
665 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
666 0 : return false;
667 : }
668 : }
669 :
670 : // Per spec, we init the parent's members first
671 0 : if (!RTCStats::Init(cx, val)) {
672 0 : return false;
673 : }
674 :
675 0 : bool isNull = val.isNullOrUndefined();
676 : // We only need these if !isNull, in which case we have |cx|.
677 0 : Maybe<JS::Rooted<JSObject *> > object;
678 0 : Maybe<JS::Rooted<JS::Value> > temp;
679 0 : if (!isNull) {
680 0 : MOZ_ASSERT(cx);
681 0 : object.emplace(cx, &val.toObject());
682 0 : temp.emplace(cx);
683 : }
684 0 : if (!isNull) {
685 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->bytesReceived_id, temp.ptr())) {
686 0 : return false;
687 : }
688 : }
689 0 : if (!isNull && !temp->isUndefined()) {
690 0 : mBytesReceived.Construct();
691 0 : if (!ValueToPrimitive<uint64_t, eDefault>(cx, temp.ref(), &(mBytesReceived.Value()))) {
692 0 : return false;
693 : }
694 0 : mIsAnyMemberPresent = true;
695 : }
696 :
697 0 : if (!isNull) {
698 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->bytesSent_id, temp.ptr())) {
699 0 : return false;
700 : }
701 : }
702 0 : if (!isNull && !temp->isUndefined()) {
703 0 : mBytesSent.Construct();
704 0 : if (!ValueToPrimitive<uint64_t, eDefault>(cx, temp.ref(), &(mBytesSent.Value()))) {
705 0 : return false;
706 : }
707 0 : mIsAnyMemberPresent = true;
708 : }
709 :
710 0 : if (!isNull) {
711 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->lastPacketReceivedTimestamp_id, temp.ptr())) {
712 0 : return false;
713 : }
714 : }
715 0 : if (!isNull && !temp->isUndefined()) {
716 0 : mLastPacketReceivedTimestamp.Construct();
717 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &(mLastPacketReceivedTimestamp.Value()))) {
718 0 : return false;
719 0 : } else if (!mozilla::IsFinite((mLastPacketReceivedTimestamp.Value()))) {
720 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'lastPacketReceivedTimestamp' member of RTCIceCandidatePairStats");
721 0 : return false;
722 : }
723 0 : mIsAnyMemberPresent = true;
724 : }
725 :
726 0 : if (!isNull) {
727 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->lastPacketSentTimestamp_id, temp.ptr())) {
728 0 : return false;
729 : }
730 : }
731 0 : if (!isNull && !temp->isUndefined()) {
732 0 : mLastPacketSentTimestamp.Construct();
733 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &(mLastPacketSentTimestamp.Value()))) {
734 0 : return false;
735 0 : } else if (!mozilla::IsFinite((mLastPacketSentTimestamp.Value()))) {
736 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'lastPacketSentTimestamp' member of RTCIceCandidatePairStats");
737 0 : return false;
738 : }
739 0 : mIsAnyMemberPresent = true;
740 : }
741 :
742 0 : if (!isNull) {
743 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->localCandidateId_id, temp.ptr())) {
744 0 : return false;
745 : }
746 : }
747 0 : if (!isNull && !temp->isUndefined()) {
748 0 : mLocalCandidateId.Construct();
749 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mLocalCandidateId.Value()))) {
750 0 : return false;
751 : }
752 0 : mIsAnyMemberPresent = true;
753 : }
754 :
755 0 : if (!isNull) {
756 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->nominated_id, temp.ptr())) {
757 0 : return false;
758 : }
759 : }
760 0 : if (!isNull && !temp->isUndefined()) {
761 0 : mNominated.Construct();
762 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &(mNominated.Value()))) {
763 0 : return false;
764 : }
765 0 : mIsAnyMemberPresent = true;
766 : }
767 :
768 0 : if (!isNull) {
769 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->priority_id, temp.ptr())) {
770 0 : return false;
771 : }
772 : }
773 0 : if (!isNull && !temp->isUndefined()) {
774 0 : mPriority.Construct();
775 0 : if (!ValueToPrimitive<uint64_t, eDefault>(cx, temp.ref(), &(mPriority.Value()))) {
776 0 : return false;
777 : }
778 0 : mIsAnyMemberPresent = true;
779 : }
780 :
781 0 : if (!isNull) {
782 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->readable_id, temp.ptr())) {
783 0 : return false;
784 : }
785 : }
786 0 : if (!isNull && !temp->isUndefined()) {
787 0 : mReadable.Construct();
788 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &(mReadable.Value()))) {
789 0 : return false;
790 : }
791 0 : mIsAnyMemberPresent = true;
792 : }
793 :
794 0 : if (!isNull) {
795 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->remoteCandidateId_id, temp.ptr())) {
796 0 : return false;
797 : }
798 : }
799 0 : if (!isNull && !temp->isUndefined()) {
800 0 : mRemoteCandidateId.Construct();
801 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mRemoteCandidateId.Value()))) {
802 0 : return false;
803 : }
804 0 : mIsAnyMemberPresent = true;
805 : }
806 :
807 0 : if (!isNull) {
808 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->selected_id, temp.ptr())) {
809 0 : return false;
810 : }
811 : }
812 0 : if (!isNull && !temp->isUndefined()) {
813 0 : mSelected.Construct();
814 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &(mSelected.Value()))) {
815 0 : return false;
816 : }
817 0 : mIsAnyMemberPresent = true;
818 : }
819 :
820 0 : if (!isNull) {
821 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->state_id, temp.ptr())) {
822 0 : return false;
823 : }
824 : }
825 0 : if (!isNull && !temp->isUndefined()) {
826 0 : mState.Construct();
827 : {
828 : int index;
829 0 : if (!FindEnumStringIndex<true>(cx, temp.ref(), RTCStatsIceCandidatePairStateValues::strings, "RTCStatsIceCandidatePairState", "'state' member of RTCIceCandidatePairStats", &index)) {
830 0 : return false;
831 : }
832 0 : MOZ_ASSERT(index >= 0);
833 0 : (mState.Value()) = static_cast<RTCStatsIceCandidatePairState>(index);
834 : }
835 0 : mIsAnyMemberPresent = true;
836 : }
837 :
838 0 : if (!isNull) {
839 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->transportId_id, temp.ptr())) {
840 0 : return false;
841 : }
842 : }
843 0 : if (!isNull && !temp->isUndefined()) {
844 0 : mTransportId.Construct();
845 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mTransportId.Value()))) {
846 0 : return false;
847 : }
848 0 : mIsAnyMemberPresent = true;
849 : }
850 :
851 0 : if (!isNull) {
852 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->writable_id, temp.ptr())) {
853 0 : return false;
854 : }
855 : }
856 0 : if (!isNull && !temp->isUndefined()) {
857 0 : mWritable.Construct();
858 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &(mWritable.Value()))) {
859 0 : return false;
860 : }
861 0 : mIsAnyMemberPresent = true;
862 : }
863 0 : return true;
864 : }
865 :
866 : bool
867 0 : RTCIceCandidatePairStats::Init(const nsAString& aJSON)
868 : {
869 0 : AutoJSAPI jsapi;
870 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
871 0 : if (!cleanGlobal) {
872 0 : return false;
873 : }
874 0 : if (!jsapi.Init(cleanGlobal)) {
875 0 : return false;
876 : }
877 0 : JSContext* cx = jsapi.cx();
878 0 : JS::Rooted<JS::Value> json(cx);
879 0 : bool ok = ParseJSON(cx, aJSON, &json);
880 0 : NS_ENSURE_TRUE(ok, false);
881 0 : return Init(cx, json);
882 : }
883 :
884 : bool
885 0 : RTCIceCandidatePairStats::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
886 : {
887 0 : RTCIceCandidatePairStatsAtoms* atomsCache = GetAtomCache<RTCIceCandidatePairStatsAtoms>(cx);
888 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
889 0 : return false;
890 : }
891 :
892 : // Per spec, we define the parent's members first
893 0 : if (!RTCStats::ToObjectInternal(cx, rval)) {
894 0 : return false;
895 : }
896 0 : JS::Rooted<JSObject*> obj(cx, &rval.toObject());
897 :
898 0 : if (mBytesReceived.WasPassed()) {
899 : do {
900 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
901 0 : JS::Rooted<JS::Value> temp(cx);
902 0 : uint64_t const & currentValue = mBytesReceived.InternalValue();
903 0 : temp.set(JS_NumberValue(double(currentValue)));
904 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->bytesReceived_id, temp, JSPROP_ENUMERATE)) {
905 0 : return false;
906 : }
907 0 : break;
908 : } while(0);
909 : }
910 :
911 0 : if (mBytesSent.WasPassed()) {
912 : do {
913 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
914 0 : JS::Rooted<JS::Value> temp(cx);
915 0 : uint64_t const & currentValue = mBytesSent.InternalValue();
916 0 : temp.set(JS_NumberValue(double(currentValue)));
917 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->bytesSent_id, temp, JSPROP_ENUMERATE)) {
918 0 : return false;
919 : }
920 0 : break;
921 : } while(0);
922 : }
923 :
924 0 : if (mLastPacketReceivedTimestamp.WasPassed()) {
925 : do {
926 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
927 0 : JS::Rooted<JS::Value> temp(cx);
928 0 : double const & currentValue = mLastPacketReceivedTimestamp.InternalValue();
929 0 : temp.set(JS_NumberValue(double(currentValue)));
930 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->lastPacketReceivedTimestamp_id, temp, JSPROP_ENUMERATE)) {
931 0 : return false;
932 : }
933 0 : break;
934 : } while(0);
935 : }
936 :
937 0 : if (mLastPacketSentTimestamp.WasPassed()) {
938 : do {
939 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
940 0 : JS::Rooted<JS::Value> temp(cx);
941 0 : double const & currentValue = mLastPacketSentTimestamp.InternalValue();
942 0 : temp.set(JS_NumberValue(double(currentValue)));
943 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->lastPacketSentTimestamp_id, temp, JSPROP_ENUMERATE)) {
944 0 : return false;
945 : }
946 0 : break;
947 : } while(0);
948 : }
949 :
950 0 : if (mLocalCandidateId.WasPassed()) {
951 : do {
952 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
953 0 : JS::Rooted<JS::Value> temp(cx);
954 0 : nsString const & currentValue = mLocalCandidateId.InternalValue();
955 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
956 0 : return false;
957 : }
958 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->localCandidateId_id, temp, JSPROP_ENUMERATE)) {
959 0 : return false;
960 : }
961 0 : break;
962 : } while(0);
963 : }
964 :
965 0 : if (mNominated.WasPassed()) {
966 : do {
967 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
968 0 : JS::Rooted<JS::Value> temp(cx);
969 0 : bool const & currentValue = mNominated.InternalValue();
970 0 : temp.setBoolean(currentValue);
971 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->nominated_id, temp, JSPROP_ENUMERATE)) {
972 0 : return false;
973 : }
974 0 : break;
975 : } while(0);
976 : }
977 :
978 0 : if (mPriority.WasPassed()) {
979 : do {
980 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
981 0 : JS::Rooted<JS::Value> temp(cx);
982 0 : uint64_t const & currentValue = mPriority.InternalValue();
983 0 : temp.set(JS_NumberValue(double(currentValue)));
984 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->priority_id, temp, JSPROP_ENUMERATE)) {
985 0 : return false;
986 : }
987 0 : break;
988 : } while(0);
989 : }
990 :
991 0 : if (mReadable.WasPassed()) {
992 : do {
993 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
994 0 : JS::Rooted<JS::Value> temp(cx);
995 0 : bool const & currentValue = mReadable.InternalValue();
996 0 : temp.setBoolean(currentValue);
997 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->readable_id, temp, JSPROP_ENUMERATE)) {
998 0 : return false;
999 : }
1000 0 : break;
1001 : } while(0);
1002 : }
1003 :
1004 0 : if (mRemoteCandidateId.WasPassed()) {
1005 : do {
1006 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1007 0 : JS::Rooted<JS::Value> temp(cx);
1008 0 : nsString const & currentValue = mRemoteCandidateId.InternalValue();
1009 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1010 0 : return false;
1011 : }
1012 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->remoteCandidateId_id, temp, JSPROP_ENUMERATE)) {
1013 0 : return false;
1014 : }
1015 0 : break;
1016 : } while(0);
1017 : }
1018 :
1019 0 : if (mSelected.WasPassed()) {
1020 : do {
1021 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1022 0 : JS::Rooted<JS::Value> temp(cx);
1023 0 : bool const & currentValue = mSelected.InternalValue();
1024 0 : temp.setBoolean(currentValue);
1025 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->selected_id, temp, JSPROP_ENUMERATE)) {
1026 0 : return false;
1027 : }
1028 0 : break;
1029 : } while(0);
1030 : }
1031 :
1032 0 : if (mState.WasPassed()) {
1033 : do {
1034 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1035 0 : JS::Rooted<JS::Value> temp(cx);
1036 0 : RTCStatsIceCandidatePairState const & currentValue = mState.InternalValue();
1037 0 : if (!ToJSValue(cx, currentValue, &temp)) {
1038 0 : return false;
1039 : }
1040 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->state_id, temp, JSPROP_ENUMERATE)) {
1041 0 : return false;
1042 : }
1043 0 : break;
1044 : } while(0);
1045 : }
1046 :
1047 0 : if (mTransportId.WasPassed()) {
1048 : do {
1049 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1050 0 : JS::Rooted<JS::Value> temp(cx);
1051 0 : nsString const & currentValue = mTransportId.InternalValue();
1052 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1053 0 : return false;
1054 : }
1055 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->transportId_id, temp, JSPROP_ENUMERATE)) {
1056 0 : return false;
1057 : }
1058 0 : break;
1059 : } while(0);
1060 : }
1061 :
1062 0 : if (mWritable.WasPassed()) {
1063 : do {
1064 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1065 0 : JS::Rooted<JS::Value> temp(cx);
1066 0 : bool const & currentValue = mWritable.InternalValue();
1067 0 : temp.setBoolean(currentValue);
1068 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->writable_id, temp, JSPROP_ENUMERATE)) {
1069 0 : return false;
1070 : }
1071 0 : break;
1072 : } while(0);
1073 : }
1074 :
1075 0 : return true;
1076 : }
1077 :
1078 : bool
1079 0 : RTCIceCandidatePairStats::ToJSON(nsAString& aJSON) const
1080 : {
1081 0 : AutoJSAPI jsapi;
1082 0 : jsapi.Init();
1083 0 : JSContext *cx = jsapi.cx();
1084 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
1085 : // because we'll only be creating objects, in ways that have no
1086 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
1087 : // which likewise guarantees no side-effects for the sorts of
1088 : // things we will pass it.
1089 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
1090 0 : JS::Rooted<JS::Value> val(cx);
1091 0 : if (!ToObjectInternal(cx, &val)) {
1092 0 : return false;
1093 : }
1094 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
1095 0 : return StringifyToJSON(cx, obj, aJSON);
1096 : }
1097 :
1098 : void
1099 0 : RTCIceCandidatePairStats::TraceDictionary(JSTracer* trc)
1100 : {
1101 0 : RTCStats::TraceDictionary(trc);
1102 0 : }
1103 :
1104 : RTCIceCandidatePairStats&
1105 0 : RTCIceCandidatePairStats::operator=(const RTCIceCandidatePairStats& aOther)
1106 : {
1107 0 : RTCStats::operator=(aOther);
1108 0 : mBytesReceived.Reset();
1109 0 : if (aOther.mBytesReceived.WasPassed()) {
1110 0 : mBytesReceived.Construct(aOther.mBytesReceived.Value());
1111 : }
1112 0 : mBytesSent.Reset();
1113 0 : if (aOther.mBytesSent.WasPassed()) {
1114 0 : mBytesSent.Construct(aOther.mBytesSent.Value());
1115 : }
1116 0 : mLastPacketReceivedTimestamp.Reset();
1117 0 : if (aOther.mLastPacketReceivedTimestamp.WasPassed()) {
1118 0 : mLastPacketReceivedTimestamp.Construct(aOther.mLastPacketReceivedTimestamp.Value());
1119 : }
1120 0 : mLastPacketSentTimestamp.Reset();
1121 0 : if (aOther.mLastPacketSentTimestamp.WasPassed()) {
1122 0 : mLastPacketSentTimestamp.Construct(aOther.mLastPacketSentTimestamp.Value());
1123 : }
1124 0 : mLocalCandidateId.Reset();
1125 0 : if (aOther.mLocalCandidateId.WasPassed()) {
1126 0 : mLocalCandidateId.Construct(aOther.mLocalCandidateId.Value());
1127 : }
1128 0 : mNominated.Reset();
1129 0 : if (aOther.mNominated.WasPassed()) {
1130 0 : mNominated.Construct(aOther.mNominated.Value());
1131 : }
1132 0 : mPriority.Reset();
1133 0 : if (aOther.mPriority.WasPassed()) {
1134 0 : mPriority.Construct(aOther.mPriority.Value());
1135 : }
1136 0 : mReadable.Reset();
1137 0 : if (aOther.mReadable.WasPassed()) {
1138 0 : mReadable.Construct(aOther.mReadable.Value());
1139 : }
1140 0 : mRemoteCandidateId.Reset();
1141 0 : if (aOther.mRemoteCandidateId.WasPassed()) {
1142 0 : mRemoteCandidateId.Construct(aOther.mRemoteCandidateId.Value());
1143 : }
1144 0 : mSelected.Reset();
1145 0 : if (aOther.mSelected.WasPassed()) {
1146 0 : mSelected.Construct(aOther.mSelected.Value());
1147 : }
1148 0 : mState.Reset();
1149 0 : if (aOther.mState.WasPassed()) {
1150 0 : mState.Construct(aOther.mState.Value());
1151 : }
1152 0 : mTransportId.Reset();
1153 0 : if (aOther.mTransportId.WasPassed()) {
1154 0 : mTransportId.Construct(aOther.mTransportId.Value());
1155 : }
1156 0 : mWritable.Reset();
1157 0 : if (aOther.mWritable.WasPassed()) {
1158 0 : mWritable.Construct(aOther.mWritable.Value());
1159 : }
1160 0 : return *this;
1161 : }
1162 :
1163 : namespace binding_detail {
1164 : } // namespace binding_detail
1165 :
1166 :
1167 :
1168 0 : RTCIceCandidateStats::RTCIceCandidateStats()
1169 0 : : RTCStats(FastDictionaryInitializer())
1170 : {
1171 : // Safe to pass a null context if we pass a null value
1172 0 : Init(nullptr, JS::NullHandleValue);
1173 0 : }
1174 :
1175 :
1176 :
1177 : bool
1178 0 : RTCIceCandidateStats::InitIds(JSContext* cx, RTCIceCandidateStatsAtoms* atomsCache)
1179 : {
1180 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1181 :
1182 : // Initialize these in reverse order so that any failure leaves the first one
1183 : // uninitialized.
1184 0 : if (!atomsCache->transport_id.init(cx, "transport") ||
1185 0 : !atomsCache->portNumber_id.init(cx, "portNumber") ||
1186 0 : !atomsCache->mozLocalTransport_id.init(cx, "mozLocalTransport") ||
1187 0 : !atomsCache->ipAddress_id.init(cx, "ipAddress") ||
1188 0 : !atomsCache->componentId_id.init(cx, "componentId") ||
1189 0 : !atomsCache->candidateType_id.init(cx, "candidateType") ||
1190 0 : !atomsCache->candidateId_id.init(cx, "candidateId")) {
1191 0 : return false;
1192 : }
1193 0 : return true;
1194 : }
1195 :
1196 : bool
1197 0 : RTCIceCandidateStats::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1198 : {
1199 : // Passing a null JSContext is OK only if we're initing from null,
1200 : // Since in that case we will not have to do any property gets
1201 : // Also evaluate isNullOrUndefined in order to avoid false-positive
1202 : // checkers by static analysis tools
1203 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1204 0 : RTCIceCandidateStatsAtoms* atomsCache = nullptr;
1205 0 : if (cx) {
1206 0 : atomsCache = GetAtomCache<RTCIceCandidateStatsAtoms>(cx);
1207 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1208 0 : return false;
1209 : }
1210 : }
1211 :
1212 : // Per spec, we init the parent's members first
1213 0 : if (!RTCStats::Init(cx, val)) {
1214 0 : return false;
1215 : }
1216 :
1217 0 : bool isNull = val.isNullOrUndefined();
1218 : // We only need these if !isNull, in which case we have |cx|.
1219 0 : Maybe<JS::Rooted<JSObject *> > object;
1220 0 : Maybe<JS::Rooted<JS::Value> > temp;
1221 0 : if (!isNull) {
1222 0 : MOZ_ASSERT(cx);
1223 0 : object.emplace(cx, &val.toObject());
1224 0 : temp.emplace(cx);
1225 : }
1226 0 : if (!isNull) {
1227 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->candidateId_id, temp.ptr())) {
1228 0 : return false;
1229 : }
1230 : }
1231 0 : if (!isNull && !temp->isUndefined()) {
1232 0 : mCandidateId.Construct();
1233 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mCandidateId.Value()))) {
1234 0 : return false;
1235 : }
1236 0 : mIsAnyMemberPresent = true;
1237 : }
1238 :
1239 0 : if (!isNull) {
1240 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->candidateType_id, temp.ptr())) {
1241 0 : return false;
1242 : }
1243 : }
1244 0 : if (!isNull && !temp->isUndefined()) {
1245 0 : mCandidateType.Construct();
1246 : {
1247 : int index;
1248 0 : if (!FindEnumStringIndex<true>(cx, temp.ref(), RTCStatsIceCandidateTypeValues::strings, "RTCStatsIceCandidateType", "'candidateType' member of RTCIceCandidateStats", &index)) {
1249 0 : return false;
1250 : }
1251 0 : MOZ_ASSERT(index >= 0);
1252 0 : (mCandidateType.Value()) = static_cast<RTCStatsIceCandidateType>(index);
1253 : }
1254 0 : mIsAnyMemberPresent = true;
1255 : }
1256 :
1257 0 : if (!isNull) {
1258 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->componentId_id, temp.ptr())) {
1259 0 : return false;
1260 : }
1261 : }
1262 0 : if (!isNull && !temp->isUndefined()) {
1263 0 : mComponentId.Construct();
1264 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mComponentId.Value()))) {
1265 0 : return false;
1266 : }
1267 0 : mIsAnyMemberPresent = true;
1268 : }
1269 :
1270 0 : if (!isNull) {
1271 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->ipAddress_id, temp.ptr())) {
1272 0 : return false;
1273 : }
1274 : }
1275 0 : if (!isNull && !temp->isUndefined()) {
1276 0 : mIpAddress.Construct();
1277 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mIpAddress.Value()))) {
1278 0 : return false;
1279 : }
1280 0 : mIsAnyMemberPresent = true;
1281 : }
1282 :
1283 0 : if (!isNull) {
1284 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->mozLocalTransport_id, temp.ptr())) {
1285 0 : return false;
1286 : }
1287 : }
1288 0 : if (!isNull && !temp->isUndefined()) {
1289 0 : mMozLocalTransport.Construct();
1290 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mMozLocalTransport.Value()))) {
1291 0 : return false;
1292 : }
1293 0 : mIsAnyMemberPresent = true;
1294 : }
1295 :
1296 0 : if (!isNull) {
1297 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->portNumber_id, temp.ptr())) {
1298 0 : return false;
1299 : }
1300 : }
1301 0 : if (!isNull && !temp->isUndefined()) {
1302 0 : mPortNumber.Construct();
1303 0 : if (!ValueToPrimitive<int32_t, eDefault>(cx, temp.ref(), &(mPortNumber.Value()))) {
1304 0 : return false;
1305 : }
1306 0 : mIsAnyMemberPresent = true;
1307 : }
1308 :
1309 0 : if (!isNull) {
1310 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->transport_id, temp.ptr())) {
1311 0 : return false;
1312 : }
1313 : }
1314 0 : if (!isNull && !temp->isUndefined()) {
1315 0 : mTransport.Construct();
1316 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mTransport.Value()))) {
1317 0 : return false;
1318 : }
1319 0 : mIsAnyMemberPresent = true;
1320 : }
1321 0 : return true;
1322 : }
1323 :
1324 : bool
1325 0 : RTCIceCandidateStats::Init(const nsAString& aJSON)
1326 : {
1327 0 : AutoJSAPI jsapi;
1328 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
1329 0 : if (!cleanGlobal) {
1330 0 : return false;
1331 : }
1332 0 : if (!jsapi.Init(cleanGlobal)) {
1333 0 : return false;
1334 : }
1335 0 : JSContext* cx = jsapi.cx();
1336 0 : JS::Rooted<JS::Value> json(cx);
1337 0 : bool ok = ParseJSON(cx, aJSON, &json);
1338 0 : NS_ENSURE_TRUE(ok, false);
1339 0 : return Init(cx, json);
1340 : }
1341 :
1342 : bool
1343 0 : RTCIceCandidateStats::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1344 : {
1345 0 : RTCIceCandidateStatsAtoms* atomsCache = GetAtomCache<RTCIceCandidateStatsAtoms>(cx);
1346 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1347 0 : return false;
1348 : }
1349 :
1350 : // Per spec, we define the parent's members first
1351 0 : if (!RTCStats::ToObjectInternal(cx, rval)) {
1352 0 : return false;
1353 : }
1354 0 : JS::Rooted<JSObject*> obj(cx, &rval.toObject());
1355 :
1356 0 : if (mCandidateId.WasPassed()) {
1357 : do {
1358 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1359 0 : JS::Rooted<JS::Value> temp(cx);
1360 0 : nsString const & currentValue = mCandidateId.InternalValue();
1361 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1362 0 : return false;
1363 : }
1364 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->candidateId_id, temp, JSPROP_ENUMERATE)) {
1365 0 : return false;
1366 : }
1367 0 : break;
1368 : } while(0);
1369 : }
1370 :
1371 0 : if (mCandidateType.WasPassed()) {
1372 : do {
1373 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1374 0 : JS::Rooted<JS::Value> temp(cx);
1375 0 : RTCStatsIceCandidateType const & currentValue = mCandidateType.InternalValue();
1376 0 : if (!ToJSValue(cx, currentValue, &temp)) {
1377 0 : return false;
1378 : }
1379 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->candidateType_id, temp, JSPROP_ENUMERATE)) {
1380 0 : return false;
1381 : }
1382 0 : break;
1383 : } while(0);
1384 : }
1385 :
1386 0 : if (mComponentId.WasPassed()) {
1387 : do {
1388 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1389 0 : JS::Rooted<JS::Value> temp(cx);
1390 0 : nsString const & currentValue = mComponentId.InternalValue();
1391 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1392 0 : return false;
1393 : }
1394 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->componentId_id, temp, JSPROP_ENUMERATE)) {
1395 0 : return false;
1396 : }
1397 0 : break;
1398 : } while(0);
1399 : }
1400 :
1401 0 : if (mIpAddress.WasPassed()) {
1402 : do {
1403 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1404 0 : JS::Rooted<JS::Value> temp(cx);
1405 0 : nsString const & currentValue = mIpAddress.InternalValue();
1406 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1407 0 : return false;
1408 : }
1409 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->ipAddress_id, temp, JSPROP_ENUMERATE)) {
1410 0 : return false;
1411 : }
1412 0 : break;
1413 : } while(0);
1414 : }
1415 :
1416 0 : if (mMozLocalTransport.WasPassed()) {
1417 : do {
1418 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1419 0 : JS::Rooted<JS::Value> temp(cx);
1420 0 : nsString const & currentValue = mMozLocalTransport.InternalValue();
1421 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1422 0 : return false;
1423 : }
1424 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->mozLocalTransport_id, temp, JSPROP_ENUMERATE)) {
1425 0 : return false;
1426 : }
1427 0 : break;
1428 : } while(0);
1429 : }
1430 :
1431 0 : if (mPortNumber.WasPassed()) {
1432 : do {
1433 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1434 0 : JS::Rooted<JS::Value> temp(cx);
1435 0 : int32_t const & currentValue = mPortNumber.InternalValue();
1436 0 : temp.setInt32(int32_t(currentValue));
1437 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->portNumber_id, temp, JSPROP_ENUMERATE)) {
1438 0 : return false;
1439 : }
1440 0 : break;
1441 : } while(0);
1442 : }
1443 :
1444 0 : if (mTransport.WasPassed()) {
1445 : do {
1446 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1447 0 : JS::Rooted<JS::Value> temp(cx);
1448 0 : nsString const & currentValue = mTransport.InternalValue();
1449 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1450 0 : return false;
1451 : }
1452 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->transport_id, temp, JSPROP_ENUMERATE)) {
1453 0 : return false;
1454 : }
1455 0 : break;
1456 : } while(0);
1457 : }
1458 :
1459 0 : return true;
1460 : }
1461 :
1462 : bool
1463 0 : RTCIceCandidateStats::ToJSON(nsAString& aJSON) const
1464 : {
1465 0 : AutoJSAPI jsapi;
1466 0 : jsapi.Init();
1467 0 : JSContext *cx = jsapi.cx();
1468 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
1469 : // because we'll only be creating objects, in ways that have no
1470 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
1471 : // which likewise guarantees no side-effects for the sorts of
1472 : // things we will pass it.
1473 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
1474 0 : JS::Rooted<JS::Value> val(cx);
1475 0 : if (!ToObjectInternal(cx, &val)) {
1476 0 : return false;
1477 : }
1478 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
1479 0 : return StringifyToJSON(cx, obj, aJSON);
1480 : }
1481 :
1482 : void
1483 0 : RTCIceCandidateStats::TraceDictionary(JSTracer* trc)
1484 : {
1485 0 : RTCStats::TraceDictionary(trc);
1486 0 : }
1487 :
1488 : RTCIceCandidateStats&
1489 0 : RTCIceCandidateStats::operator=(const RTCIceCandidateStats& aOther)
1490 : {
1491 0 : RTCStats::operator=(aOther);
1492 0 : mCandidateId.Reset();
1493 0 : if (aOther.mCandidateId.WasPassed()) {
1494 0 : mCandidateId.Construct(aOther.mCandidateId.Value());
1495 : }
1496 0 : mCandidateType.Reset();
1497 0 : if (aOther.mCandidateType.WasPassed()) {
1498 0 : mCandidateType.Construct(aOther.mCandidateType.Value());
1499 : }
1500 0 : mComponentId.Reset();
1501 0 : if (aOther.mComponentId.WasPassed()) {
1502 0 : mComponentId.Construct(aOther.mComponentId.Value());
1503 : }
1504 0 : mIpAddress.Reset();
1505 0 : if (aOther.mIpAddress.WasPassed()) {
1506 0 : mIpAddress.Construct(aOther.mIpAddress.Value());
1507 : }
1508 0 : mMozLocalTransport.Reset();
1509 0 : if (aOther.mMozLocalTransport.WasPassed()) {
1510 0 : mMozLocalTransport.Construct(aOther.mMozLocalTransport.Value());
1511 : }
1512 0 : mPortNumber.Reset();
1513 0 : if (aOther.mPortNumber.WasPassed()) {
1514 0 : mPortNumber.Construct(aOther.mPortNumber.Value());
1515 : }
1516 0 : mTransport.Reset();
1517 0 : if (aOther.mTransport.WasPassed()) {
1518 0 : mTransport.Construct(aOther.mTransport.Value());
1519 : }
1520 0 : return *this;
1521 : }
1522 :
1523 : namespace binding_detail {
1524 : } // namespace binding_detail
1525 :
1526 :
1527 :
1528 0 : RTCIceComponentStats::RTCIceComponentStats()
1529 0 : : RTCStats(FastDictionaryInitializer())
1530 : {
1531 : // Safe to pass a null context if we pass a null value
1532 0 : Init(nullptr, JS::NullHandleValue);
1533 0 : }
1534 :
1535 :
1536 :
1537 : bool
1538 0 : RTCIceComponentStats::InitIds(JSContext* cx, RTCIceComponentStatsAtoms* atomsCache)
1539 : {
1540 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1541 :
1542 : // Initialize these in reverse order so that any failure leaves the first one
1543 : // uninitialized.
1544 0 : if (!atomsCache->transportId_id.init(cx, "transportId") ||
1545 0 : !atomsCache->component_id.init(cx, "component") ||
1546 0 : !atomsCache->bytesSent_id.init(cx, "bytesSent") ||
1547 0 : !atomsCache->bytesReceived_id.init(cx, "bytesReceived") ||
1548 0 : !atomsCache->activeConnection_id.init(cx, "activeConnection")) {
1549 0 : return false;
1550 : }
1551 0 : return true;
1552 : }
1553 :
1554 : bool
1555 0 : RTCIceComponentStats::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1556 : {
1557 : // Passing a null JSContext is OK only if we're initing from null,
1558 : // Since in that case we will not have to do any property gets
1559 : // Also evaluate isNullOrUndefined in order to avoid false-positive
1560 : // checkers by static analysis tools
1561 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1562 0 : RTCIceComponentStatsAtoms* atomsCache = nullptr;
1563 0 : if (cx) {
1564 0 : atomsCache = GetAtomCache<RTCIceComponentStatsAtoms>(cx);
1565 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1566 0 : return false;
1567 : }
1568 : }
1569 :
1570 : // Per spec, we init the parent's members first
1571 0 : if (!RTCStats::Init(cx, val)) {
1572 0 : return false;
1573 : }
1574 :
1575 0 : bool isNull = val.isNullOrUndefined();
1576 : // We only need these if !isNull, in which case we have |cx|.
1577 0 : Maybe<JS::Rooted<JSObject *> > object;
1578 0 : Maybe<JS::Rooted<JS::Value> > temp;
1579 0 : if (!isNull) {
1580 0 : MOZ_ASSERT(cx);
1581 0 : object.emplace(cx, &val.toObject());
1582 0 : temp.emplace(cx);
1583 : }
1584 0 : if (!isNull) {
1585 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->activeConnection_id, temp.ptr())) {
1586 0 : return false;
1587 : }
1588 : }
1589 0 : if (!isNull && !temp->isUndefined()) {
1590 0 : mActiveConnection.Construct();
1591 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &(mActiveConnection.Value()))) {
1592 0 : return false;
1593 : }
1594 0 : mIsAnyMemberPresent = true;
1595 : }
1596 :
1597 0 : if (!isNull) {
1598 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->bytesReceived_id, temp.ptr())) {
1599 0 : return false;
1600 : }
1601 : }
1602 0 : if (!isNull && !temp->isUndefined()) {
1603 0 : mBytesReceived.Construct();
1604 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mBytesReceived.Value()))) {
1605 0 : return false;
1606 : }
1607 0 : mIsAnyMemberPresent = true;
1608 : }
1609 :
1610 0 : if (!isNull) {
1611 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->bytesSent_id, temp.ptr())) {
1612 0 : return false;
1613 : }
1614 : }
1615 0 : if (!isNull && !temp->isUndefined()) {
1616 0 : mBytesSent.Construct();
1617 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mBytesSent.Value()))) {
1618 0 : return false;
1619 : }
1620 0 : mIsAnyMemberPresent = true;
1621 : }
1622 :
1623 0 : if (!isNull) {
1624 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->component_id, temp.ptr())) {
1625 0 : return false;
1626 : }
1627 : }
1628 0 : if (!isNull && !temp->isUndefined()) {
1629 0 : mComponent.Construct();
1630 0 : if (!ValueToPrimitive<int32_t, eDefault>(cx, temp.ref(), &(mComponent.Value()))) {
1631 0 : return false;
1632 : }
1633 0 : mIsAnyMemberPresent = true;
1634 : }
1635 :
1636 0 : if (!isNull) {
1637 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->transportId_id, temp.ptr())) {
1638 0 : return false;
1639 : }
1640 : }
1641 0 : if (!isNull && !temp->isUndefined()) {
1642 0 : mTransportId.Construct();
1643 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mTransportId.Value()))) {
1644 0 : return false;
1645 : }
1646 0 : mIsAnyMemberPresent = true;
1647 : }
1648 0 : return true;
1649 : }
1650 :
1651 : bool
1652 0 : RTCIceComponentStats::Init(const nsAString& aJSON)
1653 : {
1654 0 : AutoJSAPI jsapi;
1655 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
1656 0 : if (!cleanGlobal) {
1657 0 : return false;
1658 : }
1659 0 : if (!jsapi.Init(cleanGlobal)) {
1660 0 : return false;
1661 : }
1662 0 : JSContext* cx = jsapi.cx();
1663 0 : JS::Rooted<JS::Value> json(cx);
1664 0 : bool ok = ParseJSON(cx, aJSON, &json);
1665 0 : NS_ENSURE_TRUE(ok, false);
1666 0 : return Init(cx, json);
1667 : }
1668 :
1669 : bool
1670 0 : RTCIceComponentStats::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1671 : {
1672 0 : RTCIceComponentStatsAtoms* atomsCache = GetAtomCache<RTCIceComponentStatsAtoms>(cx);
1673 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1674 0 : return false;
1675 : }
1676 :
1677 : // Per spec, we define the parent's members first
1678 0 : if (!RTCStats::ToObjectInternal(cx, rval)) {
1679 0 : return false;
1680 : }
1681 0 : JS::Rooted<JSObject*> obj(cx, &rval.toObject());
1682 :
1683 0 : if (mActiveConnection.WasPassed()) {
1684 : do {
1685 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1686 0 : JS::Rooted<JS::Value> temp(cx);
1687 0 : bool const & currentValue = mActiveConnection.InternalValue();
1688 0 : temp.setBoolean(currentValue);
1689 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->activeConnection_id, temp, JSPROP_ENUMERATE)) {
1690 0 : return false;
1691 : }
1692 0 : break;
1693 : } while(0);
1694 : }
1695 :
1696 0 : if (mBytesReceived.WasPassed()) {
1697 : do {
1698 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1699 0 : JS::Rooted<JS::Value> temp(cx);
1700 0 : uint32_t const & currentValue = mBytesReceived.InternalValue();
1701 0 : temp.setNumber(currentValue);
1702 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->bytesReceived_id, temp, JSPROP_ENUMERATE)) {
1703 0 : return false;
1704 : }
1705 0 : break;
1706 : } while(0);
1707 : }
1708 :
1709 0 : if (mBytesSent.WasPassed()) {
1710 : do {
1711 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1712 0 : JS::Rooted<JS::Value> temp(cx);
1713 0 : uint32_t const & currentValue = mBytesSent.InternalValue();
1714 0 : temp.setNumber(currentValue);
1715 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->bytesSent_id, temp, JSPROP_ENUMERATE)) {
1716 0 : return false;
1717 : }
1718 0 : break;
1719 : } while(0);
1720 : }
1721 :
1722 0 : if (mComponent.WasPassed()) {
1723 : do {
1724 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1725 0 : JS::Rooted<JS::Value> temp(cx);
1726 0 : int32_t const & currentValue = mComponent.InternalValue();
1727 0 : temp.setInt32(int32_t(currentValue));
1728 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->component_id, temp, JSPROP_ENUMERATE)) {
1729 0 : return false;
1730 : }
1731 0 : break;
1732 : } while(0);
1733 : }
1734 :
1735 0 : if (mTransportId.WasPassed()) {
1736 : do {
1737 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1738 0 : JS::Rooted<JS::Value> temp(cx);
1739 0 : nsString const & currentValue = mTransportId.InternalValue();
1740 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1741 0 : return false;
1742 : }
1743 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->transportId_id, temp, JSPROP_ENUMERATE)) {
1744 0 : return false;
1745 : }
1746 0 : break;
1747 : } while(0);
1748 : }
1749 :
1750 0 : return true;
1751 : }
1752 :
1753 : bool
1754 0 : RTCIceComponentStats::ToJSON(nsAString& aJSON) const
1755 : {
1756 0 : AutoJSAPI jsapi;
1757 0 : jsapi.Init();
1758 0 : JSContext *cx = jsapi.cx();
1759 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
1760 : // because we'll only be creating objects, in ways that have no
1761 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
1762 : // which likewise guarantees no side-effects for the sorts of
1763 : // things we will pass it.
1764 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
1765 0 : JS::Rooted<JS::Value> val(cx);
1766 0 : if (!ToObjectInternal(cx, &val)) {
1767 0 : return false;
1768 : }
1769 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
1770 0 : return StringifyToJSON(cx, obj, aJSON);
1771 : }
1772 :
1773 : void
1774 0 : RTCIceComponentStats::TraceDictionary(JSTracer* trc)
1775 : {
1776 0 : RTCStats::TraceDictionary(trc);
1777 0 : }
1778 :
1779 : RTCIceComponentStats&
1780 0 : RTCIceComponentStats::operator=(const RTCIceComponentStats& aOther)
1781 : {
1782 0 : RTCStats::operator=(aOther);
1783 0 : mActiveConnection.Reset();
1784 0 : if (aOther.mActiveConnection.WasPassed()) {
1785 0 : mActiveConnection.Construct(aOther.mActiveConnection.Value());
1786 : }
1787 0 : mBytesReceived.Reset();
1788 0 : if (aOther.mBytesReceived.WasPassed()) {
1789 0 : mBytesReceived.Construct(aOther.mBytesReceived.Value());
1790 : }
1791 0 : mBytesSent.Reset();
1792 0 : if (aOther.mBytesSent.WasPassed()) {
1793 0 : mBytesSent.Construct(aOther.mBytesSent.Value());
1794 : }
1795 0 : mComponent.Reset();
1796 0 : if (aOther.mComponent.WasPassed()) {
1797 0 : mComponent.Construct(aOther.mComponent.Value());
1798 : }
1799 0 : mTransportId.Reset();
1800 0 : if (aOther.mTransportId.WasPassed()) {
1801 0 : mTransportId.Construct(aOther.mTransportId.Value());
1802 : }
1803 0 : return *this;
1804 : }
1805 :
1806 : namespace binding_detail {
1807 : } // namespace binding_detail
1808 :
1809 :
1810 :
1811 0 : RTCMediaStreamStats::RTCMediaStreamStats()
1812 0 : : RTCStats(FastDictionaryInitializer())
1813 : {
1814 : // Safe to pass a null context if we pass a null value
1815 0 : Init(nullptr, JS::NullHandleValue);
1816 0 : }
1817 :
1818 :
1819 :
1820 : bool
1821 0 : RTCMediaStreamStats::InitIds(JSContext* cx, RTCMediaStreamStatsAtoms* atomsCache)
1822 : {
1823 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1824 :
1825 : // Initialize these in reverse order so that any failure leaves the first one
1826 : // uninitialized.
1827 0 : if (!atomsCache->trackIds_id.init(cx, "trackIds") ||
1828 0 : !atomsCache->streamIdentifier_id.init(cx, "streamIdentifier")) {
1829 0 : return false;
1830 : }
1831 0 : return true;
1832 : }
1833 :
1834 : bool
1835 0 : RTCMediaStreamStats::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1836 : {
1837 : // Passing a null JSContext is OK only if we're initing from null,
1838 : // Since in that case we will not have to do any property gets
1839 : // Also evaluate isNullOrUndefined in order to avoid false-positive
1840 : // checkers by static analysis tools
1841 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1842 0 : RTCMediaStreamStatsAtoms* atomsCache = nullptr;
1843 0 : if (cx) {
1844 0 : atomsCache = GetAtomCache<RTCMediaStreamStatsAtoms>(cx);
1845 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1846 0 : return false;
1847 : }
1848 : }
1849 :
1850 : // Per spec, we init the parent's members first
1851 0 : if (!RTCStats::Init(cx, val)) {
1852 0 : return false;
1853 : }
1854 :
1855 0 : bool isNull = val.isNullOrUndefined();
1856 : // We only need these if !isNull, in which case we have |cx|.
1857 0 : Maybe<JS::Rooted<JSObject *> > object;
1858 0 : Maybe<JS::Rooted<JS::Value> > temp;
1859 0 : if (!isNull) {
1860 0 : MOZ_ASSERT(cx);
1861 0 : object.emplace(cx, &val.toObject());
1862 0 : temp.emplace(cx);
1863 : }
1864 0 : if (!isNull) {
1865 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->streamIdentifier_id, temp.ptr())) {
1866 0 : return false;
1867 : }
1868 : }
1869 0 : if (!isNull && !temp->isUndefined()) {
1870 0 : mStreamIdentifier.Construct();
1871 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mStreamIdentifier.Value()))) {
1872 0 : return false;
1873 : }
1874 0 : mIsAnyMemberPresent = true;
1875 : }
1876 :
1877 0 : if (!isNull) {
1878 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->trackIds_id, temp.ptr())) {
1879 0 : return false;
1880 : }
1881 : }
1882 0 : if (!isNull && !temp->isUndefined()) {
1883 0 : mTrackIds.Construct();
1884 0 : if (temp.ref().isObject()) {
1885 0 : JS::ForOfIterator iter(cx);
1886 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
1887 0 : return false;
1888 : }
1889 0 : if (!iter.valueIsIterable()) {
1890 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'trackIds' member of RTCMediaStreamStats");
1891 0 : return false;
1892 : }
1893 0 : Sequence<nsString> &arr = (mTrackIds.Value());
1894 0 : JS::Rooted<JS::Value> temp(cx);
1895 : while (true) {
1896 : bool done;
1897 0 : if (!iter.next(&temp, &done)) {
1898 0 : return false;
1899 : }
1900 0 : if (done) {
1901 0 : break;
1902 : }
1903 0 : nsString* slotPtr = arr.AppendElement(mozilla::fallible);
1904 0 : if (!slotPtr) {
1905 0 : JS_ReportOutOfMemory(cx);
1906 0 : return false;
1907 : }
1908 0 : nsString& slot = *slotPtr;
1909 0 : if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
1910 0 : return false;
1911 : }
1912 0 : }
1913 : } else {
1914 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'trackIds' member of RTCMediaStreamStats");
1915 0 : return false;
1916 : }
1917 0 : mIsAnyMemberPresent = true;
1918 : }
1919 0 : return true;
1920 : }
1921 :
1922 : bool
1923 0 : RTCMediaStreamStats::Init(const nsAString& aJSON)
1924 : {
1925 0 : AutoJSAPI jsapi;
1926 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
1927 0 : if (!cleanGlobal) {
1928 0 : return false;
1929 : }
1930 0 : if (!jsapi.Init(cleanGlobal)) {
1931 0 : return false;
1932 : }
1933 0 : JSContext* cx = jsapi.cx();
1934 0 : JS::Rooted<JS::Value> json(cx);
1935 0 : bool ok = ParseJSON(cx, aJSON, &json);
1936 0 : NS_ENSURE_TRUE(ok, false);
1937 0 : return Init(cx, json);
1938 : }
1939 :
1940 : bool
1941 0 : RTCMediaStreamStats::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1942 : {
1943 0 : RTCMediaStreamStatsAtoms* atomsCache = GetAtomCache<RTCMediaStreamStatsAtoms>(cx);
1944 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1945 0 : return false;
1946 : }
1947 :
1948 : // Per spec, we define the parent's members first
1949 0 : if (!RTCStats::ToObjectInternal(cx, rval)) {
1950 0 : return false;
1951 : }
1952 0 : JS::Rooted<JSObject*> obj(cx, &rval.toObject());
1953 :
1954 0 : if (mStreamIdentifier.WasPassed()) {
1955 : do {
1956 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1957 0 : JS::Rooted<JS::Value> temp(cx);
1958 0 : nsString const & currentValue = mStreamIdentifier.InternalValue();
1959 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1960 0 : return false;
1961 : }
1962 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->streamIdentifier_id, temp, JSPROP_ENUMERATE)) {
1963 0 : return false;
1964 : }
1965 0 : break;
1966 : } while(0);
1967 : }
1968 :
1969 0 : if (mTrackIds.WasPassed()) {
1970 : do {
1971 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1972 0 : JS::Rooted<JS::Value> temp(cx);
1973 0 : Sequence<nsString> const & currentValue = mTrackIds.InternalValue();
1974 :
1975 0 : uint32_t length = currentValue.Length();
1976 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
1977 0 : if (!returnArray) {
1978 0 : return false;
1979 : }
1980 : // Scope for 'tmp'
1981 : {
1982 0 : JS::Rooted<JS::Value> tmp(cx);
1983 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
1984 : // Control block to let us common up the JS_DefineElement calls when there
1985 : // are different ways to succeed at wrapping the object.
1986 : do {
1987 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue[sequenceIdx0], &tmp)) {
1988 0 : return false;
1989 : }
1990 0 : break;
1991 : } while (0);
1992 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
1993 : JSPROP_ENUMERATE)) {
1994 0 : return false;
1995 : }
1996 : }
1997 : }
1998 0 : temp.setObject(*returnArray);
1999 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->trackIds_id, temp, JSPROP_ENUMERATE)) {
2000 0 : return false;
2001 : }
2002 0 : break;
2003 : } while(0);
2004 : }
2005 :
2006 0 : return true;
2007 : }
2008 :
2009 : bool
2010 0 : RTCMediaStreamStats::ToJSON(nsAString& aJSON) const
2011 : {
2012 0 : AutoJSAPI jsapi;
2013 0 : jsapi.Init();
2014 0 : JSContext *cx = jsapi.cx();
2015 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
2016 : // because we'll only be creating objects, in ways that have no
2017 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
2018 : // which likewise guarantees no side-effects for the sorts of
2019 : // things we will pass it.
2020 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
2021 0 : JS::Rooted<JS::Value> val(cx);
2022 0 : if (!ToObjectInternal(cx, &val)) {
2023 0 : return false;
2024 : }
2025 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
2026 0 : return StringifyToJSON(cx, obj, aJSON);
2027 : }
2028 :
2029 : void
2030 0 : RTCMediaStreamStats::TraceDictionary(JSTracer* trc)
2031 : {
2032 0 : RTCStats::TraceDictionary(trc);
2033 0 : }
2034 :
2035 : RTCMediaStreamStats&
2036 0 : RTCMediaStreamStats::operator=(const RTCMediaStreamStats& aOther)
2037 : {
2038 0 : RTCStats::operator=(aOther);
2039 0 : mStreamIdentifier.Reset();
2040 0 : if (aOther.mStreamIdentifier.WasPassed()) {
2041 0 : mStreamIdentifier.Construct(aOther.mStreamIdentifier.Value());
2042 : }
2043 0 : mTrackIds.Reset();
2044 0 : if (aOther.mTrackIds.WasPassed()) {
2045 0 : mTrackIds.Construct(aOther.mTrackIds.Value());
2046 : }
2047 0 : return *this;
2048 : }
2049 :
2050 : namespace binding_detail {
2051 : } // namespace binding_detail
2052 :
2053 :
2054 :
2055 0 : RTCMediaStreamTrackStats::RTCMediaStreamTrackStats()
2056 0 : : RTCStats(FastDictionaryInitializer())
2057 : {
2058 : // Safe to pass a null context if we pass a null value
2059 0 : Init(nullptr, JS::NullHandleValue);
2060 0 : }
2061 :
2062 :
2063 :
2064 : bool
2065 0 : RTCMediaStreamTrackStats::InitIds(JSContext* cx, RTCMediaStreamTrackStatsAtoms* atomsCache)
2066 : {
2067 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
2068 :
2069 : // Initialize these in reverse order so that any failure leaves the first one
2070 : // uninitialized.
2071 0 : if (!atomsCache->trackIdentifier_id.init(cx, "trackIdentifier") ||
2072 0 : !atomsCache->ssrcIds_id.init(cx, "ssrcIds") ||
2073 0 : !atomsCache->remoteSource_id.init(cx, "remoteSource") ||
2074 0 : !atomsCache->framesSent_id.init(cx, "framesSent") ||
2075 0 : !atomsCache->framesReceived_id.init(cx, "framesReceived") ||
2076 0 : !atomsCache->framesPerSecond_id.init(cx, "framesPerSecond") ||
2077 0 : !atomsCache->framesDropped_id.init(cx, "framesDropped") ||
2078 0 : !atomsCache->framesDecoded_id.init(cx, "framesDecoded") ||
2079 0 : !atomsCache->framesCorrupted_id.init(cx, "framesCorrupted") ||
2080 0 : !atomsCache->frameWidth_id.init(cx, "frameWidth") ||
2081 0 : !atomsCache->frameHeight_id.init(cx, "frameHeight") ||
2082 0 : !atomsCache->echoReturnLossEnhancement_id.init(cx, "echoReturnLossEnhancement") ||
2083 0 : !atomsCache->echoReturnLoss_id.init(cx, "echoReturnLoss") ||
2084 0 : !atomsCache->audioLevel_id.init(cx, "audioLevel")) {
2085 0 : return false;
2086 : }
2087 0 : return true;
2088 : }
2089 :
2090 : bool
2091 0 : RTCMediaStreamTrackStats::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
2092 : {
2093 : // Passing a null JSContext is OK only if we're initing from null,
2094 : // Since in that case we will not have to do any property gets
2095 : // Also evaluate isNullOrUndefined in order to avoid false-positive
2096 : // checkers by static analysis tools
2097 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
2098 0 : RTCMediaStreamTrackStatsAtoms* atomsCache = nullptr;
2099 0 : if (cx) {
2100 0 : atomsCache = GetAtomCache<RTCMediaStreamTrackStatsAtoms>(cx);
2101 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2102 0 : return false;
2103 : }
2104 : }
2105 :
2106 : // Per spec, we init the parent's members first
2107 0 : if (!RTCStats::Init(cx, val)) {
2108 0 : return false;
2109 : }
2110 :
2111 0 : bool isNull = val.isNullOrUndefined();
2112 : // We only need these if !isNull, in which case we have |cx|.
2113 0 : Maybe<JS::Rooted<JSObject *> > object;
2114 0 : Maybe<JS::Rooted<JS::Value> > temp;
2115 0 : if (!isNull) {
2116 0 : MOZ_ASSERT(cx);
2117 0 : object.emplace(cx, &val.toObject());
2118 0 : temp.emplace(cx);
2119 : }
2120 0 : if (!isNull) {
2121 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->audioLevel_id, temp.ptr())) {
2122 0 : return false;
2123 : }
2124 : }
2125 0 : if (!isNull && !temp->isUndefined()) {
2126 0 : mAudioLevel.Construct();
2127 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &(mAudioLevel.Value()))) {
2128 0 : return false;
2129 0 : } else if (!mozilla::IsFinite((mAudioLevel.Value()))) {
2130 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'audioLevel' member of RTCMediaStreamTrackStats");
2131 0 : return false;
2132 : }
2133 0 : mIsAnyMemberPresent = true;
2134 : }
2135 :
2136 0 : if (!isNull) {
2137 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->echoReturnLoss_id, temp.ptr())) {
2138 0 : return false;
2139 : }
2140 : }
2141 0 : if (!isNull && !temp->isUndefined()) {
2142 0 : mEchoReturnLoss.Construct();
2143 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &(mEchoReturnLoss.Value()))) {
2144 0 : return false;
2145 0 : } else if (!mozilla::IsFinite((mEchoReturnLoss.Value()))) {
2146 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'echoReturnLoss' member of RTCMediaStreamTrackStats");
2147 0 : return false;
2148 : }
2149 0 : mIsAnyMemberPresent = true;
2150 : }
2151 :
2152 0 : if (!isNull) {
2153 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->echoReturnLossEnhancement_id, temp.ptr())) {
2154 0 : return false;
2155 : }
2156 : }
2157 0 : if (!isNull && !temp->isUndefined()) {
2158 0 : mEchoReturnLossEnhancement.Construct();
2159 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &(mEchoReturnLossEnhancement.Value()))) {
2160 0 : return false;
2161 0 : } else if (!mozilla::IsFinite((mEchoReturnLossEnhancement.Value()))) {
2162 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'echoReturnLossEnhancement' member of RTCMediaStreamTrackStats");
2163 0 : return false;
2164 : }
2165 0 : mIsAnyMemberPresent = true;
2166 : }
2167 :
2168 0 : if (!isNull) {
2169 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->frameHeight_id, temp.ptr())) {
2170 0 : return false;
2171 : }
2172 : }
2173 0 : if (!isNull && !temp->isUndefined()) {
2174 0 : mFrameHeight.Construct();
2175 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mFrameHeight.Value()))) {
2176 0 : return false;
2177 : }
2178 0 : mIsAnyMemberPresent = true;
2179 : }
2180 :
2181 0 : if (!isNull) {
2182 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->frameWidth_id, temp.ptr())) {
2183 0 : return false;
2184 : }
2185 : }
2186 0 : if (!isNull && !temp->isUndefined()) {
2187 0 : mFrameWidth.Construct();
2188 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mFrameWidth.Value()))) {
2189 0 : return false;
2190 : }
2191 0 : mIsAnyMemberPresent = true;
2192 : }
2193 :
2194 0 : if (!isNull) {
2195 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->framesCorrupted_id, temp.ptr())) {
2196 0 : return false;
2197 : }
2198 : }
2199 0 : if (!isNull && !temp->isUndefined()) {
2200 0 : mFramesCorrupted.Construct();
2201 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mFramesCorrupted.Value()))) {
2202 0 : return false;
2203 : }
2204 0 : mIsAnyMemberPresent = true;
2205 : }
2206 :
2207 0 : if (!isNull) {
2208 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->framesDecoded_id, temp.ptr())) {
2209 0 : return false;
2210 : }
2211 : }
2212 0 : if (!isNull && !temp->isUndefined()) {
2213 0 : mFramesDecoded.Construct();
2214 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mFramesDecoded.Value()))) {
2215 0 : return false;
2216 : }
2217 0 : mIsAnyMemberPresent = true;
2218 : }
2219 :
2220 0 : if (!isNull) {
2221 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->framesDropped_id, temp.ptr())) {
2222 0 : return false;
2223 : }
2224 : }
2225 0 : if (!isNull && !temp->isUndefined()) {
2226 0 : mFramesDropped.Construct();
2227 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mFramesDropped.Value()))) {
2228 0 : return false;
2229 : }
2230 0 : mIsAnyMemberPresent = true;
2231 : }
2232 :
2233 0 : if (!isNull) {
2234 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->framesPerSecond_id, temp.ptr())) {
2235 0 : return false;
2236 : }
2237 : }
2238 0 : if (!isNull && !temp->isUndefined()) {
2239 0 : mFramesPerSecond.Construct();
2240 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &(mFramesPerSecond.Value()))) {
2241 0 : return false;
2242 0 : } else if (!mozilla::IsFinite((mFramesPerSecond.Value()))) {
2243 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'framesPerSecond' member of RTCMediaStreamTrackStats");
2244 0 : return false;
2245 : }
2246 0 : mIsAnyMemberPresent = true;
2247 : }
2248 :
2249 0 : if (!isNull) {
2250 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->framesReceived_id, temp.ptr())) {
2251 0 : return false;
2252 : }
2253 : }
2254 0 : if (!isNull && !temp->isUndefined()) {
2255 0 : mFramesReceived.Construct();
2256 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mFramesReceived.Value()))) {
2257 0 : return false;
2258 : }
2259 0 : mIsAnyMemberPresent = true;
2260 : }
2261 :
2262 0 : if (!isNull) {
2263 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->framesSent_id, temp.ptr())) {
2264 0 : return false;
2265 : }
2266 : }
2267 0 : if (!isNull && !temp->isUndefined()) {
2268 0 : mFramesSent.Construct();
2269 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mFramesSent.Value()))) {
2270 0 : return false;
2271 : }
2272 0 : mIsAnyMemberPresent = true;
2273 : }
2274 :
2275 0 : if (!isNull) {
2276 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->remoteSource_id, temp.ptr())) {
2277 0 : return false;
2278 : }
2279 : }
2280 0 : if (!isNull && !temp->isUndefined()) {
2281 0 : mRemoteSource.Construct();
2282 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &(mRemoteSource.Value()))) {
2283 0 : return false;
2284 : }
2285 0 : mIsAnyMemberPresent = true;
2286 : }
2287 :
2288 0 : if (!isNull) {
2289 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->ssrcIds_id, temp.ptr())) {
2290 0 : return false;
2291 : }
2292 : }
2293 0 : if (!isNull && !temp->isUndefined()) {
2294 0 : mSsrcIds.Construct();
2295 0 : if (temp.ref().isObject()) {
2296 0 : JS::ForOfIterator iter(cx);
2297 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
2298 0 : return false;
2299 : }
2300 0 : if (!iter.valueIsIterable()) {
2301 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'ssrcIds' member of RTCMediaStreamTrackStats");
2302 0 : return false;
2303 : }
2304 0 : Sequence<nsString> &arr = (mSsrcIds.Value());
2305 0 : JS::Rooted<JS::Value> temp(cx);
2306 : while (true) {
2307 : bool done;
2308 0 : if (!iter.next(&temp, &done)) {
2309 0 : return false;
2310 : }
2311 0 : if (done) {
2312 0 : break;
2313 : }
2314 0 : nsString* slotPtr = arr.AppendElement(mozilla::fallible);
2315 0 : if (!slotPtr) {
2316 0 : JS_ReportOutOfMemory(cx);
2317 0 : return false;
2318 : }
2319 0 : nsString& slot = *slotPtr;
2320 0 : if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
2321 0 : return false;
2322 : }
2323 0 : }
2324 : } else {
2325 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'ssrcIds' member of RTCMediaStreamTrackStats");
2326 0 : return false;
2327 : }
2328 0 : mIsAnyMemberPresent = true;
2329 : }
2330 :
2331 0 : if (!isNull) {
2332 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->trackIdentifier_id, temp.ptr())) {
2333 0 : return false;
2334 : }
2335 : }
2336 0 : if (!isNull && !temp->isUndefined()) {
2337 0 : mTrackIdentifier.Construct();
2338 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mTrackIdentifier.Value()))) {
2339 0 : return false;
2340 : }
2341 0 : mIsAnyMemberPresent = true;
2342 : }
2343 0 : return true;
2344 : }
2345 :
2346 : bool
2347 0 : RTCMediaStreamTrackStats::Init(const nsAString& aJSON)
2348 : {
2349 0 : AutoJSAPI jsapi;
2350 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
2351 0 : if (!cleanGlobal) {
2352 0 : return false;
2353 : }
2354 0 : if (!jsapi.Init(cleanGlobal)) {
2355 0 : return false;
2356 : }
2357 0 : JSContext* cx = jsapi.cx();
2358 0 : JS::Rooted<JS::Value> json(cx);
2359 0 : bool ok = ParseJSON(cx, aJSON, &json);
2360 0 : NS_ENSURE_TRUE(ok, false);
2361 0 : return Init(cx, json);
2362 : }
2363 :
2364 : bool
2365 0 : RTCMediaStreamTrackStats::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
2366 : {
2367 0 : RTCMediaStreamTrackStatsAtoms* atomsCache = GetAtomCache<RTCMediaStreamTrackStatsAtoms>(cx);
2368 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2369 0 : return false;
2370 : }
2371 :
2372 : // Per spec, we define the parent's members first
2373 0 : if (!RTCStats::ToObjectInternal(cx, rval)) {
2374 0 : return false;
2375 : }
2376 0 : JS::Rooted<JSObject*> obj(cx, &rval.toObject());
2377 :
2378 0 : if (mAudioLevel.WasPassed()) {
2379 : do {
2380 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2381 0 : JS::Rooted<JS::Value> temp(cx);
2382 0 : double const & currentValue = mAudioLevel.InternalValue();
2383 0 : temp.set(JS_NumberValue(double(currentValue)));
2384 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->audioLevel_id, temp, JSPROP_ENUMERATE)) {
2385 0 : return false;
2386 : }
2387 0 : break;
2388 : } while(0);
2389 : }
2390 :
2391 0 : if (mEchoReturnLoss.WasPassed()) {
2392 : do {
2393 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2394 0 : JS::Rooted<JS::Value> temp(cx);
2395 0 : double const & currentValue = mEchoReturnLoss.InternalValue();
2396 0 : temp.set(JS_NumberValue(double(currentValue)));
2397 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->echoReturnLoss_id, temp, JSPROP_ENUMERATE)) {
2398 0 : return false;
2399 : }
2400 0 : break;
2401 : } while(0);
2402 : }
2403 :
2404 0 : if (mEchoReturnLossEnhancement.WasPassed()) {
2405 : do {
2406 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2407 0 : JS::Rooted<JS::Value> temp(cx);
2408 0 : double const & currentValue = mEchoReturnLossEnhancement.InternalValue();
2409 0 : temp.set(JS_NumberValue(double(currentValue)));
2410 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->echoReturnLossEnhancement_id, temp, JSPROP_ENUMERATE)) {
2411 0 : return false;
2412 : }
2413 0 : break;
2414 : } while(0);
2415 : }
2416 :
2417 0 : if (mFrameHeight.WasPassed()) {
2418 : do {
2419 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2420 0 : JS::Rooted<JS::Value> temp(cx);
2421 0 : uint32_t const & currentValue = mFrameHeight.InternalValue();
2422 0 : temp.setNumber(currentValue);
2423 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->frameHeight_id, temp, JSPROP_ENUMERATE)) {
2424 0 : return false;
2425 : }
2426 0 : break;
2427 : } while(0);
2428 : }
2429 :
2430 0 : if (mFrameWidth.WasPassed()) {
2431 : do {
2432 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2433 0 : JS::Rooted<JS::Value> temp(cx);
2434 0 : uint32_t const & currentValue = mFrameWidth.InternalValue();
2435 0 : temp.setNumber(currentValue);
2436 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->frameWidth_id, temp, JSPROP_ENUMERATE)) {
2437 0 : return false;
2438 : }
2439 0 : break;
2440 : } while(0);
2441 : }
2442 :
2443 0 : if (mFramesCorrupted.WasPassed()) {
2444 : do {
2445 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2446 0 : JS::Rooted<JS::Value> temp(cx);
2447 0 : uint32_t const & currentValue = mFramesCorrupted.InternalValue();
2448 0 : temp.setNumber(currentValue);
2449 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->framesCorrupted_id, temp, JSPROP_ENUMERATE)) {
2450 0 : return false;
2451 : }
2452 0 : break;
2453 : } while(0);
2454 : }
2455 :
2456 0 : if (mFramesDecoded.WasPassed()) {
2457 : do {
2458 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2459 0 : JS::Rooted<JS::Value> temp(cx);
2460 0 : uint32_t const & currentValue = mFramesDecoded.InternalValue();
2461 0 : temp.setNumber(currentValue);
2462 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->framesDecoded_id, temp, JSPROP_ENUMERATE)) {
2463 0 : return false;
2464 : }
2465 0 : break;
2466 : } while(0);
2467 : }
2468 :
2469 0 : if (mFramesDropped.WasPassed()) {
2470 : do {
2471 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2472 0 : JS::Rooted<JS::Value> temp(cx);
2473 0 : uint32_t const & currentValue = mFramesDropped.InternalValue();
2474 0 : temp.setNumber(currentValue);
2475 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->framesDropped_id, temp, JSPROP_ENUMERATE)) {
2476 0 : return false;
2477 : }
2478 0 : break;
2479 : } while(0);
2480 : }
2481 :
2482 0 : if (mFramesPerSecond.WasPassed()) {
2483 : do {
2484 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2485 0 : JS::Rooted<JS::Value> temp(cx);
2486 0 : double const & currentValue = mFramesPerSecond.InternalValue();
2487 0 : temp.set(JS_NumberValue(double(currentValue)));
2488 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->framesPerSecond_id, temp, JSPROP_ENUMERATE)) {
2489 0 : return false;
2490 : }
2491 0 : break;
2492 : } while(0);
2493 : }
2494 :
2495 0 : if (mFramesReceived.WasPassed()) {
2496 : do {
2497 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2498 0 : JS::Rooted<JS::Value> temp(cx);
2499 0 : uint32_t const & currentValue = mFramesReceived.InternalValue();
2500 0 : temp.setNumber(currentValue);
2501 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->framesReceived_id, temp, JSPROP_ENUMERATE)) {
2502 0 : return false;
2503 : }
2504 0 : break;
2505 : } while(0);
2506 : }
2507 :
2508 0 : if (mFramesSent.WasPassed()) {
2509 : do {
2510 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2511 0 : JS::Rooted<JS::Value> temp(cx);
2512 0 : uint32_t const & currentValue = mFramesSent.InternalValue();
2513 0 : temp.setNumber(currentValue);
2514 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->framesSent_id, temp, JSPROP_ENUMERATE)) {
2515 0 : return false;
2516 : }
2517 0 : break;
2518 : } while(0);
2519 : }
2520 :
2521 0 : if (mRemoteSource.WasPassed()) {
2522 : do {
2523 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2524 0 : JS::Rooted<JS::Value> temp(cx);
2525 0 : bool const & currentValue = mRemoteSource.InternalValue();
2526 0 : temp.setBoolean(currentValue);
2527 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->remoteSource_id, temp, JSPROP_ENUMERATE)) {
2528 0 : return false;
2529 : }
2530 0 : break;
2531 : } while(0);
2532 : }
2533 :
2534 0 : if (mSsrcIds.WasPassed()) {
2535 : do {
2536 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2537 0 : JS::Rooted<JS::Value> temp(cx);
2538 0 : Sequence<nsString> const & currentValue = mSsrcIds.InternalValue();
2539 :
2540 0 : uint32_t length = currentValue.Length();
2541 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
2542 0 : if (!returnArray) {
2543 0 : return false;
2544 : }
2545 : // Scope for 'tmp'
2546 : {
2547 0 : JS::Rooted<JS::Value> tmp(cx);
2548 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
2549 : // Control block to let us common up the JS_DefineElement calls when there
2550 : // are different ways to succeed at wrapping the object.
2551 : do {
2552 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue[sequenceIdx0], &tmp)) {
2553 0 : return false;
2554 : }
2555 0 : break;
2556 : } while (0);
2557 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
2558 : JSPROP_ENUMERATE)) {
2559 0 : return false;
2560 : }
2561 : }
2562 : }
2563 0 : temp.setObject(*returnArray);
2564 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->ssrcIds_id, temp, JSPROP_ENUMERATE)) {
2565 0 : return false;
2566 : }
2567 0 : break;
2568 : } while(0);
2569 : }
2570 :
2571 0 : if (mTrackIdentifier.WasPassed()) {
2572 : do {
2573 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2574 0 : JS::Rooted<JS::Value> temp(cx);
2575 0 : nsString const & currentValue = mTrackIdentifier.InternalValue();
2576 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
2577 0 : return false;
2578 : }
2579 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->trackIdentifier_id, temp, JSPROP_ENUMERATE)) {
2580 0 : return false;
2581 : }
2582 0 : break;
2583 : } while(0);
2584 : }
2585 :
2586 0 : return true;
2587 : }
2588 :
2589 : bool
2590 0 : RTCMediaStreamTrackStats::ToJSON(nsAString& aJSON) const
2591 : {
2592 0 : AutoJSAPI jsapi;
2593 0 : jsapi.Init();
2594 0 : JSContext *cx = jsapi.cx();
2595 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
2596 : // because we'll only be creating objects, in ways that have no
2597 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
2598 : // which likewise guarantees no side-effects for the sorts of
2599 : // things we will pass it.
2600 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
2601 0 : JS::Rooted<JS::Value> val(cx);
2602 0 : if (!ToObjectInternal(cx, &val)) {
2603 0 : return false;
2604 : }
2605 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
2606 0 : return StringifyToJSON(cx, obj, aJSON);
2607 : }
2608 :
2609 : void
2610 0 : RTCMediaStreamTrackStats::TraceDictionary(JSTracer* trc)
2611 : {
2612 0 : RTCStats::TraceDictionary(trc);
2613 0 : }
2614 :
2615 : RTCMediaStreamTrackStats&
2616 0 : RTCMediaStreamTrackStats::operator=(const RTCMediaStreamTrackStats& aOther)
2617 : {
2618 0 : RTCStats::operator=(aOther);
2619 0 : mAudioLevel.Reset();
2620 0 : if (aOther.mAudioLevel.WasPassed()) {
2621 0 : mAudioLevel.Construct(aOther.mAudioLevel.Value());
2622 : }
2623 0 : mEchoReturnLoss.Reset();
2624 0 : if (aOther.mEchoReturnLoss.WasPassed()) {
2625 0 : mEchoReturnLoss.Construct(aOther.mEchoReturnLoss.Value());
2626 : }
2627 0 : mEchoReturnLossEnhancement.Reset();
2628 0 : if (aOther.mEchoReturnLossEnhancement.WasPassed()) {
2629 0 : mEchoReturnLossEnhancement.Construct(aOther.mEchoReturnLossEnhancement.Value());
2630 : }
2631 0 : mFrameHeight.Reset();
2632 0 : if (aOther.mFrameHeight.WasPassed()) {
2633 0 : mFrameHeight.Construct(aOther.mFrameHeight.Value());
2634 : }
2635 0 : mFrameWidth.Reset();
2636 0 : if (aOther.mFrameWidth.WasPassed()) {
2637 0 : mFrameWidth.Construct(aOther.mFrameWidth.Value());
2638 : }
2639 0 : mFramesCorrupted.Reset();
2640 0 : if (aOther.mFramesCorrupted.WasPassed()) {
2641 0 : mFramesCorrupted.Construct(aOther.mFramesCorrupted.Value());
2642 : }
2643 0 : mFramesDecoded.Reset();
2644 0 : if (aOther.mFramesDecoded.WasPassed()) {
2645 0 : mFramesDecoded.Construct(aOther.mFramesDecoded.Value());
2646 : }
2647 0 : mFramesDropped.Reset();
2648 0 : if (aOther.mFramesDropped.WasPassed()) {
2649 0 : mFramesDropped.Construct(aOther.mFramesDropped.Value());
2650 : }
2651 0 : mFramesPerSecond.Reset();
2652 0 : if (aOther.mFramesPerSecond.WasPassed()) {
2653 0 : mFramesPerSecond.Construct(aOther.mFramesPerSecond.Value());
2654 : }
2655 0 : mFramesReceived.Reset();
2656 0 : if (aOther.mFramesReceived.WasPassed()) {
2657 0 : mFramesReceived.Construct(aOther.mFramesReceived.Value());
2658 : }
2659 0 : mFramesSent.Reset();
2660 0 : if (aOther.mFramesSent.WasPassed()) {
2661 0 : mFramesSent.Construct(aOther.mFramesSent.Value());
2662 : }
2663 0 : mRemoteSource.Reset();
2664 0 : if (aOther.mRemoteSource.WasPassed()) {
2665 0 : mRemoteSource.Construct(aOther.mRemoteSource.Value());
2666 : }
2667 0 : mSsrcIds.Reset();
2668 0 : if (aOther.mSsrcIds.WasPassed()) {
2669 0 : mSsrcIds.Construct(aOther.mSsrcIds.Value());
2670 : }
2671 0 : mTrackIdentifier.Reset();
2672 0 : if (aOther.mTrackIdentifier.WasPassed()) {
2673 0 : mTrackIdentifier.Construct(aOther.mTrackIdentifier.Value());
2674 : }
2675 0 : return *this;
2676 : }
2677 :
2678 : namespace binding_detail {
2679 : } // namespace binding_detail
2680 :
2681 :
2682 :
2683 0 : RTCRTPContributingSourceStats::RTCRTPContributingSourceStats()
2684 0 : : RTCStats(FastDictionaryInitializer())
2685 : {
2686 : // Safe to pass a null context if we pass a null value
2687 0 : Init(nullptr, JS::NullHandleValue);
2688 0 : }
2689 :
2690 :
2691 :
2692 : bool
2693 0 : RTCRTPContributingSourceStats::InitIds(JSContext* cx, RTCRTPContributingSourceStatsAtoms* atomsCache)
2694 : {
2695 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
2696 :
2697 : // Initialize these in reverse order so that any failure leaves the first one
2698 : // uninitialized.
2699 0 : if (!atomsCache->inboundRtpStreamId_id.init(cx, "inboundRtpStreamId") ||
2700 0 : !atomsCache->contributorSsrc_id.init(cx, "contributorSsrc")) {
2701 0 : return false;
2702 : }
2703 0 : return true;
2704 : }
2705 :
2706 : bool
2707 0 : RTCRTPContributingSourceStats::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
2708 : {
2709 : // Passing a null JSContext is OK only if we're initing from null,
2710 : // Since in that case we will not have to do any property gets
2711 : // Also evaluate isNullOrUndefined in order to avoid false-positive
2712 : // checkers by static analysis tools
2713 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
2714 0 : RTCRTPContributingSourceStatsAtoms* atomsCache = nullptr;
2715 0 : if (cx) {
2716 0 : atomsCache = GetAtomCache<RTCRTPContributingSourceStatsAtoms>(cx);
2717 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2718 0 : return false;
2719 : }
2720 : }
2721 :
2722 : // Per spec, we init the parent's members first
2723 0 : if (!RTCStats::Init(cx, val)) {
2724 0 : return false;
2725 : }
2726 :
2727 0 : bool isNull = val.isNullOrUndefined();
2728 : // We only need these if !isNull, in which case we have |cx|.
2729 0 : Maybe<JS::Rooted<JSObject *> > object;
2730 0 : Maybe<JS::Rooted<JS::Value> > temp;
2731 0 : if (!isNull) {
2732 0 : MOZ_ASSERT(cx);
2733 0 : object.emplace(cx, &val.toObject());
2734 0 : temp.emplace(cx);
2735 : }
2736 0 : if (!isNull) {
2737 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->contributorSsrc_id, temp.ptr())) {
2738 0 : return false;
2739 : }
2740 : }
2741 0 : if (!isNull && !temp->isUndefined()) {
2742 0 : mContributorSsrc.Construct();
2743 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mContributorSsrc.Value()))) {
2744 0 : return false;
2745 : }
2746 0 : mIsAnyMemberPresent = true;
2747 : }
2748 :
2749 0 : if (!isNull) {
2750 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->inboundRtpStreamId_id, temp.ptr())) {
2751 0 : return false;
2752 : }
2753 : }
2754 0 : if (!isNull && !temp->isUndefined()) {
2755 0 : mInboundRtpStreamId.Construct();
2756 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mInboundRtpStreamId.Value()))) {
2757 0 : return false;
2758 : }
2759 0 : mIsAnyMemberPresent = true;
2760 : }
2761 0 : return true;
2762 : }
2763 :
2764 : bool
2765 0 : RTCRTPContributingSourceStats::Init(const nsAString& aJSON)
2766 : {
2767 0 : AutoJSAPI jsapi;
2768 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
2769 0 : if (!cleanGlobal) {
2770 0 : return false;
2771 : }
2772 0 : if (!jsapi.Init(cleanGlobal)) {
2773 0 : return false;
2774 : }
2775 0 : JSContext* cx = jsapi.cx();
2776 0 : JS::Rooted<JS::Value> json(cx);
2777 0 : bool ok = ParseJSON(cx, aJSON, &json);
2778 0 : NS_ENSURE_TRUE(ok, false);
2779 0 : return Init(cx, json);
2780 : }
2781 :
2782 : bool
2783 0 : RTCRTPContributingSourceStats::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
2784 : {
2785 0 : RTCRTPContributingSourceStatsAtoms* atomsCache = GetAtomCache<RTCRTPContributingSourceStatsAtoms>(cx);
2786 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2787 0 : return false;
2788 : }
2789 :
2790 : // Per spec, we define the parent's members first
2791 0 : if (!RTCStats::ToObjectInternal(cx, rval)) {
2792 0 : return false;
2793 : }
2794 0 : JS::Rooted<JSObject*> obj(cx, &rval.toObject());
2795 :
2796 0 : if (mContributorSsrc.WasPassed()) {
2797 : do {
2798 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2799 0 : JS::Rooted<JS::Value> temp(cx);
2800 0 : uint32_t const & currentValue = mContributorSsrc.InternalValue();
2801 0 : temp.setNumber(currentValue);
2802 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->contributorSsrc_id, temp, JSPROP_ENUMERATE)) {
2803 0 : return false;
2804 : }
2805 0 : break;
2806 : } while(0);
2807 : }
2808 :
2809 0 : if (mInboundRtpStreamId.WasPassed()) {
2810 : do {
2811 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2812 0 : JS::Rooted<JS::Value> temp(cx);
2813 0 : nsString const & currentValue = mInboundRtpStreamId.InternalValue();
2814 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
2815 0 : return false;
2816 : }
2817 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->inboundRtpStreamId_id, temp, JSPROP_ENUMERATE)) {
2818 0 : return false;
2819 : }
2820 0 : break;
2821 : } while(0);
2822 : }
2823 :
2824 0 : return true;
2825 : }
2826 :
2827 : bool
2828 0 : RTCRTPContributingSourceStats::ToJSON(nsAString& aJSON) const
2829 : {
2830 0 : AutoJSAPI jsapi;
2831 0 : jsapi.Init();
2832 0 : JSContext *cx = jsapi.cx();
2833 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
2834 : // because we'll only be creating objects, in ways that have no
2835 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
2836 : // which likewise guarantees no side-effects for the sorts of
2837 : // things we will pass it.
2838 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
2839 0 : JS::Rooted<JS::Value> val(cx);
2840 0 : if (!ToObjectInternal(cx, &val)) {
2841 0 : return false;
2842 : }
2843 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
2844 0 : return StringifyToJSON(cx, obj, aJSON);
2845 : }
2846 :
2847 : void
2848 0 : RTCRTPContributingSourceStats::TraceDictionary(JSTracer* trc)
2849 : {
2850 0 : RTCStats::TraceDictionary(trc);
2851 0 : }
2852 :
2853 : RTCRTPContributingSourceStats&
2854 0 : RTCRTPContributingSourceStats::operator=(const RTCRTPContributingSourceStats& aOther)
2855 : {
2856 0 : RTCStats::operator=(aOther);
2857 0 : mContributorSsrc.Reset();
2858 0 : if (aOther.mContributorSsrc.WasPassed()) {
2859 0 : mContributorSsrc.Construct(aOther.mContributorSsrc.Value());
2860 : }
2861 0 : mInboundRtpStreamId.Reset();
2862 0 : if (aOther.mInboundRtpStreamId.WasPassed()) {
2863 0 : mInboundRtpStreamId.Construct(aOther.mInboundRtpStreamId.Value());
2864 : }
2865 0 : return *this;
2866 : }
2867 :
2868 : namespace binding_detail {
2869 : } // namespace binding_detail
2870 :
2871 :
2872 :
2873 0 : RTCRTPStreamStats::RTCRTPStreamStats()
2874 0 : : RTCStats(FastDictionaryInitializer())
2875 : {
2876 : // Safe to pass a null context if we pass a null value
2877 0 : Init(nullptr, JS::NullHandleValue);
2878 0 : }
2879 :
2880 :
2881 :
2882 : bool
2883 0 : RTCRTPStreamStats::InitIds(JSContext* cx, RTCRTPStreamStatsAtoms* atomsCache)
2884 : {
2885 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
2886 :
2887 : // Initialize these in reverse order so that any failure leaves the first one
2888 : // uninitialized.
2889 0 : if (!atomsCache->transportId_id.init(cx, "transportId") ||
2890 0 : !atomsCache->ssrc_id.init(cx, "ssrc") ||
2891 0 : !atomsCache->remoteId_id.init(cx, "remoteId") ||
2892 0 : !atomsCache->pliCount_id.init(cx, "pliCount") ||
2893 0 : !atomsCache->nackCount_id.init(cx, "nackCount") ||
2894 0 : !atomsCache->mediaType_id.init(cx, "mediaType") ||
2895 0 : !atomsCache->mediaTrackId_id.init(cx, "mediaTrackId") ||
2896 0 : !atomsCache->isRemote_id.init(cx, "isRemote") ||
2897 0 : !atomsCache->framerateStdDev_id.init(cx, "framerateStdDev") ||
2898 0 : !atomsCache->framerateMean_id.init(cx, "framerateMean") ||
2899 0 : !atomsCache->firCount_id.init(cx, "firCount") ||
2900 0 : !atomsCache->codecId_id.init(cx, "codecId") ||
2901 0 : !atomsCache->bitrateStdDev_id.init(cx, "bitrateStdDev") ||
2902 0 : !atomsCache->bitrateMean_id.init(cx, "bitrateMean")) {
2903 0 : return false;
2904 : }
2905 0 : return true;
2906 : }
2907 :
2908 : bool
2909 0 : RTCRTPStreamStats::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
2910 : {
2911 : // Passing a null JSContext is OK only if we're initing from null,
2912 : // Since in that case we will not have to do any property gets
2913 : // Also evaluate isNullOrUndefined in order to avoid false-positive
2914 : // checkers by static analysis tools
2915 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
2916 0 : RTCRTPStreamStatsAtoms* atomsCache = nullptr;
2917 0 : if (cx) {
2918 0 : atomsCache = GetAtomCache<RTCRTPStreamStatsAtoms>(cx);
2919 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2920 0 : return false;
2921 : }
2922 : }
2923 :
2924 : // Per spec, we init the parent's members first
2925 0 : if (!RTCStats::Init(cx, val)) {
2926 0 : return false;
2927 : }
2928 :
2929 0 : bool isNull = val.isNullOrUndefined();
2930 : // We only need these if !isNull, in which case we have |cx|.
2931 0 : Maybe<JS::Rooted<JSObject *> > object;
2932 0 : Maybe<JS::Rooted<JS::Value> > temp;
2933 0 : if (!isNull) {
2934 0 : MOZ_ASSERT(cx);
2935 0 : object.emplace(cx, &val.toObject());
2936 0 : temp.emplace(cx);
2937 : }
2938 0 : if (!isNull) {
2939 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->bitrateMean_id, temp.ptr())) {
2940 0 : return false;
2941 : }
2942 : }
2943 0 : if (!isNull && !temp->isUndefined()) {
2944 0 : mBitrateMean.Construct();
2945 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &(mBitrateMean.Value()))) {
2946 0 : return false;
2947 0 : } else if (!mozilla::IsFinite((mBitrateMean.Value()))) {
2948 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'bitrateMean' member of RTCRTPStreamStats");
2949 0 : return false;
2950 : }
2951 0 : mIsAnyMemberPresent = true;
2952 : }
2953 :
2954 0 : if (!isNull) {
2955 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->bitrateStdDev_id, temp.ptr())) {
2956 0 : return false;
2957 : }
2958 : }
2959 0 : if (!isNull && !temp->isUndefined()) {
2960 0 : mBitrateStdDev.Construct();
2961 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &(mBitrateStdDev.Value()))) {
2962 0 : return false;
2963 0 : } else if (!mozilla::IsFinite((mBitrateStdDev.Value()))) {
2964 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'bitrateStdDev' member of RTCRTPStreamStats");
2965 0 : return false;
2966 : }
2967 0 : mIsAnyMemberPresent = true;
2968 : }
2969 :
2970 0 : if (!isNull) {
2971 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->codecId_id, temp.ptr())) {
2972 0 : return false;
2973 : }
2974 : }
2975 0 : if (!isNull && !temp->isUndefined()) {
2976 0 : mCodecId.Construct();
2977 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mCodecId.Value()))) {
2978 0 : return false;
2979 : }
2980 0 : mIsAnyMemberPresent = true;
2981 : }
2982 :
2983 0 : if (!isNull) {
2984 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->firCount_id, temp.ptr())) {
2985 0 : return false;
2986 : }
2987 : }
2988 0 : if (!isNull && !temp->isUndefined()) {
2989 0 : mFirCount.Construct();
2990 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mFirCount.Value()))) {
2991 0 : return false;
2992 : }
2993 0 : mIsAnyMemberPresent = true;
2994 : }
2995 :
2996 0 : if (!isNull) {
2997 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->framerateMean_id, temp.ptr())) {
2998 0 : return false;
2999 : }
3000 : }
3001 0 : if (!isNull && !temp->isUndefined()) {
3002 0 : mFramerateMean.Construct();
3003 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &(mFramerateMean.Value()))) {
3004 0 : return false;
3005 0 : } else if (!mozilla::IsFinite((mFramerateMean.Value()))) {
3006 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'framerateMean' member of RTCRTPStreamStats");
3007 0 : return false;
3008 : }
3009 0 : mIsAnyMemberPresent = true;
3010 : }
3011 :
3012 0 : if (!isNull) {
3013 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->framerateStdDev_id, temp.ptr())) {
3014 0 : return false;
3015 : }
3016 : }
3017 0 : if (!isNull && !temp->isUndefined()) {
3018 0 : mFramerateStdDev.Construct();
3019 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &(mFramerateStdDev.Value()))) {
3020 0 : return false;
3021 0 : } else if (!mozilla::IsFinite((mFramerateStdDev.Value()))) {
3022 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'framerateStdDev' member of RTCRTPStreamStats");
3023 0 : return false;
3024 : }
3025 0 : mIsAnyMemberPresent = true;
3026 : }
3027 :
3028 0 : if (!isNull) {
3029 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->isRemote_id, temp.ptr())) {
3030 0 : return false;
3031 : }
3032 : }
3033 0 : if (!isNull && !temp->isUndefined()) {
3034 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mIsRemote)) {
3035 0 : return false;
3036 : }
3037 : } else {
3038 0 : mIsRemote = false;
3039 : }
3040 0 : mIsAnyMemberPresent = true;
3041 :
3042 0 : if (!isNull) {
3043 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->mediaTrackId_id, temp.ptr())) {
3044 0 : return false;
3045 : }
3046 : }
3047 0 : if (!isNull && !temp->isUndefined()) {
3048 0 : mMediaTrackId.Construct();
3049 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mMediaTrackId.Value()))) {
3050 0 : return false;
3051 : }
3052 0 : mIsAnyMemberPresent = true;
3053 : }
3054 :
3055 0 : if (!isNull) {
3056 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->mediaType_id, temp.ptr())) {
3057 0 : return false;
3058 : }
3059 : }
3060 0 : if (!isNull && !temp->isUndefined()) {
3061 0 : mMediaType.Construct();
3062 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mMediaType.Value()))) {
3063 0 : return false;
3064 : }
3065 0 : mIsAnyMemberPresent = true;
3066 : }
3067 :
3068 0 : if (!isNull) {
3069 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->nackCount_id, temp.ptr())) {
3070 0 : return false;
3071 : }
3072 : }
3073 0 : if (!isNull && !temp->isUndefined()) {
3074 0 : mNackCount.Construct();
3075 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mNackCount.Value()))) {
3076 0 : return false;
3077 : }
3078 0 : mIsAnyMemberPresent = true;
3079 : }
3080 :
3081 0 : if (!isNull) {
3082 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->pliCount_id, temp.ptr())) {
3083 0 : return false;
3084 : }
3085 : }
3086 0 : if (!isNull && !temp->isUndefined()) {
3087 0 : mPliCount.Construct();
3088 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mPliCount.Value()))) {
3089 0 : return false;
3090 : }
3091 0 : mIsAnyMemberPresent = true;
3092 : }
3093 :
3094 0 : if (!isNull) {
3095 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->remoteId_id, temp.ptr())) {
3096 0 : return false;
3097 : }
3098 : }
3099 0 : if (!isNull && !temp->isUndefined()) {
3100 0 : mRemoteId.Construct();
3101 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mRemoteId.Value()))) {
3102 0 : return false;
3103 : }
3104 0 : mIsAnyMemberPresent = true;
3105 : }
3106 :
3107 0 : if (!isNull) {
3108 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->ssrc_id, temp.ptr())) {
3109 0 : return false;
3110 : }
3111 : }
3112 0 : if (!isNull && !temp->isUndefined()) {
3113 0 : mSsrc.Construct();
3114 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mSsrc.Value()))) {
3115 0 : return false;
3116 : }
3117 0 : mIsAnyMemberPresent = true;
3118 : }
3119 :
3120 0 : if (!isNull) {
3121 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->transportId_id, temp.ptr())) {
3122 0 : return false;
3123 : }
3124 : }
3125 0 : if (!isNull && !temp->isUndefined()) {
3126 0 : mTransportId.Construct();
3127 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mTransportId.Value()))) {
3128 0 : return false;
3129 : }
3130 0 : mIsAnyMemberPresent = true;
3131 : }
3132 0 : return true;
3133 : }
3134 :
3135 : bool
3136 0 : RTCRTPStreamStats::Init(const nsAString& aJSON)
3137 : {
3138 0 : AutoJSAPI jsapi;
3139 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
3140 0 : if (!cleanGlobal) {
3141 0 : return false;
3142 : }
3143 0 : if (!jsapi.Init(cleanGlobal)) {
3144 0 : return false;
3145 : }
3146 0 : JSContext* cx = jsapi.cx();
3147 0 : JS::Rooted<JS::Value> json(cx);
3148 0 : bool ok = ParseJSON(cx, aJSON, &json);
3149 0 : NS_ENSURE_TRUE(ok, false);
3150 0 : return Init(cx, json);
3151 : }
3152 :
3153 : bool
3154 0 : RTCRTPStreamStats::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
3155 : {
3156 0 : RTCRTPStreamStatsAtoms* atomsCache = GetAtomCache<RTCRTPStreamStatsAtoms>(cx);
3157 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
3158 0 : return false;
3159 : }
3160 :
3161 : // Per spec, we define the parent's members first
3162 0 : if (!RTCStats::ToObjectInternal(cx, rval)) {
3163 0 : return false;
3164 : }
3165 0 : JS::Rooted<JSObject*> obj(cx, &rval.toObject());
3166 :
3167 0 : if (mBitrateMean.WasPassed()) {
3168 : do {
3169 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3170 0 : JS::Rooted<JS::Value> temp(cx);
3171 0 : double const & currentValue = mBitrateMean.InternalValue();
3172 0 : temp.set(JS_NumberValue(double(currentValue)));
3173 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->bitrateMean_id, temp, JSPROP_ENUMERATE)) {
3174 0 : return false;
3175 : }
3176 0 : break;
3177 : } while(0);
3178 : }
3179 :
3180 0 : if (mBitrateStdDev.WasPassed()) {
3181 : do {
3182 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3183 0 : JS::Rooted<JS::Value> temp(cx);
3184 0 : double const & currentValue = mBitrateStdDev.InternalValue();
3185 0 : temp.set(JS_NumberValue(double(currentValue)));
3186 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->bitrateStdDev_id, temp, JSPROP_ENUMERATE)) {
3187 0 : return false;
3188 : }
3189 0 : break;
3190 : } while(0);
3191 : }
3192 :
3193 0 : if (mCodecId.WasPassed()) {
3194 : do {
3195 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3196 0 : JS::Rooted<JS::Value> temp(cx);
3197 0 : nsString const & currentValue = mCodecId.InternalValue();
3198 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3199 0 : return false;
3200 : }
3201 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->codecId_id, temp, JSPROP_ENUMERATE)) {
3202 0 : return false;
3203 : }
3204 0 : break;
3205 : } while(0);
3206 : }
3207 :
3208 0 : if (mFirCount.WasPassed()) {
3209 : do {
3210 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3211 0 : JS::Rooted<JS::Value> temp(cx);
3212 0 : uint32_t const & currentValue = mFirCount.InternalValue();
3213 0 : temp.setNumber(currentValue);
3214 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->firCount_id, temp, JSPROP_ENUMERATE)) {
3215 0 : return false;
3216 : }
3217 0 : break;
3218 : } while(0);
3219 : }
3220 :
3221 0 : if (mFramerateMean.WasPassed()) {
3222 : do {
3223 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3224 0 : JS::Rooted<JS::Value> temp(cx);
3225 0 : double const & currentValue = mFramerateMean.InternalValue();
3226 0 : temp.set(JS_NumberValue(double(currentValue)));
3227 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->framerateMean_id, temp, JSPROP_ENUMERATE)) {
3228 0 : return false;
3229 : }
3230 0 : break;
3231 : } while(0);
3232 : }
3233 :
3234 0 : if (mFramerateStdDev.WasPassed()) {
3235 : do {
3236 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3237 0 : JS::Rooted<JS::Value> temp(cx);
3238 0 : double const & currentValue = mFramerateStdDev.InternalValue();
3239 0 : temp.set(JS_NumberValue(double(currentValue)));
3240 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->framerateStdDev_id, temp, JSPROP_ENUMERATE)) {
3241 0 : return false;
3242 : }
3243 0 : break;
3244 : } while(0);
3245 : }
3246 :
3247 : do {
3248 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3249 0 : JS::Rooted<JS::Value> temp(cx);
3250 0 : bool const & currentValue = mIsRemote;
3251 0 : temp.setBoolean(currentValue);
3252 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->isRemote_id, temp, JSPROP_ENUMERATE)) {
3253 0 : return false;
3254 : }
3255 0 : break;
3256 : } while(0);
3257 :
3258 0 : if (mMediaTrackId.WasPassed()) {
3259 : do {
3260 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3261 0 : JS::Rooted<JS::Value> temp(cx);
3262 0 : nsString const & currentValue = mMediaTrackId.InternalValue();
3263 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3264 0 : return false;
3265 : }
3266 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->mediaTrackId_id, temp, JSPROP_ENUMERATE)) {
3267 0 : return false;
3268 : }
3269 0 : break;
3270 : } while(0);
3271 : }
3272 :
3273 0 : if (mMediaType.WasPassed()) {
3274 : do {
3275 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3276 0 : JS::Rooted<JS::Value> temp(cx);
3277 0 : nsString const & currentValue = mMediaType.InternalValue();
3278 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3279 0 : return false;
3280 : }
3281 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->mediaType_id, temp, JSPROP_ENUMERATE)) {
3282 0 : return false;
3283 : }
3284 0 : break;
3285 : } while(0);
3286 : }
3287 :
3288 0 : if (mNackCount.WasPassed()) {
3289 : do {
3290 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3291 0 : JS::Rooted<JS::Value> temp(cx);
3292 0 : uint32_t const & currentValue = mNackCount.InternalValue();
3293 0 : temp.setNumber(currentValue);
3294 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->nackCount_id, temp, JSPROP_ENUMERATE)) {
3295 0 : return false;
3296 : }
3297 0 : break;
3298 : } while(0);
3299 : }
3300 :
3301 0 : if (mPliCount.WasPassed()) {
3302 : do {
3303 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3304 0 : JS::Rooted<JS::Value> temp(cx);
3305 0 : uint32_t const & currentValue = mPliCount.InternalValue();
3306 0 : temp.setNumber(currentValue);
3307 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->pliCount_id, temp, JSPROP_ENUMERATE)) {
3308 0 : return false;
3309 : }
3310 0 : break;
3311 : } while(0);
3312 : }
3313 :
3314 0 : if (mRemoteId.WasPassed()) {
3315 : do {
3316 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3317 0 : JS::Rooted<JS::Value> temp(cx);
3318 0 : nsString const & currentValue = mRemoteId.InternalValue();
3319 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3320 0 : return false;
3321 : }
3322 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->remoteId_id, temp, JSPROP_ENUMERATE)) {
3323 0 : return false;
3324 : }
3325 0 : break;
3326 : } while(0);
3327 : }
3328 :
3329 0 : if (mSsrc.WasPassed()) {
3330 : do {
3331 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3332 0 : JS::Rooted<JS::Value> temp(cx);
3333 0 : nsString const & currentValue = mSsrc.InternalValue();
3334 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3335 0 : return false;
3336 : }
3337 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->ssrc_id, temp, JSPROP_ENUMERATE)) {
3338 0 : return false;
3339 : }
3340 0 : break;
3341 : } while(0);
3342 : }
3343 :
3344 0 : if (mTransportId.WasPassed()) {
3345 : do {
3346 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3347 0 : JS::Rooted<JS::Value> temp(cx);
3348 0 : nsString const & currentValue = mTransportId.InternalValue();
3349 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3350 0 : return false;
3351 : }
3352 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->transportId_id, temp, JSPROP_ENUMERATE)) {
3353 0 : return false;
3354 : }
3355 0 : break;
3356 : } while(0);
3357 : }
3358 :
3359 0 : return true;
3360 : }
3361 :
3362 : bool
3363 0 : RTCRTPStreamStats::ToJSON(nsAString& aJSON) const
3364 : {
3365 0 : AutoJSAPI jsapi;
3366 0 : jsapi.Init();
3367 0 : JSContext *cx = jsapi.cx();
3368 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
3369 : // because we'll only be creating objects, in ways that have no
3370 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
3371 : // which likewise guarantees no side-effects for the sorts of
3372 : // things we will pass it.
3373 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
3374 0 : JS::Rooted<JS::Value> val(cx);
3375 0 : if (!ToObjectInternal(cx, &val)) {
3376 0 : return false;
3377 : }
3378 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
3379 0 : return StringifyToJSON(cx, obj, aJSON);
3380 : }
3381 :
3382 : void
3383 0 : RTCRTPStreamStats::TraceDictionary(JSTracer* trc)
3384 : {
3385 0 : RTCStats::TraceDictionary(trc);
3386 0 : }
3387 :
3388 : RTCRTPStreamStats&
3389 0 : RTCRTPStreamStats::operator=(const RTCRTPStreamStats& aOther)
3390 : {
3391 0 : RTCStats::operator=(aOther);
3392 0 : mBitrateMean.Reset();
3393 0 : if (aOther.mBitrateMean.WasPassed()) {
3394 0 : mBitrateMean.Construct(aOther.mBitrateMean.Value());
3395 : }
3396 0 : mBitrateStdDev.Reset();
3397 0 : if (aOther.mBitrateStdDev.WasPassed()) {
3398 0 : mBitrateStdDev.Construct(aOther.mBitrateStdDev.Value());
3399 : }
3400 0 : mCodecId.Reset();
3401 0 : if (aOther.mCodecId.WasPassed()) {
3402 0 : mCodecId.Construct(aOther.mCodecId.Value());
3403 : }
3404 0 : mFirCount.Reset();
3405 0 : if (aOther.mFirCount.WasPassed()) {
3406 0 : mFirCount.Construct(aOther.mFirCount.Value());
3407 : }
3408 0 : mFramerateMean.Reset();
3409 0 : if (aOther.mFramerateMean.WasPassed()) {
3410 0 : mFramerateMean.Construct(aOther.mFramerateMean.Value());
3411 : }
3412 0 : mFramerateStdDev.Reset();
3413 0 : if (aOther.mFramerateStdDev.WasPassed()) {
3414 0 : mFramerateStdDev.Construct(aOther.mFramerateStdDev.Value());
3415 : }
3416 0 : mIsRemote = aOther.mIsRemote;
3417 0 : mMediaTrackId.Reset();
3418 0 : if (aOther.mMediaTrackId.WasPassed()) {
3419 0 : mMediaTrackId.Construct(aOther.mMediaTrackId.Value());
3420 : }
3421 0 : mMediaType.Reset();
3422 0 : if (aOther.mMediaType.WasPassed()) {
3423 0 : mMediaType.Construct(aOther.mMediaType.Value());
3424 : }
3425 0 : mNackCount.Reset();
3426 0 : if (aOther.mNackCount.WasPassed()) {
3427 0 : mNackCount.Construct(aOther.mNackCount.Value());
3428 : }
3429 0 : mPliCount.Reset();
3430 0 : if (aOther.mPliCount.WasPassed()) {
3431 0 : mPliCount.Construct(aOther.mPliCount.Value());
3432 : }
3433 0 : mRemoteId.Reset();
3434 0 : if (aOther.mRemoteId.WasPassed()) {
3435 0 : mRemoteId.Construct(aOther.mRemoteId.Value());
3436 : }
3437 0 : mSsrc.Reset();
3438 0 : if (aOther.mSsrc.WasPassed()) {
3439 0 : mSsrc.Construct(aOther.mSsrc.Value());
3440 : }
3441 0 : mTransportId.Reset();
3442 0 : if (aOther.mTransportId.WasPassed()) {
3443 0 : mTransportId.Construct(aOther.mTransportId.Value());
3444 : }
3445 0 : return *this;
3446 : }
3447 :
3448 : namespace binding_detail {
3449 : } // namespace binding_detail
3450 :
3451 :
3452 :
3453 0 : RTCTransportStats::RTCTransportStats()
3454 0 : : RTCStats(FastDictionaryInitializer())
3455 : {
3456 : // Safe to pass a null context if we pass a null value
3457 0 : Init(nullptr, JS::NullHandleValue);
3458 0 : }
3459 :
3460 :
3461 :
3462 : bool
3463 0 : RTCTransportStats::InitIds(JSContext* cx, RTCTransportStatsAtoms* atomsCache)
3464 : {
3465 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
3466 :
3467 : // Initialize these in reverse order so that any failure leaves the first one
3468 : // uninitialized.
3469 0 : if (!atomsCache->bytesSent_id.init(cx, "bytesSent") ||
3470 0 : !atomsCache->bytesReceived_id.init(cx, "bytesReceived")) {
3471 0 : return false;
3472 : }
3473 0 : return true;
3474 : }
3475 :
3476 : bool
3477 0 : RTCTransportStats::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
3478 : {
3479 : // Passing a null JSContext is OK only if we're initing from null,
3480 : // Since in that case we will not have to do any property gets
3481 : // Also evaluate isNullOrUndefined in order to avoid false-positive
3482 : // checkers by static analysis tools
3483 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
3484 0 : RTCTransportStatsAtoms* atomsCache = nullptr;
3485 0 : if (cx) {
3486 0 : atomsCache = GetAtomCache<RTCTransportStatsAtoms>(cx);
3487 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
3488 0 : return false;
3489 : }
3490 : }
3491 :
3492 : // Per spec, we init the parent's members first
3493 0 : if (!RTCStats::Init(cx, val)) {
3494 0 : return false;
3495 : }
3496 :
3497 0 : bool isNull = val.isNullOrUndefined();
3498 : // We only need these if !isNull, in which case we have |cx|.
3499 0 : Maybe<JS::Rooted<JSObject *> > object;
3500 0 : Maybe<JS::Rooted<JS::Value> > temp;
3501 0 : if (!isNull) {
3502 0 : MOZ_ASSERT(cx);
3503 0 : object.emplace(cx, &val.toObject());
3504 0 : temp.emplace(cx);
3505 : }
3506 0 : if (!isNull) {
3507 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->bytesReceived_id, temp.ptr())) {
3508 0 : return false;
3509 : }
3510 : }
3511 0 : if (!isNull && !temp->isUndefined()) {
3512 0 : mBytesReceived.Construct();
3513 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mBytesReceived.Value()))) {
3514 0 : return false;
3515 : }
3516 0 : mIsAnyMemberPresent = true;
3517 : }
3518 :
3519 0 : if (!isNull) {
3520 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->bytesSent_id, temp.ptr())) {
3521 0 : return false;
3522 : }
3523 : }
3524 0 : if (!isNull && !temp->isUndefined()) {
3525 0 : mBytesSent.Construct();
3526 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mBytesSent.Value()))) {
3527 0 : return false;
3528 : }
3529 0 : mIsAnyMemberPresent = true;
3530 : }
3531 0 : return true;
3532 : }
3533 :
3534 : bool
3535 0 : RTCTransportStats::Init(const nsAString& aJSON)
3536 : {
3537 0 : AutoJSAPI jsapi;
3538 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
3539 0 : if (!cleanGlobal) {
3540 0 : return false;
3541 : }
3542 0 : if (!jsapi.Init(cleanGlobal)) {
3543 0 : return false;
3544 : }
3545 0 : JSContext* cx = jsapi.cx();
3546 0 : JS::Rooted<JS::Value> json(cx);
3547 0 : bool ok = ParseJSON(cx, aJSON, &json);
3548 0 : NS_ENSURE_TRUE(ok, false);
3549 0 : return Init(cx, json);
3550 : }
3551 :
3552 : bool
3553 0 : RTCTransportStats::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
3554 : {
3555 0 : RTCTransportStatsAtoms* atomsCache = GetAtomCache<RTCTransportStatsAtoms>(cx);
3556 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
3557 0 : return false;
3558 : }
3559 :
3560 : // Per spec, we define the parent's members first
3561 0 : if (!RTCStats::ToObjectInternal(cx, rval)) {
3562 0 : return false;
3563 : }
3564 0 : JS::Rooted<JSObject*> obj(cx, &rval.toObject());
3565 :
3566 0 : if (mBytesReceived.WasPassed()) {
3567 : do {
3568 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3569 0 : JS::Rooted<JS::Value> temp(cx);
3570 0 : uint32_t const & currentValue = mBytesReceived.InternalValue();
3571 0 : temp.setNumber(currentValue);
3572 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->bytesReceived_id, temp, JSPROP_ENUMERATE)) {
3573 0 : return false;
3574 : }
3575 0 : break;
3576 : } while(0);
3577 : }
3578 :
3579 0 : if (mBytesSent.WasPassed()) {
3580 : do {
3581 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3582 0 : JS::Rooted<JS::Value> temp(cx);
3583 0 : uint32_t const & currentValue = mBytesSent.InternalValue();
3584 0 : temp.setNumber(currentValue);
3585 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->bytesSent_id, temp, JSPROP_ENUMERATE)) {
3586 0 : return false;
3587 : }
3588 0 : break;
3589 : } while(0);
3590 : }
3591 :
3592 0 : return true;
3593 : }
3594 :
3595 : bool
3596 0 : RTCTransportStats::ToJSON(nsAString& aJSON) const
3597 : {
3598 0 : AutoJSAPI jsapi;
3599 0 : jsapi.Init();
3600 0 : JSContext *cx = jsapi.cx();
3601 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
3602 : // because we'll only be creating objects, in ways that have no
3603 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
3604 : // which likewise guarantees no side-effects for the sorts of
3605 : // things we will pass it.
3606 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
3607 0 : JS::Rooted<JS::Value> val(cx);
3608 0 : if (!ToObjectInternal(cx, &val)) {
3609 0 : return false;
3610 : }
3611 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
3612 0 : return StringifyToJSON(cx, obj, aJSON);
3613 : }
3614 :
3615 : void
3616 0 : RTCTransportStats::TraceDictionary(JSTracer* trc)
3617 : {
3618 0 : RTCStats::TraceDictionary(trc);
3619 0 : }
3620 :
3621 : RTCTransportStats&
3622 0 : RTCTransportStats::operator=(const RTCTransportStats& aOther)
3623 : {
3624 0 : RTCStats::operator=(aOther);
3625 0 : mBytesReceived.Reset();
3626 0 : if (aOther.mBytesReceived.WasPassed()) {
3627 0 : mBytesReceived.Construct(aOther.mBytesReceived.Value());
3628 : }
3629 0 : mBytesSent.Reset();
3630 0 : if (aOther.mBytesSent.WasPassed()) {
3631 0 : mBytesSent.Construct(aOther.mBytesSent.Value());
3632 : }
3633 0 : return *this;
3634 : }
3635 :
3636 : namespace binding_detail {
3637 : } // namespace binding_detail
3638 :
3639 :
3640 :
3641 0 : RTCInboundRTPStreamStats::RTCInboundRTPStreamStats()
3642 0 : : RTCRTPStreamStats(FastDictionaryInitializer())
3643 : {
3644 : // Safe to pass a null context if we pass a null value
3645 0 : Init(nullptr, JS::NullHandleValue);
3646 0 : }
3647 :
3648 :
3649 :
3650 : bool
3651 0 : RTCInboundRTPStreamStats::InitIds(JSContext* cx, RTCInboundRTPStreamStatsAtoms* atomsCache)
3652 : {
3653 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
3654 :
3655 : // Initialize these in reverse order so that any failure leaves the first one
3656 : // uninitialized.
3657 0 : if (!atomsCache->roundTripTime_id.init(cx, "roundTripTime") ||
3658 0 : !atomsCache->packetsReceived_id.init(cx, "packetsReceived") ||
3659 0 : !atomsCache->packetsLost_id.init(cx, "packetsLost") ||
3660 0 : !atomsCache->mozJitterBufferDelay_id.init(cx, "mozJitterBufferDelay") ||
3661 0 : !atomsCache->mozAvSyncDelay_id.init(cx, "mozAvSyncDelay") ||
3662 0 : !atomsCache->jitter_id.init(cx, "jitter") ||
3663 0 : !atomsCache->framesDecoded_id.init(cx, "framesDecoded") ||
3664 0 : !atomsCache->discardedPackets_id.init(cx, "discardedPackets") ||
3665 0 : !atomsCache->bytesReceived_id.init(cx, "bytesReceived")) {
3666 0 : return false;
3667 : }
3668 0 : return true;
3669 : }
3670 :
3671 : bool
3672 0 : RTCInboundRTPStreamStats::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
3673 : {
3674 : // Passing a null JSContext is OK only if we're initing from null,
3675 : // Since in that case we will not have to do any property gets
3676 : // Also evaluate isNullOrUndefined in order to avoid false-positive
3677 : // checkers by static analysis tools
3678 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
3679 0 : RTCInboundRTPStreamStatsAtoms* atomsCache = nullptr;
3680 0 : if (cx) {
3681 0 : atomsCache = GetAtomCache<RTCInboundRTPStreamStatsAtoms>(cx);
3682 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
3683 0 : return false;
3684 : }
3685 : }
3686 :
3687 : // Per spec, we init the parent's members first
3688 0 : if (!RTCRTPStreamStats::Init(cx, val)) {
3689 0 : return false;
3690 : }
3691 :
3692 0 : bool isNull = val.isNullOrUndefined();
3693 : // We only need these if !isNull, in which case we have |cx|.
3694 0 : Maybe<JS::Rooted<JSObject *> > object;
3695 0 : Maybe<JS::Rooted<JS::Value> > temp;
3696 0 : if (!isNull) {
3697 0 : MOZ_ASSERT(cx);
3698 0 : object.emplace(cx, &val.toObject());
3699 0 : temp.emplace(cx);
3700 : }
3701 0 : if (!isNull) {
3702 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->bytesReceived_id, temp.ptr())) {
3703 0 : return false;
3704 : }
3705 : }
3706 0 : if (!isNull && !temp->isUndefined()) {
3707 0 : mBytesReceived.Construct();
3708 0 : if (!ValueToPrimitive<uint64_t, eDefault>(cx, temp.ref(), &(mBytesReceived.Value()))) {
3709 0 : return false;
3710 : }
3711 0 : mIsAnyMemberPresent = true;
3712 : }
3713 :
3714 0 : if (!isNull) {
3715 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->discardedPackets_id, temp.ptr())) {
3716 0 : return false;
3717 : }
3718 : }
3719 0 : if (!isNull && !temp->isUndefined()) {
3720 0 : mDiscardedPackets.Construct();
3721 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mDiscardedPackets.Value()))) {
3722 0 : return false;
3723 : }
3724 0 : mIsAnyMemberPresent = true;
3725 : }
3726 :
3727 0 : if (!isNull) {
3728 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->framesDecoded_id, temp.ptr())) {
3729 0 : return false;
3730 : }
3731 : }
3732 0 : if (!isNull && !temp->isUndefined()) {
3733 0 : mFramesDecoded.Construct();
3734 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mFramesDecoded.Value()))) {
3735 0 : return false;
3736 : }
3737 0 : mIsAnyMemberPresent = true;
3738 : }
3739 :
3740 0 : if (!isNull) {
3741 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->jitter_id, temp.ptr())) {
3742 0 : return false;
3743 : }
3744 : }
3745 0 : if (!isNull && !temp->isUndefined()) {
3746 0 : mJitter.Construct();
3747 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &(mJitter.Value()))) {
3748 0 : return false;
3749 0 : } else if (!mozilla::IsFinite((mJitter.Value()))) {
3750 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'jitter' member of RTCInboundRTPStreamStats");
3751 0 : return false;
3752 : }
3753 0 : mIsAnyMemberPresent = true;
3754 : }
3755 :
3756 0 : if (!isNull) {
3757 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->mozAvSyncDelay_id, temp.ptr())) {
3758 0 : return false;
3759 : }
3760 : }
3761 0 : if (!isNull && !temp->isUndefined()) {
3762 0 : mMozAvSyncDelay.Construct();
3763 0 : if (!ValueToPrimitive<int32_t, eDefault>(cx, temp.ref(), &(mMozAvSyncDelay.Value()))) {
3764 0 : return false;
3765 : }
3766 0 : mIsAnyMemberPresent = true;
3767 : }
3768 :
3769 0 : if (!isNull) {
3770 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->mozJitterBufferDelay_id, temp.ptr())) {
3771 0 : return false;
3772 : }
3773 : }
3774 0 : if (!isNull && !temp->isUndefined()) {
3775 0 : mMozJitterBufferDelay.Construct();
3776 0 : if (!ValueToPrimitive<int32_t, eDefault>(cx, temp.ref(), &(mMozJitterBufferDelay.Value()))) {
3777 0 : return false;
3778 : }
3779 0 : mIsAnyMemberPresent = true;
3780 : }
3781 :
3782 0 : if (!isNull) {
3783 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->packetsLost_id, temp.ptr())) {
3784 0 : return false;
3785 : }
3786 : }
3787 0 : if (!isNull && !temp->isUndefined()) {
3788 0 : mPacketsLost.Construct();
3789 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mPacketsLost.Value()))) {
3790 0 : return false;
3791 : }
3792 0 : mIsAnyMemberPresent = true;
3793 : }
3794 :
3795 0 : if (!isNull) {
3796 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->packetsReceived_id, temp.ptr())) {
3797 0 : return false;
3798 : }
3799 : }
3800 0 : if (!isNull && !temp->isUndefined()) {
3801 0 : mPacketsReceived.Construct();
3802 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mPacketsReceived.Value()))) {
3803 0 : return false;
3804 : }
3805 0 : mIsAnyMemberPresent = true;
3806 : }
3807 :
3808 0 : if (!isNull) {
3809 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->roundTripTime_id, temp.ptr())) {
3810 0 : return false;
3811 : }
3812 : }
3813 0 : if (!isNull && !temp->isUndefined()) {
3814 0 : mRoundTripTime.Construct();
3815 0 : if (!ValueToPrimitive<int32_t, eDefault>(cx, temp.ref(), &(mRoundTripTime.Value()))) {
3816 0 : return false;
3817 : }
3818 0 : mIsAnyMemberPresent = true;
3819 : }
3820 0 : return true;
3821 : }
3822 :
3823 : bool
3824 0 : RTCInboundRTPStreamStats::Init(const nsAString& aJSON)
3825 : {
3826 0 : AutoJSAPI jsapi;
3827 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
3828 0 : if (!cleanGlobal) {
3829 0 : return false;
3830 : }
3831 0 : if (!jsapi.Init(cleanGlobal)) {
3832 0 : return false;
3833 : }
3834 0 : JSContext* cx = jsapi.cx();
3835 0 : JS::Rooted<JS::Value> json(cx);
3836 0 : bool ok = ParseJSON(cx, aJSON, &json);
3837 0 : NS_ENSURE_TRUE(ok, false);
3838 0 : return Init(cx, json);
3839 : }
3840 :
3841 : bool
3842 0 : RTCInboundRTPStreamStats::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
3843 : {
3844 0 : RTCInboundRTPStreamStatsAtoms* atomsCache = GetAtomCache<RTCInboundRTPStreamStatsAtoms>(cx);
3845 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
3846 0 : return false;
3847 : }
3848 :
3849 : // Per spec, we define the parent's members first
3850 0 : if (!RTCRTPStreamStats::ToObjectInternal(cx, rval)) {
3851 0 : return false;
3852 : }
3853 0 : JS::Rooted<JSObject*> obj(cx, &rval.toObject());
3854 :
3855 0 : if (mBytesReceived.WasPassed()) {
3856 : do {
3857 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3858 0 : JS::Rooted<JS::Value> temp(cx);
3859 0 : uint64_t const & currentValue = mBytesReceived.InternalValue();
3860 0 : temp.set(JS_NumberValue(double(currentValue)));
3861 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->bytesReceived_id, temp, JSPROP_ENUMERATE)) {
3862 0 : return false;
3863 : }
3864 0 : break;
3865 : } while(0);
3866 : }
3867 :
3868 0 : if (mDiscardedPackets.WasPassed()) {
3869 : do {
3870 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3871 0 : JS::Rooted<JS::Value> temp(cx);
3872 0 : uint32_t const & currentValue = mDiscardedPackets.InternalValue();
3873 0 : temp.setNumber(currentValue);
3874 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->discardedPackets_id, temp, JSPROP_ENUMERATE)) {
3875 0 : return false;
3876 : }
3877 0 : break;
3878 : } while(0);
3879 : }
3880 :
3881 0 : if (mFramesDecoded.WasPassed()) {
3882 : do {
3883 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3884 0 : JS::Rooted<JS::Value> temp(cx);
3885 0 : uint32_t const & currentValue = mFramesDecoded.InternalValue();
3886 0 : temp.setNumber(currentValue);
3887 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->framesDecoded_id, temp, JSPROP_ENUMERATE)) {
3888 0 : return false;
3889 : }
3890 0 : break;
3891 : } while(0);
3892 : }
3893 :
3894 0 : if (mJitter.WasPassed()) {
3895 : do {
3896 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3897 0 : JS::Rooted<JS::Value> temp(cx);
3898 0 : double const & currentValue = mJitter.InternalValue();
3899 0 : temp.set(JS_NumberValue(double(currentValue)));
3900 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->jitter_id, temp, JSPROP_ENUMERATE)) {
3901 0 : return false;
3902 : }
3903 0 : break;
3904 : } while(0);
3905 : }
3906 :
3907 0 : if (mMozAvSyncDelay.WasPassed()) {
3908 : do {
3909 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3910 0 : JS::Rooted<JS::Value> temp(cx);
3911 0 : int32_t const & currentValue = mMozAvSyncDelay.InternalValue();
3912 0 : temp.setInt32(int32_t(currentValue));
3913 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->mozAvSyncDelay_id, temp, JSPROP_ENUMERATE)) {
3914 0 : return false;
3915 : }
3916 0 : break;
3917 : } while(0);
3918 : }
3919 :
3920 0 : if (mMozJitterBufferDelay.WasPassed()) {
3921 : do {
3922 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3923 0 : JS::Rooted<JS::Value> temp(cx);
3924 0 : int32_t const & currentValue = mMozJitterBufferDelay.InternalValue();
3925 0 : temp.setInt32(int32_t(currentValue));
3926 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->mozJitterBufferDelay_id, temp, JSPROP_ENUMERATE)) {
3927 0 : return false;
3928 : }
3929 0 : break;
3930 : } while(0);
3931 : }
3932 :
3933 0 : if (mPacketsLost.WasPassed()) {
3934 : do {
3935 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3936 0 : JS::Rooted<JS::Value> temp(cx);
3937 0 : uint32_t const & currentValue = mPacketsLost.InternalValue();
3938 0 : temp.setNumber(currentValue);
3939 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->packetsLost_id, temp, JSPROP_ENUMERATE)) {
3940 0 : return false;
3941 : }
3942 0 : break;
3943 : } while(0);
3944 : }
3945 :
3946 0 : if (mPacketsReceived.WasPassed()) {
3947 : do {
3948 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3949 0 : JS::Rooted<JS::Value> temp(cx);
3950 0 : uint32_t const & currentValue = mPacketsReceived.InternalValue();
3951 0 : temp.setNumber(currentValue);
3952 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->packetsReceived_id, temp, JSPROP_ENUMERATE)) {
3953 0 : return false;
3954 : }
3955 0 : break;
3956 : } while(0);
3957 : }
3958 :
3959 0 : if (mRoundTripTime.WasPassed()) {
3960 : do {
3961 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3962 0 : JS::Rooted<JS::Value> temp(cx);
3963 0 : int32_t const & currentValue = mRoundTripTime.InternalValue();
3964 0 : temp.setInt32(int32_t(currentValue));
3965 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->roundTripTime_id, temp, JSPROP_ENUMERATE)) {
3966 0 : return false;
3967 : }
3968 0 : break;
3969 : } while(0);
3970 : }
3971 :
3972 0 : return true;
3973 : }
3974 :
3975 : bool
3976 0 : RTCInboundRTPStreamStats::ToJSON(nsAString& aJSON) const
3977 : {
3978 0 : AutoJSAPI jsapi;
3979 0 : jsapi.Init();
3980 0 : JSContext *cx = jsapi.cx();
3981 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
3982 : // because we'll only be creating objects, in ways that have no
3983 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
3984 : // which likewise guarantees no side-effects for the sorts of
3985 : // things we will pass it.
3986 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
3987 0 : JS::Rooted<JS::Value> val(cx);
3988 0 : if (!ToObjectInternal(cx, &val)) {
3989 0 : return false;
3990 : }
3991 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
3992 0 : return StringifyToJSON(cx, obj, aJSON);
3993 : }
3994 :
3995 : void
3996 0 : RTCInboundRTPStreamStats::TraceDictionary(JSTracer* trc)
3997 : {
3998 0 : RTCRTPStreamStats::TraceDictionary(trc);
3999 0 : }
4000 :
4001 : RTCInboundRTPStreamStats&
4002 0 : RTCInboundRTPStreamStats::operator=(const RTCInboundRTPStreamStats& aOther)
4003 : {
4004 0 : RTCRTPStreamStats::operator=(aOther);
4005 0 : mBytesReceived.Reset();
4006 0 : if (aOther.mBytesReceived.WasPassed()) {
4007 0 : mBytesReceived.Construct(aOther.mBytesReceived.Value());
4008 : }
4009 0 : mDiscardedPackets.Reset();
4010 0 : if (aOther.mDiscardedPackets.WasPassed()) {
4011 0 : mDiscardedPackets.Construct(aOther.mDiscardedPackets.Value());
4012 : }
4013 0 : mFramesDecoded.Reset();
4014 0 : if (aOther.mFramesDecoded.WasPassed()) {
4015 0 : mFramesDecoded.Construct(aOther.mFramesDecoded.Value());
4016 : }
4017 0 : mJitter.Reset();
4018 0 : if (aOther.mJitter.WasPassed()) {
4019 0 : mJitter.Construct(aOther.mJitter.Value());
4020 : }
4021 0 : mMozAvSyncDelay.Reset();
4022 0 : if (aOther.mMozAvSyncDelay.WasPassed()) {
4023 0 : mMozAvSyncDelay.Construct(aOther.mMozAvSyncDelay.Value());
4024 : }
4025 0 : mMozJitterBufferDelay.Reset();
4026 0 : if (aOther.mMozJitterBufferDelay.WasPassed()) {
4027 0 : mMozJitterBufferDelay.Construct(aOther.mMozJitterBufferDelay.Value());
4028 : }
4029 0 : mPacketsLost.Reset();
4030 0 : if (aOther.mPacketsLost.WasPassed()) {
4031 0 : mPacketsLost.Construct(aOther.mPacketsLost.Value());
4032 : }
4033 0 : mPacketsReceived.Reset();
4034 0 : if (aOther.mPacketsReceived.WasPassed()) {
4035 0 : mPacketsReceived.Construct(aOther.mPacketsReceived.Value());
4036 : }
4037 0 : mRoundTripTime.Reset();
4038 0 : if (aOther.mRoundTripTime.WasPassed()) {
4039 0 : mRoundTripTime.Construct(aOther.mRoundTripTime.Value());
4040 : }
4041 0 : return *this;
4042 : }
4043 :
4044 : namespace binding_detail {
4045 : } // namespace binding_detail
4046 :
4047 :
4048 :
4049 0 : RTCOutboundRTPStreamStats::RTCOutboundRTPStreamStats()
4050 0 : : RTCRTPStreamStats(FastDictionaryInitializer())
4051 : {
4052 : // Safe to pass a null context if we pass a null value
4053 0 : Init(nullptr, JS::NullHandleValue);
4054 0 : }
4055 :
4056 :
4057 :
4058 : bool
4059 0 : RTCOutboundRTPStreamStats::InitIds(JSContext* cx, RTCOutboundRTPStreamStatsAtoms* atomsCache)
4060 : {
4061 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
4062 :
4063 : // Initialize these in reverse order so that any failure leaves the first one
4064 : // uninitialized.
4065 0 : if (!atomsCache->targetBitrate_id.init(cx, "targetBitrate") ||
4066 0 : !atomsCache->packetsSent_id.init(cx, "packetsSent") ||
4067 0 : !atomsCache->framesEncoded_id.init(cx, "framesEncoded") ||
4068 0 : !atomsCache->droppedFrames_id.init(cx, "droppedFrames") ||
4069 0 : !atomsCache->bytesSent_id.init(cx, "bytesSent")) {
4070 0 : return false;
4071 : }
4072 0 : return true;
4073 : }
4074 :
4075 : bool
4076 0 : RTCOutboundRTPStreamStats::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
4077 : {
4078 : // Passing a null JSContext is OK only if we're initing from null,
4079 : // Since in that case we will not have to do any property gets
4080 : // Also evaluate isNullOrUndefined in order to avoid false-positive
4081 : // checkers by static analysis tools
4082 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
4083 0 : RTCOutboundRTPStreamStatsAtoms* atomsCache = nullptr;
4084 0 : if (cx) {
4085 0 : atomsCache = GetAtomCache<RTCOutboundRTPStreamStatsAtoms>(cx);
4086 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
4087 0 : return false;
4088 : }
4089 : }
4090 :
4091 : // Per spec, we init the parent's members first
4092 0 : if (!RTCRTPStreamStats::Init(cx, val)) {
4093 0 : return false;
4094 : }
4095 :
4096 0 : bool isNull = val.isNullOrUndefined();
4097 : // We only need these if !isNull, in which case we have |cx|.
4098 0 : Maybe<JS::Rooted<JSObject *> > object;
4099 0 : Maybe<JS::Rooted<JS::Value> > temp;
4100 0 : if (!isNull) {
4101 0 : MOZ_ASSERT(cx);
4102 0 : object.emplace(cx, &val.toObject());
4103 0 : temp.emplace(cx);
4104 : }
4105 0 : if (!isNull) {
4106 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->bytesSent_id, temp.ptr())) {
4107 0 : return false;
4108 : }
4109 : }
4110 0 : if (!isNull && !temp->isUndefined()) {
4111 0 : mBytesSent.Construct();
4112 0 : if (!ValueToPrimitive<uint64_t, eDefault>(cx, temp.ref(), &(mBytesSent.Value()))) {
4113 0 : return false;
4114 : }
4115 0 : mIsAnyMemberPresent = true;
4116 : }
4117 :
4118 0 : if (!isNull) {
4119 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->droppedFrames_id, temp.ptr())) {
4120 0 : return false;
4121 : }
4122 : }
4123 0 : if (!isNull && !temp->isUndefined()) {
4124 0 : mDroppedFrames.Construct();
4125 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mDroppedFrames.Value()))) {
4126 0 : return false;
4127 : }
4128 0 : mIsAnyMemberPresent = true;
4129 : }
4130 :
4131 0 : if (!isNull) {
4132 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->framesEncoded_id, temp.ptr())) {
4133 0 : return false;
4134 : }
4135 : }
4136 0 : if (!isNull && !temp->isUndefined()) {
4137 0 : mFramesEncoded.Construct();
4138 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mFramesEncoded.Value()))) {
4139 0 : return false;
4140 : }
4141 0 : mIsAnyMemberPresent = true;
4142 : }
4143 :
4144 0 : if (!isNull) {
4145 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->packetsSent_id, temp.ptr())) {
4146 0 : return false;
4147 : }
4148 : }
4149 0 : if (!isNull && !temp->isUndefined()) {
4150 0 : mPacketsSent.Construct();
4151 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mPacketsSent.Value()))) {
4152 0 : return false;
4153 : }
4154 0 : mIsAnyMemberPresent = true;
4155 : }
4156 :
4157 0 : if (!isNull) {
4158 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->targetBitrate_id, temp.ptr())) {
4159 0 : return false;
4160 : }
4161 : }
4162 0 : if (!isNull && !temp->isUndefined()) {
4163 0 : mTargetBitrate.Construct();
4164 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &(mTargetBitrate.Value()))) {
4165 0 : return false;
4166 0 : } else if (!mozilla::IsFinite((mTargetBitrate.Value()))) {
4167 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'targetBitrate' member of RTCOutboundRTPStreamStats");
4168 0 : return false;
4169 : }
4170 0 : mIsAnyMemberPresent = true;
4171 : }
4172 0 : return true;
4173 : }
4174 :
4175 : bool
4176 0 : RTCOutboundRTPStreamStats::Init(const nsAString& aJSON)
4177 : {
4178 0 : AutoJSAPI jsapi;
4179 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
4180 0 : if (!cleanGlobal) {
4181 0 : return false;
4182 : }
4183 0 : if (!jsapi.Init(cleanGlobal)) {
4184 0 : return false;
4185 : }
4186 0 : JSContext* cx = jsapi.cx();
4187 0 : JS::Rooted<JS::Value> json(cx);
4188 0 : bool ok = ParseJSON(cx, aJSON, &json);
4189 0 : NS_ENSURE_TRUE(ok, false);
4190 0 : return Init(cx, json);
4191 : }
4192 :
4193 : bool
4194 0 : RTCOutboundRTPStreamStats::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
4195 : {
4196 0 : RTCOutboundRTPStreamStatsAtoms* atomsCache = GetAtomCache<RTCOutboundRTPStreamStatsAtoms>(cx);
4197 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
4198 0 : return false;
4199 : }
4200 :
4201 : // Per spec, we define the parent's members first
4202 0 : if (!RTCRTPStreamStats::ToObjectInternal(cx, rval)) {
4203 0 : return false;
4204 : }
4205 0 : JS::Rooted<JSObject*> obj(cx, &rval.toObject());
4206 :
4207 0 : if (mBytesSent.WasPassed()) {
4208 : do {
4209 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
4210 0 : JS::Rooted<JS::Value> temp(cx);
4211 0 : uint64_t const & currentValue = mBytesSent.InternalValue();
4212 0 : temp.set(JS_NumberValue(double(currentValue)));
4213 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->bytesSent_id, temp, JSPROP_ENUMERATE)) {
4214 0 : return false;
4215 : }
4216 0 : break;
4217 : } while(0);
4218 : }
4219 :
4220 0 : if (mDroppedFrames.WasPassed()) {
4221 : do {
4222 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
4223 0 : JS::Rooted<JS::Value> temp(cx);
4224 0 : uint32_t const & currentValue = mDroppedFrames.InternalValue();
4225 0 : temp.setNumber(currentValue);
4226 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->droppedFrames_id, temp, JSPROP_ENUMERATE)) {
4227 0 : return false;
4228 : }
4229 0 : break;
4230 : } while(0);
4231 : }
4232 :
4233 0 : if (mFramesEncoded.WasPassed()) {
4234 : do {
4235 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
4236 0 : JS::Rooted<JS::Value> temp(cx);
4237 0 : uint32_t const & currentValue = mFramesEncoded.InternalValue();
4238 0 : temp.setNumber(currentValue);
4239 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->framesEncoded_id, temp, JSPROP_ENUMERATE)) {
4240 0 : return false;
4241 : }
4242 0 : break;
4243 : } while(0);
4244 : }
4245 :
4246 0 : if (mPacketsSent.WasPassed()) {
4247 : do {
4248 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
4249 0 : JS::Rooted<JS::Value> temp(cx);
4250 0 : uint32_t const & currentValue = mPacketsSent.InternalValue();
4251 0 : temp.setNumber(currentValue);
4252 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->packetsSent_id, temp, JSPROP_ENUMERATE)) {
4253 0 : return false;
4254 : }
4255 0 : break;
4256 : } while(0);
4257 : }
4258 :
4259 0 : if (mTargetBitrate.WasPassed()) {
4260 : do {
4261 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
4262 0 : JS::Rooted<JS::Value> temp(cx);
4263 0 : double const & currentValue = mTargetBitrate.InternalValue();
4264 0 : temp.set(JS_NumberValue(double(currentValue)));
4265 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->targetBitrate_id, temp, JSPROP_ENUMERATE)) {
4266 0 : return false;
4267 : }
4268 0 : break;
4269 : } while(0);
4270 : }
4271 :
4272 0 : return true;
4273 : }
4274 :
4275 : bool
4276 0 : RTCOutboundRTPStreamStats::ToJSON(nsAString& aJSON) const
4277 : {
4278 0 : AutoJSAPI jsapi;
4279 0 : jsapi.Init();
4280 0 : JSContext *cx = jsapi.cx();
4281 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
4282 : // because we'll only be creating objects, in ways that have no
4283 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
4284 : // which likewise guarantees no side-effects for the sorts of
4285 : // things we will pass it.
4286 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
4287 0 : JS::Rooted<JS::Value> val(cx);
4288 0 : if (!ToObjectInternal(cx, &val)) {
4289 0 : return false;
4290 : }
4291 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
4292 0 : return StringifyToJSON(cx, obj, aJSON);
4293 : }
4294 :
4295 : void
4296 0 : RTCOutboundRTPStreamStats::TraceDictionary(JSTracer* trc)
4297 : {
4298 0 : RTCRTPStreamStats::TraceDictionary(trc);
4299 0 : }
4300 :
4301 : RTCOutboundRTPStreamStats&
4302 0 : RTCOutboundRTPStreamStats::operator=(const RTCOutboundRTPStreamStats& aOther)
4303 : {
4304 0 : RTCRTPStreamStats::operator=(aOther);
4305 0 : mBytesSent.Reset();
4306 0 : if (aOther.mBytesSent.WasPassed()) {
4307 0 : mBytesSent.Construct(aOther.mBytesSent.Value());
4308 : }
4309 0 : mDroppedFrames.Reset();
4310 0 : if (aOther.mDroppedFrames.WasPassed()) {
4311 0 : mDroppedFrames.Construct(aOther.mDroppedFrames.Value());
4312 : }
4313 0 : mFramesEncoded.Reset();
4314 0 : if (aOther.mFramesEncoded.WasPassed()) {
4315 0 : mFramesEncoded.Construct(aOther.mFramesEncoded.Value());
4316 : }
4317 0 : mPacketsSent.Reset();
4318 0 : if (aOther.mPacketsSent.WasPassed()) {
4319 0 : mPacketsSent.Construct(aOther.mPacketsSent.Value());
4320 : }
4321 0 : mTargetBitrate.Reset();
4322 0 : if (aOther.mTargetBitrate.WasPassed()) {
4323 0 : mTargetBitrate.Construct(aOther.mTargetBitrate.Value());
4324 : }
4325 0 : return *this;
4326 : }
4327 :
4328 : namespace binding_detail {
4329 : } // namespace binding_detail
4330 :
4331 :
4332 :
4333 0 : RTCStatsReportInternal::RTCStatsReportInternal()
4334 : {
4335 : // Safe to pass a null context if we pass a null value
4336 0 : Init(nullptr, JS::NullHandleValue);
4337 0 : }
4338 :
4339 :
4340 :
4341 : bool
4342 0 : RTCStatsReportInternal::InitIds(JSContext* cx, RTCStatsReportInternalAtoms* atomsCache)
4343 : {
4344 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
4345 :
4346 : // Initialize these in reverse order so that any failure leaves the first one
4347 : // uninitialized.
4348 0 : if (!atomsCache->transportStats_id.init(cx, "transportStats") ||
4349 0 : !atomsCache->timestamp_id.init(cx, "timestamp") ||
4350 0 : !atomsCache->rtpContributingSourceStats_id.init(cx, "rtpContributingSourceStats") ||
4351 0 : !atomsCache->remoteSdp_id.init(cx, "remoteSdp") ||
4352 0 : !atomsCache->pcid_id.init(cx, "pcid") ||
4353 0 : !atomsCache->outboundRTPStreamStats_id.init(cx, "outboundRTPStreamStats") ||
4354 0 : !atomsCache->mediaStreamTrackStats_id.init(cx, "mediaStreamTrackStats") ||
4355 0 : !atomsCache->mediaStreamStats_id.init(cx, "mediaStreamStats") ||
4356 0 : !atomsCache->localSdp_id.init(cx, "localSdp") ||
4357 0 : !atomsCache->inboundRTPStreamStats_id.init(cx, "inboundRTPStreamStats") ||
4358 0 : !atomsCache->iceRollbacks_id.init(cx, "iceRollbacks") ||
4359 0 : !atomsCache->iceRestarts_id.init(cx, "iceRestarts") ||
4360 0 : !atomsCache->iceComponentStats_id.init(cx, "iceComponentStats") ||
4361 0 : !atomsCache->iceCandidateStats_id.init(cx, "iceCandidateStats") ||
4362 0 : !atomsCache->iceCandidatePairStats_id.init(cx, "iceCandidatePairStats") ||
4363 0 : !atomsCache->codecStats_id.init(cx, "codecStats") ||
4364 0 : !atomsCache->closed_id.init(cx, "closed")) {
4365 0 : return false;
4366 : }
4367 0 : return true;
4368 : }
4369 :
4370 : bool
4371 0 : RTCStatsReportInternal::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
4372 : {
4373 : // Passing a null JSContext is OK only if we're initing from null,
4374 : // Since in that case we will not have to do any property gets
4375 : // Also evaluate isNullOrUndefined in order to avoid false-positive
4376 : // checkers by static analysis tools
4377 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
4378 0 : RTCStatsReportInternalAtoms* atomsCache = nullptr;
4379 0 : if (cx) {
4380 0 : atomsCache = GetAtomCache<RTCStatsReportInternalAtoms>(cx);
4381 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
4382 0 : return false;
4383 : }
4384 : }
4385 :
4386 0 : if (!IsConvertibleToDictionary(val)) {
4387 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
4388 : }
4389 :
4390 0 : bool isNull = val.isNullOrUndefined();
4391 : // We only need these if !isNull, in which case we have |cx|.
4392 0 : Maybe<JS::Rooted<JSObject *> > object;
4393 0 : Maybe<JS::Rooted<JS::Value> > temp;
4394 0 : if (!isNull) {
4395 0 : MOZ_ASSERT(cx);
4396 0 : object.emplace(cx, &val.toObject());
4397 0 : temp.emplace(cx);
4398 : }
4399 0 : if (!isNull) {
4400 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->closed_id, temp.ptr())) {
4401 0 : return false;
4402 : }
4403 : }
4404 0 : if (!isNull && !temp->isUndefined()) {
4405 0 : mClosed.Construct();
4406 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &(mClosed.Value()))) {
4407 0 : return false;
4408 : }
4409 0 : mIsAnyMemberPresent = true;
4410 : }
4411 :
4412 0 : if (!isNull) {
4413 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->codecStats_id, temp.ptr())) {
4414 0 : return false;
4415 : }
4416 : }
4417 0 : if (!isNull && !temp->isUndefined()) {
4418 0 : mCodecStats.Construct();
4419 0 : if (temp.ref().isObject()) {
4420 0 : JS::ForOfIterator iter(cx);
4421 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
4422 0 : return false;
4423 : }
4424 0 : if (!iter.valueIsIterable()) {
4425 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'codecStats' member of RTCStatsReportInternal");
4426 0 : return false;
4427 : }
4428 0 : Sequence<RTCCodecStats> &arr = (mCodecStats.Value());
4429 0 : JS::Rooted<JS::Value> temp(cx);
4430 : while (true) {
4431 : bool done;
4432 0 : if (!iter.next(&temp, &done)) {
4433 0 : return false;
4434 : }
4435 0 : if (done) {
4436 0 : break;
4437 : }
4438 0 : RTCCodecStats* slotPtr = arr.AppendElement(mozilla::fallible);
4439 0 : if (!slotPtr) {
4440 0 : JS_ReportOutOfMemory(cx);
4441 0 : return false;
4442 : }
4443 0 : RTCCodecStats& slot = *slotPtr;
4444 0 : if (!slot.Init(cx, temp, "Element of 'codecStats' member of RTCStatsReportInternal", passedToJSImpl)) {
4445 0 : return false;
4446 : }
4447 0 : }
4448 : } else {
4449 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'codecStats' member of RTCStatsReportInternal");
4450 0 : return false;
4451 : }
4452 0 : mIsAnyMemberPresent = true;
4453 : }
4454 :
4455 0 : if (!isNull) {
4456 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->iceCandidatePairStats_id, temp.ptr())) {
4457 0 : return false;
4458 : }
4459 : }
4460 0 : if (!isNull && !temp->isUndefined()) {
4461 0 : mIceCandidatePairStats.Construct();
4462 0 : if (temp.ref().isObject()) {
4463 0 : JS::ForOfIterator iter(cx);
4464 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
4465 0 : return false;
4466 : }
4467 0 : if (!iter.valueIsIterable()) {
4468 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'iceCandidatePairStats' member of RTCStatsReportInternal");
4469 0 : return false;
4470 : }
4471 0 : Sequence<RTCIceCandidatePairStats> &arr = (mIceCandidatePairStats.Value());
4472 0 : JS::Rooted<JS::Value> temp(cx);
4473 : while (true) {
4474 : bool done;
4475 0 : if (!iter.next(&temp, &done)) {
4476 0 : return false;
4477 : }
4478 0 : if (done) {
4479 0 : break;
4480 : }
4481 0 : RTCIceCandidatePairStats* slotPtr = arr.AppendElement(mozilla::fallible);
4482 0 : if (!slotPtr) {
4483 0 : JS_ReportOutOfMemory(cx);
4484 0 : return false;
4485 : }
4486 0 : RTCIceCandidatePairStats& slot = *slotPtr;
4487 0 : if (!slot.Init(cx, temp, "Element of 'iceCandidatePairStats' member of RTCStatsReportInternal", passedToJSImpl)) {
4488 0 : return false;
4489 : }
4490 0 : }
4491 : } else {
4492 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'iceCandidatePairStats' member of RTCStatsReportInternal");
4493 0 : return false;
4494 : }
4495 0 : mIsAnyMemberPresent = true;
4496 : }
4497 :
4498 0 : if (!isNull) {
4499 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->iceCandidateStats_id, temp.ptr())) {
4500 0 : return false;
4501 : }
4502 : }
4503 0 : if (!isNull && !temp->isUndefined()) {
4504 0 : mIceCandidateStats.Construct();
4505 0 : if (temp.ref().isObject()) {
4506 0 : JS::ForOfIterator iter(cx);
4507 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
4508 0 : return false;
4509 : }
4510 0 : if (!iter.valueIsIterable()) {
4511 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'iceCandidateStats' member of RTCStatsReportInternal");
4512 0 : return false;
4513 : }
4514 0 : Sequence<RTCIceCandidateStats> &arr = (mIceCandidateStats.Value());
4515 0 : JS::Rooted<JS::Value> temp(cx);
4516 : while (true) {
4517 : bool done;
4518 0 : if (!iter.next(&temp, &done)) {
4519 0 : return false;
4520 : }
4521 0 : if (done) {
4522 0 : break;
4523 : }
4524 0 : RTCIceCandidateStats* slotPtr = arr.AppendElement(mozilla::fallible);
4525 0 : if (!slotPtr) {
4526 0 : JS_ReportOutOfMemory(cx);
4527 0 : return false;
4528 : }
4529 0 : RTCIceCandidateStats& slot = *slotPtr;
4530 0 : if (!slot.Init(cx, temp, "Element of 'iceCandidateStats' member of RTCStatsReportInternal", passedToJSImpl)) {
4531 0 : return false;
4532 : }
4533 0 : }
4534 : } else {
4535 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'iceCandidateStats' member of RTCStatsReportInternal");
4536 0 : return false;
4537 : }
4538 0 : mIsAnyMemberPresent = true;
4539 : }
4540 :
4541 0 : if (!isNull) {
4542 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->iceComponentStats_id, temp.ptr())) {
4543 0 : return false;
4544 : }
4545 : }
4546 0 : if (!isNull && !temp->isUndefined()) {
4547 0 : mIceComponentStats.Construct();
4548 0 : if (temp.ref().isObject()) {
4549 0 : JS::ForOfIterator iter(cx);
4550 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
4551 0 : return false;
4552 : }
4553 0 : if (!iter.valueIsIterable()) {
4554 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'iceComponentStats' member of RTCStatsReportInternal");
4555 0 : return false;
4556 : }
4557 0 : Sequence<RTCIceComponentStats> &arr = (mIceComponentStats.Value());
4558 0 : JS::Rooted<JS::Value> temp(cx);
4559 : while (true) {
4560 : bool done;
4561 0 : if (!iter.next(&temp, &done)) {
4562 0 : return false;
4563 : }
4564 0 : if (done) {
4565 0 : break;
4566 : }
4567 0 : RTCIceComponentStats* slotPtr = arr.AppendElement(mozilla::fallible);
4568 0 : if (!slotPtr) {
4569 0 : JS_ReportOutOfMemory(cx);
4570 0 : return false;
4571 : }
4572 0 : RTCIceComponentStats& slot = *slotPtr;
4573 0 : if (!slot.Init(cx, temp, "Element of 'iceComponentStats' member of RTCStatsReportInternal", passedToJSImpl)) {
4574 0 : return false;
4575 : }
4576 0 : }
4577 : } else {
4578 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'iceComponentStats' member of RTCStatsReportInternal");
4579 0 : return false;
4580 : }
4581 0 : mIsAnyMemberPresent = true;
4582 : }
4583 :
4584 0 : if (!isNull) {
4585 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->iceRestarts_id, temp.ptr())) {
4586 0 : return false;
4587 : }
4588 : }
4589 0 : if (!isNull && !temp->isUndefined()) {
4590 0 : mIceRestarts.Construct();
4591 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mIceRestarts.Value()))) {
4592 0 : return false;
4593 : }
4594 0 : mIsAnyMemberPresent = true;
4595 : }
4596 :
4597 0 : if (!isNull) {
4598 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->iceRollbacks_id, temp.ptr())) {
4599 0 : return false;
4600 : }
4601 : }
4602 0 : if (!isNull && !temp->isUndefined()) {
4603 0 : mIceRollbacks.Construct();
4604 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mIceRollbacks.Value()))) {
4605 0 : return false;
4606 : }
4607 0 : mIsAnyMemberPresent = true;
4608 : }
4609 :
4610 0 : if (!isNull) {
4611 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->inboundRTPStreamStats_id, temp.ptr())) {
4612 0 : return false;
4613 : }
4614 : }
4615 0 : if (!isNull && !temp->isUndefined()) {
4616 0 : mInboundRTPStreamStats.Construct();
4617 0 : if (temp.ref().isObject()) {
4618 0 : JS::ForOfIterator iter(cx);
4619 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
4620 0 : return false;
4621 : }
4622 0 : if (!iter.valueIsIterable()) {
4623 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'inboundRTPStreamStats' member of RTCStatsReportInternal");
4624 0 : return false;
4625 : }
4626 0 : Sequence<RTCInboundRTPStreamStats> &arr = (mInboundRTPStreamStats.Value());
4627 0 : JS::Rooted<JS::Value> temp(cx);
4628 : while (true) {
4629 : bool done;
4630 0 : if (!iter.next(&temp, &done)) {
4631 0 : return false;
4632 : }
4633 0 : if (done) {
4634 0 : break;
4635 : }
4636 0 : RTCInboundRTPStreamStats* slotPtr = arr.AppendElement(mozilla::fallible);
4637 0 : if (!slotPtr) {
4638 0 : JS_ReportOutOfMemory(cx);
4639 0 : return false;
4640 : }
4641 0 : RTCInboundRTPStreamStats& slot = *slotPtr;
4642 0 : if (!slot.Init(cx, temp, "Element of 'inboundRTPStreamStats' member of RTCStatsReportInternal", passedToJSImpl)) {
4643 0 : return false;
4644 : }
4645 0 : }
4646 : } else {
4647 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'inboundRTPStreamStats' member of RTCStatsReportInternal");
4648 0 : return false;
4649 : }
4650 0 : mIsAnyMemberPresent = true;
4651 : }
4652 :
4653 0 : if (!isNull) {
4654 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->localSdp_id, temp.ptr())) {
4655 0 : return false;
4656 : }
4657 : }
4658 0 : if (!isNull && !temp->isUndefined()) {
4659 0 : mLocalSdp.Construct();
4660 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mLocalSdp.Value()))) {
4661 0 : return false;
4662 : }
4663 0 : mIsAnyMemberPresent = true;
4664 : }
4665 :
4666 0 : if (!isNull) {
4667 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->mediaStreamStats_id, temp.ptr())) {
4668 0 : return false;
4669 : }
4670 : }
4671 0 : if (!isNull && !temp->isUndefined()) {
4672 0 : mMediaStreamStats.Construct();
4673 0 : if (temp.ref().isObject()) {
4674 0 : JS::ForOfIterator iter(cx);
4675 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
4676 0 : return false;
4677 : }
4678 0 : if (!iter.valueIsIterable()) {
4679 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'mediaStreamStats' member of RTCStatsReportInternal");
4680 0 : return false;
4681 : }
4682 0 : Sequence<RTCMediaStreamStats> &arr = (mMediaStreamStats.Value());
4683 0 : JS::Rooted<JS::Value> temp(cx);
4684 : while (true) {
4685 : bool done;
4686 0 : if (!iter.next(&temp, &done)) {
4687 0 : return false;
4688 : }
4689 0 : if (done) {
4690 0 : break;
4691 : }
4692 0 : RTCMediaStreamStats* slotPtr = arr.AppendElement(mozilla::fallible);
4693 0 : if (!slotPtr) {
4694 0 : JS_ReportOutOfMemory(cx);
4695 0 : return false;
4696 : }
4697 0 : RTCMediaStreamStats& slot = *slotPtr;
4698 0 : if (!slot.Init(cx, temp, "Element of 'mediaStreamStats' member of RTCStatsReportInternal", passedToJSImpl)) {
4699 0 : return false;
4700 : }
4701 0 : }
4702 : } else {
4703 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'mediaStreamStats' member of RTCStatsReportInternal");
4704 0 : return false;
4705 : }
4706 0 : mIsAnyMemberPresent = true;
4707 : }
4708 :
4709 0 : if (!isNull) {
4710 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->mediaStreamTrackStats_id, temp.ptr())) {
4711 0 : return false;
4712 : }
4713 : }
4714 0 : if (!isNull && !temp->isUndefined()) {
4715 0 : mMediaStreamTrackStats.Construct();
4716 0 : if (temp.ref().isObject()) {
4717 0 : JS::ForOfIterator iter(cx);
4718 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
4719 0 : return false;
4720 : }
4721 0 : if (!iter.valueIsIterable()) {
4722 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'mediaStreamTrackStats' member of RTCStatsReportInternal");
4723 0 : return false;
4724 : }
4725 0 : Sequence<RTCMediaStreamTrackStats> &arr = (mMediaStreamTrackStats.Value());
4726 0 : JS::Rooted<JS::Value> temp(cx);
4727 : while (true) {
4728 : bool done;
4729 0 : if (!iter.next(&temp, &done)) {
4730 0 : return false;
4731 : }
4732 0 : if (done) {
4733 0 : break;
4734 : }
4735 0 : RTCMediaStreamTrackStats* slotPtr = arr.AppendElement(mozilla::fallible);
4736 0 : if (!slotPtr) {
4737 0 : JS_ReportOutOfMemory(cx);
4738 0 : return false;
4739 : }
4740 0 : RTCMediaStreamTrackStats& slot = *slotPtr;
4741 0 : if (!slot.Init(cx, temp, "Element of 'mediaStreamTrackStats' member of RTCStatsReportInternal", passedToJSImpl)) {
4742 0 : return false;
4743 : }
4744 0 : }
4745 : } else {
4746 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'mediaStreamTrackStats' member of RTCStatsReportInternal");
4747 0 : return false;
4748 : }
4749 0 : mIsAnyMemberPresent = true;
4750 : }
4751 :
4752 0 : if (!isNull) {
4753 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->outboundRTPStreamStats_id, temp.ptr())) {
4754 0 : return false;
4755 : }
4756 : }
4757 0 : if (!isNull && !temp->isUndefined()) {
4758 0 : mOutboundRTPStreamStats.Construct();
4759 0 : if (temp.ref().isObject()) {
4760 0 : JS::ForOfIterator iter(cx);
4761 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
4762 0 : return false;
4763 : }
4764 0 : if (!iter.valueIsIterable()) {
4765 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'outboundRTPStreamStats' member of RTCStatsReportInternal");
4766 0 : return false;
4767 : }
4768 0 : Sequence<RTCOutboundRTPStreamStats> &arr = (mOutboundRTPStreamStats.Value());
4769 0 : JS::Rooted<JS::Value> temp(cx);
4770 : while (true) {
4771 : bool done;
4772 0 : if (!iter.next(&temp, &done)) {
4773 0 : return false;
4774 : }
4775 0 : if (done) {
4776 0 : break;
4777 : }
4778 0 : RTCOutboundRTPStreamStats* slotPtr = arr.AppendElement(mozilla::fallible);
4779 0 : if (!slotPtr) {
4780 0 : JS_ReportOutOfMemory(cx);
4781 0 : return false;
4782 : }
4783 0 : RTCOutboundRTPStreamStats& slot = *slotPtr;
4784 0 : if (!slot.Init(cx, temp, "Element of 'outboundRTPStreamStats' member of RTCStatsReportInternal", passedToJSImpl)) {
4785 0 : return false;
4786 : }
4787 0 : }
4788 : } else {
4789 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'outboundRTPStreamStats' member of RTCStatsReportInternal");
4790 0 : return false;
4791 : }
4792 0 : mIsAnyMemberPresent = true;
4793 : }
4794 :
4795 0 : if (!isNull) {
4796 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->pcid_id, temp.ptr())) {
4797 0 : return false;
4798 : }
4799 : }
4800 0 : if (!isNull && !temp->isUndefined()) {
4801 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mPcid)) {
4802 0 : return false;
4803 : }
4804 : } else {
4805 : static const char16_t data[] = { 0 };
4806 0 : mPcid.Rebind(data, ArrayLength(data) - 1);
4807 : }
4808 0 : mIsAnyMemberPresent = true;
4809 :
4810 0 : if (!isNull) {
4811 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->remoteSdp_id, temp.ptr())) {
4812 0 : return false;
4813 : }
4814 : }
4815 0 : if (!isNull && !temp->isUndefined()) {
4816 0 : mRemoteSdp.Construct();
4817 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mRemoteSdp.Value()))) {
4818 0 : return false;
4819 : }
4820 0 : mIsAnyMemberPresent = true;
4821 : }
4822 :
4823 0 : if (!isNull) {
4824 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->rtpContributingSourceStats_id, temp.ptr())) {
4825 0 : return false;
4826 : }
4827 : }
4828 0 : if (!isNull && !temp->isUndefined()) {
4829 0 : mRtpContributingSourceStats.Construct();
4830 0 : if (temp.ref().isObject()) {
4831 0 : JS::ForOfIterator iter(cx);
4832 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
4833 0 : return false;
4834 : }
4835 0 : if (!iter.valueIsIterable()) {
4836 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'rtpContributingSourceStats' member of RTCStatsReportInternal");
4837 0 : return false;
4838 : }
4839 0 : Sequence<RTCRTPContributingSourceStats> &arr = (mRtpContributingSourceStats.Value());
4840 0 : JS::Rooted<JS::Value> temp(cx);
4841 : while (true) {
4842 : bool done;
4843 0 : if (!iter.next(&temp, &done)) {
4844 0 : return false;
4845 : }
4846 0 : if (done) {
4847 0 : break;
4848 : }
4849 0 : RTCRTPContributingSourceStats* slotPtr = arr.AppendElement(mozilla::fallible);
4850 0 : if (!slotPtr) {
4851 0 : JS_ReportOutOfMemory(cx);
4852 0 : return false;
4853 : }
4854 0 : RTCRTPContributingSourceStats& slot = *slotPtr;
4855 0 : if (!slot.Init(cx, temp, "Element of 'rtpContributingSourceStats' member of RTCStatsReportInternal", passedToJSImpl)) {
4856 0 : return false;
4857 : }
4858 0 : }
4859 : } else {
4860 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'rtpContributingSourceStats' member of RTCStatsReportInternal");
4861 0 : return false;
4862 : }
4863 0 : mIsAnyMemberPresent = true;
4864 : }
4865 :
4866 0 : if (!isNull) {
4867 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->timestamp_id, temp.ptr())) {
4868 0 : return false;
4869 : }
4870 : }
4871 0 : if (!isNull && !temp->isUndefined()) {
4872 0 : mTimestamp.Construct();
4873 0 : if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), &(mTimestamp.Value()))) {
4874 0 : return false;
4875 0 : } else if (!mozilla::IsFinite((mTimestamp.Value()))) {
4876 0 : ThrowErrorMessage(cx, MSG_NOT_FINITE, "'timestamp' member of RTCStatsReportInternal");
4877 0 : return false;
4878 : }
4879 0 : mIsAnyMemberPresent = true;
4880 : }
4881 :
4882 0 : if (!isNull) {
4883 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->transportStats_id, temp.ptr())) {
4884 0 : return false;
4885 : }
4886 : }
4887 0 : if (!isNull && !temp->isUndefined()) {
4888 0 : mTransportStats.Construct();
4889 0 : if (temp.ref().isObject()) {
4890 0 : JS::ForOfIterator iter(cx);
4891 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
4892 0 : return false;
4893 : }
4894 0 : if (!iter.valueIsIterable()) {
4895 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'transportStats' member of RTCStatsReportInternal");
4896 0 : return false;
4897 : }
4898 0 : Sequence<RTCTransportStats> &arr = (mTransportStats.Value());
4899 0 : JS::Rooted<JS::Value> temp(cx);
4900 : while (true) {
4901 : bool done;
4902 0 : if (!iter.next(&temp, &done)) {
4903 0 : return false;
4904 : }
4905 0 : if (done) {
4906 0 : break;
4907 : }
4908 0 : RTCTransportStats* slotPtr = arr.AppendElement(mozilla::fallible);
4909 0 : if (!slotPtr) {
4910 0 : JS_ReportOutOfMemory(cx);
4911 0 : return false;
4912 : }
4913 0 : RTCTransportStats& slot = *slotPtr;
4914 0 : if (!slot.Init(cx, temp, "Element of 'transportStats' member of RTCStatsReportInternal", passedToJSImpl)) {
4915 0 : return false;
4916 : }
4917 0 : }
4918 : } else {
4919 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'transportStats' member of RTCStatsReportInternal");
4920 0 : return false;
4921 : }
4922 0 : mIsAnyMemberPresent = true;
4923 : }
4924 0 : return true;
4925 : }
4926 :
4927 : bool
4928 0 : RTCStatsReportInternal::Init(const nsAString& aJSON)
4929 : {
4930 0 : AutoJSAPI jsapi;
4931 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
4932 0 : if (!cleanGlobal) {
4933 0 : return false;
4934 : }
4935 0 : if (!jsapi.Init(cleanGlobal)) {
4936 0 : return false;
4937 : }
4938 0 : JSContext* cx = jsapi.cx();
4939 0 : JS::Rooted<JS::Value> json(cx);
4940 0 : bool ok = ParseJSON(cx, aJSON, &json);
4941 0 : NS_ENSURE_TRUE(ok, false);
4942 0 : return Init(cx, json);
4943 : }
4944 :
4945 : bool
4946 0 : RTCStatsReportInternal::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
4947 : {
4948 0 : RTCStatsReportInternalAtoms* atomsCache = GetAtomCache<RTCStatsReportInternalAtoms>(cx);
4949 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
4950 0 : return false;
4951 : }
4952 :
4953 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
4954 0 : if (!obj) {
4955 0 : return false;
4956 : }
4957 0 : rval.set(JS::ObjectValue(*obj));
4958 :
4959 0 : if (mClosed.WasPassed()) {
4960 : do {
4961 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
4962 0 : JS::Rooted<JS::Value> temp(cx);
4963 0 : bool const & currentValue = mClosed.InternalValue();
4964 0 : temp.setBoolean(currentValue);
4965 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->closed_id, temp, JSPROP_ENUMERATE)) {
4966 0 : return false;
4967 : }
4968 0 : break;
4969 : } while(0);
4970 : }
4971 :
4972 0 : if (mCodecStats.WasPassed()) {
4973 : do {
4974 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
4975 0 : JS::Rooted<JS::Value> temp(cx);
4976 0 : Sequence<RTCCodecStats> const & currentValue = mCodecStats.InternalValue();
4977 :
4978 0 : uint32_t length = currentValue.Length();
4979 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
4980 0 : if (!returnArray) {
4981 0 : return false;
4982 : }
4983 : // Scope for 'tmp'
4984 : {
4985 0 : JS::Rooted<JS::Value> tmp(cx);
4986 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
4987 : // Control block to let us common up the JS_DefineElement calls when there
4988 : // are different ways to succeed at wrapping the object.
4989 : do {
4990 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
4991 0 : return false;
4992 : }
4993 0 : break;
4994 : } while (0);
4995 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
4996 : JSPROP_ENUMERATE)) {
4997 0 : return false;
4998 : }
4999 : }
5000 : }
5001 0 : temp.setObject(*returnArray);
5002 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->codecStats_id, temp, JSPROP_ENUMERATE)) {
5003 0 : return false;
5004 : }
5005 0 : break;
5006 : } while(0);
5007 : }
5008 :
5009 0 : if (mIceCandidatePairStats.WasPassed()) {
5010 : do {
5011 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
5012 0 : JS::Rooted<JS::Value> temp(cx);
5013 0 : Sequence<RTCIceCandidatePairStats> const & currentValue = mIceCandidatePairStats.InternalValue();
5014 :
5015 0 : uint32_t length = currentValue.Length();
5016 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
5017 0 : if (!returnArray) {
5018 0 : return false;
5019 : }
5020 : // Scope for 'tmp'
5021 : {
5022 0 : JS::Rooted<JS::Value> tmp(cx);
5023 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
5024 : // Control block to let us common up the JS_DefineElement calls when there
5025 : // are different ways to succeed at wrapping the object.
5026 : do {
5027 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
5028 0 : return false;
5029 : }
5030 0 : break;
5031 : } while (0);
5032 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
5033 : JSPROP_ENUMERATE)) {
5034 0 : return false;
5035 : }
5036 : }
5037 : }
5038 0 : temp.setObject(*returnArray);
5039 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->iceCandidatePairStats_id, temp, JSPROP_ENUMERATE)) {
5040 0 : return false;
5041 : }
5042 0 : break;
5043 : } while(0);
5044 : }
5045 :
5046 0 : if (mIceCandidateStats.WasPassed()) {
5047 : do {
5048 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
5049 0 : JS::Rooted<JS::Value> temp(cx);
5050 0 : Sequence<RTCIceCandidateStats> const & currentValue = mIceCandidateStats.InternalValue();
5051 :
5052 0 : uint32_t length = currentValue.Length();
5053 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
5054 0 : if (!returnArray) {
5055 0 : return false;
5056 : }
5057 : // Scope for 'tmp'
5058 : {
5059 0 : JS::Rooted<JS::Value> tmp(cx);
5060 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
5061 : // Control block to let us common up the JS_DefineElement calls when there
5062 : // are different ways to succeed at wrapping the object.
5063 : do {
5064 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
5065 0 : return false;
5066 : }
5067 0 : break;
5068 : } while (0);
5069 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
5070 : JSPROP_ENUMERATE)) {
5071 0 : return false;
5072 : }
5073 : }
5074 : }
5075 0 : temp.setObject(*returnArray);
5076 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->iceCandidateStats_id, temp, JSPROP_ENUMERATE)) {
5077 0 : return false;
5078 : }
5079 0 : break;
5080 : } while(0);
5081 : }
5082 :
5083 0 : if (mIceComponentStats.WasPassed()) {
5084 : do {
5085 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
5086 0 : JS::Rooted<JS::Value> temp(cx);
5087 0 : Sequence<RTCIceComponentStats> const & currentValue = mIceComponentStats.InternalValue();
5088 :
5089 0 : uint32_t length = currentValue.Length();
5090 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
5091 0 : if (!returnArray) {
5092 0 : return false;
5093 : }
5094 : // Scope for 'tmp'
5095 : {
5096 0 : JS::Rooted<JS::Value> tmp(cx);
5097 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
5098 : // Control block to let us common up the JS_DefineElement calls when there
5099 : // are different ways to succeed at wrapping the object.
5100 : do {
5101 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
5102 0 : return false;
5103 : }
5104 0 : break;
5105 : } while (0);
5106 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
5107 : JSPROP_ENUMERATE)) {
5108 0 : return false;
5109 : }
5110 : }
5111 : }
5112 0 : temp.setObject(*returnArray);
5113 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->iceComponentStats_id, temp, JSPROP_ENUMERATE)) {
5114 0 : return false;
5115 : }
5116 0 : break;
5117 : } while(0);
5118 : }
5119 :
5120 0 : if (mIceRestarts.WasPassed()) {
5121 : do {
5122 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
5123 0 : JS::Rooted<JS::Value> temp(cx);
5124 0 : uint32_t const & currentValue = mIceRestarts.InternalValue();
5125 0 : temp.setNumber(currentValue);
5126 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->iceRestarts_id, temp, JSPROP_ENUMERATE)) {
5127 0 : return false;
5128 : }
5129 0 : break;
5130 : } while(0);
5131 : }
5132 :
5133 0 : if (mIceRollbacks.WasPassed()) {
5134 : do {
5135 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
5136 0 : JS::Rooted<JS::Value> temp(cx);
5137 0 : uint32_t const & currentValue = mIceRollbacks.InternalValue();
5138 0 : temp.setNumber(currentValue);
5139 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->iceRollbacks_id, temp, JSPROP_ENUMERATE)) {
5140 0 : return false;
5141 : }
5142 0 : break;
5143 : } while(0);
5144 : }
5145 :
5146 0 : if (mInboundRTPStreamStats.WasPassed()) {
5147 : do {
5148 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
5149 0 : JS::Rooted<JS::Value> temp(cx);
5150 0 : Sequence<RTCInboundRTPStreamStats> const & currentValue = mInboundRTPStreamStats.InternalValue();
5151 :
5152 0 : uint32_t length = currentValue.Length();
5153 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
5154 0 : if (!returnArray) {
5155 0 : return false;
5156 : }
5157 : // Scope for 'tmp'
5158 : {
5159 0 : JS::Rooted<JS::Value> tmp(cx);
5160 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
5161 : // Control block to let us common up the JS_DefineElement calls when there
5162 : // are different ways to succeed at wrapping the object.
5163 : do {
5164 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
5165 0 : return false;
5166 : }
5167 0 : break;
5168 : } while (0);
5169 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
5170 : JSPROP_ENUMERATE)) {
5171 0 : return false;
5172 : }
5173 : }
5174 : }
5175 0 : temp.setObject(*returnArray);
5176 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->inboundRTPStreamStats_id, temp, JSPROP_ENUMERATE)) {
5177 0 : return false;
5178 : }
5179 0 : break;
5180 : } while(0);
5181 : }
5182 :
5183 0 : if (mLocalSdp.WasPassed()) {
5184 : do {
5185 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
5186 0 : JS::Rooted<JS::Value> temp(cx);
5187 0 : nsString const & currentValue = mLocalSdp.InternalValue();
5188 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
5189 0 : return false;
5190 : }
5191 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->localSdp_id, temp, JSPROP_ENUMERATE)) {
5192 0 : return false;
5193 : }
5194 0 : break;
5195 : } while(0);
5196 : }
5197 :
5198 0 : if (mMediaStreamStats.WasPassed()) {
5199 : do {
5200 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
5201 0 : JS::Rooted<JS::Value> temp(cx);
5202 0 : Sequence<RTCMediaStreamStats> const & currentValue = mMediaStreamStats.InternalValue();
5203 :
5204 0 : uint32_t length = currentValue.Length();
5205 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
5206 0 : if (!returnArray) {
5207 0 : return false;
5208 : }
5209 : // Scope for 'tmp'
5210 : {
5211 0 : JS::Rooted<JS::Value> tmp(cx);
5212 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
5213 : // Control block to let us common up the JS_DefineElement calls when there
5214 : // are different ways to succeed at wrapping the object.
5215 : do {
5216 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
5217 0 : return false;
5218 : }
5219 0 : break;
5220 : } while (0);
5221 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
5222 : JSPROP_ENUMERATE)) {
5223 0 : return false;
5224 : }
5225 : }
5226 : }
5227 0 : temp.setObject(*returnArray);
5228 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->mediaStreamStats_id, temp, JSPROP_ENUMERATE)) {
5229 0 : return false;
5230 : }
5231 0 : break;
5232 : } while(0);
5233 : }
5234 :
5235 0 : if (mMediaStreamTrackStats.WasPassed()) {
5236 : do {
5237 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
5238 0 : JS::Rooted<JS::Value> temp(cx);
5239 0 : Sequence<RTCMediaStreamTrackStats> const & currentValue = mMediaStreamTrackStats.InternalValue();
5240 :
5241 0 : uint32_t length = currentValue.Length();
5242 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
5243 0 : if (!returnArray) {
5244 0 : return false;
5245 : }
5246 : // Scope for 'tmp'
5247 : {
5248 0 : JS::Rooted<JS::Value> tmp(cx);
5249 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
5250 : // Control block to let us common up the JS_DefineElement calls when there
5251 : // are different ways to succeed at wrapping the object.
5252 : do {
5253 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
5254 0 : return false;
5255 : }
5256 0 : break;
5257 : } while (0);
5258 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
5259 : JSPROP_ENUMERATE)) {
5260 0 : return false;
5261 : }
5262 : }
5263 : }
5264 0 : temp.setObject(*returnArray);
5265 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->mediaStreamTrackStats_id, temp, JSPROP_ENUMERATE)) {
5266 0 : return false;
5267 : }
5268 0 : break;
5269 : } while(0);
5270 : }
5271 :
5272 0 : if (mOutboundRTPStreamStats.WasPassed()) {
5273 : do {
5274 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
5275 0 : JS::Rooted<JS::Value> temp(cx);
5276 0 : Sequence<RTCOutboundRTPStreamStats> const & currentValue = mOutboundRTPStreamStats.InternalValue();
5277 :
5278 0 : uint32_t length = currentValue.Length();
5279 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
5280 0 : if (!returnArray) {
5281 0 : return false;
5282 : }
5283 : // Scope for 'tmp'
5284 : {
5285 0 : JS::Rooted<JS::Value> tmp(cx);
5286 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
5287 : // Control block to let us common up the JS_DefineElement calls when there
5288 : // are different ways to succeed at wrapping the object.
5289 : do {
5290 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
5291 0 : return false;
5292 : }
5293 0 : break;
5294 : } while (0);
5295 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
5296 : JSPROP_ENUMERATE)) {
5297 0 : return false;
5298 : }
5299 : }
5300 : }
5301 0 : temp.setObject(*returnArray);
5302 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->outboundRTPStreamStats_id, temp, JSPROP_ENUMERATE)) {
5303 0 : return false;
5304 : }
5305 0 : break;
5306 : } while(0);
5307 : }
5308 :
5309 : do {
5310 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
5311 0 : JS::Rooted<JS::Value> temp(cx);
5312 0 : nsString const & currentValue = mPcid;
5313 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
5314 0 : return false;
5315 : }
5316 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->pcid_id, temp, JSPROP_ENUMERATE)) {
5317 0 : return false;
5318 : }
5319 0 : break;
5320 : } while(0);
5321 :
5322 0 : if (mRemoteSdp.WasPassed()) {
5323 : do {
5324 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
5325 0 : JS::Rooted<JS::Value> temp(cx);
5326 0 : nsString const & currentValue = mRemoteSdp.InternalValue();
5327 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
5328 0 : return false;
5329 : }
5330 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->remoteSdp_id, temp, JSPROP_ENUMERATE)) {
5331 0 : return false;
5332 : }
5333 0 : break;
5334 : } while(0);
5335 : }
5336 :
5337 0 : if (mRtpContributingSourceStats.WasPassed()) {
5338 : do {
5339 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
5340 0 : JS::Rooted<JS::Value> temp(cx);
5341 0 : Sequence<RTCRTPContributingSourceStats> const & currentValue = mRtpContributingSourceStats.InternalValue();
5342 :
5343 0 : uint32_t length = currentValue.Length();
5344 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
5345 0 : if (!returnArray) {
5346 0 : return false;
5347 : }
5348 : // Scope for 'tmp'
5349 : {
5350 0 : JS::Rooted<JS::Value> tmp(cx);
5351 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
5352 : // Control block to let us common up the JS_DefineElement calls when there
5353 : // are different ways to succeed at wrapping the object.
5354 : do {
5355 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
5356 0 : return false;
5357 : }
5358 0 : break;
5359 : } while (0);
5360 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
5361 : JSPROP_ENUMERATE)) {
5362 0 : return false;
5363 : }
5364 : }
5365 : }
5366 0 : temp.setObject(*returnArray);
5367 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->rtpContributingSourceStats_id, temp, JSPROP_ENUMERATE)) {
5368 0 : return false;
5369 : }
5370 0 : break;
5371 : } while(0);
5372 : }
5373 :
5374 0 : if (mTimestamp.WasPassed()) {
5375 : do {
5376 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
5377 0 : JS::Rooted<JS::Value> temp(cx);
5378 0 : double const & currentValue = mTimestamp.InternalValue();
5379 0 : temp.set(JS_NumberValue(double(currentValue)));
5380 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->timestamp_id, temp, JSPROP_ENUMERATE)) {
5381 0 : return false;
5382 : }
5383 0 : break;
5384 : } while(0);
5385 : }
5386 :
5387 0 : if (mTransportStats.WasPassed()) {
5388 : do {
5389 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
5390 0 : JS::Rooted<JS::Value> temp(cx);
5391 0 : Sequence<RTCTransportStats> const & currentValue = mTransportStats.InternalValue();
5392 :
5393 0 : uint32_t length = currentValue.Length();
5394 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
5395 0 : if (!returnArray) {
5396 0 : return false;
5397 : }
5398 : // Scope for 'tmp'
5399 : {
5400 0 : JS::Rooted<JS::Value> tmp(cx);
5401 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
5402 : // Control block to let us common up the JS_DefineElement calls when there
5403 : // are different ways to succeed at wrapping the object.
5404 : do {
5405 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
5406 0 : return false;
5407 : }
5408 0 : break;
5409 : } while (0);
5410 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
5411 : JSPROP_ENUMERATE)) {
5412 0 : return false;
5413 : }
5414 : }
5415 : }
5416 0 : temp.setObject(*returnArray);
5417 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->transportStats_id, temp, JSPROP_ENUMERATE)) {
5418 0 : return false;
5419 : }
5420 0 : break;
5421 : } while(0);
5422 : }
5423 :
5424 0 : return true;
5425 : }
5426 :
5427 : bool
5428 0 : RTCStatsReportInternal::ToJSON(nsAString& aJSON) const
5429 : {
5430 0 : AutoJSAPI jsapi;
5431 0 : jsapi.Init();
5432 0 : JSContext *cx = jsapi.cx();
5433 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
5434 : // because we'll only be creating objects, in ways that have no
5435 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
5436 : // which likewise guarantees no side-effects for the sorts of
5437 : // things we will pass it.
5438 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
5439 0 : JS::Rooted<JS::Value> val(cx);
5440 0 : if (!ToObjectInternal(cx, &val)) {
5441 0 : return false;
5442 : }
5443 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
5444 0 : return StringifyToJSON(cx, obj, aJSON);
5445 : }
5446 :
5447 : void
5448 0 : RTCStatsReportInternal::TraceDictionary(JSTracer* trc)
5449 : {
5450 0 : }
5451 :
5452 : RTCStatsReportInternal&
5453 0 : RTCStatsReportInternal::operator=(const RTCStatsReportInternal& aOther)
5454 : {
5455 0 : mClosed.Reset();
5456 0 : if (aOther.mClosed.WasPassed()) {
5457 0 : mClosed.Construct(aOther.mClosed.Value());
5458 : }
5459 0 : mCodecStats.Reset();
5460 0 : if (aOther.mCodecStats.WasPassed()) {
5461 0 : mCodecStats.Construct(aOther.mCodecStats.Value());
5462 : }
5463 0 : mIceCandidatePairStats.Reset();
5464 0 : if (aOther.mIceCandidatePairStats.WasPassed()) {
5465 0 : mIceCandidatePairStats.Construct(aOther.mIceCandidatePairStats.Value());
5466 : }
5467 0 : mIceCandidateStats.Reset();
5468 0 : if (aOther.mIceCandidateStats.WasPassed()) {
5469 0 : mIceCandidateStats.Construct(aOther.mIceCandidateStats.Value());
5470 : }
5471 0 : mIceComponentStats.Reset();
5472 0 : if (aOther.mIceComponentStats.WasPassed()) {
5473 0 : mIceComponentStats.Construct(aOther.mIceComponentStats.Value());
5474 : }
5475 0 : mIceRestarts.Reset();
5476 0 : if (aOther.mIceRestarts.WasPassed()) {
5477 0 : mIceRestarts.Construct(aOther.mIceRestarts.Value());
5478 : }
5479 0 : mIceRollbacks.Reset();
5480 0 : if (aOther.mIceRollbacks.WasPassed()) {
5481 0 : mIceRollbacks.Construct(aOther.mIceRollbacks.Value());
5482 : }
5483 0 : mInboundRTPStreamStats.Reset();
5484 0 : if (aOther.mInboundRTPStreamStats.WasPassed()) {
5485 0 : mInboundRTPStreamStats.Construct(aOther.mInboundRTPStreamStats.Value());
5486 : }
5487 0 : mLocalSdp.Reset();
5488 0 : if (aOther.mLocalSdp.WasPassed()) {
5489 0 : mLocalSdp.Construct(aOther.mLocalSdp.Value());
5490 : }
5491 0 : mMediaStreamStats.Reset();
5492 0 : if (aOther.mMediaStreamStats.WasPassed()) {
5493 0 : mMediaStreamStats.Construct(aOther.mMediaStreamStats.Value());
5494 : }
5495 0 : mMediaStreamTrackStats.Reset();
5496 0 : if (aOther.mMediaStreamTrackStats.WasPassed()) {
5497 0 : mMediaStreamTrackStats.Construct(aOther.mMediaStreamTrackStats.Value());
5498 : }
5499 0 : mOutboundRTPStreamStats.Reset();
5500 0 : if (aOther.mOutboundRTPStreamStats.WasPassed()) {
5501 0 : mOutboundRTPStreamStats.Construct(aOther.mOutboundRTPStreamStats.Value());
5502 : }
5503 0 : mPcid = aOther.mPcid;
5504 0 : mRemoteSdp.Reset();
5505 0 : if (aOther.mRemoteSdp.WasPassed()) {
5506 0 : mRemoteSdp.Construct(aOther.mRemoteSdp.Value());
5507 : }
5508 0 : mRtpContributingSourceStats.Reset();
5509 0 : if (aOther.mRtpContributingSourceStats.WasPassed()) {
5510 0 : mRtpContributingSourceStats.Construct(aOther.mRtpContributingSourceStats.Value());
5511 : }
5512 0 : mTimestamp.Reset();
5513 0 : if (aOther.mTimestamp.WasPassed()) {
5514 0 : mTimestamp.Construct(aOther.mTimestamp.Value());
5515 : }
5516 0 : mTransportStats.Reset();
5517 0 : if (aOther.mTransportStats.WasPassed()) {
5518 0 : mTransportStats.Construct(aOther.mTransportStats.Value());
5519 : }
5520 0 : return *this;
5521 : }
5522 :
5523 : namespace binding_detail {
5524 : } // namespace binding_detail
5525 :
5526 :
5527 : namespace RTCStatsReportBinding {
5528 :
5529 : namespace MaplikeHelpers {
5530 : void
5531 0 : Clear(mozilla::dom::RTCStatsReport* self, ErrorResult& aRv)
5532 : {
5533 0 : MOZ_ASSERT(self);
5534 0 : AutoJSAPI jsapi;
5535 0 : jsapi.Init();
5536 0 : JSContext* cx = jsapi.cx();
5537 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
5538 : // all we want is to wrap into _some_ scope and then unwrap to find
5539 : // the reflector, and wrapping has no side-effects.
5540 0 : JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
5541 0 : JS::Rooted<JS::Value> v(cx);
5542 0 : if(!ToJSValue(cx, self, &v)) {
5543 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
5544 0 : return;
5545 : }
5546 : // This is a reflector, but due to trying to name things
5547 : // similarly across method generators, it's called obj here.
5548 0 : JS::Rooted<JSObject*> obj(cx);
5549 0 : obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
5550 0 : JSAutoCompartment reflectorCompartment(cx, obj);
5551 :
5552 0 : JS::Rooted<JSObject*> backingObj(cx);
5553 0 : bool created = false;
5554 0 : if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
5555 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
5556 0 : return;
5557 : }
5558 0 : if (created) {
5559 0 : PreserveWrapper<mozilla::dom::RTCStatsReport>(self);
5560 : }
5561 0 : if (!JS::MapClear(cx, backingObj)) {
5562 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
5563 0 : return;
5564 : }
5565 0 : return;
5566 : }
5567 : bool
5568 0 : Delete(mozilla::dom::RTCStatsReport* self, const nsAString& aKey, ErrorResult& aRv)
5569 : {
5570 0 : MOZ_ASSERT(self);
5571 0 : AutoJSAPI jsapi;
5572 0 : jsapi.Init();
5573 0 : JSContext* cx = jsapi.cx();
5574 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
5575 : // all we want is to wrap into _some_ scope and then unwrap to find
5576 : // the reflector, and wrapping has no side-effects.
5577 0 : JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
5578 0 : JS::Rooted<JS::Value> v(cx);
5579 0 : if(!ToJSValue(cx, self, &v)) {
5580 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
5581 0 : return false;
5582 : }
5583 : // This is a reflector, but due to trying to name things
5584 : // similarly across method generators, it's called obj here.
5585 0 : JS::Rooted<JSObject*> obj(cx);
5586 0 : obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
5587 0 : JSAutoCompartment reflectorCompartment(cx, obj);
5588 : bool aRetVal;
5589 0 : JS::AutoValueVector argv(cx);
5590 0 : if (!argv.resize(1)) {
5591 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
5592 0 : return false;
5593 : }
5594 : do {
5595 0 : nsString mutableStr(aKey);
5596 0 : if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
5597 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
5598 0 : return false;
5599 : }
5600 0 : break;
5601 : } while (0);
5602 :
5603 0 : JS::Rooted<JSObject*> backingObj(cx);
5604 0 : bool created = false;
5605 0 : if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
5606 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
5607 0 : return false;
5608 : }
5609 0 : if (created) {
5610 0 : PreserveWrapper<mozilla::dom::RTCStatsReport>(self);
5611 : }
5612 0 : if (!JS::MapDelete(cx, backingObj, argv[0], &aRetVal)) {
5613 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
5614 0 : return false;
5615 : }
5616 0 : return aRetVal;
5617 : }
5618 : bool
5619 0 : Has(mozilla::dom::RTCStatsReport* self, const nsAString& aKey, ErrorResult& aRv)
5620 : {
5621 0 : MOZ_ASSERT(self);
5622 0 : AutoJSAPI jsapi;
5623 0 : jsapi.Init();
5624 0 : JSContext* cx = jsapi.cx();
5625 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
5626 : // all we want is to wrap into _some_ scope and then unwrap to find
5627 : // the reflector, and wrapping has no side-effects.
5628 0 : JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
5629 0 : JS::Rooted<JS::Value> v(cx);
5630 0 : if(!ToJSValue(cx, self, &v)) {
5631 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
5632 0 : return false;
5633 : }
5634 : // This is a reflector, but due to trying to name things
5635 : // similarly across method generators, it's called obj here.
5636 0 : JS::Rooted<JSObject*> obj(cx);
5637 0 : obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
5638 0 : JSAutoCompartment reflectorCompartment(cx, obj);
5639 : bool aRetVal;
5640 0 : JS::AutoValueVector argv(cx);
5641 0 : if (!argv.resize(1)) {
5642 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
5643 0 : return false;
5644 : }
5645 : do {
5646 0 : nsString mutableStr(aKey);
5647 0 : if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
5648 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
5649 0 : return false;
5650 : }
5651 0 : break;
5652 : } while (0);
5653 :
5654 0 : JS::Rooted<JSObject*> backingObj(cx);
5655 0 : bool created = false;
5656 0 : if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
5657 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
5658 0 : return false;
5659 : }
5660 0 : if (created) {
5661 0 : PreserveWrapper<mozilla::dom::RTCStatsReport>(self);
5662 : }
5663 0 : if (!JS::MapHas(cx, backingObj, argv[0], &aRetVal)) {
5664 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
5665 0 : return false;
5666 : }
5667 0 : return aRetVal;
5668 : }
5669 : void
5670 0 : Set(mozilla::dom::RTCStatsReport* self, const nsAString& aKey, JS::Handle<JSObject*> aValue, ErrorResult& aRv)
5671 : {
5672 0 : MOZ_ASSERT(self);
5673 0 : AutoJSAPI jsapi;
5674 0 : jsapi.Init();
5675 0 : JSContext* cx = jsapi.cx();
5676 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
5677 : // all we want is to wrap into _some_ scope and then unwrap to find
5678 : // the reflector, and wrapping has no side-effects.
5679 0 : JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
5680 0 : JS::Rooted<JS::Value> v(cx);
5681 0 : if(!ToJSValue(cx, self, &v)) {
5682 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
5683 0 : return;
5684 : }
5685 : // This is a reflector, but due to trying to name things
5686 : // similarly across method generators, it's called obj here.
5687 0 : JS::Rooted<JSObject*> obj(cx);
5688 0 : obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
5689 0 : JSAutoCompartment reflectorCompartment(cx, obj);
5690 0 : JS::AutoValueVector argv(cx);
5691 0 : if (!argv.resize(2)) {
5692 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
5693 0 : return;
5694 : }
5695 : do {
5696 0 : JS::ExposeObjectToActiveJS(aValue);
5697 0 : argv[1].setObject(*aValue);
5698 0 : if (!MaybeWrapObjectValue(cx, argv[1])) {
5699 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
5700 0 : return;
5701 : }
5702 0 : break;
5703 : } while (0);
5704 :
5705 : do {
5706 0 : nsString mutableStr(aKey);
5707 0 : if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
5708 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
5709 0 : return;
5710 : }
5711 0 : break;
5712 : } while (0);
5713 :
5714 0 : JS::Rooted<JSObject*> backingObj(cx);
5715 0 : bool created = false;
5716 0 : if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
5717 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
5718 0 : return;
5719 : }
5720 0 : if (created) {
5721 0 : PreserveWrapper<mozilla::dom::RTCStatsReport>(self);
5722 : }
5723 0 : if (!JS::MapSet(cx, backingObj, argv[0], argv[1])) {
5724 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
5725 0 : return;
5726 : }
5727 0 : return;
5728 : }
5729 : } // namespace MaplikeHelpers
5730 :
5731 : static bool
5732 0 : get_mozPcid(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCStatsReport* self, JSJitGetterCallArgs args)
5733 : {
5734 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
5735 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
5736 0 : if (objIsXray) {
5737 0 : unwrappedObj.emplace(cx, obj);
5738 : }
5739 0 : if (objIsXray) {
5740 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
5741 0 : if (!unwrappedObj.ref()) {
5742 0 : return false;
5743 : }
5744 : }
5745 0 : binding_detail::FastErrorResult rv;
5746 0 : DOMString result;
5747 0 : self->GetMozPcid(result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
5748 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
5749 0 : return false;
5750 : }
5751 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
5752 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
5753 0 : return false;
5754 : }
5755 0 : return true;
5756 : }
5757 :
5758 : static const JSJitInfo mozPcid_getterinfo = {
5759 : { (JSJitGetterOp)get_mozPcid },
5760 : { prototypes::id::RTCStatsReport },
5761 : { PrototypeTraits<prototypes::id::RTCStatsReport>::Depth },
5762 : JSJitInfo::Getter,
5763 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
5764 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
5765 : false, /* isInfallible. False in setters. */
5766 : false, /* isMovable. Not relevant for setters. */
5767 : false, /* isEliminatable. Not relevant for setters. */
5768 : false, /* isAlwaysInSlot. Only relevant for getters. */
5769 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
5770 : false, /* isTypedMethod. Only relevant for methods. */
5771 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
5772 : };
5773 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
5774 : static_assert(0 < 2, "There is no slot for us");
5775 :
5776 : static bool
5777 0 : get_size(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCStatsReport* self, JSJitGetterCallArgs args)
5778 : {
5779 0 : JS::Rooted<JSObject*> backingObj(cx);
5780 0 : bool created = false;
5781 0 : if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
5782 0 : return false;
5783 : }
5784 0 : if (created) {
5785 0 : PreserveWrapper<mozilla::dom::RTCStatsReport>(self);
5786 : }
5787 0 : uint32_t result = JS::MapSize(cx, backingObj);
5788 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
5789 0 : args.rval().setNumber(result);
5790 0 : return true;
5791 : }
5792 :
5793 : static const JSJitInfo size_getterinfo = {
5794 : { (JSJitGetterOp)get_size },
5795 : { prototypes::id::RTCStatsReport },
5796 : { PrototypeTraits<prototypes::id::RTCStatsReport>::Depth },
5797 : JSJitInfo::Getter,
5798 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
5799 : JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
5800 : false, /* isInfallible. False in setters. */
5801 : false, /* isMovable. Not relevant for setters. */
5802 : false, /* isEliminatable. Not relevant for setters. */
5803 : false, /* isAlwaysInSlot. Only relevant for getters. */
5804 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
5805 : false, /* isTypedMethod. Only relevant for methods. */
5806 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
5807 : };
5808 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
5809 : static_assert(0 < 2, "There is no slot for us");
5810 :
5811 : static bool
5812 0 : entries(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCStatsReport* self, const JSJitMethodCallArgs& args)
5813 : {
5814 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
5815 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
5816 0 : if (objIsXray) {
5817 0 : unwrappedObj.emplace(cx, obj);
5818 : }
5819 0 : if (objIsXray) {
5820 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
5821 0 : if (!unwrappedObj.ref()) {
5822 0 : return false;
5823 : }
5824 : }
5825 0 : JS::Rooted<JSObject*> backingObj(cx);
5826 0 : bool created = false;
5827 0 : if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
5828 0 : return false;
5829 : }
5830 0 : if (created) {
5831 0 : PreserveWrapper<mozilla::dom::RTCStatsReport>(self);
5832 : }
5833 : // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
5834 : // after bug 1023984 is fixed.
5835 0 : if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
5836 0 : JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
5837 0 : return false;
5838 : }
5839 0 : JS::Rooted<JSObject*> result(cx);
5840 0 : JS::Rooted<JS::Value> v(cx);
5841 0 : if (!JS::MapEntries(cx, backingObj, &v)) {
5842 0 : return false;
5843 : }
5844 0 : result = &v.toObject();
5845 0 : JS::ExposeObjectToActiveJS(result);
5846 0 : args.rval().setObject(*result);
5847 0 : if (!MaybeWrapObjectValue(cx, args.rval())) {
5848 0 : return false;
5849 : }
5850 0 : return true;
5851 : }
5852 :
5853 : static const JSJitInfo::ArgType entries_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
5854 : static const JSTypedMethodJitInfo entries_methodinfo = {
5855 : {
5856 : { (JSJitGetterOp)entries },
5857 : { prototypes::id::RTCStatsReport },
5858 : { PrototypeTraits<prototypes::id::RTCStatsReport>::Depth },
5859 : JSJitInfo::Method,
5860 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
5861 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
5862 : false, /* isInfallible. False in setters. */
5863 : false, /* isMovable. Not relevant for setters. */
5864 : false, /* isEliminatable. Not relevant for setters. */
5865 : false, /* isAlwaysInSlot. Only relevant for getters. */
5866 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
5867 : true, /* isTypedMethod. Only relevant for methods. */
5868 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
5869 : },
5870 : entries_methodinfo_argTypes
5871 : };
5872 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
5873 : static_assert(0 < 2, "There is no slot for us");
5874 :
5875 : static bool
5876 0 : keys(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCStatsReport* self, const JSJitMethodCallArgs& args)
5877 : {
5878 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
5879 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
5880 0 : if (objIsXray) {
5881 0 : unwrappedObj.emplace(cx, obj);
5882 : }
5883 0 : if (objIsXray) {
5884 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
5885 0 : if (!unwrappedObj.ref()) {
5886 0 : return false;
5887 : }
5888 : }
5889 0 : JS::Rooted<JSObject*> backingObj(cx);
5890 0 : bool created = false;
5891 0 : if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
5892 0 : return false;
5893 : }
5894 0 : if (created) {
5895 0 : PreserveWrapper<mozilla::dom::RTCStatsReport>(self);
5896 : }
5897 : // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
5898 : // after bug 1023984 is fixed.
5899 0 : if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
5900 0 : JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
5901 0 : return false;
5902 : }
5903 0 : JS::Rooted<JSObject*> result(cx);
5904 0 : JS::Rooted<JS::Value> v(cx);
5905 0 : if (!JS::MapKeys(cx, backingObj, &v)) {
5906 0 : return false;
5907 : }
5908 0 : result = &v.toObject();
5909 0 : JS::ExposeObjectToActiveJS(result);
5910 0 : args.rval().setObject(*result);
5911 0 : if (!MaybeWrapObjectValue(cx, args.rval())) {
5912 0 : return false;
5913 : }
5914 0 : return true;
5915 : }
5916 :
5917 : static const JSJitInfo::ArgType keys_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
5918 : static const JSTypedMethodJitInfo keys_methodinfo = {
5919 : {
5920 : { (JSJitGetterOp)keys },
5921 : { prototypes::id::RTCStatsReport },
5922 : { PrototypeTraits<prototypes::id::RTCStatsReport>::Depth },
5923 : JSJitInfo::Method,
5924 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
5925 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
5926 : false, /* isInfallible. False in setters. */
5927 : false, /* isMovable. Not relevant for setters. */
5928 : false, /* isEliminatable. Not relevant for setters. */
5929 : false, /* isAlwaysInSlot. Only relevant for getters. */
5930 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
5931 : true, /* isTypedMethod. Only relevant for methods. */
5932 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
5933 : },
5934 : keys_methodinfo_argTypes
5935 : };
5936 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
5937 : static_assert(0 < 2, "There is no slot for us");
5938 :
5939 : static bool
5940 0 : values(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCStatsReport* self, const JSJitMethodCallArgs& args)
5941 : {
5942 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
5943 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
5944 0 : if (objIsXray) {
5945 0 : unwrappedObj.emplace(cx, obj);
5946 : }
5947 0 : if (objIsXray) {
5948 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
5949 0 : if (!unwrappedObj.ref()) {
5950 0 : return false;
5951 : }
5952 : }
5953 0 : JS::Rooted<JSObject*> backingObj(cx);
5954 0 : bool created = false;
5955 0 : if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
5956 0 : return false;
5957 : }
5958 0 : if (created) {
5959 0 : PreserveWrapper<mozilla::dom::RTCStatsReport>(self);
5960 : }
5961 : // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
5962 : // after bug 1023984 is fixed.
5963 0 : if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
5964 0 : JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
5965 0 : return false;
5966 : }
5967 0 : JS::Rooted<JSObject*> result(cx);
5968 0 : JS::Rooted<JS::Value> v(cx);
5969 0 : if (!JS::MapValues(cx, backingObj, &v)) {
5970 0 : return false;
5971 : }
5972 0 : result = &v.toObject();
5973 0 : JS::ExposeObjectToActiveJS(result);
5974 0 : args.rval().setObject(*result);
5975 0 : if (!MaybeWrapObjectValue(cx, args.rval())) {
5976 0 : return false;
5977 : }
5978 0 : return true;
5979 : }
5980 :
5981 : static const JSJitInfo::ArgType values_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
5982 : static const JSTypedMethodJitInfo values_methodinfo = {
5983 : {
5984 : { (JSJitGetterOp)values },
5985 : { prototypes::id::RTCStatsReport },
5986 : { PrototypeTraits<prototypes::id::RTCStatsReport>::Depth },
5987 : JSJitInfo::Method,
5988 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
5989 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
5990 : false, /* isInfallible. False in setters. */
5991 : false, /* isMovable. Not relevant for setters. */
5992 : false, /* isEliminatable. Not relevant for setters. */
5993 : false, /* isAlwaysInSlot. Only relevant for getters. */
5994 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
5995 : true, /* isTypedMethod. Only relevant for methods. */
5996 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
5997 : },
5998 : values_methodinfo_argTypes
5999 : };
6000 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
6001 : static_assert(0 < 2, "There is no slot for us");
6002 :
6003 : static bool
6004 0 : forEach(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCStatsReport* self, const JSJitMethodCallArgs& args)
6005 : {
6006 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
6007 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
6008 0 : if (objIsXray) {
6009 0 : unwrappedObj.emplace(cx, obj);
6010 : }
6011 0 : JS::Rooted<JSObject*> arg0(cx);
6012 0 : if (args.get(0).isObject()) {
6013 : #ifdef __clang__
6014 : #pragma clang diagnostic push
6015 : #pragma clang diagnostic ignored "-Wunreachable-code"
6016 : #pragma clang diagnostic ignored "-Wunreachable-code-return"
6017 : #endif // __clang__
6018 0 : if ((true) && !CallerSubsumes(args.get(0))) {
6019 0 : ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "argument 1 of RTCStatsReport.forEach");
6020 0 : return false;
6021 : }
6022 : #ifdef __clang__
6023 : #pragma clang diagnostic pop
6024 : #endif // __clang__
6025 0 : arg0 = &args.get(0).toObject();
6026 : } else {
6027 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of RTCStatsReport.forEach");
6028 0 : return false;
6029 : }
6030 0 : JS::Rooted<JS::Value> arg1(cx);
6031 0 : if (args.hasDefined(1)) {
6032 : #ifdef __clang__
6033 : #pragma clang diagnostic push
6034 : #pragma clang diagnostic ignored "-Wunreachable-code"
6035 : #pragma clang diagnostic ignored "-Wunreachable-code-return"
6036 : #endif // __clang__
6037 0 : if ((true) && !CallerSubsumes(args.get(1))) {
6038 0 : ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "argument 2 of RTCStatsReport.forEach");
6039 0 : return false;
6040 : }
6041 : #ifdef __clang__
6042 : #pragma clang diagnostic pop
6043 : #endif // __clang__
6044 0 : arg1 = args.get(1);
6045 : } else {
6046 0 : arg1 = JS::UndefinedValue();
6047 : }
6048 0 : if (objIsXray) {
6049 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
6050 0 : if (!unwrappedObj.ref()) {
6051 0 : return false;
6052 : }
6053 : }
6054 0 : JS::Rooted<JSObject*> backingObj(cx);
6055 0 : bool created = false;
6056 0 : if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
6057 0 : return false;
6058 : }
6059 0 : if (created) {
6060 0 : PreserveWrapper<mozilla::dom::RTCStatsReport>(self);
6061 : }
6062 : // Create a wrapper function.
6063 0 : JSFunction* func = js::NewFunctionWithReserved(cx, ForEachHandler, 3, 0, nullptr);
6064 0 : if (!func) {
6065 0 : return false;
6066 : }
6067 0 : JS::Rooted<JSObject*> funcObj(cx, JS_GetFunctionObject(func));
6068 0 : JS::Rooted<JS::Value> funcVal(cx, JS::ObjectValue(*funcObj));
6069 0 : js::SetFunctionNativeReserved(funcObj, FOREACH_CALLBACK_SLOT,
6070 0 : JS::ObjectValue(*arg0));
6071 0 : js::SetFunctionNativeReserved(funcObj, FOREACH_MAPLIKEORSETLIKEOBJ_SLOT,
6072 0 : JS::ObjectValue(*obj));
6073 0 : if (!JS::MapForEach(cx, backingObj, funcVal, arg1)) {
6074 0 : return false;
6075 : }
6076 0 : args.rval().setUndefined();
6077 0 : return true;
6078 : }
6079 :
6080 : static const JSJitInfo forEach_methodinfo = {
6081 : { (JSJitGetterOp)forEach },
6082 : { prototypes::id::RTCStatsReport },
6083 : { PrototypeTraits<prototypes::id::RTCStatsReport>::Depth },
6084 : JSJitInfo::Method,
6085 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
6086 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
6087 : false, /* isInfallible. False in setters. */
6088 : false, /* isMovable. Not relevant for setters. */
6089 : false, /* isEliminatable. Not relevant for setters. */
6090 : false, /* isAlwaysInSlot. Only relevant for getters. */
6091 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
6092 : false, /* isTypedMethod. Only relevant for methods. */
6093 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
6094 : };
6095 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
6096 : static_assert(0 < 2, "There is no slot for us");
6097 :
6098 : static bool
6099 0 : has(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCStatsReport* self, const JSJitMethodCallArgs& args)
6100 : {
6101 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
6102 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
6103 0 : if (objIsXray) {
6104 0 : unwrappedObj.emplace(cx, obj);
6105 : }
6106 0 : binding_detail::FakeString arg0;
6107 0 : if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
6108 0 : return false;
6109 : }
6110 0 : if (objIsXray) {
6111 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
6112 0 : if (!unwrappedObj.ref()) {
6113 0 : return false;
6114 : }
6115 : }
6116 0 : JS::Rooted<JSObject*> backingObj(cx);
6117 0 : bool created = false;
6118 0 : if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
6119 0 : return false;
6120 : }
6121 0 : if (created) {
6122 0 : PreserveWrapper<mozilla::dom::RTCStatsReport>(self);
6123 : }
6124 0 : JS::Rooted<JS::Value> arg0Val(cx);
6125 0 : if (!ToJSValue(cx, arg0, &arg0Val)) {
6126 0 : return false;
6127 : }
6128 : bool result;
6129 0 : if (!JS::MapHas(cx, backingObj, arg0Val, &result)) {
6130 0 : return false;
6131 : }
6132 0 : args.rval().setBoolean(result);
6133 0 : return true;
6134 : }
6135 :
6136 : static const JSJitInfo::ArgType has_methodinfo_argTypes[] = { JSJitInfo::String, JSJitInfo::ArgTypeListEnd };
6137 : static const JSTypedMethodJitInfo has_methodinfo = {
6138 : {
6139 : { (JSJitGetterOp)has },
6140 : { prototypes::id::RTCStatsReport },
6141 : { PrototypeTraits<prototypes::id::RTCStatsReport>::Depth },
6142 : JSJitInfo::Method,
6143 : JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
6144 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
6145 : false, /* isInfallible. False in setters. */
6146 : false, /* isMovable. Not relevant for setters. */
6147 : false, /* isEliminatable. Not relevant for setters. */
6148 : false, /* isAlwaysInSlot. Only relevant for getters. */
6149 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
6150 : true, /* isTypedMethod. Only relevant for methods. */
6151 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
6152 : },
6153 : has_methodinfo_argTypes
6154 : };
6155 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
6156 : static_assert(0 < 2, "There is no slot for us");
6157 :
6158 : static bool
6159 0 : __clear(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCStatsReport* self, const JSJitMethodCallArgs& args)
6160 : {
6161 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
6162 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
6163 0 : if (objIsXray) {
6164 0 : unwrappedObj.emplace(cx, obj);
6165 : }
6166 0 : if (objIsXray) {
6167 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
6168 0 : if (!unwrappedObj.ref()) {
6169 0 : return false;
6170 : }
6171 : }
6172 0 : JS::Rooted<JSObject*> backingObj(cx);
6173 0 : bool created = false;
6174 0 : if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
6175 0 : return false;
6176 : }
6177 0 : if (created) {
6178 0 : PreserveWrapper<mozilla::dom::RTCStatsReport>(self);
6179 : }
6180 0 : if (!JS::MapClear(cx, backingObj)) {
6181 0 : return false;
6182 : }
6183 0 : args.rval().setUndefined();
6184 0 : return true;
6185 : }
6186 :
6187 : static const JSJitInfo __clear_methodinfo = {
6188 : { (JSJitGetterOp)__clear },
6189 : { prototypes::id::RTCStatsReport },
6190 : { PrototypeTraits<prototypes::id::RTCStatsReport>::Depth },
6191 : JSJitInfo::Method,
6192 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
6193 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
6194 : false, /* isInfallible. False in setters. */
6195 : false, /* isMovable. Not relevant for setters. */
6196 : false, /* isEliminatable. Not relevant for setters. */
6197 : false, /* isAlwaysInSlot. Only relevant for getters. */
6198 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
6199 : false, /* isTypedMethod. Only relevant for methods. */
6200 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
6201 : };
6202 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
6203 : static_assert(0 < 2, "There is no slot for us");
6204 :
6205 : static bool
6206 0 : __delete(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCStatsReport* self, const JSJitMethodCallArgs& args)
6207 : {
6208 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
6209 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
6210 0 : if (objIsXray) {
6211 0 : unwrappedObj.emplace(cx, obj);
6212 : }
6213 0 : binding_detail::FakeString arg0;
6214 0 : if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
6215 0 : return false;
6216 : }
6217 0 : if (objIsXray) {
6218 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
6219 0 : if (!unwrappedObj.ref()) {
6220 0 : return false;
6221 : }
6222 : }
6223 0 : JS::Rooted<JSObject*> backingObj(cx);
6224 0 : bool created = false;
6225 0 : if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
6226 0 : return false;
6227 : }
6228 0 : if (created) {
6229 0 : PreserveWrapper<mozilla::dom::RTCStatsReport>(self);
6230 : }
6231 0 : JS::Rooted<JS::Value> arg0Val(cx);
6232 0 : if (!ToJSValue(cx, arg0, &arg0Val)) {
6233 0 : return false;
6234 : }
6235 : bool result;
6236 0 : if (!JS::MapDelete(cx, backingObj, arg0Val, &result)) {
6237 0 : return false;
6238 : }
6239 0 : args.rval().setBoolean(result);
6240 0 : return true;
6241 : }
6242 :
6243 : static const JSJitInfo __delete_methodinfo = {
6244 : { (JSJitGetterOp)__delete },
6245 : { prototypes::id::RTCStatsReport },
6246 : { PrototypeTraits<prototypes::id::RTCStatsReport>::Depth },
6247 : JSJitInfo::Method,
6248 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
6249 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
6250 : false, /* isInfallible. False in setters. */
6251 : false, /* isMovable. Not relevant for setters. */
6252 : false, /* isEliminatable. Not relevant for setters. */
6253 : false, /* isAlwaysInSlot. Only relevant for getters. */
6254 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
6255 : false, /* isTypedMethod. Only relevant for methods. */
6256 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
6257 : };
6258 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
6259 : static_assert(0 < 2, "There is no slot for us");
6260 :
6261 : static bool
6262 0 : get(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCStatsReport* self, const JSJitMethodCallArgs& args)
6263 : {
6264 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
6265 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
6266 0 : if (objIsXray) {
6267 0 : unwrappedObj.emplace(cx, obj);
6268 : }
6269 0 : binding_detail::FakeString arg0;
6270 0 : if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
6271 0 : return false;
6272 : }
6273 0 : if (objIsXray) {
6274 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
6275 0 : if (!unwrappedObj.ref()) {
6276 0 : return false;
6277 : }
6278 : }
6279 0 : JS::Rooted<JSObject*> backingObj(cx);
6280 0 : bool created = false;
6281 0 : if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
6282 0 : return false;
6283 : }
6284 0 : if (created) {
6285 0 : PreserveWrapper<mozilla::dom::RTCStatsReport>(self);
6286 : }
6287 0 : JS::Rooted<JS::Value> arg0Val(cx);
6288 0 : if (!ToJSValue(cx, arg0, &arg0Val)) {
6289 0 : return false;
6290 : }
6291 0 : JS::Rooted<JS::Value> result(cx);
6292 0 : if (!JS::MapGet(cx, backingObj, arg0Val, &result)) {
6293 0 : return false;
6294 : }
6295 0 : JS::ExposeValueToActiveJS(result);
6296 0 : args.rval().set(result);
6297 0 : if (!MaybeWrapValue(cx, args.rval())) {
6298 0 : return false;
6299 : }
6300 0 : return true;
6301 : }
6302 :
6303 : static const JSJitInfo::ArgType get_methodinfo_argTypes[] = { JSJitInfo::String, JSJitInfo::ArgTypeListEnd };
6304 : static const JSTypedMethodJitInfo get_methodinfo = {
6305 : {
6306 : { (JSJitGetterOp)get },
6307 : { prototypes::id::RTCStatsReport },
6308 : { PrototypeTraits<prototypes::id::RTCStatsReport>::Depth },
6309 : JSJitInfo::Method,
6310 : JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
6311 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
6312 : false, /* isInfallible. False in setters. */
6313 : false, /* isMovable. Not relevant for setters. */
6314 : false, /* isEliminatable. Not relevant for setters. */
6315 : false, /* isAlwaysInSlot. Only relevant for getters. */
6316 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
6317 : true, /* isTypedMethod. Only relevant for methods. */
6318 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
6319 : },
6320 : get_methodinfo_argTypes
6321 : };
6322 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
6323 : static_assert(0 < 2, "There is no slot for us");
6324 :
6325 : static bool
6326 0 : __set(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::RTCStatsReport* self, const JSJitMethodCallArgs& args)
6327 : {
6328 0 : Maybe<JS::Rooted<JSObject*> > unwrappedObj;
6329 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
6330 0 : if (objIsXray) {
6331 0 : unwrappedObj.emplace(cx, obj);
6332 : }
6333 0 : binding_detail::FakeString arg0;
6334 0 : if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
6335 0 : return false;
6336 : }
6337 0 : JS::Rooted<JSObject*> arg1(cx);
6338 0 : if (args.get(1).isObject()) {
6339 : #ifdef __clang__
6340 : #pragma clang diagnostic push
6341 : #pragma clang diagnostic ignored "-Wunreachable-code"
6342 : #pragma clang diagnostic ignored "-Wunreachable-code-return"
6343 : #endif // __clang__
6344 0 : if ((true) && !CallerSubsumes(args.get(1))) {
6345 0 : ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "argument 2 of RTCStatsReport.__set");
6346 0 : return false;
6347 : }
6348 : #ifdef __clang__
6349 : #pragma clang diagnostic pop
6350 : #endif // __clang__
6351 0 : arg1 = &args.get(1).toObject();
6352 : } else {
6353 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of RTCStatsReport.__set");
6354 0 : return false;
6355 : }
6356 0 : if (objIsXray) {
6357 0 : unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
6358 0 : if (!unwrappedObj.ref()) {
6359 0 : return false;
6360 : }
6361 : }
6362 0 : JS::Rooted<JSObject*> backingObj(cx);
6363 0 : bool created = false;
6364 0 : if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
6365 0 : return false;
6366 : }
6367 0 : if (created) {
6368 0 : PreserveWrapper<mozilla::dom::RTCStatsReport>(self);
6369 : }
6370 0 : JS::Rooted<JS::Value> arg0Val(cx);
6371 0 : if (!ToJSValue(cx, arg0, &arg0Val)) {
6372 0 : return false;
6373 : }
6374 0 : JS::Rooted<JS::Value> arg1Val(cx);
6375 0 : if (!ToJSValue(cx, arg1, &arg1Val)) {
6376 0 : return false;
6377 : }
6378 0 : JS::Rooted<JSObject*> result(cx);
6379 0 : if (!JS::MapSet(cx, backingObj, arg0Val, arg1Val)) {
6380 0 : return false;
6381 : }
6382 0 : result = obj;
6383 0 : JS::ExposeObjectToActiveJS(result);
6384 0 : args.rval().setObject(*result);
6385 0 : if (!MaybeWrapObjectValue(cx, args.rval())) {
6386 0 : return false;
6387 : }
6388 0 : return true;
6389 : }
6390 :
6391 : static const JSJitInfo __set_methodinfo = {
6392 : { (JSJitGetterOp)__set },
6393 : { prototypes::id::RTCStatsReport },
6394 : { PrototypeTraits<prototypes::id::RTCStatsReport>::Depth },
6395 : JSJitInfo::Method,
6396 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
6397 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
6398 : false, /* isInfallible. False in setters. */
6399 : false, /* isMovable. Not relevant for setters. */
6400 : false, /* isEliminatable. Not relevant for setters. */
6401 : false, /* isAlwaysInSlot. Only relevant for getters. */
6402 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
6403 : false, /* isTypedMethod. Only relevant for methods. */
6404 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
6405 : };
6406 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
6407 : static_assert(0 < 2, "There is no slot for us");
6408 :
6409 : static bool
6410 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
6411 : {
6412 0 : mozilla::dom::RTCStatsReport* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::RTCStatsReport>(obj);
6413 : // We don't want to preserve if we don't have a wrapper, and we
6414 : // obviously can't preserve if we're not initialized.
6415 0 : if (self && self->GetWrapperPreserveColor()) {
6416 0 : PreserveWrapper(self);
6417 : }
6418 0 : return true;
6419 : }
6420 :
6421 : static void
6422 0 : _finalize(js::FreeOp* fop, JSObject* obj)
6423 : {
6424 0 : mozilla::dom::RTCStatsReport* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::RTCStatsReport>(obj);
6425 0 : if (self) {
6426 0 : ClearWrapper(self, self, obj);
6427 0 : AddForDeferredFinalization<mozilla::dom::RTCStatsReport>(self);
6428 : }
6429 0 : }
6430 :
6431 : static void
6432 0 : _objectMoved(JSObject* obj, const JSObject* old)
6433 : {
6434 0 : mozilla::dom::RTCStatsReport* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::RTCStatsReport>(obj);
6435 0 : if (self) {
6436 0 : UpdateWrapper(self, self, obj, old);
6437 : }
6438 0 : }
6439 :
6440 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
6441 : #if defined(__clang__)
6442 : #pragma clang diagnostic push
6443 : #pragma clang diagnostic ignored "-Wmissing-braces"
6444 : #endif
6445 : static const JSFunctionSpec sChromeStaticMethods_specs[] = {
6446 : JS_FNSPEC("_create", RTCStatsReport::_Create, nullptr, 2, 0, nullptr),
6447 : JS_FS_END
6448 : };
6449 : #if defined(__clang__)
6450 : #pragma clang diagnostic pop
6451 : #endif
6452 :
6453 :
6454 : // Can't be const because the pref-enabled boolean needs to be writable
6455 : static Prefable<const JSFunctionSpec> sChromeStaticMethods[] = {
6456 : { nullptr, &sChromeStaticMethods_specs[0] },
6457 : { nullptr, nullptr }
6458 : };
6459 :
6460 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
6461 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
6462 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
6463 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
6464 :
6465 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
6466 : #if defined(__clang__)
6467 : #pragma clang diagnostic push
6468 : #pragma clang diagnostic ignored "-Wmissing-braces"
6469 : #endif
6470 : static const JSFunctionSpec sMethods_specs[] = {
6471 : JS_FNSPEC("entries", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&entries_methodinfo), 0, 0, nullptr),
6472 : JS_FNSPEC("keys", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&keys_methodinfo), 0, 0, nullptr),
6473 : JS_FNSPEC("values", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&values_methodinfo), 0, 0, nullptr),
6474 : JS_FNSPEC("forEach", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&forEach_methodinfo), 1, 0, nullptr),
6475 : JS_FNSPEC("has", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&has_methodinfo), 1, 0, nullptr),
6476 : JS_FNSPEC("get", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&get_methodinfo), 1, 0, nullptr),
6477 : JS_FS_END
6478 : };
6479 : #if defined(__clang__)
6480 : #pragma clang diagnostic pop
6481 : #endif
6482 :
6483 :
6484 : // Can't be const because the pref-enabled boolean needs to be writable
6485 : static Prefable<const JSFunctionSpec> sMethods[] = {
6486 : { nullptr, &sMethods_specs[0] },
6487 : { nullptr, nullptr }
6488 : };
6489 :
6490 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
6491 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
6492 : static_assert(6 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
6493 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
6494 :
6495 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
6496 : #if defined(__clang__)
6497 : #pragma clang diagnostic push
6498 : #pragma clang diagnostic ignored "-Wmissing-braces"
6499 : #endif
6500 : static const JSFunctionSpec sChromeMethods_specs[] = {
6501 : JS_FNSPEC("__clear", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&__clear_methodinfo), 0, 0, nullptr),
6502 : JS_FNSPEC("__delete", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&__delete_methodinfo), 1, 0, nullptr),
6503 : JS_FNSPEC("__set", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&__set_methodinfo), 2, 0, nullptr),
6504 : JS_FS_END
6505 : };
6506 : #if defined(__clang__)
6507 : #pragma clang diagnostic pop
6508 : #endif
6509 :
6510 :
6511 : // Can't be const because the pref-enabled boolean needs to be writable
6512 : static Prefable<const JSFunctionSpec> sChromeMethods[] = {
6513 : { nullptr, &sChromeMethods_specs[0] },
6514 : { nullptr, nullptr }
6515 : };
6516 :
6517 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
6518 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
6519 : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
6520 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
6521 :
6522 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
6523 : #if defined(__clang__)
6524 : #pragma clang diagnostic push
6525 : #pragma clang diagnostic ignored "-Wmissing-braces"
6526 : #endif
6527 : static const JSPropertySpec sAttributes_specs[] = {
6528 : { "size", JSPROP_SHARED, GenericBindingGetter, &size_getterinfo, nullptr, nullptr },
6529 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
6530 : };
6531 : #if defined(__clang__)
6532 : #pragma clang diagnostic pop
6533 : #endif
6534 :
6535 :
6536 : // Can't be const because the pref-enabled boolean needs to be writable
6537 : static Prefable<const JSPropertySpec> sAttributes[] = {
6538 : { nullptr, &sAttributes_specs[0] },
6539 : { nullptr, nullptr }
6540 : };
6541 :
6542 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
6543 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
6544 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
6545 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
6546 :
6547 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
6548 : #if defined(__clang__)
6549 : #pragma clang diagnostic push
6550 : #pragma clang diagnostic ignored "-Wmissing-braces"
6551 : #endif
6552 : static const JSPropertySpec sChromeAttributes_specs[] = {
6553 : { "mozPcid", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &mozPcid_getterinfo, nullptr, nullptr },
6554 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
6555 : };
6556 : #if defined(__clang__)
6557 : #pragma clang diagnostic pop
6558 : #endif
6559 :
6560 :
6561 : // Can't be const because the pref-enabled boolean needs to be writable
6562 : static Prefable<const JSPropertySpec> sChromeAttributes[] = {
6563 : { nullptr, &sChromeAttributes_specs[0] },
6564 : { nullptr, nullptr }
6565 : };
6566 :
6567 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
6568 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
6569 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
6570 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
6571 :
6572 :
6573 : static uint16_t sNativeProperties_sortedPropertyIndices[7];
6574 : static PropertyInfo sNativeProperties_propertyInfos[7];
6575 :
6576 : static const NativePropertiesN<2> sNativeProperties = {
6577 : false, 0,
6578 : false, 0,
6579 : true, 0 /* sMethods */,
6580 : true, 1 /* sAttributes */,
6581 : false, 0,
6582 : false, 0,
6583 : false, 0,
6584 : 0,
6585 : 7,
6586 : sNativeProperties_sortedPropertyIndices,
6587 : {
6588 : { sMethods, &sNativeProperties_propertyInfos[0] },
6589 : { sAttributes, &sNativeProperties_propertyInfos[6] }
6590 : }
6591 : };
6592 : static_assert(7 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
6593 : "We have a property info count that is oversized");
6594 :
6595 : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[5];
6596 : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[5];
6597 :
6598 : static const NativePropertiesN<3> sChromeOnlyNativeProperties = {
6599 : true, 0 /* sChromeStaticMethods */,
6600 : false, 0,
6601 : true, 1 /* sChromeMethods */,
6602 : true, 2 /* sChromeAttributes */,
6603 : false, 0,
6604 : false, 0,
6605 : false, 0,
6606 : 0,
6607 : 5,
6608 : sChromeOnlyNativeProperties_sortedPropertyIndices,
6609 : {
6610 : { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] },
6611 : { sChromeMethods, &sChromeOnlyNativeProperties_propertyInfos[1] },
6612 : { sChromeAttributes, &sChromeOnlyNativeProperties_propertyInfos[4] }
6613 : }
6614 : };
6615 : static_assert(5 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
6616 : "We have a property info count that is oversized");
6617 :
6618 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
6619 : {
6620 : "Function",
6621 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
6622 : &sBoringInterfaceObjectClassClassOps,
6623 : JS_NULL_CLASS_SPEC,
6624 : JS_NULL_CLASS_EXT,
6625 : &sInterfaceObjectClassObjectOps
6626 : },
6627 : eInterface,
6628 : true,
6629 : prototypes::id::RTCStatsReport,
6630 : PrototypeTraits<prototypes::id::RTCStatsReport>::Depth,
6631 : sNativePropertyHooks,
6632 : "function RTCStatsReport() {\n [native code]\n}",
6633 : JS::GetRealmFunctionPrototype
6634 : };
6635 :
6636 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
6637 : {
6638 : "RTCStatsReportPrototype",
6639 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
6640 : JS_NULL_CLASS_OPS,
6641 : JS_NULL_CLASS_SPEC,
6642 : JS_NULL_CLASS_EXT,
6643 : JS_NULL_OBJECT_OPS
6644 : },
6645 : eInterfacePrototype,
6646 : false,
6647 : prototypes::id::RTCStatsReport,
6648 : PrototypeTraits<prototypes::id::RTCStatsReport>::Depth,
6649 : sNativePropertyHooks,
6650 : "[object RTCStatsReportPrototype]",
6651 : JS::GetRealmObjectPrototype
6652 : };
6653 :
6654 : bool
6655 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
6656 : {
6657 : static bool sPrefValue;
6658 : static bool sPrefCacheSetUp = false;
6659 0 : if (!sPrefCacheSetUp) {
6660 0 : sPrefCacheSetUp = true;
6661 0 : Preferences::AddBoolVarCache(&sPrefValue, "media.peerconnection.enabled");
6662 : }
6663 :
6664 0 : return sPrefValue;
6665 : }
6666 :
6667 : JSObject*
6668 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
6669 : {
6670 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
6671 : }
6672 :
6673 : static const js::ClassOps sClassOps = {
6674 : _addProperty, /* addProperty */
6675 : nullptr, /* delProperty */
6676 : nullptr, /* getProperty */
6677 : nullptr, /* setProperty */
6678 : nullptr, /* enumerate */
6679 : nullptr, /* newEnumerate */
6680 : nullptr, /* resolve */
6681 : nullptr, /* mayResolve */
6682 : _finalize, /* finalize */
6683 : nullptr, /* call */
6684 : nullptr, /* hasInstance */
6685 : nullptr, /* construct */
6686 : nullptr, /* trace */
6687 : };
6688 :
6689 : static const js::ClassExtension sClassExtension = {
6690 : nullptr, /* weakmapKeyDelegateOp */
6691 : _objectMoved /* objectMovedOp */
6692 : };
6693 :
6694 : static const DOMJSClass sClass = {
6695 : { "RTCStatsReport",
6696 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2),
6697 : &sClassOps,
6698 : JS_NULL_CLASS_SPEC,
6699 : &sClassExtension,
6700 : JS_NULL_OBJECT_OPS
6701 : },
6702 : { prototypes::id::RTCStatsReport, 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 },
6703 : IsBaseOf<nsISupports, mozilla::dom::RTCStatsReport >::value,
6704 : sNativePropertyHooks,
6705 : FindAssociatedGlobalForNative<mozilla::dom::RTCStatsReport>::Get,
6706 : GetProtoObjectHandle,
6707 : GetCCParticipant<mozilla::dom::RTCStatsReport>::Get()
6708 : };
6709 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
6710 : "Must have the right minimal number of reserved slots.");
6711 : static_assert(2 >= 2,
6712 : "Must have enough reserved slots.");
6713 :
6714 : const JSClass*
6715 0 : GetJSClass()
6716 : {
6717 0 : return sClass.ToJSClass();
6718 : }
6719 :
6720 : bool
6721 0 : Wrap(JSContext* aCx, mozilla::dom::RTCStatsReport* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
6722 : {
6723 : MOZ_ASSERT(static_cast<mozilla::dom::RTCStatsReport*>(aObject) ==
6724 : reinterpret_cast<mozilla::dom::RTCStatsReport*>(aObject),
6725 : "Multiple inheritance for mozilla::dom::RTCStatsReport is broken.");
6726 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
6727 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
6728 0 : MOZ_ASSERT(!aCache->GetWrapper(),
6729 : "You should probably not be using Wrap() directly; use "
6730 : "GetOrCreateDOMReflector instead");
6731 :
6732 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
6733 : "nsISupports must be on our primary inheritance chain");
6734 :
6735 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
6736 0 : if (!global) {
6737 0 : return false;
6738 : }
6739 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
6740 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
6741 :
6742 : // That might have ended up wrapping us already, due to the wonders
6743 : // of XBL. Check for that, and bail out as needed.
6744 0 : aReflector.set(aCache->GetWrapper());
6745 0 : if (aReflector) {
6746 : #ifdef DEBUG
6747 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
6748 : #endif // DEBUG
6749 0 : return true;
6750 : }
6751 :
6752 0 : JSAutoCompartment ac(aCx, global);
6753 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
6754 0 : if (!canonicalProto) {
6755 0 : return false;
6756 : }
6757 0 : JS::Rooted<JSObject*> proto(aCx);
6758 0 : if (aGivenProto) {
6759 0 : proto = aGivenProto;
6760 : // Unfortunately, while aGivenProto was in the compartment of aCx
6761 : // coming in, we changed compartments to that of "parent" so may need
6762 : // to wrap the proto here.
6763 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
6764 0 : if (!JS_WrapObject(aCx, &proto)) {
6765 0 : return false;
6766 : }
6767 : }
6768 : } else {
6769 0 : proto = canonicalProto;
6770 : }
6771 :
6772 0 : BindingJSObjectCreator<mozilla::dom::RTCStatsReport> creator(aCx);
6773 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
6774 0 : if (!aReflector) {
6775 0 : return false;
6776 : }
6777 :
6778 0 : aCache->SetWrapper(aReflector);
6779 0 : creator.InitializationSucceeded();
6780 :
6781 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
6782 : aCache->GetWrapperPreserveColor() == aReflector);
6783 : // If proto != canonicalProto, we have to preserve our wrapper;
6784 : // otherwise we won't be able to properly recreate it later, since
6785 : // we won't know what proto to use. Note that we don't check
6786 : // aGivenProto here, since it's entirely possible (and even
6787 : // somewhat common) to have a non-null aGivenProto which is the
6788 : // same as canonicalProto.
6789 0 : if (proto != canonicalProto) {
6790 0 : PreserveWrapper(aObject);
6791 : }
6792 :
6793 0 : return true;
6794 : }
6795 :
6796 : // This may allocate too many slots, because we only really need
6797 : // slots for our non-interface-typed members that we cache. But
6798 : // allocating slots only for those would make the slot index
6799 : // computations much more complicated, so let's do this the simple
6800 : // way for now.
6801 : DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 1);
6802 :
6803 : const NativePropertyHooks sNativePropertyHooks[] = { {
6804 : nullptr,
6805 : nullptr,
6806 : nullptr,
6807 : { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
6808 : prototypes::id::RTCStatsReport,
6809 : constructors::id::RTCStatsReport,
6810 : nullptr,
6811 : &sXrayExpandoObjectClass
6812 : } };
6813 :
6814 : void
6815 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
6816 : {
6817 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
6818 0 : if (!parentProto) {
6819 0 : return;
6820 : }
6821 :
6822 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
6823 0 : if (!constructorProto) {
6824 0 : return;
6825 : }
6826 :
6827 : static bool sIdsInited = false;
6828 0 : if (!sIdsInited && NS_IsMainThread()) {
6829 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
6830 0 : return;
6831 : }
6832 0 : if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
6833 0 : return;
6834 : }
6835 0 : sIdsInited = true;
6836 : }
6837 :
6838 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::RTCStatsReport);
6839 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::RTCStatsReport);
6840 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
6841 : &sPrototypeClass.mBase, protoCache,
6842 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
6843 : interfaceCache,
6844 : sNativeProperties.Upcast(),
6845 0 : nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
6846 : "RTCStatsReport", aDefineOnGlobal,
6847 : nullptr,
6848 0 : false);
6849 :
6850 : // Set up aliases on the interface prototype object we just created.
6851 0 : JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx);
6852 0 : if (!proto) {
6853 0 : *protoCache = nullptr;
6854 0 : if (interfaceCache) {
6855 0 : *interfaceCache = nullptr;
6856 : }
6857 0 : return;
6858 : }
6859 :
6860 0 : JS::Rooted<JS::Value> aliasedVal(aCx);
6861 :
6862 0 : if (!JS_GetProperty(aCx, proto, "entries", &aliasedVal)) {
6863 0 : *protoCache = nullptr;
6864 0 : if (interfaceCache) {
6865 0 : *interfaceCache = nullptr;
6866 : }
6867 0 : return;
6868 : }
6869 0 : JS::Rooted<jsid> iteratorId(aCx, SYMBOL_TO_JSID(JS::GetWellKnownSymbol(aCx, JS::SymbolCode::iterator)));
6870 0 : if (!JS_DefinePropertyById(aCx, proto, iteratorId, aliasedVal, 0)) {
6871 0 : *protoCache = nullptr;
6872 0 : if (interfaceCache) {
6873 0 : *interfaceCache = nullptr;
6874 : }
6875 0 : return;
6876 : }
6877 : }
6878 :
6879 : JS::Handle<JSObject*>
6880 0 : GetProtoObjectHandle(JSContext* aCx)
6881 : {
6882 : /* Get the interface prototype object for this class. This will create the
6883 : object as needed. */
6884 0 : bool aDefineOnGlobal = true;
6885 :
6886 : /* Make sure our global is sane. Hopefully we can remove this sometime */
6887 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
6888 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
6889 0 : return nullptr;
6890 : }
6891 :
6892 : /* Check to see whether the interface objects are already installed */
6893 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
6894 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::RTCStatsReport)) {
6895 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
6896 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
6897 : }
6898 :
6899 : /*
6900 : * The object might _still_ be null, but that's OK.
6901 : *
6902 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
6903 : * traced by TraceProtoAndIfaceCache() and its contents are never
6904 : * changed after they have been set.
6905 : *
6906 : * Calling address() avoids the read read barrier that does gray
6907 : * unmarking, but it's not possible for the object to be gray here.
6908 : */
6909 :
6910 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::RTCStatsReport);
6911 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
6912 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
6913 : }
6914 :
6915 : JS::Handle<JSObject*>
6916 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
6917 : {
6918 : /* Get the interface object for this class. This will create the object as
6919 : needed. */
6920 :
6921 : /* Make sure our global is sane. Hopefully we can remove this sometime */
6922 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
6923 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
6924 0 : return nullptr;
6925 : }
6926 :
6927 : /* Check to see whether the interface objects are already installed */
6928 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
6929 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::RTCStatsReport)) {
6930 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
6931 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
6932 : }
6933 :
6934 : /*
6935 : * The object might _still_ be null, but that's OK.
6936 : *
6937 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
6938 : * traced by TraceProtoAndIfaceCache() and its contents are never
6939 : * changed after they have been set.
6940 : *
6941 : * Calling address() avoids the read read barrier that does gray
6942 : * unmarking, but it's not possible for the object to be gray here.
6943 : */
6944 :
6945 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::RTCStatsReport);
6946 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
6947 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
6948 : }
6949 :
6950 : JSObject*
6951 0 : GetConstructorObject(JSContext* aCx)
6952 : {
6953 0 : return GetConstructorObjectHandle(aCx);
6954 : }
6955 :
6956 : } // namespace RTCStatsReportBinding
6957 :
6958 :
6959 :
6960 : void
6961 0 : RTCStatsReportJSImpl::Entries(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
6962 : {
6963 0 : CallSetup s(this, aRv, "RTCStatsReport.entries", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
6964 0 : JSContext* cx = s.GetContext();
6965 0 : if (!cx) {
6966 0 : MOZ_ASSERT(aRv.Failed());
6967 0 : return;
6968 : }
6969 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
6970 :
6971 0 : JS::Rooted<JS::Value> callable(cx);
6972 0 : RTCStatsReportAtoms* atomsCache = GetAtomCache<RTCStatsReportAtoms>(cx);
6973 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
6974 0 : !GetCallableProperty(cx, atomsCache->entries_id, &callable)) {
6975 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
6976 0 : return;
6977 : }
6978 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
6979 0 : if (!JS::Call(cx, thisValue, callable,
6980 0 : JS::HandleValueArray::empty(), &rval)) {
6981 0 : aRv.NoteJSContextException(cx);
6982 0 : return;
6983 : }
6984 0 : JS::Rooted<JSObject*> rvalDecl(cx);
6985 0 : if (rval.isObject()) {
6986 : #ifdef __clang__
6987 : #pragma clang diagnostic push
6988 : #pragma clang diagnostic ignored "-Wunreachable-code"
6989 : #pragma clang diagnostic ignored "-Wunreachable-code-return"
6990 : #endif // __clang__
6991 0 : if ((false) && !CallerSubsumes(rval)) {
6992 0 : ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "return value of RTCStatsReport.entries");
6993 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
6994 0 : return;
6995 : }
6996 : #ifdef __clang__
6997 : #pragma clang diagnostic pop
6998 : #endif // __clang__
6999 0 : rvalDecl = &rval.toObject();
7000 : } else {
7001 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of RTCStatsReport.entries");
7002 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7003 0 : return;
7004 : }
7005 0 : aRetVal.set(rvalDecl);
7006 : }
7007 :
7008 : void
7009 0 : RTCStatsReportJSImpl::Keys(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
7010 : {
7011 0 : CallSetup s(this, aRv, "RTCStatsReport.keys", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
7012 0 : JSContext* cx = s.GetContext();
7013 0 : if (!cx) {
7014 0 : MOZ_ASSERT(aRv.Failed());
7015 0 : return;
7016 : }
7017 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
7018 :
7019 0 : JS::Rooted<JS::Value> callable(cx);
7020 0 : RTCStatsReportAtoms* atomsCache = GetAtomCache<RTCStatsReportAtoms>(cx);
7021 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
7022 0 : !GetCallableProperty(cx, atomsCache->keys_id, &callable)) {
7023 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7024 0 : return;
7025 : }
7026 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
7027 0 : if (!JS::Call(cx, thisValue, callable,
7028 0 : JS::HandleValueArray::empty(), &rval)) {
7029 0 : aRv.NoteJSContextException(cx);
7030 0 : return;
7031 : }
7032 0 : JS::Rooted<JSObject*> rvalDecl(cx);
7033 0 : if (rval.isObject()) {
7034 : #ifdef __clang__
7035 : #pragma clang diagnostic push
7036 : #pragma clang diagnostic ignored "-Wunreachable-code"
7037 : #pragma clang diagnostic ignored "-Wunreachable-code-return"
7038 : #endif // __clang__
7039 0 : if ((false) && !CallerSubsumes(rval)) {
7040 0 : ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "return value of RTCStatsReport.keys");
7041 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7042 0 : return;
7043 : }
7044 : #ifdef __clang__
7045 : #pragma clang diagnostic pop
7046 : #endif // __clang__
7047 0 : rvalDecl = &rval.toObject();
7048 : } else {
7049 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of RTCStatsReport.keys");
7050 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7051 0 : return;
7052 : }
7053 0 : aRetVal.set(rvalDecl);
7054 : }
7055 :
7056 : void
7057 0 : RTCStatsReportJSImpl::Values(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
7058 : {
7059 0 : CallSetup s(this, aRv, "RTCStatsReport.values", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
7060 0 : JSContext* cx = s.GetContext();
7061 0 : if (!cx) {
7062 0 : MOZ_ASSERT(aRv.Failed());
7063 0 : return;
7064 : }
7065 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
7066 :
7067 0 : JS::Rooted<JS::Value> callable(cx);
7068 0 : RTCStatsReportAtoms* atomsCache = GetAtomCache<RTCStatsReportAtoms>(cx);
7069 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
7070 0 : !GetCallableProperty(cx, atomsCache->values_id, &callable)) {
7071 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7072 0 : return;
7073 : }
7074 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
7075 0 : if (!JS::Call(cx, thisValue, callable,
7076 0 : JS::HandleValueArray::empty(), &rval)) {
7077 0 : aRv.NoteJSContextException(cx);
7078 0 : return;
7079 : }
7080 0 : JS::Rooted<JSObject*> rvalDecl(cx);
7081 0 : if (rval.isObject()) {
7082 : #ifdef __clang__
7083 : #pragma clang diagnostic push
7084 : #pragma clang diagnostic ignored "-Wunreachable-code"
7085 : #pragma clang diagnostic ignored "-Wunreachable-code-return"
7086 : #endif // __clang__
7087 0 : if ((false) && !CallerSubsumes(rval)) {
7088 0 : ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "return value of RTCStatsReport.values");
7089 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7090 0 : return;
7091 : }
7092 : #ifdef __clang__
7093 : #pragma clang diagnostic pop
7094 : #endif // __clang__
7095 0 : rvalDecl = &rval.toObject();
7096 : } else {
7097 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of RTCStatsReport.values");
7098 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7099 0 : return;
7100 : }
7101 0 : aRetVal.set(rvalDecl);
7102 : }
7103 :
7104 : void
7105 0 : RTCStatsReportJSImpl::ForEach(JS::Handle<JSObject*> callback, JS::Handle<JS::Value> thisArg, ErrorResult& aRv, JSCompartment* aCompartment)
7106 : {
7107 0 : CallSetup s(this, aRv, "RTCStatsReport.forEach", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
7108 0 : JSContext* cx = s.GetContext();
7109 0 : if (!cx) {
7110 0 : MOZ_ASSERT(aRv.Failed());
7111 0 : return;
7112 : }
7113 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
7114 0 : JS::AutoValueVector argv(cx);
7115 0 : if (!argv.resize(2)) {
7116 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
7117 0 : return;
7118 : }
7119 0 : unsigned argc = 2;
7120 :
7121 : do {
7122 0 : JS::ExposeValueToActiveJS(thisArg);
7123 0 : argv[1].set(thisArg);
7124 0 : if (!MaybeWrapValue(cx, argv[1])) {
7125 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7126 0 : return;
7127 : }
7128 0 : break;
7129 : } while (0);
7130 :
7131 : do {
7132 0 : JS::ExposeObjectToActiveJS(callback);
7133 0 : argv[0].setObject(*callback);
7134 0 : if (!MaybeWrapObjectValue(cx, argv[0])) {
7135 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7136 0 : return;
7137 : }
7138 0 : break;
7139 : } while (0);
7140 :
7141 0 : JS::Rooted<JS::Value> callable(cx);
7142 0 : RTCStatsReportAtoms* atomsCache = GetAtomCache<RTCStatsReportAtoms>(cx);
7143 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
7144 0 : !GetCallableProperty(cx, atomsCache->forEach_id, &callable)) {
7145 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7146 0 : return;
7147 : }
7148 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
7149 0 : if (!JS::Call(cx, thisValue, callable,
7150 0 : JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
7151 0 : aRv.NoteJSContextException(cx);
7152 0 : return;
7153 : }
7154 : }
7155 :
7156 : bool
7157 0 : RTCStatsReportJSImpl::Has(const nsAString& key, ErrorResult& aRv, JSCompartment* aCompartment)
7158 : {
7159 0 : CallSetup s(this, aRv, "RTCStatsReport.has", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
7160 0 : JSContext* cx = s.GetContext();
7161 0 : if (!cx) {
7162 0 : MOZ_ASSERT(aRv.Failed());
7163 0 : return bool(0);
7164 : }
7165 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
7166 0 : JS::AutoValueVector argv(cx);
7167 0 : if (!argv.resize(1)) {
7168 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
7169 0 : return bool(0);
7170 : }
7171 0 : unsigned argc = 1;
7172 :
7173 : do {
7174 0 : nsString mutableStr(key);
7175 0 : if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
7176 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7177 0 : return bool(0);
7178 : }
7179 0 : break;
7180 : } while (0);
7181 :
7182 0 : JS::Rooted<JS::Value> callable(cx);
7183 0 : RTCStatsReportAtoms* atomsCache = GetAtomCache<RTCStatsReportAtoms>(cx);
7184 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
7185 0 : !GetCallableProperty(cx, atomsCache->has_id, &callable)) {
7186 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7187 0 : return bool(0);
7188 : }
7189 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
7190 0 : if (!JS::Call(cx, thisValue, callable,
7191 0 : JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
7192 0 : aRv.NoteJSContextException(cx);
7193 0 : return bool(0);
7194 : }
7195 : bool rvalDecl;
7196 0 : if (!ValueToPrimitive<bool, eDefault>(cx, rval, &rvalDecl)) {
7197 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7198 0 : return bool(0);
7199 : }
7200 0 : return rvalDecl;
7201 : }
7202 :
7203 : void
7204 0 : RTCStatsReportJSImpl::__clear(ErrorResult& aRv, JSCompartment* aCompartment)
7205 : {
7206 0 : CallSetup s(this, aRv, "RTCStatsReport.__clear", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
7207 0 : JSContext* cx = s.GetContext();
7208 0 : if (!cx) {
7209 0 : MOZ_ASSERT(aRv.Failed());
7210 0 : return;
7211 : }
7212 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
7213 :
7214 0 : JS::Rooted<JS::Value> callable(cx);
7215 0 : RTCStatsReportAtoms* atomsCache = GetAtomCache<RTCStatsReportAtoms>(cx);
7216 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
7217 0 : !GetCallableProperty(cx, atomsCache->__clear_id, &callable)) {
7218 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7219 0 : return;
7220 : }
7221 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
7222 0 : if (!JS::Call(cx, thisValue, callable,
7223 0 : JS::HandleValueArray::empty(), &rval)) {
7224 0 : aRv.NoteJSContextException(cx);
7225 0 : return;
7226 : }
7227 : }
7228 :
7229 : bool
7230 0 : RTCStatsReportJSImpl::__delete(const nsAString& key, ErrorResult& aRv, JSCompartment* aCompartment)
7231 : {
7232 0 : CallSetup s(this, aRv, "RTCStatsReport.__delete", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
7233 0 : JSContext* cx = s.GetContext();
7234 0 : if (!cx) {
7235 0 : MOZ_ASSERT(aRv.Failed());
7236 0 : return bool(0);
7237 : }
7238 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
7239 0 : JS::AutoValueVector argv(cx);
7240 0 : if (!argv.resize(1)) {
7241 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
7242 0 : return bool(0);
7243 : }
7244 0 : unsigned argc = 1;
7245 :
7246 : do {
7247 0 : nsString mutableStr(key);
7248 0 : if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
7249 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7250 0 : return bool(0);
7251 : }
7252 0 : break;
7253 : } while (0);
7254 :
7255 0 : JS::Rooted<JS::Value> callable(cx);
7256 0 : RTCStatsReportAtoms* atomsCache = GetAtomCache<RTCStatsReportAtoms>(cx);
7257 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
7258 0 : !GetCallableProperty(cx, atomsCache->__delete_id, &callable)) {
7259 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7260 0 : return bool(0);
7261 : }
7262 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
7263 0 : if (!JS::Call(cx, thisValue, callable,
7264 0 : JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
7265 0 : aRv.NoteJSContextException(cx);
7266 0 : return bool(0);
7267 : }
7268 : bool rvalDecl;
7269 0 : if (!ValueToPrimitive<bool, eDefault>(cx, rval, &rvalDecl)) {
7270 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7271 0 : return bool(0);
7272 : }
7273 0 : return rvalDecl;
7274 : }
7275 :
7276 : void
7277 0 : RTCStatsReportJSImpl::Get(const nsAString& key, JS::MutableHandle<JS::Value> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
7278 : {
7279 0 : CallSetup s(this, aRv, "RTCStatsReport.get", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
7280 0 : JSContext* cx = s.GetContext();
7281 0 : if (!cx) {
7282 0 : MOZ_ASSERT(aRv.Failed());
7283 0 : return;
7284 : }
7285 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
7286 0 : JS::AutoValueVector argv(cx);
7287 0 : if (!argv.resize(1)) {
7288 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
7289 0 : return;
7290 : }
7291 0 : unsigned argc = 1;
7292 :
7293 : do {
7294 0 : nsString mutableStr(key);
7295 0 : if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
7296 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7297 0 : return;
7298 : }
7299 0 : break;
7300 : } while (0);
7301 :
7302 0 : JS::Rooted<JS::Value> callable(cx);
7303 0 : RTCStatsReportAtoms* atomsCache = GetAtomCache<RTCStatsReportAtoms>(cx);
7304 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
7305 0 : !GetCallableProperty(cx, atomsCache->get_id, &callable)) {
7306 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7307 0 : return;
7308 : }
7309 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
7310 0 : if (!JS::Call(cx, thisValue, callable,
7311 0 : JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
7312 0 : aRv.NoteJSContextException(cx);
7313 0 : return;
7314 : }
7315 0 : JS::Rooted<JS::Value> rvalDecl(cx);
7316 : #ifdef __clang__
7317 : #pragma clang diagnostic push
7318 : #pragma clang diagnostic ignored "-Wunreachable-code"
7319 : #pragma clang diagnostic ignored "-Wunreachable-code-return"
7320 : #endif // __clang__
7321 0 : if ((false) && !CallerSubsumes(rval)) {
7322 0 : ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "return value of RTCStatsReport.get");
7323 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7324 0 : return;
7325 : }
7326 : #ifdef __clang__
7327 : #pragma clang diagnostic pop
7328 : #endif // __clang__
7329 0 : rvalDecl = rval;
7330 0 : aRetVal.set(rvalDecl);
7331 : }
7332 :
7333 : void
7334 0 : RTCStatsReportJSImpl::__set(const nsAString& key, JS::Handle<JSObject*> value, JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
7335 : {
7336 0 : CallSetup s(this, aRv, "RTCStatsReport.__set", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
7337 0 : JSContext* cx = s.GetContext();
7338 0 : if (!cx) {
7339 0 : MOZ_ASSERT(aRv.Failed());
7340 0 : return;
7341 : }
7342 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
7343 0 : JS::AutoValueVector argv(cx);
7344 0 : if (!argv.resize(2)) {
7345 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
7346 0 : return;
7347 : }
7348 0 : unsigned argc = 2;
7349 :
7350 : do {
7351 0 : JS::ExposeObjectToActiveJS(value);
7352 0 : argv[1].setObject(*value);
7353 0 : if (!MaybeWrapObjectValue(cx, argv[1])) {
7354 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7355 0 : return;
7356 : }
7357 0 : break;
7358 : } while (0);
7359 :
7360 : do {
7361 0 : nsString mutableStr(key);
7362 0 : if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
7363 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7364 0 : return;
7365 : }
7366 0 : break;
7367 : } while (0);
7368 :
7369 0 : JS::Rooted<JS::Value> callable(cx);
7370 0 : RTCStatsReportAtoms* atomsCache = GetAtomCache<RTCStatsReportAtoms>(cx);
7371 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
7372 0 : !GetCallableProperty(cx, atomsCache->__set_id, &callable)) {
7373 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7374 0 : return;
7375 : }
7376 0 : JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
7377 0 : if (!JS::Call(cx, thisValue, callable,
7378 0 : JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
7379 0 : aRv.NoteJSContextException(cx);
7380 0 : return;
7381 : }
7382 0 : JS::Rooted<JSObject*> rvalDecl(cx);
7383 0 : if (rval.isObject()) {
7384 : #ifdef __clang__
7385 : #pragma clang diagnostic push
7386 : #pragma clang diagnostic ignored "-Wunreachable-code"
7387 : #pragma clang diagnostic ignored "-Wunreachable-code-return"
7388 : #endif // __clang__
7389 0 : if ((false) && !CallerSubsumes(rval)) {
7390 0 : ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "return value of RTCStatsReport.__set");
7391 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7392 0 : return;
7393 : }
7394 : #ifdef __clang__
7395 : #pragma clang diagnostic pop
7396 : #endif // __clang__
7397 0 : rvalDecl = &rval.toObject();
7398 : } else {
7399 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of RTCStatsReport.__set");
7400 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7401 0 : return;
7402 : }
7403 0 : aRetVal.set(rvalDecl);
7404 : }
7405 :
7406 : bool
7407 0 : RTCStatsReportJSImpl::InitIds(JSContext* cx, RTCStatsReportAtoms* atomsCache)
7408 : {
7409 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
7410 :
7411 : // Initialize these in reverse order so that any failure leaves the first one
7412 : // uninitialized.
7413 0 : if (!atomsCache->__set_id.init(cx, "__set") ||
7414 0 : !atomsCache->get_id.init(cx, "get") ||
7415 0 : !atomsCache->__delete_id.init(cx, "__delete") ||
7416 0 : !atomsCache->__clear_id.init(cx, "__clear") ||
7417 0 : !atomsCache->has_id.init(cx, "has") ||
7418 0 : !atomsCache->forEach_id.init(cx, "forEach") ||
7419 0 : !atomsCache->values_id.init(cx, "values") ||
7420 0 : !atomsCache->keys_id.init(cx, "keys") ||
7421 0 : !atomsCache->entries_id.init(cx, "entries") ||
7422 0 : !atomsCache->size_id.init(cx, "size") ||
7423 0 : !atomsCache->mozPcid_id.init(cx, "mozPcid")) {
7424 0 : return false;
7425 : }
7426 0 : return true;
7427 : }
7428 :
7429 :
7430 : void
7431 0 : RTCStatsReportJSImpl::GetMozPcid(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
7432 : {
7433 0 : CallSetup s(this, aRv, "RTCStatsReport.mozPcid", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
7434 0 : JSContext* cx = s.GetContext();
7435 0 : if (!cx) {
7436 0 : MOZ_ASSERT(aRv.Failed());
7437 0 : return;
7438 : }
7439 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
7440 :
7441 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
7442 0 : RTCStatsReportAtoms* atomsCache = GetAtomCache<RTCStatsReportAtoms>(cx);
7443 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
7444 0 : !JS_GetPropertyById(cx, callback, atomsCache->mozPcid_id, &rval)) {
7445 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7446 0 : return;
7447 : }
7448 0 : binding_detail::FakeString rvalDecl;
7449 0 : if (!ConvertJSValueToString(cx, rval, eStringify, eStringify, rvalDecl)) {
7450 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7451 0 : return;
7452 : }
7453 0 : aRetVal = rvalDecl;
7454 : }
7455 :
7456 : uint32_t
7457 0 : RTCStatsReportJSImpl::GetSize(ErrorResult& aRv, JSCompartment* aCompartment)
7458 : {
7459 0 : CallSetup s(this, aRv, "RTCStatsReport.size", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
7460 0 : JSContext* cx = s.GetContext();
7461 0 : if (!cx) {
7462 0 : MOZ_ASSERT(aRv.Failed());
7463 0 : return uint32_t(0);
7464 : }
7465 0 : JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
7466 :
7467 0 : JS::Rooted<JSObject *> callback(cx, mCallback);
7468 0 : RTCStatsReportAtoms* atomsCache = GetAtomCache<RTCStatsReportAtoms>(cx);
7469 0 : if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
7470 0 : !JS_GetPropertyById(cx, callback, atomsCache->size_id, &rval)) {
7471 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7472 0 : return uint32_t(0);
7473 : }
7474 : uint32_t rvalDecl;
7475 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, rval, &rvalDecl)) {
7476 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
7477 0 : return uint32_t(0);
7478 : }
7479 0 : return rvalDecl;
7480 : }
7481 :
7482 :
7483 : NS_IMPL_CYCLE_COLLECTION_CLASS(RTCStatsReport)
7484 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(RTCStatsReport)
7485 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mImpl)
7486 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
7487 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
7488 0 : tmp->ClearWeakReferences();
7489 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
7490 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(RTCStatsReport)
7491 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImpl)
7492 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
7493 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
7494 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(RTCStatsReport)
7495 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(RTCStatsReport)
7496 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(RTCStatsReport)
7497 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RTCStatsReport)
7498 0 : NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
7499 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
7500 0 : NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
7501 0 : NS_INTERFACE_MAP_END
7502 :
7503 0 : RTCStatsReport::RTCStatsReport(JS::Handle<JSObject*> aJSImplObject, nsIGlobalObject* aParent)
7504 0 : : mImpl(new RTCStatsReportJSImpl(nullptr, aJSImplObject, /* aIncumbentGlobal = */ nullptr)),
7505 0 : mParent(aParent)
7506 : {
7507 0 : }
7508 :
7509 :
7510 0 : RTCStatsReport::~RTCStatsReport()
7511 : {
7512 0 : }
7513 :
7514 : nsISupports*
7515 0 : RTCStatsReport::GetParentObject() const
7516 : {
7517 0 : return mParent;
7518 : }
7519 :
7520 : JSObject*
7521 0 : RTCStatsReport::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
7522 : {
7523 0 : JS::Rooted<JSObject*> obj(aCx, RTCStatsReportBinding::Wrap(aCx, this, aGivenProto));
7524 0 : if (!obj) {
7525 0 : return nullptr;
7526 : }
7527 :
7528 : // Now define it on our chrome object
7529 0 : JSAutoCompartment ac(aCx, mImpl->CallbackOrNull());
7530 0 : if (!JS_WrapObject(aCx, &obj)) {
7531 0 : return nullptr;
7532 : }
7533 0 : if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
7534 0 : return nullptr;
7535 : }
7536 0 : return obj;
7537 : }
7538 :
7539 : void
7540 0 : RTCStatsReport::GetMozPcid(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment) const
7541 : {
7542 0 : return mImpl->GetMozPcid(aRetVal, aRv, aCompartment);
7543 : }
7544 :
7545 : uint32_t
7546 0 : RTCStatsReport::GetSize(ErrorResult& aRv, JSCompartment* aCompartment) const
7547 : {
7548 0 : return mImpl->GetSize(aRv, aCompartment);
7549 : }
7550 :
7551 : void
7552 0 : RTCStatsReport::Entries(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
7553 : {
7554 0 : return mImpl->Entries(aRetVal, aRv, aCompartment);
7555 : }
7556 :
7557 : void
7558 0 : RTCStatsReport::Keys(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
7559 : {
7560 0 : return mImpl->Keys(aRetVal, aRv, aCompartment);
7561 : }
7562 :
7563 : void
7564 0 : RTCStatsReport::Values(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
7565 : {
7566 0 : return mImpl->Values(aRetVal, aRv, aCompartment);
7567 : }
7568 :
7569 : void
7570 0 : RTCStatsReport::ForEach(JS::Handle<JSObject*> callback, JS::Handle<JS::Value> thisArg, ErrorResult& aRv, JSCompartment* aCompartment)
7571 : {
7572 0 : return mImpl->ForEach(callback, thisArg, aRv, aCompartment);
7573 : }
7574 :
7575 : bool
7576 0 : RTCStatsReport::Has(const nsAString& key, ErrorResult& aRv, JSCompartment* aCompartment)
7577 : {
7578 0 : return mImpl->Has(key, aRv, aCompartment);
7579 : }
7580 :
7581 : void
7582 0 : RTCStatsReport::__clear(ErrorResult& aRv, JSCompartment* aCompartment)
7583 : {
7584 0 : return mImpl->__clear(aRv, aCompartment);
7585 : }
7586 :
7587 : bool
7588 0 : RTCStatsReport::__delete(const nsAString& key, ErrorResult& aRv, JSCompartment* aCompartment)
7589 : {
7590 0 : return mImpl->__delete(key, aRv, aCompartment);
7591 : }
7592 :
7593 : void
7594 0 : RTCStatsReport::Get(const nsAString& key, JS::MutableHandle<JS::Value> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
7595 : {
7596 0 : return mImpl->Get(key, aRetVal, aRv, aCompartment);
7597 : }
7598 :
7599 : void
7600 0 : RTCStatsReport::__set(const nsAString& key, JS::Handle<JSObject*> value, JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
7601 : {
7602 0 : return mImpl->__set(key, value, aRetVal, aRv, aCompartment);
7603 : }
7604 :
7605 : bool
7606 0 : RTCStatsReport::_Create(JSContext* cx, unsigned argc, JS::Value* vp)
7607 : {
7608 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
7609 0 : if (args.length() < 2) {
7610 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "RTCStatsReport._create");
7611 : }
7612 0 : if (!args[0].isObject()) {
7613 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of RTCStatsReport._create");
7614 : }
7615 0 : if (!args[1].isObject()) {
7616 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of RTCStatsReport._create");
7617 : }
7618 :
7619 : // GlobalObject will go through wrappers as needed for us, and
7620 : // is simpler than the right UnwrapArg incantation.
7621 0 : GlobalObject global(cx, &args[0].toObject());
7622 0 : if (global.Failed()) {
7623 0 : return false;
7624 : }
7625 0 : nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports());
7626 0 : MOZ_ASSERT(globalHolder);
7627 0 : JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
7628 0 : RefPtr<RTCStatsReport> impl = new RTCStatsReport(arg, globalHolder);
7629 0 : MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
7630 0 : return GetOrCreateDOMReflector(cx, impl, args.rval());
7631 : }
7632 :
7633 :
7634 : } // namespace dom
7635 : } // namespace mozilla
|