LCOV - code coverage report
Current view: top level - obj-x86_64-pc-linux-gnu/dom/bindings - ThreadSafeChromeUtilsBinding.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 24 482 5.0 %
Date: 2017-07-14 16:53:18 Functions: 4 34 11.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* THIS FILE IS AUTOGENERATED FROM ThreadSafeChromeUtils.webidl BY Codegen.py - DO NOT EDIT */
       2             : 
       3             : #include "AtomList.h"
       4             : #include "ThreadSafeChromeUtilsBinding.h"
       5             : #include "WrapperFactory.h"
       6             : #include "jsapi.h"
       7             : #include "jsfriendapi.h"
       8             : #include "mozilla/OwningNonNull.h"
       9             : #include "mozilla/devtools/HeapSnapshot.h"
      10             : #include "mozilla/dom/BindingUtils.h"
      11             : #include "mozilla/dom/ChromeUtils.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/TypedArray.h"
      18             : #include "mozilla/dom/UnionConversions.h"
      19             : #include "mozilla/dom/UnionTypes.h"
      20             : #include "mozilla/dom/XrayExpandoClass.h"
      21             : #include "nsContentUtils.h"
      22             : 
      23             : namespace mozilla {
      24             : namespace dom {
      25             : 
      26             : namespace Base64URLDecodePaddingValues {
      27             : extern const EnumEntry strings[4] = {
      28             :   {"require", 7},
      29             :   {"ignore", 6},
      30             :   {"reject", 6},
      31             :   { nullptr, 0 }
      32             : };
      33             : } // namespace Base64URLDecodePaddingValues
      34             : 
      35             : bool
      36           0 : ToJSValue(JSContext* aCx, Base64URLDecodePadding aArgument, JS::MutableHandle<JS::Value> aValue)
      37             : {
      38           0 :   MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(Base64URLDecodePaddingValues::strings));
      39             :   JSString* resultStr =
      40           0 :     JS_NewStringCopyN(aCx, Base64URLDecodePaddingValues::strings[uint32_t(aArgument)].value,
      41           0 :                       Base64URLDecodePaddingValues::strings[uint32_t(aArgument)].length);
      42           0 :   if (!resultStr) {
      43           0 :     return false;
      44             :   }
      45           0 :   aValue.setString(resultStr);
      46           0 :   return true;
      47             : }
      48             : 
      49             : 
      50             : 
      51           0 : Base64URLDecodeOptions::Base64URLDecodeOptions()
      52             : {
      53             :   // Safe to pass a null context if we pass a null value
      54           0 :   Init(nullptr, JS::NullHandleValue);
      55           0 : }
      56             : 
      57             : 
      58             : 
      59             : bool
      60           0 : Base64URLDecodeOptions::InitIds(JSContext* cx, Base64URLDecodeOptionsAtoms* atomsCache)
      61             : {
      62           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
      63             : 
      64             :   // Initialize these in reverse order so that any failure leaves the first one
      65             :   // uninitialized.
      66           0 :   if (!atomsCache->padding_id.init(cx, "padding")) {
      67           0 :     return false;
      68             :   }
      69           0 :   return true;
      70             : }
      71             : 
      72             : bool
      73           0 : Base64URLDecodeOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
      74             : {
      75             :   // Passing a null JSContext is OK only if we're initing from null,
      76             :   // Since in that case we will not have to do any property gets
      77             :   // Also evaluate isNullOrUndefined in order to avoid false-positive
      78             :   // checkers by static analysis tools
      79           0 :   MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
      80           0 :   Base64URLDecodeOptionsAtoms* atomsCache = nullptr;
      81           0 :   if (cx) {
      82           0 :     atomsCache = GetAtomCache<Base64URLDecodeOptionsAtoms>(cx);
      83           0 :     if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
      84           0 :       return false;
      85             :     }
      86             :   }
      87             : 
      88           0 :   if (!IsConvertibleToDictionary(val)) {
      89           0 :     return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
      90             :   }
      91             : 
      92           0 :   bool isNull = val.isNullOrUndefined();
      93             :   // We only need these if !isNull, in which case we have |cx|.
      94           0 :   Maybe<JS::Rooted<JSObject *> > object;
      95           0 :   Maybe<JS::Rooted<JS::Value> > temp;
      96           0 :   if (!isNull) {
      97           0 :     MOZ_ASSERT(cx);
      98           0 :     object.emplace(cx, &val.toObject());
      99           0 :     temp.emplace(cx);
     100             :   }
     101           0 :   if (!isNull) {
     102           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->padding_id, temp.ptr())) {
     103           0 :       return false;
     104             :     }
     105             :   }
     106           0 :   if (!isNull && !temp->isUndefined()) {
     107             :     {
     108             :       int index;
     109           0 :       if (!FindEnumStringIndex<true>(cx, temp.ref(), Base64URLDecodePaddingValues::strings, "Base64URLDecodePadding", "'padding' member of Base64URLDecodeOptions", &index)) {
     110           0 :         return false;
     111             :       }
     112           0 :       MOZ_ASSERT(index >= 0);
     113           0 :       mPadding = static_cast<Base64URLDecodePadding>(index);
     114             :     }
     115           0 :     mIsAnyMemberPresent = true;
     116           0 :   } else if (cx) {
     117             :     // Don't error out if we have no cx.  In that
     118             :     // situation the caller is default-constructing us and we'll
     119             :     // just assume they know what they're doing.
     120           0 :     return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
     121           0 :                              "'padding' member of Base64URLDecodeOptions");
     122             :   }
     123           0 :   return true;
     124             : }
     125             : 
     126             : bool
     127           0 : Base64URLDecodeOptions::Init(const nsAString& aJSON)
     128             : {
     129           0 :   AutoJSAPI jsapi;
     130           0 :   JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
     131           0 :   if (!cleanGlobal) {
     132           0 :     return false;
     133             :   }
     134           0 :   if (!jsapi.Init(cleanGlobal)) {
     135           0 :     return false;
     136             :   }
     137           0 :   JSContext* cx = jsapi.cx();
     138           0 :   JS::Rooted<JS::Value> json(cx);
     139           0 :   bool ok = ParseJSON(cx, aJSON, &json);
     140           0 :   NS_ENSURE_TRUE(ok, false);
     141           0 :   return Init(cx, json);
     142             : }
     143             : 
     144             : bool
     145           0 : Base64URLDecodeOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
     146             : {
     147           0 :   Base64URLDecodeOptionsAtoms* atomsCache = GetAtomCache<Base64URLDecodeOptionsAtoms>(cx);
     148           0 :   if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     149           0 :     return false;
     150             :   }
     151             : 
     152           0 :   JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
     153           0 :   if (!obj) {
     154           0 :     return false;
     155             :   }
     156           0 :   rval.set(JS::ObjectValue(*obj));
     157             : 
     158             :   do {
     159             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     160           0 :     JS::Rooted<JS::Value> temp(cx);
     161           0 :     Base64URLDecodePadding const & currentValue = mPadding;
     162           0 :     if (!ToJSValue(cx, currentValue, &temp)) {
     163           0 :       return false;
     164             :     }
     165           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->padding_id, temp, JSPROP_ENUMERATE)) {
     166           0 :       return false;
     167             :     }
     168           0 :     break;
     169             :   } while(0);
     170             : 
     171           0 :   return true;
     172             : }
     173             : 
     174             : bool
     175           0 : Base64URLDecodeOptions::ToJSON(nsAString& aJSON) const
     176             : {
     177           0 :   AutoJSAPI jsapi;
     178           0 :   jsapi.Init();
     179           0 :   JSContext *cx = jsapi.cx();
     180             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
     181             :   // because we'll only be creating objects, in ways that have no
     182             :   // side-effects, followed by a call to JS::ToJSONMaybeSafely,
     183             :   // which likewise guarantees no side-effects for the sorts of
     184             :   // things we will pass it.
     185           0 :   JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
     186           0 :   JS::Rooted<JS::Value> val(cx);
     187           0 :   if (!ToObjectInternal(cx, &val)) {
     188           0 :     return false;
     189             :   }
     190           0 :   JS::Rooted<JSObject*> obj(cx, &val.toObject());
     191           0 :   return StringifyToJSON(cx, obj, aJSON);
     192             : }
     193             : 
     194             : void
     195           0 : Base64URLDecodeOptions::TraceDictionary(JSTracer* trc)
     196             : {
     197           0 : }
     198             : 
     199             : Base64URLDecodeOptions&
     200           0 : Base64URLDecodeOptions::operator=(const Base64URLDecodeOptions& aOther)
     201             : {
     202           0 :   mPadding = aOther.mPadding;
     203           0 :   return *this;
     204             : }
     205             : 
     206             : namespace binding_detail {
     207             : } // namespace binding_detail
     208             : 
     209             : 
     210             : 
     211           0 : Base64URLEncodeOptions::Base64URLEncodeOptions()
     212             : {
     213             :   // Safe to pass a null context if we pass a null value
     214           0 :   Init(nullptr, JS::NullHandleValue);
     215           0 : }
     216             : 
     217             : 
     218             : 
     219             : bool
     220           0 : Base64URLEncodeOptions::InitIds(JSContext* cx, Base64URLEncodeOptionsAtoms* atomsCache)
     221             : {
     222           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
     223             : 
     224             :   // Initialize these in reverse order so that any failure leaves the first one
     225             :   // uninitialized.
     226           0 :   if (!atomsCache->pad_id.init(cx, "pad")) {
     227           0 :     return false;
     228             :   }
     229           0 :   return true;
     230             : }
     231             : 
     232             : bool
     233           0 : Base64URLEncodeOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
     234             : {
     235             :   // Passing a null JSContext is OK only if we're initing from null,
     236             :   // Since in that case we will not have to do any property gets
     237             :   // Also evaluate isNullOrUndefined in order to avoid false-positive
     238             :   // checkers by static analysis tools
     239           0 :   MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
     240           0 :   Base64URLEncodeOptionsAtoms* atomsCache = nullptr;
     241           0 :   if (cx) {
     242           0 :     atomsCache = GetAtomCache<Base64URLEncodeOptionsAtoms>(cx);
     243           0 :     if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     244           0 :       return false;
     245             :     }
     246             :   }
     247             : 
     248           0 :   if (!IsConvertibleToDictionary(val)) {
     249           0 :     return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
     250             :   }
     251             : 
     252           0 :   bool isNull = val.isNullOrUndefined();
     253             :   // We only need these if !isNull, in which case we have |cx|.
     254           0 :   Maybe<JS::Rooted<JSObject *> > object;
     255           0 :   Maybe<JS::Rooted<JS::Value> > temp;
     256           0 :   if (!isNull) {
     257           0 :     MOZ_ASSERT(cx);
     258           0 :     object.emplace(cx, &val.toObject());
     259           0 :     temp.emplace(cx);
     260             :   }
     261           0 :   if (!isNull) {
     262           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->pad_id, temp.ptr())) {
     263           0 :       return false;
     264             :     }
     265             :   }
     266           0 :   if (!isNull && !temp->isUndefined()) {
     267           0 :     if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mPad)) {
     268           0 :       return false;
     269             :     }
     270           0 :     mIsAnyMemberPresent = true;
     271           0 :   } else if (cx) {
     272             :     // Don't error out if we have no cx.  In that
     273             :     // situation the caller is default-constructing us and we'll
     274             :     // just assume they know what they're doing.
     275           0 :     return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
     276           0 :                              "'pad' member of Base64URLEncodeOptions");
     277             :   }
     278           0 :   return true;
     279             : }
     280             : 
     281             : bool
     282           0 : Base64URLEncodeOptions::Init(const nsAString& aJSON)
     283             : {
     284           0 :   AutoJSAPI jsapi;
     285           0 :   JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
     286           0 :   if (!cleanGlobal) {
     287           0 :     return false;
     288             :   }
     289           0 :   if (!jsapi.Init(cleanGlobal)) {
     290           0 :     return false;
     291             :   }
     292           0 :   JSContext* cx = jsapi.cx();
     293           0 :   JS::Rooted<JS::Value> json(cx);
     294           0 :   bool ok = ParseJSON(cx, aJSON, &json);
     295           0 :   NS_ENSURE_TRUE(ok, false);
     296           0 :   return Init(cx, json);
     297             : }
     298             : 
     299             : bool
     300           0 : Base64URLEncodeOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
     301             : {
     302           0 :   Base64URLEncodeOptionsAtoms* atomsCache = GetAtomCache<Base64URLEncodeOptionsAtoms>(cx);
     303           0 :   if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     304           0 :     return false;
     305             :   }
     306             : 
     307           0 :   JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
     308           0 :   if (!obj) {
     309           0 :     return false;
     310             :   }
     311           0 :   rval.set(JS::ObjectValue(*obj));
     312             : 
     313             :   do {
     314             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     315           0 :     JS::Rooted<JS::Value> temp(cx);
     316           0 :     bool const & currentValue = mPad;
     317           0 :     temp.setBoolean(currentValue);
     318           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->pad_id, temp, JSPROP_ENUMERATE)) {
     319           0 :       return false;
     320             :     }
     321           0 :     break;
     322             :   } while(0);
     323             : 
     324           0 :   return true;
     325             : }
     326             : 
     327             : bool
     328           0 : Base64URLEncodeOptions::ToJSON(nsAString& aJSON) const
     329             : {
     330           0 :   AutoJSAPI jsapi;
     331           0 :   jsapi.Init();
     332           0 :   JSContext *cx = jsapi.cx();
     333             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
     334             :   // because we'll only be creating objects, in ways that have no
     335             :   // side-effects, followed by a call to JS::ToJSONMaybeSafely,
     336             :   // which likewise guarantees no side-effects for the sorts of
     337             :   // things we will pass it.
     338           0 :   JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
     339           0 :   JS::Rooted<JS::Value> val(cx);
     340           0 :   if (!ToObjectInternal(cx, &val)) {
     341           0 :     return false;
     342             :   }
     343           0 :   JS::Rooted<JSObject*> obj(cx, &val.toObject());
     344           0 :   return StringifyToJSON(cx, obj, aJSON);
     345             : }
     346             : 
     347             : void
     348           0 : Base64URLEncodeOptions::TraceDictionary(JSTracer* trc)
     349             : {
     350           0 : }
     351             : 
     352             : Base64URLEncodeOptions&
     353           0 : Base64URLEncodeOptions::operator=(const Base64URLEncodeOptions& aOther)
     354             : {
     355           0 :   mPad = aOther.mPad;
     356           0 :   return *this;
     357             : }
     358             : 
     359             : namespace binding_detail {
     360             : } // namespace binding_detail
     361             : 
     362             : 
     363             : 
     364           0 : HeapSnapshotBoundaries::HeapSnapshotBoundaries()
     365             : {
     366             :   // Safe to pass a null context if we pass a null value
     367           0 :   Init(nullptr, JS::NullHandleValue);
     368           0 : }
     369             : 
     370             : 
     371             : bool
     372           0 : HeapSnapshotBoundaries::InitIds(JSContext* cx, HeapSnapshotBoundariesAtoms* atomsCache)
     373             : {
     374           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
     375             : 
     376             :   // Initialize these in reverse order so that any failure leaves the first one
     377             :   // uninitialized.
     378           0 :   if (!atomsCache->runtime_id.init(cx, "runtime") ||
     379           0 :       !atomsCache->globals_id.init(cx, "globals") ||
     380           0 :       !atomsCache->debugger_id.init(cx, "debugger")) {
     381           0 :     return false;
     382             :   }
     383           0 :   return true;
     384             : }
     385             : 
     386             : bool
     387           0 : HeapSnapshotBoundaries::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
     388             : {
     389             :   // Passing a null JSContext is OK only if we're initing from null,
     390             :   // Since in that case we will not have to do any property gets
     391             :   // Also evaluate isNullOrUndefined in order to avoid false-positive
     392             :   // checkers by static analysis tools
     393           0 :   MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
     394           0 :   HeapSnapshotBoundariesAtoms* atomsCache = nullptr;
     395           0 :   if (cx) {
     396           0 :     atomsCache = GetAtomCache<HeapSnapshotBoundariesAtoms>(cx);
     397           0 :     if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     398           0 :       return false;
     399             :     }
     400             :   }
     401             : 
     402           0 :   if (!IsConvertibleToDictionary(val)) {
     403           0 :     return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
     404             :   }
     405             : 
     406           0 :   bool isNull = val.isNullOrUndefined();
     407             :   // We only need these if !isNull, in which case we have |cx|.
     408           0 :   Maybe<JS::Rooted<JSObject *> > object;
     409           0 :   Maybe<JS::Rooted<JS::Value> > temp;
     410           0 :   if (!isNull) {
     411           0 :     MOZ_ASSERT(cx);
     412           0 :     object.emplace(cx, &val.toObject());
     413           0 :     temp.emplace(cx);
     414             :   }
     415           0 :   if (!isNull) {
     416           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->debugger_id, temp.ptr())) {
     417           0 :       return false;
     418             :     }
     419             :   }
     420           0 :   if (!isNull && !temp->isUndefined()) {
     421           0 :     mDebugger.Construct();
     422           0 :     if (temp.ref().isObject()) {
     423             : #ifdef __clang__
     424             : #pragma clang diagnostic push
     425             : #pragma clang diagnostic ignored "-Wunreachable-code"
     426             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
     427             : #endif // __clang__
     428           0 :       if ((passedToJSImpl) && !CallerSubsumes(temp.ref())) {
     429           0 :         ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "'debugger' member of HeapSnapshotBoundaries");
     430           0 :         return false;
     431             :       }
     432             : #ifdef __clang__
     433             : #pragma clang diagnostic pop
     434             : #endif // __clang__
     435           0 :       (mDebugger.Value()) = &temp.ref().toObject();
     436             :     } else {
     437           0 :       ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'debugger' member of HeapSnapshotBoundaries");
     438           0 :       return false;
     439             :     }
     440           0 :     mIsAnyMemberPresent = true;
     441             :   }
     442             : 
     443           0 :   if (!isNull) {
     444           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->globals_id, temp.ptr())) {
     445           0 :       return false;
     446             :     }
     447             :   }
     448           0 :   if (!isNull && !temp->isUndefined()) {
     449           0 :     mGlobals.Construct();
     450           0 :     if (temp.ref().isObject()) {
     451           0 :       JS::ForOfIterator iter(cx);
     452           0 :       if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
     453           0 :         return false;
     454             :       }
     455           0 :       if (!iter.valueIsIterable()) {
     456           0 :         ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'globals' member of HeapSnapshotBoundaries");
     457           0 :         return false;
     458             :       }
     459           0 :       Sequence<JSObject*> &arr = (mGlobals.Value());
     460           0 :       JS::Rooted<JS::Value> temp(cx);
     461             :       while (true) {
     462             :         bool done;
     463           0 :         if (!iter.next(&temp, &done)) {
     464           0 :           return false;
     465             :         }
     466           0 :         if (done) {
     467           0 :           break;
     468             :         }
     469           0 :         JSObject** slotPtr = arr.AppendElement(mozilla::fallible);
     470           0 :         if (!slotPtr) {
     471           0 :           JS_ReportOutOfMemory(cx);
     472           0 :           return false;
     473             :         }
     474           0 :         JSObject*& slot = *slotPtr;
     475           0 :         if (temp.isObject()) {
     476             : #ifdef __clang__
     477             : #pragma clang diagnostic push
     478             : #pragma clang diagnostic ignored "-Wunreachable-code"
     479             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
     480             : #endif // __clang__
     481           0 :           if ((passedToJSImpl) && !CallerSubsumes(temp)) {
     482           0 :             ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "element of 'globals' member of HeapSnapshotBoundaries");
     483           0 :             return false;
     484             :           }
     485             : #ifdef __clang__
     486             : #pragma clang diagnostic pop
     487             : #endif // __clang__
     488           0 :           slot = &temp.toObject();
     489             :         } else {
     490           0 :           ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Element of 'globals' member of HeapSnapshotBoundaries");
     491           0 :           return false;
     492             :         }
     493           0 :       }
     494             :     } else {
     495           0 :       ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'globals' member of HeapSnapshotBoundaries");
     496           0 :       return false;
     497             :     }
     498           0 :     mIsAnyMemberPresent = true;
     499             :   }
     500             : 
     501           0 :   if (!isNull) {
     502           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->runtime_id, temp.ptr())) {
     503           0 :       return false;
     504             :     }
     505             :   }
     506           0 :   if (!isNull && !temp->isUndefined()) {
     507           0 :     mRuntime.Construct();
     508           0 :     if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &(mRuntime.Value()))) {
     509           0 :       return false;
     510             :     }
     511           0 :     mIsAnyMemberPresent = true;
     512             :   }
     513           0 :   return true;
     514             : }
     515             : 
     516             : bool
     517           0 : HeapSnapshotBoundaries::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
     518             : {
     519           0 :   HeapSnapshotBoundariesAtoms* atomsCache = GetAtomCache<HeapSnapshotBoundariesAtoms>(cx);
     520           0 :   if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     521           0 :     return false;
     522             :   }
     523             : 
     524           0 :   JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
     525           0 :   if (!obj) {
     526           0 :     return false;
     527             :   }
     528           0 :   rval.set(JS::ObjectValue(*obj));
     529             : 
     530           0 :   if (mDebugger.WasPassed()) {
     531             :     do {
     532             :       // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     533           0 :       JS::Rooted<JS::Value> temp(cx);
     534           0 :       JSObject* const & currentValue = mDebugger.InternalValue();
     535           0 :       JS::ExposeObjectToActiveJS(currentValue);
     536           0 :       temp.setObject(*currentValue);
     537           0 :       if (!MaybeWrapObjectValue(cx, &temp)) {
     538           0 :         return false;
     539             :       }
     540           0 :       if (!JS_DefinePropertyById(cx, obj, atomsCache->debugger_id, temp, JSPROP_ENUMERATE)) {
     541           0 :         return false;
     542             :       }
     543           0 :       break;
     544             :     } while(0);
     545             :   }
     546             : 
     547           0 :   if (mGlobals.WasPassed()) {
     548             :     do {
     549             :       // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     550           0 :       JS::Rooted<JS::Value> temp(cx);
     551           0 :       Sequence<JSObject*> const & currentValue = mGlobals.InternalValue();
     552             : 
     553           0 :       uint32_t length = currentValue.Length();
     554           0 :       JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
     555           0 :       if (!returnArray) {
     556           0 :         return false;
     557             :       }
     558             :       // Scope for 'tmp'
     559             :       {
     560           0 :         JS::Rooted<JS::Value> tmp(cx);
     561           0 :         for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
     562             :           // Control block to let us common up the JS_DefineElement calls when there
     563             :           // are different ways to succeed at wrapping the object.
     564             :           do {
     565           0 :             JS::ExposeObjectToActiveJS(currentValue[sequenceIdx0]);
     566           0 :             tmp.setObject(*currentValue[sequenceIdx0]);
     567           0 :             if (!MaybeWrapObjectValue(cx, &tmp)) {
     568           0 :               return false;
     569             :             }
     570           0 :             break;
     571             :           } while (0);
     572           0 :           if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
     573             :                                 JSPROP_ENUMERATE)) {
     574           0 :             return false;
     575             :           }
     576             :         }
     577             :       }
     578           0 :       temp.setObject(*returnArray);
     579           0 :       if (!JS_DefinePropertyById(cx, obj, atomsCache->globals_id, temp, JSPROP_ENUMERATE)) {
     580           0 :         return false;
     581             :       }
     582           0 :       break;
     583             :     } while(0);
     584             :   }
     585             : 
     586           0 :   if (mRuntime.WasPassed()) {
     587             :     do {
     588             :       // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     589           0 :       JS::Rooted<JS::Value> temp(cx);
     590           0 :       bool const & currentValue = mRuntime.InternalValue();
     591           0 :       temp.setBoolean(currentValue);
     592           0 :       if (!JS_DefinePropertyById(cx, obj, atomsCache->runtime_id, temp, JSPROP_ENUMERATE)) {
     593           0 :         return false;
     594             :       }
     595           0 :       break;
     596             :     } while(0);
     597             :   }
     598             : 
     599           0 :   return true;
     600             : }
     601             : 
     602             : void
     603           0 : HeapSnapshotBoundaries::TraceDictionary(JSTracer* trc)
     604             : {
     605           0 :   if (mDebugger.WasPassed()) {
     606           0 :     JS::UnsafeTraceRoot(trc, &mDebugger.Value(), "HeapSnapshotBoundaries.mDebugger");
     607             :   }
     608             : 
     609           0 :   if (mGlobals.WasPassed()) {
     610           0 :     DoTraceSequence(trc, mGlobals.Value());
     611             :   }
     612           0 : }
     613             : 
     614             : namespace binding_detail {
     615             : } // namespace binding_detail
     616             : 
     617             : 
     618             : namespace ThreadSafeChromeUtilsBinding {
     619             : 
     620             : static bool
     621           0 : saveHeapSnapshot(JSContext* cx, unsigned argc, JS::Value* vp)
     622             : {
     623           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
     624           0 :   JS::Rooted<JSObject*> obj(cx, &args.callee());
     625             : 
     626           0 :   GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
     627           0 :   if (global.Failed()) {
     628           0 :     return false;
     629             :   }
     630             : 
     631           0 :   RootedDictionary<binding_detail::FastHeapSnapshotBoundaries> arg0(cx);
     632           0 :   if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue,  "Argument 1 of ThreadSafeChromeUtils.saveHeapSnapshot", false)) {
     633           0 :     return false;
     634             :   }
     635           0 :   binding_detail::FastErrorResult rv;
     636           0 :   DOMString result;
     637           0 :   mozilla::dom::ThreadSafeChromeUtils::SaveHeapSnapshot(global, Constify(arg0), result, rv);
     638           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     639           0 :     return false;
     640             :   }
     641           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     642           0 :   if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
     643           0 :     return false;
     644             :   }
     645           0 :   return true;
     646             : }
     647             : 
     648             : static bool
     649           0 : saveHeapSnapshotGetId(JSContext* cx, unsigned argc, JS::Value* vp)
     650             : {
     651           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
     652           0 :   JS::Rooted<JSObject*> obj(cx, &args.callee());
     653             : 
     654           0 :   GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
     655           0 :   if (global.Failed()) {
     656           0 :     return false;
     657             :   }
     658             : 
     659           0 :   RootedDictionary<binding_detail::FastHeapSnapshotBoundaries> arg0(cx);
     660           0 :   if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue,  "Argument 1 of ThreadSafeChromeUtils.saveHeapSnapshotGetId", false)) {
     661           0 :     return false;
     662             :   }
     663           0 :   binding_detail::FastErrorResult rv;
     664           0 :   DOMString result;
     665           0 :   mozilla::dom::ThreadSafeChromeUtils::SaveHeapSnapshotGetId(global, Constify(arg0), result, rv);
     666           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     667           0 :     return false;
     668             :   }
     669           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     670           0 :   if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
     671           0 :     return false;
     672             :   }
     673           0 :   return true;
     674             : }
     675             : 
     676             : static bool
     677           0 : readHeapSnapshot(JSContext* cx, unsigned argc, JS::Value* vp)
     678             : {
     679           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
     680           0 :   JS::Rooted<JSObject*> obj(cx, &args.callee());
     681             : 
     682           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
     683           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ThreadSafeChromeUtils.readHeapSnapshot");
     684             :   }
     685           0 :   GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
     686           0 :   if (global.Failed()) {
     687           0 :     return false;
     688             :   }
     689             : 
     690           0 :   binding_detail::FakeString arg0;
     691           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
     692           0 :     return false;
     693             :   }
     694           0 :   binding_detail::FastErrorResult rv;
     695           0 :   auto result(StrongOrRawPtr<mozilla::devtools::HeapSnapshot>(mozilla::dom::ThreadSafeChromeUtils::ReadHeapSnapshot(global, NonNullHelper(Constify(arg0)), rv)));
     696           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     697           0 :     return false;
     698             :   }
     699           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     700             :   static_assert(!IsPointer<decltype(result)>::value,
     701             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
     702           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
     703           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     704           0 :     return false;
     705             :   }
     706           0 :   return true;
     707             : }
     708             : 
     709             : static bool
     710           0 : nondeterministicGetWeakMapKeys(JSContext* cx, unsigned argc, JS::Value* vp)
     711             : {
     712           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
     713           0 :   JS::Rooted<JSObject*> obj(cx, &args.callee());
     714             : 
     715           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
     716           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ThreadSafeChromeUtils.nondeterministicGetWeakMapKeys");
     717             :   }
     718           0 :   GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
     719           0 :   if (global.Failed()) {
     720           0 :     return false;
     721             :   }
     722             : 
     723           0 :   JS::Rooted<JS::Value> arg0(cx);
     724           0 :   arg0 = args[0];
     725           0 :   binding_detail::FastErrorResult rv;
     726           0 :   JS::Rooted<JS::Value> result(cx);
     727           0 :   mozilla::dom::ThreadSafeChromeUtils::NondeterministicGetWeakMapKeys(global, arg0, &result, rv);
     728           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     729           0 :     return false;
     730             :   }
     731           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     732           0 :   JS::ExposeValueToActiveJS(result);
     733           0 :   args.rval().set(result);
     734           0 :   if (!MaybeWrapValue(cx, args.rval())) {
     735           0 :     return false;
     736             :   }
     737           0 :   return true;
     738             : }
     739             : 
     740             : static bool
     741           0 : nondeterministicGetWeakSetKeys(JSContext* cx, unsigned argc, JS::Value* vp)
     742             : {
     743           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
     744           0 :   JS::Rooted<JSObject*> obj(cx, &args.callee());
     745             : 
     746           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
     747           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ThreadSafeChromeUtils.nondeterministicGetWeakSetKeys");
     748             :   }
     749           0 :   GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
     750           0 :   if (global.Failed()) {
     751           0 :     return false;
     752             :   }
     753             : 
     754           0 :   JS::Rooted<JS::Value> arg0(cx);
     755           0 :   arg0 = args[0];
     756           0 :   binding_detail::FastErrorResult rv;
     757           0 :   JS::Rooted<JS::Value> result(cx);
     758           0 :   mozilla::dom::ThreadSafeChromeUtils::NondeterministicGetWeakSetKeys(global, arg0, &result, rv);
     759           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     760           0 :     return false;
     761             :   }
     762           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     763           0 :   JS::ExposeValueToActiveJS(result);
     764           0 :   args.rval().set(result);
     765           0 :   if (!MaybeWrapValue(cx, args.rval())) {
     766           0 :     return false;
     767             :   }
     768           0 :   return true;
     769             : }
     770             : 
     771             : static bool
     772           0 : base64URLEncode(JSContext* cx, unsigned argc, JS::Value* vp)
     773             : {
     774           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
     775           0 :   JS::Rooted<JSObject*> obj(cx, &args.callee());
     776             : 
     777           0 :   if (MOZ_UNLIKELY(args.length() < 2)) {
     778           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ThreadSafeChromeUtils.base64URLEncode");
     779             :   }
     780           0 :   GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
     781           0 :   if (global.Failed()) {
     782           0 :     return false;
     783             :   }
     784             : 
     785           0 :   ArrayBufferViewOrArrayBuffer arg0;
     786           0 :   ArrayBufferViewOrArrayBufferArgument arg0_holder(arg0);
     787             :   {
     788           0 :     bool done = false, failed = false, tryNext;
     789           0 :     if (args[0].isObject()) {
     790           0 :       done = (failed = !arg0_holder.TrySetToArrayBufferView(cx, args[0], tryNext, false)) || !tryNext ||
     791           0 :              (failed = !arg0_holder.TrySetToArrayBuffer(cx, args[0], tryNext, false)) || !tryNext;
     792             : 
     793             :     }
     794           0 :     if (failed) {
     795           0 :       return false;
     796             :     }
     797           0 :     if (!done) {
     798           0 :       ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 1 of ThreadSafeChromeUtils.base64URLEncode", "ArrayBufferView, ArrayBuffer");
     799           0 :       return false;
     800             :     }
     801             :   }
     802           0 :   binding_detail::FastBase64URLEncodeOptions arg1;
     803           0 :   if (!arg1.Init(cx, args[1],  "Argument 2 of ThreadSafeChromeUtils.base64URLEncode", false)) {
     804           0 :     return false;
     805             :   }
     806           0 :   binding_detail::FastErrorResult rv;
     807           0 :   nsCString result;
     808           0 :   mozilla::dom::ThreadSafeChromeUtils::Base64URLEncode(global, Constify(arg0), Constify(arg1), result, rv);
     809           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     810           0 :     return false;
     811             :   }
     812           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     813           0 :   if (!NonVoidByteStringToJsval(cx, result, args.rval())) {
     814           0 :     return false;
     815             :   }
     816           0 :   return true;
     817             : }
     818             : 
     819             : static bool
     820           0 : base64URLDecode(JSContext* cx, unsigned argc, JS::Value* vp)
     821             : {
     822           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
     823           0 :   JS::Rooted<JSObject*> obj(cx, &args.callee());
     824             : 
     825           0 :   if (MOZ_UNLIKELY(args.length() < 2)) {
     826           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ThreadSafeChromeUtils.base64URLDecode");
     827             :   }
     828           0 :   GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
     829           0 :   if (global.Failed()) {
     830           0 :     return false;
     831             :   }
     832             : 
     833           0 :   nsCString arg0;
     834           0 :   if (!ConvertJSValueToByteString(cx, args[0], false, arg0)) {
     835           0 :     return false;
     836             :   }
     837           0 :   binding_detail::FastBase64URLDecodeOptions arg1;
     838           0 :   if (!arg1.Init(cx, args[1],  "Argument 2 of ThreadSafeChromeUtils.base64URLDecode", false)) {
     839           0 :     return false;
     840             :   }
     841           0 :   binding_detail::FastErrorResult rv;
     842           0 :   JS::Rooted<JSObject*> result(cx);
     843           0 :   mozilla::dom::ThreadSafeChromeUtils::Base64URLDecode(global, Constify(arg0), Constify(arg1), &result, rv);
     844           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     845           0 :     return false;
     846             :   }
     847           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     848           0 :   JS::ExposeObjectToActiveJS(result);
     849           0 :   args.rval().setObject(*result);
     850           0 :   if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
     851           0 :     return false;
     852             :   }
     853           0 :   return true;
     854             : }
     855             : 
     856             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
     857             : #if defined(__clang__)
     858             : #pragma clang diagnostic push
     859             : #pragma clang diagnostic ignored "-Wmissing-braces"
     860             : #endif
     861             : static const JSFunctionSpec sStaticMethods_specs[] = {
     862             :   JS_FNSPEC("saveHeapSnapshot", saveHeapSnapshot, nullptr, 0, JSPROP_ENUMERATE, nullptr),
     863             :   JS_FNSPEC("saveHeapSnapshotGetId", saveHeapSnapshotGetId, nullptr, 0, JSPROP_ENUMERATE, nullptr),
     864             :   JS_FNSPEC("readHeapSnapshot", readHeapSnapshot, nullptr, 1, JSPROP_ENUMERATE, nullptr),
     865             :   JS_FNSPEC("nondeterministicGetWeakMapKeys", nondeterministicGetWeakMapKeys, nullptr, 1, JSPROP_ENUMERATE, nullptr),
     866             :   JS_FNSPEC("nondeterministicGetWeakSetKeys", nondeterministicGetWeakSetKeys, nullptr, 1, JSPROP_ENUMERATE, nullptr),
     867             :   JS_FNSPEC("base64URLEncode", base64URLEncode, nullptr, 2, JSPROP_ENUMERATE, nullptr),
     868             :   JS_FNSPEC("base64URLDecode", base64URLDecode, nullptr, 2, JSPROP_ENUMERATE, nullptr),
     869             :   JS_FS_END
     870             : };
     871             : #if defined(__clang__)
     872             : #pragma clang diagnostic pop
     873             : #endif
     874             : 
     875             : 
     876             : // Can't be const because the pref-enabled boolean needs to be writable
     877             : static Prefable<const JSFunctionSpec> sStaticMethods[] = {
     878             :   { nullptr, &sStaticMethods_specs[0] },
     879             :   { nullptr, nullptr }
     880             : };
     881             : 
     882             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
     883             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
     884             : static_assert(7 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
     885             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
     886             : 
     887             : 
     888             : static uint16_t sNativeProperties_sortedPropertyIndices[7];
     889             : static PropertyInfo sNativeProperties_propertyInfos[7];
     890             : 
     891             : static const NativePropertiesN<1> sNativeProperties = {
     892             :   true,  0 /* sStaticMethods */,
     893             :   false, 0,
     894             :   false, 0,
     895             :   false, 0,
     896             :   false, 0,
     897             :   false, 0,
     898             :   false, 0,
     899             :   -1,
     900             :   7,
     901             :   sNativeProperties_sortedPropertyIndices,
     902             :   {
     903             :     { sStaticMethods, &sNativeProperties_propertyInfos[0] }
     904             :   }
     905             : };
     906             : static_assert(7 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
     907             :     "We have a property info count that is oversized");
     908             : 
     909             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
     910             :   {
     911             :     "Function",
     912             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
     913             :     &sBoringInterfaceObjectClassClassOps,
     914             :     JS_NULL_CLASS_SPEC,
     915             :     JS_NULL_CLASS_EXT,
     916             :     &sInterfaceObjectClassObjectOps
     917             :   },
     918             :   eInterface,
     919             :   false,
     920             :   prototypes::id::_ID_Count,
     921             :   0,
     922             :   sNativePropertyHooks,
     923             :   "function ThreadSafeChromeUtils() {\n    [native code]\n}",
     924             :   JS::GetRealmFunctionPrototype
     925             : };
     926             : 
     927             : bool
     928           1 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
     929             : {
     930           1 :   return nsContentUtils::ThreadsafeIsSystemCaller(aCx);
     931             : }
     932             : 
     933             : JSObject*
     934           0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
     935             : {
     936           0 :   return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
     937             : }
     938             : 
     939             : const NativePropertyHooks sNativePropertyHooks[] = { {
     940             :   nullptr,
     941             :   nullptr,
     942             :   nullptr,
     943             :   { sNativeProperties.Upcast(), nullptr },
     944             :   prototypes::id::_ID_Count,
     945             :   constructors::id::ThreadSafeChromeUtils,
     946             :   nullptr,
     947             :   &DefaultXrayExpandoObjectClass
     948             : } };
     949             : 
     950             : void
     951           2 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
     952             : {
     953           4 :   JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
     954           2 :   if (!constructorProto) {
     955           0 :     return;
     956             :   }
     957             : 
     958             :   static bool sIdsInited = false;
     959           2 :   if (!sIdsInited && NS_IsMainThread()) {
     960           1 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
     961           0 :       return;
     962             :     }
     963           1 :     sIdsInited = true;
     964             :   }
     965             : 
     966           2 :   JS::Heap<JSObject*>* protoCache = nullptr;
     967           2 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::ThreadSafeChromeUtils);
     968           4 :   dom::CreateInterfaceObjects(aCx, aGlobal, nullptr,
     969             :                               nullptr, protoCache,
     970             :                               constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
     971             :                               interfaceCache,
     972             :                               sNativeProperties.Upcast(),
     973             :                               nullptr,
     974             :                               "ThreadSafeChromeUtils", aDefineOnGlobal,
     975             :                               nullptr,
     976           2 :                               false);
     977             : }
     978             : 
     979             : JS::Handle<JSObject*>
     980           2 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
     981             : {
     982             :   /* Get the interface object for this class.  This will create the object as
     983             :      needed. */
     984             : 
     985             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
     986           2 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
     987           2 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
     988           0 :     return nullptr;
     989             :   }
     990             : 
     991             :   /* Check to see whether the interface objects are already installed */
     992           2 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
     993           2 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::ThreadSafeChromeUtils)) {
     994           4 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
     995           2 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
     996             :   }
     997             : 
     998             :   /*
     999             :    * The object might _still_ be null, but that's OK.
    1000             :    *
    1001             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    1002             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    1003             :    * changed after they have been set.
    1004             :    *
    1005             :    * Calling address() avoids the read read barrier that does gray
    1006             :    * unmarking, but it's not possible for the object to be gray here.
    1007             :    */
    1008             : 
    1009           2 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::ThreadSafeChromeUtils);
    1010           2 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    1011           2 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    1012             : }
    1013             : 
    1014             : JSObject*
    1015           1 : GetConstructorObject(JSContext* aCx)
    1016             : {
    1017           1 :   return GetConstructorObjectHandle(aCx);
    1018             : }
    1019             : 
    1020             : } // namespace ThreadSafeChromeUtilsBinding
    1021             : 
    1022             : 
    1023             : 
    1024             : } // namespace dom
    1025             : } // namespace mozilla

Generated by: LCOV version 1.13