LCOV - code coverage report
Current view: top level - obj-x86_64-pc-linux-gnu/dom/bindings - ChromeUtilsBinding.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 127 536 23.7 %
Date: 2017-07-14 16:53:18 Functions: 11 35 31.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13