LCOV - code coverage report
Current view: top level - obj-x86_64-pc-linux-gnu/dom/bindings - RTCStatsReportBinding.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 4082 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 168 0.0 %
Legend: Lines: hit not hit

          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

Generated by: LCOV version 1.13