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

          Line data    Source code
       1             : /* THIS FILE IS AUTOGENERATED FROM WebExtensionContentScript.webidl BY Codegen.py - DO NOT EDIT */
       2             : 
       3             : #include "AtomList.h"
       4             : #include "WebExtensionContentScriptBinding.h"
       5             : #include "WrapperFactory.h"
       6             : #include "jsapi.h"
       7             : #include "mozilla/OwningNonNull.h"
       8             : #include "mozilla/dom/BindingUtils.h"
       9             : #include "mozilla/dom/DOMJSClass.h"
      10             : #include "mozilla/dom/NonRefcountedDOMObject.h"
      11             : #include "mozilla/dom/Nullable.h"
      12             : #include "mozilla/dom/PrimitiveConversions.h"
      13             : #include "mozilla/dom/ScriptSettings.h"
      14             : #include "mozilla/extensions/MatchGlob.h"
      15             : #include "mozilla/extensions/MatchPattern.h"
      16             : #include "mozilla/extensions/WebExtensionContentScript.h"
      17             : #include "mozilla/extensions/WebExtensionPolicy.h"
      18             : #include "nsContentUtils.h"
      19             : #include "nsILoadInfo.h"
      20             : #include "nsIURI.h"
      21             : #include "nsPIDOMWindow.h"
      22             : #include "nsThreadUtils.h"
      23             : 
      24             : namespace mozilla {
      25             : namespace dom {
      26             : 
      27             : namespace ContentScriptRunAtValues {
      28             : extern const EnumEntry strings[4] = {
      29             :   {"document_start", 14},
      30             :   {"document_end", 12},
      31             :   {"document_idle", 13},
      32             :   { nullptr, 0 }
      33             : };
      34             : } // namespace ContentScriptRunAtValues
      35             : 
      36             : bool
      37           0 : ToJSValue(JSContext* aCx, ContentScriptRunAt aArgument, JS::MutableHandle<JS::Value> aValue)
      38             : {
      39           0 :   MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(ContentScriptRunAtValues::strings));
      40             :   JSString* resultStr =
      41           0 :     JS_NewStringCopyN(aCx, ContentScriptRunAtValues::strings[uint32_t(aArgument)].value,
      42           0 :                       ContentScriptRunAtValues::strings[uint32_t(aArgument)].length);
      43           0 :   if (!resultStr) {
      44           0 :     return false;
      45             :   }
      46           0 :   aValue.setString(resultStr);
      47           0 :   return true;
      48             : }
      49             : 
      50             : 
      51             : 
      52           0 : WebExtensionContentScriptInit::WebExtensionContentScriptInit()
      53             : {
      54             :   // Safe to pass a null context if we pass a null value
      55           0 :   Init(nullptr, JS::NullHandleValue);
      56           0 : }
      57             : 
      58             : 
      59             : 
      60             : bool
      61           0 : WebExtensionContentScriptInit::InitIds(JSContext* cx, WebExtensionContentScriptInitAtoms* atomsCache)
      62             : {
      63           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
      64             : 
      65             :   // Initialize these in reverse order so that any failure leaves the first one
      66             :   // uninitialized.
      67           0 :   if (!atomsCache->runAt_id.init(cx, "runAt") ||
      68           0 :       !atomsCache->matches_id.init(cx, "matches") ||
      69           0 :       !atomsCache->matchAboutBlank_id.init(cx, "matchAboutBlank") ||
      70           0 :       !atomsCache->jsPaths_id.init(cx, "jsPaths") ||
      71           0 :       !atomsCache->includeGlobs_id.init(cx, "includeGlobs") ||
      72           0 :       !atomsCache->frameID_id.init(cx, "frameID") ||
      73           0 :       !atomsCache->excludeMatches_id.init(cx, "excludeMatches") ||
      74           0 :       !atomsCache->excludeGlobs_id.init(cx, "excludeGlobs") ||
      75           0 :       !atomsCache->cssPaths_id.init(cx, "cssPaths") ||
      76           0 :       !atomsCache->allFrames_id.init(cx, "allFrames")) {
      77           0 :     return false;
      78             :   }
      79           0 :   return true;
      80             : }
      81             : 
      82             : bool
      83           0 : WebExtensionContentScriptInit::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
      84             : {
      85             :   // Passing a null JSContext is OK only if we're initing from null,
      86             :   // Since in that case we will not have to do any property gets
      87             :   // Also evaluate isNullOrUndefined in order to avoid false-positive
      88             :   // checkers by static analysis tools
      89           0 :   MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
      90           0 :   WebExtensionContentScriptInitAtoms* atomsCache = nullptr;
      91           0 :   if (cx) {
      92           0 :     atomsCache = GetAtomCache<WebExtensionContentScriptInitAtoms>(cx);
      93           0 :     if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
      94           0 :       return false;
      95             :     }
      96             :   }
      97             : 
      98           0 :   if (!IsConvertibleToDictionary(val)) {
      99           0 :     return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
     100             :   }
     101             : 
     102           0 :   bool isNull = val.isNullOrUndefined();
     103             :   // We only need these if !isNull, in which case we have |cx|.
     104           0 :   Maybe<JS::Rooted<JSObject *> > object;
     105           0 :   Maybe<JS::Rooted<JS::Value> > temp;
     106           0 :   if (!isNull) {
     107           0 :     MOZ_ASSERT(cx);
     108           0 :     object.emplace(cx, &val.toObject());
     109           0 :     temp.emplace(cx);
     110             :   }
     111           0 :   if (!isNull) {
     112           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->allFrames_id, temp.ptr())) {
     113           0 :       return false;
     114             :     }
     115             :   }
     116           0 :   if (!isNull && !temp->isUndefined()) {
     117           0 :     if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mAllFrames)) {
     118           0 :       return false;
     119             :     }
     120             :   } else {
     121           0 :     mAllFrames = false;
     122             :   }
     123           0 :   mIsAnyMemberPresent = true;
     124             : 
     125           0 :   if (!isNull) {
     126           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->cssPaths_id, temp.ptr())) {
     127           0 :       return false;
     128             :     }
     129             :   }
     130           0 :   if (!isNull && !temp->isUndefined()) {
     131           0 :     if (temp.ref().isObject()) {
     132           0 :       JS::ForOfIterator iter(cx);
     133           0 :       if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
     134           0 :         return false;
     135             :       }
     136           0 :       if (!iter.valueIsIterable()) {
     137           0 :         ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'cssPaths' member of WebExtensionContentScriptInit");
     138           0 :         return false;
     139             :       }
     140           0 :       Sequence<nsString> &arr = mCssPaths;
     141           0 :       JS::Rooted<JS::Value> temp(cx);
     142             :       while (true) {
     143             :         bool done;
     144           0 :         if (!iter.next(&temp, &done)) {
     145           0 :           return false;
     146             :         }
     147           0 :         if (done) {
     148           0 :           break;
     149             :         }
     150           0 :         nsString* slotPtr = arr.AppendElement(mozilla::fallible);
     151           0 :         if (!slotPtr) {
     152           0 :           JS_ReportOutOfMemory(cx);
     153           0 :           return false;
     154             :         }
     155           0 :         nsString& slot = *slotPtr;
     156           0 :         if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
     157           0 :           return false;
     158             :         }
     159           0 :       }
     160             :     } else {
     161           0 :       ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'cssPaths' member of WebExtensionContentScriptInit");
     162           0 :       return false;
     163             :     }
     164             :   } else {
     165             :     /* Array is already empty; nothing to do */
     166             :   }
     167           0 :   mIsAnyMemberPresent = true;
     168             : 
     169           0 :   if (!isNull) {
     170           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->excludeGlobs_id, temp.ptr())) {
     171           0 :       return false;
     172             :     }
     173             :   }
     174           0 :   if (!isNull && !temp->isUndefined()) {
     175           0 :     if (temp.ref().isObject()) {
     176           0 :       JS::ForOfIterator iter(cx);
     177           0 :       if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
     178           0 :         return false;
     179             :       }
     180           0 :       if (!iter.valueIsIterable()) {
     181           0 :         ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'excludeGlobs' member of WebExtensionContentScriptInit");
     182           0 :         return false;
     183             :       }
     184           0 :       Sequence<OwningNonNull<mozilla::extensions::MatchGlob>> &arr = mExcludeGlobs.SetValue();
     185           0 :       JS::Rooted<JS::Value> temp(cx);
     186             :       while (true) {
     187             :         bool done;
     188           0 :         if (!iter.next(&temp, &done)) {
     189           0 :           return false;
     190             :         }
     191           0 :         if (done) {
     192           0 :           break;
     193             :         }
     194           0 :         OwningNonNull<mozilla::extensions::MatchGlob>* slotPtr = arr.AppendElement(mozilla::fallible);
     195           0 :         if (!slotPtr) {
     196           0 :           JS_ReportOutOfMemory(cx);
     197           0 :           return false;
     198             :         }
     199           0 :         OwningNonNull<mozilla::extensions::MatchGlob>& slot = *slotPtr;
     200           0 :         if (temp.isObject()) {
     201             :           static_assert(IsRefcounted<mozilla::extensions::MatchGlob>::value, "We can only store refcounted classes.");{
     202           0 :             nsresult rv = UnwrapObject<prototypes::id::MatchGlob, mozilla::extensions::MatchGlob>(&temp, slot);
     203           0 :             if (NS_FAILED(rv)) {
     204           0 :               ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Element of 'excludeGlobs' member of WebExtensionContentScriptInit", "MatchGlob");
     205           0 :               return false;
     206             :             }
     207             :           }
     208             :         } else {
     209           0 :           ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Element of 'excludeGlobs' member of WebExtensionContentScriptInit");
     210           0 :           return false;
     211             :         }
     212           0 :       }
     213           0 :     } else if (temp.ref().isNullOrUndefined()) {
     214           0 :       mExcludeGlobs.SetNull();
     215             :     } else {
     216           0 :       ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'excludeGlobs' member of WebExtensionContentScriptInit");
     217           0 :       return false;
     218             :     }
     219             :   } else {
     220           0 :     mExcludeGlobs.SetNull();
     221             :   }
     222           0 :   mIsAnyMemberPresent = true;
     223             : 
     224           0 :   if (!isNull) {
     225           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->excludeMatches_id, temp.ptr())) {
     226           0 :       return false;
     227             :     }
     228             :   }
     229           0 :   if (!isNull && !temp->isUndefined()) {
     230           0 :     if (temp.ref().isObject()) {
     231             :       static_assert(IsRefcounted<mozilla::extensions::MatchPatternSet>::value, "We can only store refcounted classes.");{
     232           0 :         nsresult rv = UnwrapObject<prototypes::id::MatchPatternSet, mozilla::extensions::MatchPatternSet>(temp.ptr(), mExcludeMatches);
     233           0 :         if (NS_FAILED(rv)) {
     234           0 :           ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "'excludeMatches' member of WebExtensionContentScriptInit", "MatchPatternSet");
     235           0 :           return false;
     236             :         }
     237             :       }
     238           0 :     } else if (temp.ref().isNullOrUndefined()) {
     239           0 :       mExcludeMatches = nullptr;
     240             :     } else {
     241           0 :       ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'excludeMatches' member of WebExtensionContentScriptInit");
     242           0 :       return false;
     243             :     }
     244             :   } else {
     245           0 :     mExcludeMatches = nullptr;
     246             :   }
     247           0 :   mIsAnyMemberPresent = true;
     248             : 
     249           0 :   if (!isNull) {
     250           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->frameID_id, temp.ptr())) {
     251           0 :       return false;
     252             :     }
     253             :   }
     254           0 :   if (!(!isNull && !temp->isUndefined()) || temp.ref().isNullOrUndefined()) {
     255           0 :     mFrameID.SetNull();
     256           0 :   } else if (!ValueToPrimitive<uint64_t, eDefault>(cx, temp.ref(), &mFrameID.SetValue())) {
     257           0 :     return false;
     258             :   }
     259           0 :   mIsAnyMemberPresent = true;
     260             : 
     261           0 :   if (!isNull) {
     262           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->includeGlobs_id, temp.ptr())) {
     263           0 :       return false;
     264             :     }
     265             :   }
     266           0 :   if (!isNull && !temp->isUndefined()) {
     267           0 :     if (temp.ref().isObject()) {
     268           0 :       JS::ForOfIterator iter(cx);
     269           0 :       if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
     270           0 :         return false;
     271             :       }
     272           0 :       if (!iter.valueIsIterable()) {
     273           0 :         ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'includeGlobs' member of WebExtensionContentScriptInit");
     274           0 :         return false;
     275             :       }
     276           0 :       Sequence<OwningNonNull<mozilla::extensions::MatchGlob>> &arr = mIncludeGlobs.SetValue();
     277           0 :       JS::Rooted<JS::Value> temp(cx);
     278             :       while (true) {
     279             :         bool done;
     280           0 :         if (!iter.next(&temp, &done)) {
     281           0 :           return false;
     282             :         }
     283           0 :         if (done) {
     284           0 :           break;
     285             :         }
     286           0 :         OwningNonNull<mozilla::extensions::MatchGlob>* slotPtr = arr.AppendElement(mozilla::fallible);
     287           0 :         if (!slotPtr) {
     288           0 :           JS_ReportOutOfMemory(cx);
     289           0 :           return false;
     290             :         }
     291           0 :         OwningNonNull<mozilla::extensions::MatchGlob>& slot = *slotPtr;
     292           0 :         if (temp.isObject()) {
     293             :           static_assert(IsRefcounted<mozilla::extensions::MatchGlob>::value, "We can only store refcounted classes.");{
     294           0 :             nsresult rv = UnwrapObject<prototypes::id::MatchGlob, mozilla::extensions::MatchGlob>(&temp, slot);
     295           0 :             if (NS_FAILED(rv)) {
     296           0 :               ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Element of 'includeGlobs' member of WebExtensionContentScriptInit", "MatchGlob");
     297           0 :               return false;
     298             :             }
     299             :           }
     300             :         } else {
     301           0 :           ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Element of 'includeGlobs' member of WebExtensionContentScriptInit");
     302           0 :           return false;
     303             :         }
     304           0 :       }
     305           0 :     } else if (temp.ref().isNullOrUndefined()) {
     306           0 :       mIncludeGlobs.SetNull();
     307             :     } else {
     308           0 :       ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'includeGlobs' member of WebExtensionContentScriptInit");
     309           0 :       return false;
     310             :     }
     311             :   } else {
     312           0 :     mIncludeGlobs.SetNull();
     313             :   }
     314           0 :   mIsAnyMemberPresent = true;
     315             : 
     316           0 :   if (!isNull) {
     317           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->jsPaths_id, temp.ptr())) {
     318           0 :       return false;
     319             :     }
     320             :   }
     321           0 :   if (!isNull && !temp->isUndefined()) {
     322           0 :     if (temp.ref().isObject()) {
     323           0 :       JS::ForOfIterator iter(cx);
     324           0 :       if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
     325           0 :         return false;
     326             :       }
     327           0 :       if (!iter.valueIsIterable()) {
     328           0 :         ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'jsPaths' member of WebExtensionContentScriptInit");
     329           0 :         return false;
     330             :       }
     331           0 :       Sequence<nsString> &arr = mJsPaths;
     332           0 :       JS::Rooted<JS::Value> temp(cx);
     333             :       while (true) {
     334             :         bool done;
     335           0 :         if (!iter.next(&temp, &done)) {
     336           0 :           return false;
     337             :         }
     338           0 :         if (done) {
     339           0 :           break;
     340             :         }
     341           0 :         nsString* slotPtr = arr.AppendElement(mozilla::fallible);
     342           0 :         if (!slotPtr) {
     343           0 :           JS_ReportOutOfMemory(cx);
     344           0 :           return false;
     345             :         }
     346           0 :         nsString& slot = *slotPtr;
     347           0 :         if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
     348           0 :           return false;
     349             :         }
     350           0 :       }
     351             :     } else {
     352           0 :       ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'jsPaths' member of WebExtensionContentScriptInit");
     353           0 :       return false;
     354             :     }
     355             :   } else {
     356             :     /* Array is already empty; nothing to do */
     357             :   }
     358           0 :   mIsAnyMemberPresent = true;
     359             : 
     360           0 :   if (!isNull) {
     361           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->matchAboutBlank_id, temp.ptr())) {
     362           0 :       return false;
     363             :     }
     364             :   }
     365           0 :   if (!isNull && !temp->isUndefined()) {
     366           0 :     if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mMatchAboutBlank)) {
     367           0 :       return false;
     368             :     }
     369             :   } else {
     370           0 :     mMatchAboutBlank = false;
     371             :   }
     372           0 :   mIsAnyMemberPresent = true;
     373             : 
     374           0 :   if (!isNull) {
     375           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->matches_id, temp.ptr())) {
     376           0 :       return false;
     377             :     }
     378             :   }
     379           0 :   if (!isNull && !temp->isUndefined()) {
     380           0 :     if (temp.ref().isObject()) {
     381             :       static_assert(IsRefcounted<mozilla::extensions::MatchPatternSet>::value, "We can only store refcounted classes.");{
     382           0 :         nsresult rv = UnwrapObject<prototypes::id::MatchPatternSet, mozilla::extensions::MatchPatternSet>(temp.ptr(), mMatches);
     383           0 :         if (NS_FAILED(rv)) {
     384           0 :           ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "'matches' member of WebExtensionContentScriptInit", "MatchPatternSet");
     385           0 :           return false;
     386             :         }
     387             :       }
     388             :     } else {
     389           0 :       ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'matches' member of WebExtensionContentScriptInit");
     390           0 :       return false;
     391             :     }
     392           0 :     mIsAnyMemberPresent = true;
     393           0 :   } else if (cx) {
     394             :     // Don't error out if we have no cx.  In that
     395             :     // situation the caller is default-constructing us and we'll
     396             :     // just assume they know what they're doing.
     397           0 :     return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
     398           0 :                              "'matches' member of WebExtensionContentScriptInit");
     399             :   }
     400             : 
     401           0 :   if (!isNull) {
     402           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->runAt_id, temp.ptr())) {
     403           0 :       return false;
     404             :     }
     405             :   }
     406           0 :   if (!isNull && !temp->isUndefined()) {
     407             :     {
     408             :       int index;
     409           0 :       if (!FindEnumStringIndex<true>(cx, temp.ref(), ContentScriptRunAtValues::strings, "ContentScriptRunAt", "'runAt' member of WebExtensionContentScriptInit", &index)) {
     410           0 :         return false;
     411             :       }
     412           0 :       MOZ_ASSERT(index >= 0);
     413           0 :       mRunAt = static_cast<ContentScriptRunAt>(index);
     414             :     }
     415             :   } else {
     416           0 :     mRunAt = ContentScriptRunAt::Document_idle;
     417             :   }
     418           0 :   mIsAnyMemberPresent = true;
     419           0 :   return true;
     420             : }
     421             : 
     422             : bool
     423           0 : WebExtensionContentScriptInit::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
     424             : {
     425           0 :   WebExtensionContentScriptInitAtoms* atomsCache = GetAtomCache<WebExtensionContentScriptInitAtoms>(cx);
     426           0 :   if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     427           0 :     return false;
     428             :   }
     429             : 
     430           0 :   JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
     431           0 :   if (!obj) {
     432           0 :     return false;
     433             :   }
     434           0 :   rval.set(JS::ObjectValue(*obj));
     435             : 
     436             :   do {
     437             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     438           0 :     JS::Rooted<JS::Value> temp(cx);
     439           0 :     bool const & currentValue = mAllFrames;
     440           0 :     temp.setBoolean(currentValue);
     441           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->allFrames_id, temp, JSPROP_ENUMERATE)) {
     442           0 :       return false;
     443             :     }
     444           0 :     break;
     445             :   } while(0);
     446             : 
     447             :   do {
     448             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     449           0 :     JS::Rooted<JS::Value> temp(cx);
     450           0 :     Sequence<nsString> const & currentValue = mCssPaths;
     451             : 
     452           0 :     uint32_t length = currentValue.Length();
     453           0 :     JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
     454           0 :     if (!returnArray) {
     455           0 :       return false;
     456             :     }
     457             :     // Scope for 'tmp'
     458             :     {
     459           0 :       JS::Rooted<JS::Value> tmp(cx);
     460           0 :       for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
     461             :         // Control block to let us common up the JS_DefineElement calls when there
     462             :         // are different ways to succeed at wrapping the object.
     463             :         do {
     464           0 :           if (!xpc::NonVoidStringToJsval(cx, currentValue[sequenceIdx0], &tmp)) {
     465           0 :             return false;
     466             :           }
     467           0 :           break;
     468             :         } while (0);
     469           0 :         if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
     470             :                               JSPROP_ENUMERATE)) {
     471           0 :           return false;
     472             :         }
     473             :       }
     474             :     }
     475           0 :     temp.setObject(*returnArray);
     476           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->cssPaths_id, temp, JSPROP_ENUMERATE)) {
     477           0 :       return false;
     478             :     }
     479           0 :     break;
     480             :   } while(0);
     481             : 
     482             :   do {
     483             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     484           0 :     JS::Rooted<JS::Value> temp(cx);
     485           0 :     Nullable<Sequence<OwningNonNull<mozilla::extensions::MatchGlob>>> const & currentValue = mExcludeGlobs;
     486             : 
     487           0 :     if (currentValue.IsNull()) {
     488           0 :       temp.setNull();
     489           0 :       if (!JS_DefinePropertyById(cx, obj, atomsCache->excludeGlobs_id, temp, JSPROP_ENUMERATE)) {
     490           0 :         return false;
     491             :       }
     492           0 :       break;
     493             :     }
     494             : 
     495           0 :     uint32_t length = currentValue.Value().Length();
     496           0 :     JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
     497           0 :     if (!returnArray) {
     498           0 :       return false;
     499             :     }
     500             :     // Scope for 'tmp'
     501             :     {
     502           0 :       JS::Rooted<JS::Value> tmp(cx);
     503           0 :       for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
     504             :         // Control block to let us common up the JS_DefineElement calls when there
     505             :         // are different ways to succeed at wrapping the object.
     506             :         do {
     507           0 :           if (!GetOrCreateDOMReflector(cx, currentValue.Value()[sequenceIdx0], &tmp)) {
     508           0 :             MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     509           0 :             return false;
     510             :           }
     511           0 :           break;
     512             :         } while (0);
     513           0 :         if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
     514             :                               JSPROP_ENUMERATE)) {
     515           0 :           return false;
     516             :         }
     517             :       }
     518             :     }
     519           0 :     temp.setObject(*returnArray);
     520           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->excludeGlobs_id, temp, JSPROP_ENUMERATE)) {
     521           0 :       return false;
     522             :     }
     523           0 :     break;
     524             :   } while(0);
     525             : 
     526             :   do {
     527             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     528           0 :     JS::Rooted<JS::Value> temp(cx);
     529           0 :     RefPtr<mozilla::extensions::MatchPatternSet> const & currentValue = mExcludeMatches;
     530           0 :     if (!currentValue) {
     531           0 :       temp.setNull();
     532           0 :       if (!JS_DefinePropertyById(cx, obj, atomsCache->excludeMatches_id, temp, JSPROP_ENUMERATE)) {
     533           0 :         return false;
     534             :       }
     535           0 :       break;
     536             :     }
     537           0 :     if (!GetOrCreateDOMReflector(cx, currentValue, &temp)) {
     538           0 :       MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     539           0 :       return false;
     540             :     }
     541           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->excludeMatches_id, temp, JSPROP_ENUMERATE)) {
     542           0 :       return false;
     543             :     }
     544           0 :     break;
     545             :   } while(0);
     546             : 
     547             :   do {
     548             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     549           0 :     JS::Rooted<JS::Value> temp(cx);
     550           0 :     Nullable<uint64_t> const & currentValue = mFrameID;
     551           0 :     if (currentValue.IsNull()) {
     552           0 :       temp.setNull();
     553           0 :       if (!JS_DefinePropertyById(cx, obj, atomsCache->frameID_id, temp, JSPROP_ENUMERATE)) {
     554           0 :         return false;
     555             :       }
     556           0 :       break;
     557             :     }
     558           0 :     temp.set(JS_NumberValue(double(currentValue.Value())));
     559           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->frameID_id, temp, JSPROP_ENUMERATE)) {
     560           0 :       return false;
     561             :     }
     562           0 :     break;
     563             :   } while(0);
     564             : 
     565             :   do {
     566             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     567           0 :     JS::Rooted<JS::Value> temp(cx);
     568           0 :     Nullable<Sequence<OwningNonNull<mozilla::extensions::MatchGlob>>> const & currentValue = mIncludeGlobs;
     569             : 
     570           0 :     if (currentValue.IsNull()) {
     571           0 :       temp.setNull();
     572           0 :       if (!JS_DefinePropertyById(cx, obj, atomsCache->includeGlobs_id, temp, JSPROP_ENUMERATE)) {
     573           0 :         return false;
     574             :       }
     575           0 :       break;
     576             :     }
     577             : 
     578           0 :     uint32_t length = currentValue.Value().Length();
     579           0 :     JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
     580           0 :     if (!returnArray) {
     581           0 :       return false;
     582             :     }
     583             :     // Scope for 'tmp'
     584             :     {
     585           0 :       JS::Rooted<JS::Value> tmp(cx);
     586           0 :       for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
     587             :         // Control block to let us common up the JS_DefineElement calls when there
     588             :         // are different ways to succeed at wrapping the object.
     589             :         do {
     590           0 :           if (!GetOrCreateDOMReflector(cx, currentValue.Value()[sequenceIdx0], &tmp)) {
     591           0 :             MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     592           0 :             return false;
     593             :           }
     594           0 :           break;
     595             :         } while (0);
     596           0 :         if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
     597             :                               JSPROP_ENUMERATE)) {
     598           0 :           return false;
     599             :         }
     600             :       }
     601             :     }
     602           0 :     temp.setObject(*returnArray);
     603           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->includeGlobs_id, temp, JSPROP_ENUMERATE)) {
     604           0 :       return false;
     605             :     }
     606           0 :     break;
     607             :   } while(0);
     608             : 
     609             :   do {
     610             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     611           0 :     JS::Rooted<JS::Value> temp(cx);
     612           0 :     Sequence<nsString> const & currentValue = mJsPaths;
     613             : 
     614           0 :     uint32_t length = currentValue.Length();
     615           0 :     JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
     616           0 :     if (!returnArray) {
     617           0 :       return false;
     618             :     }
     619             :     // Scope for 'tmp'
     620             :     {
     621           0 :       JS::Rooted<JS::Value> tmp(cx);
     622           0 :       for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
     623             :         // Control block to let us common up the JS_DefineElement calls when there
     624             :         // are different ways to succeed at wrapping the object.
     625             :         do {
     626           0 :           if (!xpc::NonVoidStringToJsval(cx, currentValue[sequenceIdx0], &tmp)) {
     627           0 :             return false;
     628             :           }
     629           0 :           break;
     630             :         } while (0);
     631           0 :         if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
     632             :                               JSPROP_ENUMERATE)) {
     633           0 :           return false;
     634             :         }
     635             :       }
     636             :     }
     637           0 :     temp.setObject(*returnArray);
     638           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->jsPaths_id, temp, JSPROP_ENUMERATE)) {
     639           0 :       return false;
     640             :     }
     641           0 :     break;
     642             :   } while(0);
     643             : 
     644             :   do {
     645             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     646           0 :     JS::Rooted<JS::Value> temp(cx);
     647           0 :     bool const & currentValue = mMatchAboutBlank;
     648           0 :     temp.setBoolean(currentValue);
     649           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->matchAboutBlank_id, temp, JSPROP_ENUMERATE)) {
     650           0 :       return false;
     651             :     }
     652           0 :     break;
     653             :   } while(0);
     654             : 
     655             :   do {
     656             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     657           0 :     JS::Rooted<JS::Value> temp(cx);
     658           0 :     OwningNonNull<mozilla::extensions::MatchPatternSet> const & currentValue = mMatches;
     659           0 :     if (!GetOrCreateDOMReflector(cx, currentValue, &temp)) {
     660           0 :       MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     661           0 :       return false;
     662             :     }
     663           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->matches_id, temp, JSPROP_ENUMERATE)) {
     664           0 :       return false;
     665             :     }
     666           0 :     break;
     667             :   } while(0);
     668             : 
     669             :   do {
     670             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     671           0 :     JS::Rooted<JS::Value> temp(cx);
     672           0 :     ContentScriptRunAt const & currentValue = mRunAt;
     673           0 :     if (!ToJSValue(cx, currentValue, &temp)) {
     674           0 :       return false;
     675             :     }
     676           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->runAt_id, temp, JSPROP_ENUMERATE)) {
     677           0 :       return false;
     678             :     }
     679           0 :     break;
     680             :   } while(0);
     681             : 
     682           0 :   return true;
     683             : }
     684             : 
     685             : void
     686           0 : WebExtensionContentScriptInit::TraceDictionary(JSTracer* trc)
     687             : {
     688           0 : }
     689             : 
     690             : WebExtensionContentScriptInit&
     691           0 : WebExtensionContentScriptInit::operator=(const WebExtensionContentScriptInit& aOther)
     692             : {
     693           0 :   mAllFrames = aOther.mAllFrames;
     694           0 :   mCssPaths = aOther.mCssPaths;
     695           0 :   mExcludeGlobs = aOther.mExcludeGlobs;
     696           0 :   mExcludeMatches = aOther.mExcludeMatches;
     697           0 :   mFrameID = aOther.mFrameID;
     698           0 :   mIncludeGlobs = aOther.mIncludeGlobs;
     699           0 :   mJsPaths = aOther.mJsPaths;
     700           0 :   mMatchAboutBlank = aOther.mMatchAboutBlank;
     701           0 :   mMatches = aOther.mMatches;
     702           0 :   mRunAt = aOther.mRunAt;
     703           0 :   return *this;
     704             : }
     705             : 
     706             : namespace binding_detail {
     707             : } // namespace binding_detail
     708             : 
     709             : 
     710             : namespace WebExtensionContentScriptBinding {
     711             : 
     712             : static bool
     713           0 : matchesURI(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionContentScript* self, const JSJitMethodCallArgs& args)
     714             : {
     715           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
     716           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "WebExtensionContentScript.matchesURI");
     717             :   }
     718             :   nsIURI* arg0;
     719           0 :   RefPtr<nsIURI> arg0_holder;
     720           0 :   if (args[0].isObject()) {
     721           0 :     JS::Rooted<JSObject*> source(cx, &args[0].toObject());
     722           0 :     if (NS_FAILED(UnwrapArg<nsIURI>(cx, source, getter_AddRefs(arg0_holder)))) {
     723           0 :       ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of WebExtensionContentScript.matchesURI", "URI");
     724           0 :       return false;
     725             :     }
     726           0 :     MOZ_ASSERT(arg0_holder);
     727           0 :     arg0 = arg0_holder;
     728             :   } else {
     729           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of WebExtensionContentScript.matchesURI");
     730           0 :     return false;
     731             :   }
     732           0 :   bool result(self->MatchesURI(NonNullHelper(arg0)));
     733           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     734           0 :   args.rval().setBoolean(result);
     735           0 :   return true;
     736             : }
     737             : 
     738             : static const JSJitInfo matchesURI_methodinfo = {
     739             :   { (JSJitGetterOp)matchesURI },
     740             :   { prototypes::id::WebExtensionContentScript },
     741             :   { PrototypeTraits<prototypes::id::WebExtensionContentScript>::Depth },
     742             :   JSJitInfo::Method,
     743             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     744             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
     745             :   false,  /* isInfallible. False in setters. */
     746             :   false,  /* isMovable.  Not relevant for setters. */
     747             :   false, /* isEliminatable.  Not relevant for setters. */
     748             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     749             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     750             :   false,  /* isTypedMethod.  Only relevant for methods. */
     751             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     752             : };
     753             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     754             : static_assert(0 < 5, "There is no slot for us");
     755             : 
     756             : static bool
     757           0 : matchesLoadInfo(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionContentScript* self, const JSJitMethodCallArgs& args)
     758             : {
     759           0 :   if (MOZ_UNLIKELY(args.length() < 2)) {
     760           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "WebExtensionContentScript.matchesLoadInfo");
     761             :   }
     762             :   nsIURI* arg0;
     763           0 :   RefPtr<nsIURI> arg0_holder;
     764           0 :   if (args[0].isObject()) {
     765           0 :     JS::Rooted<JSObject*> source(cx, &args[0].toObject());
     766           0 :     if (NS_FAILED(UnwrapArg<nsIURI>(cx, source, getter_AddRefs(arg0_holder)))) {
     767           0 :       ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of WebExtensionContentScript.matchesLoadInfo", "URI");
     768           0 :       return false;
     769             :     }
     770           0 :     MOZ_ASSERT(arg0_holder);
     771           0 :     arg0 = arg0_holder;
     772             :   } else {
     773           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of WebExtensionContentScript.matchesLoadInfo");
     774           0 :     return false;
     775             :   }
     776             :   nsILoadInfo* arg1;
     777           0 :   RefPtr<nsILoadInfo> arg1_holder;
     778           0 :   if (args[1].isObject()) {
     779           0 :     JS::Rooted<JSObject*> source(cx, &args[1].toObject());
     780           0 :     if (NS_FAILED(UnwrapArg<nsILoadInfo>(cx, source, getter_AddRefs(arg1_holder)))) {
     781           0 :       ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 2 of WebExtensionContentScript.matchesLoadInfo", "LoadInfo");
     782           0 :       return false;
     783             :     }
     784           0 :     MOZ_ASSERT(arg1_holder);
     785           0 :     arg1 = arg1_holder;
     786             :   } else {
     787           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of WebExtensionContentScript.matchesLoadInfo");
     788           0 :     return false;
     789             :   }
     790           0 :   bool result(self->MatchesLoadInfo(NonNullHelper(arg0), NonNullHelper(arg1)));
     791           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     792           0 :   args.rval().setBoolean(result);
     793           0 :   return true;
     794             : }
     795             : 
     796             : static const JSJitInfo matchesLoadInfo_methodinfo = {
     797             :   { (JSJitGetterOp)matchesLoadInfo },
     798             :   { prototypes::id::WebExtensionContentScript },
     799             :   { PrototypeTraits<prototypes::id::WebExtensionContentScript>::Depth },
     800             :   JSJitInfo::Method,
     801             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     802             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
     803             :   false,  /* isInfallible. False in setters. */
     804             :   false,  /* isMovable.  Not relevant for setters. */
     805             :   false, /* isEliminatable.  Not relevant for setters. */
     806             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     807             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     808             :   false,  /* isTypedMethod.  Only relevant for methods. */
     809             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     810             : };
     811             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     812             : static_assert(0 < 5, "There is no slot for us");
     813             : 
     814             : static bool
     815           0 : matchesWindow(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionContentScript* self, const JSJitMethodCallArgs& args)
     816             : {
     817           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
     818           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "WebExtensionContentScript.matchesWindow");
     819             :   }
     820             :   nsPIDOMWindowOuter* arg0;
     821           0 :   RefPtr<nsPIDOMWindowOuter> arg0_holder;
     822           0 :   if (args[0].isObject()) {
     823           0 :     JS::Rooted<JSObject*> source(cx, &args[0].toObject());
     824           0 :     if (NS_FAILED(UnwrapArg<nsPIDOMWindowOuter>(cx, source, getter_AddRefs(arg0_holder)))) {
     825           0 :       ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of WebExtensionContentScript.matchesWindow", "WindowProxy");
     826           0 :       return false;
     827             :     }
     828           0 :     MOZ_ASSERT(arg0_holder);
     829           0 :     arg0 = arg0_holder;
     830             :   } else {
     831           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of WebExtensionContentScript.matchesWindow");
     832           0 :     return false;
     833             :   }
     834           0 :   bool result(self->MatchesWindow(NonNullHelper(arg0)));
     835           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     836           0 :   args.rval().setBoolean(result);
     837           0 :   return true;
     838             : }
     839             : 
     840             : static const JSJitInfo matchesWindow_methodinfo = {
     841             :   { (JSJitGetterOp)matchesWindow },
     842             :   { prototypes::id::WebExtensionContentScript },
     843             :   { PrototypeTraits<prototypes::id::WebExtensionContentScript>::Depth },
     844             :   JSJitInfo::Method,
     845             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     846             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
     847             :   false,  /* isInfallible. False in setters. */
     848             :   false,  /* isMovable.  Not relevant for setters. */
     849             :   false, /* isEliminatable.  Not relevant for setters. */
     850             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     851             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     852             :   false,  /* isTypedMethod.  Only relevant for methods. */
     853             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     854             : };
     855             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     856             : static_assert(0 < 5, "There is no slot for us");
     857             : 
     858             : static bool
     859           0 : get_extension(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionContentScript* self, JSJitGetterCallArgs args)
     860             : {
     861           0 :   auto result(StrongOrRawPtr<mozilla::extensions::WebExtensionPolicy>(self->Extension()));
     862           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     863           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
     864           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     865           0 :     return false;
     866             :   }
     867           0 :   return true;
     868             : }
     869             : 
     870             : static const JSJitInfo extension_getterinfo = {
     871             :   { (JSJitGetterOp)get_extension },
     872             :   { prototypes::id::WebExtensionContentScript },
     873             :   { PrototypeTraits<prototypes::id::WebExtensionContentScript>::Depth },
     874             :   JSJitInfo::Getter,
     875             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
     876             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     877             :   false,  /* isInfallible. False in setters. */
     878             :   true,  /* isMovable.  Not relevant for setters. */
     879             :   true, /* isEliminatable.  Not relevant for setters. */
     880             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     881             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     882             :   false,  /* isTypedMethod.  Only relevant for methods. */
     883             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     884             : };
     885             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     886             : static_assert(0 < 5, "There is no slot for us");
     887             : 
     888             : static bool
     889           0 : get_allFrames(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionContentScript* self, JSJitGetterCallArgs args)
     890             : {
     891           0 :   bool result(self->AllFrames());
     892           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     893           0 :   args.rval().setBoolean(result);
     894           0 :   return true;
     895             : }
     896             : 
     897             : static const JSJitInfo allFrames_getterinfo = {
     898             :   { (JSJitGetterOp)get_allFrames },
     899             :   { prototypes::id::WebExtensionContentScript },
     900             :   { PrototypeTraits<prototypes::id::WebExtensionContentScript>::Depth },
     901             :   JSJitInfo::Getter,
     902             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
     903             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
     904             :   true,  /* isInfallible. False in setters. */
     905             :   true,  /* isMovable.  Not relevant for setters. */
     906             :   true, /* isEliminatable.  Not relevant for setters. */
     907             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     908             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     909             :   false,  /* isTypedMethod.  Only relevant for methods. */
     910             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     911             : };
     912             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     913             : static_assert(0 < 5, "There is no slot for us");
     914             : 
     915             : static bool
     916           0 : get_matchAboutBlank(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionContentScript* self, JSJitGetterCallArgs args)
     917             : {
     918           0 :   bool result(self->MatchAboutBlank());
     919           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     920           0 :   args.rval().setBoolean(result);
     921           0 :   return true;
     922             : }
     923             : 
     924             : static const JSJitInfo matchAboutBlank_getterinfo = {
     925             :   { (JSJitGetterOp)get_matchAboutBlank },
     926             :   { prototypes::id::WebExtensionContentScript },
     927             :   { PrototypeTraits<prototypes::id::WebExtensionContentScript>::Depth },
     928             :   JSJitInfo::Getter,
     929             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
     930             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
     931             :   true,  /* isInfallible. False in setters. */
     932             :   true,  /* isMovable.  Not relevant for setters. */
     933             :   true, /* isEliminatable.  Not relevant for setters. */
     934             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     935             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     936             :   false,  /* isTypedMethod.  Only relevant for methods. */
     937             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     938             : };
     939             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     940             : static_assert(0 < 5, "There is no slot for us");
     941             : 
     942             : static bool
     943           0 : get_runAt(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionContentScript* self, JSJitGetterCallArgs args)
     944             : {
     945           0 :   ContentScriptRunAt result(self->RunAt());
     946           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     947           0 :   if (!ToJSValue(cx, result, args.rval())) {
     948           0 :     return false;
     949             :   }
     950           0 :   return true;
     951             : }
     952             : 
     953             : static const JSJitInfo runAt_getterinfo = {
     954             :   { (JSJitGetterOp)get_runAt },
     955             :   { prototypes::id::WebExtensionContentScript },
     956             :   { PrototypeTraits<prototypes::id::WebExtensionContentScript>::Depth },
     957             :   JSJitInfo::Getter,
     958             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
     959             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
     960             :   false,  /* isInfallible. False in setters. */
     961             :   true,  /* isMovable.  Not relevant for setters. */
     962             :   true, /* isEliminatable.  Not relevant for setters. */
     963             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     964             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     965             :   false,  /* isTypedMethod.  Only relevant for methods. */
     966             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     967             : };
     968             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     969             : static_assert(0 < 5, "There is no slot for us");
     970             : 
     971             : static bool
     972           0 : get_frameID(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionContentScript* self, JSJitGetterCallArgs args)
     973             : {
     974           0 :   Nullable<uint64_t> result(self->GetFrameID());
     975           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     976           0 :   if (result.IsNull()) {
     977           0 :     args.rval().setNull();
     978           0 :     return true;
     979             :   }
     980           0 :   args.rval().set(JS_NumberValue(double(result.Value())));
     981           0 :   return true;
     982             : }
     983             : 
     984             : static const JSJitInfo frameID_getterinfo = {
     985             :   { (JSJitGetterOp)get_frameID },
     986             :   { prototypes::id::WebExtensionContentScript },
     987             :   { PrototypeTraits<prototypes::id::WebExtensionContentScript>::Depth },
     988             :   JSJitInfo::Getter,
     989             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
     990             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
     991             :   true,  /* isInfallible. False in setters. */
     992             :   true,  /* isMovable.  Not relevant for setters. */
     993             :   true, /* isEliminatable.  Not relevant for setters. */
     994             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     995             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     996             :   false,  /* isTypedMethod.  Only relevant for methods. */
     997             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     998             : };
     999             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1000             : static_assert(0 < 5, "There is no slot for us");
    1001             : 
    1002             : static bool
    1003           0 : get_matches(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionContentScript* self, JSJitGetterCallArgs args)
    1004             : {
    1005           0 :   auto result(StrongOrRawPtr<mozilla::extensions::MatchPatternSet>(self->Matches()));
    1006           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1007           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    1008           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1009           0 :     return false;
    1010             :   }
    1011           0 :   return true;
    1012             : }
    1013             : 
    1014             : static const JSJitInfo matches_getterinfo = {
    1015             :   { (JSJitGetterOp)get_matches },
    1016             :   { prototypes::id::WebExtensionContentScript },
    1017             :   { PrototypeTraits<prototypes::id::WebExtensionContentScript>::Depth },
    1018             :   JSJitInfo::Getter,
    1019             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    1020             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1021             :   false,  /* isInfallible. False in setters. */
    1022             :   true,  /* isMovable.  Not relevant for setters. */
    1023             :   true, /* isEliminatable.  Not relevant for setters. */
    1024             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1025             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1026             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1027             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1028             : };
    1029             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1030             : static_assert(0 < 5, "There is no slot for us");
    1031             : 
    1032             : static bool
    1033           0 : get_excludeMatches(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionContentScript* self, JSJitGetterCallArgs args)
    1034             : {
    1035           0 :   auto result(StrongOrRawPtr<mozilla::extensions::MatchPatternSet>(self->GetExcludeMatches()));
    1036           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1037           0 :   if (!result) {
    1038           0 :     args.rval().setNull();
    1039           0 :     return true;
    1040             :   }
    1041           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    1042           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1043           0 :     return false;
    1044             :   }
    1045           0 :   return true;
    1046             : }
    1047             : 
    1048             : static const JSJitInfo excludeMatches_getterinfo = {
    1049             :   { (JSJitGetterOp)get_excludeMatches },
    1050             :   { prototypes::id::WebExtensionContentScript },
    1051             :   { PrototypeTraits<prototypes::id::WebExtensionContentScript>::Depth },
    1052             :   JSJitInfo::Getter,
    1053             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    1054             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    1055             :   false,  /* isInfallible. False in setters. */
    1056             :   true,  /* isMovable.  Not relevant for setters. */
    1057             :   true, /* isEliminatable.  Not relevant for setters. */
    1058             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1059             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1060             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1061             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1062             : };
    1063             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1064             : static_assert(0 < 5, "There is no slot for us");
    1065             : 
    1066             : static bool
    1067           0 : get_includeGlobs(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionContentScript* self, JSJitGetterCallArgs args)
    1068             : {
    1069             :   // Have to either root across the getter call or reget after.
    1070           0 :   JS::Rooted<JSObject*> slotStorage(cx, js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false));
    1071           0 :   MOZ_ASSERT(IsDOMObject(slotStorage));
    1072           0 :   const size_t slotIndex = (DOM_INSTANCE_RESERVED_SLOTS + 0);
    1073           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    1074             :   {
    1075             :     // Scope for cachedVal
    1076           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    1077           0 :     if (!cachedVal.isUndefined()) {
    1078           0 :       args.rval().set(cachedVal);
    1079             :       // The cached value is in the compartment of slotStorage,
    1080             :       // so wrap into the caller compartment as needed.
    1081           0 :       return MaybeWrapNonDOMObjectOrNullValue(cx, args.rval());
    1082             :     }
    1083             :   }
    1084             : 
    1085           0 :   Nullable<nsTArray<StrongPtrForMember<mozilla::extensions::MatchGlob>::Type>> result;
    1086           0 :   self->GetIncludeGlobs(result);
    1087           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1088             :   {
    1089           0 :     JS::Rooted<JSObject*> conversionScope(cx, slotStorage);
    1090           0 :     JSAutoCompartment ac(cx, conversionScope);
    1091             :     do { // block we break out of when done wrapping
    1092             : 
    1093           0 :       if (result.IsNull()) {
    1094           0 :         args.rval().setNull();
    1095           0 :         break;
    1096             :       }
    1097             : 
    1098           0 :       uint32_t length = result.Value().Length();
    1099           0 :       JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
    1100           0 :       if (!returnArray) {
    1101           0 :         return false;
    1102             :       }
    1103             :       // Scope for 'tmp'
    1104             :       {
    1105           0 :         JS::Rooted<JS::Value> tmp(cx);
    1106           0 :         for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
    1107             :           // Control block to let us common up the JS_DefineElement calls when there
    1108             :           // are different ways to succeed at wrapping the object.
    1109             :           do {
    1110           0 :             if (!GetOrCreateDOMReflector(cx, result.Value()[sequenceIdx0], &tmp)) {
    1111           0 :               MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1112           0 :               return false;
    1113             :             }
    1114           0 :             break;
    1115             :           } while (0);
    1116           0 :           if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
    1117             :                                 JSPROP_ENUMERATE)) {
    1118           0 :             return false;
    1119             :           }
    1120             :         }
    1121             :       }
    1122           0 :       args.rval().setObject(*returnArray);
    1123           0 :       break;
    1124             :     } while (0);
    1125           0 :     if (args.rval().isObject()) {
    1126           0 :       JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
    1127           0 :       if (!JS_FreezeObject(cx, rvalObj)) {
    1128           0 :         return false;
    1129             :       }
    1130             :     }
    1131             :   }
    1132             :   { // And now store things in the compartment of our slotStorage.
    1133           0 :     JSAutoCompartment ac(cx, slotStorage);
    1134             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    1135           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    1136           0 :     if (!MaybeWrapNonDOMObjectOrNullValue(cx, &storedVal)) {
    1137           0 :       return false;
    1138             :     }
    1139           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    1140           0 :     PreserveWrapper(self);
    1141             :   }
    1142             :   // And now make sure args.rval() is in the caller compartment
    1143           0 :   return MaybeWrapNonDOMObjectOrNullValue(cx, args.rval());
    1144             : }
    1145             : 
    1146             : static const JSJitInfo includeGlobs_getterinfo = {
    1147             :   { (JSJitGetterOp)get_includeGlobs },
    1148             :   { prototypes::id::WebExtensionContentScript },
    1149             :   { PrototypeTraits<prototypes::id::WebExtensionContentScript>::Depth },
    1150             :   JSJitInfo::Getter,
    1151             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    1152             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    1153             :   false,  /* isInfallible. False in setters. */
    1154             :   true,  /* isMovable.  Not relevant for setters. */
    1155             :   true, /* isEliminatable.  Not relevant for setters. */
    1156             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1157             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1158             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1159             :   (DOM_INSTANCE_RESERVED_SLOTS + 0)   /* Reserved slot index, if we're stored in a slot, else 0. */
    1160             : };
    1161             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit");
    1162             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 5, "There is no slot for us");
    1163             : 
    1164             : static bool
    1165           0 : get_excludeGlobs(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionContentScript* self, JSJitGetterCallArgs args)
    1166             : {
    1167             :   // Have to either root across the getter call or reget after.
    1168           0 :   JS::Rooted<JSObject*> slotStorage(cx, js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false));
    1169           0 :   MOZ_ASSERT(IsDOMObject(slotStorage));
    1170           0 :   const size_t slotIndex = (DOM_INSTANCE_RESERVED_SLOTS + 1);
    1171           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    1172             :   {
    1173             :     // Scope for cachedVal
    1174           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    1175           0 :     if (!cachedVal.isUndefined()) {
    1176           0 :       args.rval().set(cachedVal);
    1177             :       // The cached value is in the compartment of slotStorage,
    1178             :       // so wrap into the caller compartment as needed.
    1179           0 :       return MaybeWrapNonDOMObjectOrNullValue(cx, args.rval());
    1180             :     }
    1181             :   }
    1182             : 
    1183           0 :   Nullable<nsTArray<StrongPtrForMember<mozilla::extensions::MatchGlob>::Type>> result;
    1184           0 :   self->GetExcludeGlobs(result);
    1185           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1186             :   {
    1187           0 :     JS::Rooted<JSObject*> conversionScope(cx, slotStorage);
    1188           0 :     JSAutoCompartment ac(cx, conversionScope);
    1189             :     do { // block we break out of when done wrapping
    1190             : 
    1191           0 :       if (result.IsNull()) {
    1192           0 :         args.rval().setNull();
    1193           0 :         break;
    1194             :       }
    1195             : 
    1196           0 :       uint32_t length = result.Value().Length();
    1197           0 :       JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
    1198           0 :       if (!returnArray) {
    1199           0 :         return false;
    1200             :       }
    1201             :       // Scope for 'tmp'
    1202             :       {
    1203           0 :         JS::Rooted<JS::Value> tmp(cx);
    1204           0 :         for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
    1205             :           // Control block to let us common up the JS_DefineElement calls when there
    1206             :           // are different ways to succeed at wrapping the object.
    1207             :           do {
    1208           0 :             if (!GetOrCreateDOMReflector(cx, result.Value()[sequenceIdx0], &tmp)) {
    1209           0 :               MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1210           0 :               return false;
    1211             :             }
    1212           0 :             break;
    1213             :           } while (0);
    1214           0 :           if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
    1215             :                                 JSPROP_ENUMERATE)) {
    1216           0 :             return false;
    1217             :           }
    1218             :         }
    1219             :       }
    1220           0 :       args.rval().setObject(*returnArray);
    1221           0 :       break;
    1222             :     } while (0);
    1223           0 :     if (args.rval().isObject()) {
    1224           0 :       JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
    1225           0 :       if (!JS_FreezeObject(cx, rvalObj)) {
    1226           0 :         return false;
    1227             :       }
    1228             :     }
    1229             :   }
    1230             :   { // And now store things in the compartment of our slotStorage.
    1231           0 :     JSAutoCompartment ac(cx, slotStorage);
    1232             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    1233           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    1234           0 :     if (!MaybeWrapNonDOMObjectOrNullValue(cx, &storedVal)) {
    1235           0 :       return false;
    1236             :     }
    1237           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    1238           0 :     PreserveWrapper(self);
    1239             :   }
    1240             :   // And now make sure args.rval() is in the caller compartment
    1241           0 :   return MaybeWrapNonDOMObjectOrNullValue(cx, args.rval());
    1242             : }
    1243             : 
    1244             : static const JSJitInfo excludeGlobs_getterinfo = {
    1245             :   { (JSJitGetterOp)get_excludeGlobs },
    1246             :   { prototypes::id::WebExtensionContentScript },
    1247             :   { PrototypeTraits<prototypes::id::WebExtensionContentScript>::Depth },
    1248             :   JSJitInfo::Getter,
    1249             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    1250             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    1251             :   false,  /* isInfallible. False in setters. */
    1252             :   true,  /* isMovable.  Not relevant for setters. */
    1253             :   true, /* isEliminatable.  Not relevant for setters. */
    1254             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1255             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1256             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1257             :   (DOM_INSTANCE_RESERVED_SLOTS + 1)   /* Reserved slot index, if we're stored in a slot, else 0. */
    1258             : };
    1259             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 1) <= JSJitInfo::maxSlotIndex, "We won't fit");
    1260             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 1) < 5, "There is no slot for us");
    1261             : 
    1262             : static bool
    1263           0 : get_cssPaths(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionContentScript* self, JSJitGetterCallArgs args)
    1264             : {
    1265             :   // Have to either root across the getter call or reget after.
    1266           0 :   JS::Rooted<JSObject*> slotStorage(cx, js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false));
    1267           0 :   MOZ_ASSERT(IsDOMObject(slotStorage));
    1268           0 :   const size_t slotIndex = (DOM_INSTANCE_RESERVED_SLOTS + 2);
    1269           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    1270             :   {
    1271             :     // Scope for cachedVal
    1272           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    1273           0 :     if (!cachedVal.isUndefined()) {
    1274           0 :       args.rval().set(cachedVal);
    1275             :       // The cached value is in the compartment of slotStorage,
    1276             :       // so wrap into the caller compartment as needed.
    1277           0 :       return MaybeWrapNonDOMObjectValue(cx, args.rval());
    1278             :     }
    1279             :   }
    1280             : 
    1281           0 :   nsTArray<nsString> result;
    1282           0 :   self->GetCssPaths(result);
    1283           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1284             :   {
    1285           0 :     JS::Rooted<JSObject*> conversionScope(cx, slotStorage);
    1286           0 :     JSAutoCompartment ac(cx, conversionScope);
    1287             :     do { // block we break out of when done wrapping
    1288             : 
    1289           0 :       uint32_t length = result.Length();
    1290           0 :       JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
    1291           0 :       if (!returnArray) {
    1292           0 :         return false;
    1293             :       }
    1294             :       // Scope for 'tmp'
    1295             :       {
    1296           0 :         JS::Rooted<JS::Value> tmp(cx);
    1297           0 :         for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
    1298             :           // Control block to let us common up the JS_DefineElement calls when there
    1299             :           // are different ways to succeed at wrapping the object.
    1300             :           do {
    1301           0 :             if (!xpc::NonVoidStringToJsval(cx, result[sequenceIdx0], &tmp)) {
    1302           0 :               return false;
    1303             :             }
    1304           0 :             break;
    1305             :           } while (0);
    1306           0 :           if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
    1307             :                                 JSPROP_ENUMERATE)) {
    1308           0 :             return false;
    1309             :           }
    1310             :         }
    1311             :       }
    1312           0 :       args.rval().setObject(*returnArray);
    1313           0 :       break;
    1314             :     } while (0);
    1315           0 :     JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
    1316           0 :     if (!JS_FreezeObject(cx, rvalObj)) {
    1317           0 :       return false;
    1318             :     }
    1319             :   }
    1320             :   { // And now store things in the compartment of our slotStorage.
    1321           0 :     JSAutoCompartment ac(cx, slotStorage);
    1322             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    1323           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    1324           0 :     if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
    1325           0 :       return false;
    1326             :     }
    1327           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    1328           0 :     PreserveWrapper(self);
    1329             :   }
    1330             :   // And now make sure args.rval() is in the caller compartment
    1331           0 :   return MaybeWrapNonDOMObjectValue(cx, args.rval());
    1332             : }
    1333             : 
    1334             : static const JSJitInfo cssPaths_getterinfo = {
    1335             :   { (JSJitGetterOp)get_cssPaths },
    1336             :   { prototypes::id::WebExtensionContentScript },
    1337             :   { PrototypeTraits<prototypes::id::WebExtensionContentScript>::Depth },
    1338             :   JSJitInfo::Getter,
    1339             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    1340             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1341             :   false,  /* isInfallible. False in setters. */
    1342             :   true,  /* isMovable.  Not relevant for setters. */
    1343             :   true, /* isEliminatable.  Not relevant for setters. */
    1344             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1345             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1346             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1347             :   (DOM_INSTANCE_RESERVED_SLOTS + 2)   /* Reserved slot index, if we're stored in a slot, else 0. */
    1348             : };
    1349             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 2) <= JSJitInfo::maxSlotIndex, "We won't fit");
    1350             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 2) < 5, "There is no slot for us");
    1351             : 
    1352             : static bool
    1353           0 : get_jsPaths(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::extensions::WebExtensionContentScript* self, JSJitGetterCallArgs args)
    1354             : {
    1355             :   // Have to either root across the getter call or reget after.
    1356           0 :   JS::Rooted<JSObject*> slotStorage(cx, js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false));
    1357           0 :   MOZ_ASSERT(IsDOMObject(slotStorage));
    1358           0 :   const size_t slotIndex = (DOM_INSTANCE_RESERVED_SLOTS + 3);
    1359           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    1360             :   {
    1361             :     // Scope for cachedVal
    1362           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    1363           0 :     if (!cachedVal.isUndefined()) {
    1364           0 :       args.rval().set(cachedVal);
    1365             :       // The cached value is in the compartment of slotStorage,
    1366             :       // so wrap into the caller compartment as needed.
    1367           0 :       return MaybeWrapNonDOMObjectValue(cx, args.rval());
    1368             :     }
    1369             :   }
    1370             : 
    1371           0 :   nsTArray<nsString> result;
    1372           0 :   self->GetJsPaths(result);
    1373           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1374             :   {
    1375           0 :     JS::Rooted<JSObject*> conversionScope(cx, slotStorage);
    1376           0 :     JSAutoCompartment ac(cx, conversionScope);
    1377             :     do { // block we break out of when done wrapping
    1378             : 
    1379           0 :       uint32_t length = result.Length();
    1380           0 :       JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
    1381           0 :       if (!returnArray) {
    1382           0 :         return false;
    1383             :       }
    1384             :       // Scope for 'tmp'
    1385             :       {
    1386           0 :         JS::Rooted<JS::Value> tmp(cx);
    1387           0 :         for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
    1388             :           // Control block to let us common up the JS_DefineElement calls when there
    1389             :           // are different ways to succeed at wrapping the object.
    1390             :           do {
    1391           0 :             if (!xpc::NonVoidStringToJsval(cx, result[sequenceIdx0], &tmp)) {
    1392           0 :               return false;
    1393             :             }
    1394           0 :             break;
    1395             :           } while (0);
    1396           0 :           if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
    1397             :                                 JSPROP_ENUMERATE)) {
    1398           0 :             return false;
    1399             :           }
    1400             :         }
    1401             :       }
    1402           0 :       args.rval().setObject(*returnArray);
    1403           0 :       break;
    1404             :     } while (0);
    1405           0 :     JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
    1406           0 :     if (!JS_FreezeObject(cx, rvalObj)) {
    1407           0 :       return false;
    1408             :     }
    1409             :   }
    1410             :   { // And now store things in the compartment of our slotStorage.
    1411           0 :     JSAutoCompartment ac(cx, slotStorage);
    1412             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    1413           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    1414           0 :     if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
    1415           0 :       return false;
    1416             :     }
    1417           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    1418           0 :     PreserveWrapper(self);
    1419             :   }
    1420             :   // And now make sure args.rval() is in the caller compartment
    1421           0 :   return MaybeWrapNonDOMObjectValue(cx, args.rval());
    1422             : }
    1423             : 
    1424             : static const JSJitInfo jsPaths_getterinfo = {
    1425             :   { (JSJitGetterOp)get_jsPaths },
    1426             :   { prototypes::id::WebExtensionContentScript },
    1427             :   { PrototypeTraits<prototypes::id::WebExtensionContentScript>::Depth },
    1428             :   JSJitInfo::Getter,
    1429             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    1430             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1431             :   false,  /* isInfallible. False in setters. */
    1432             :   true,  /* isMovable.  Not relevant for setters. */
    1433             :   true, /* isEliminatable.  Not relevant for setters. */
    1434             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1435             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1436             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1437             :   (DOM_INSTANCE_RESERVED_SLOTS + 3)   /* Reserved slot index, if we're stored in a slot, else 0. */
    1438             : };
    1439             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 3) <= JSJitInfo::maxSlotIndex, "We won't fit");
    1440             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 3) < 5, "There is no slot for us");
    1441             : 
    1442             : static bool
    1443           0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
    1444             : {
    1445           0 :   mozilla::extensions::WebExtensionContentScript* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::extensions::WebExtensionContentScript>(obj);
    1446             :   // We don't want to preserve if we don't have a wrapper, and we
    1447             :   // obviously can't preserve if we're not initialized.
    1448           0 :   if (self && self->GetWrapperPreserveColor()) {
    1449           0 :     PreserveWrapper(self);
    1450             :   }
    1451           0 :   return true;
    1452             : }
    1453             : 
    1454             : static void
    1455           0 : _finalize(js::FreeOp* fop, JSObject* obj)
    1456             : {
    1457           0 :   mozilla::extensions::WebExtensionContentScript* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::extensions::WebExtensionContentScript>(obj);
    1458           0 :   if (self) {
    1459           0 :     ClearWrapper(self, self, obj);
    1460           0 :     AddForDeferredFinalization<mozilla::extensions::WebExtensionContentScript>(self);
    1461             :   }
    1462           0 : }
    1463             : 
    1464             : static void
    1465           0 : _objectMoved(JSObject* obj, const JSObject* old)
    1466             : {
    1467           0 :   mozilla::extensions::WebExtensionContentScript* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::extensions::WebExtensionContentScript>(obj);
    1468           0 :   if (self) {
    1469           0 :     UpdateWrapper(self, self, obj, old);
    1470             :   }
    1471           0 : }
    1472             : 
    1473             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    1474             : #if defined(__clang__)
    1475             : #pragma clang diagnostic push
    1476             : #pragma clang diagnostic ignored "-Wmissing-braces"
    1477             : #endif
    1478             : static const JSFunctionSpec sMethods_specs[] = {
    1479             :   JS_FNSPEC("matchesURI", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&matchesURI_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    1480             :   JS_FNSPEC("matchesLoadInfo", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&matchesLoadInfo_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
    1481             :   JS_FNSPEC("matchesWindow", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&matchesWindow_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    1482             :   JS_FS_END
    1483             : };
    1484             : #if defined(__clang__)
    1485             : #pragma clang diagnostic pop
    1486             : #endif
    1487             : 
    1488             : 
    1489             : // Can't be const because the pref-enabled boolean needs to be writable
    1490             : static Prefable<const JSFunctionSpec> sMethods[] = {
    1491             :   { nullptr, &sMethods_specs[0] },
    1492             :   { nullptr, nullptr }
    1493             : };
    1494             : 
    1495             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    1496             : #if defined(__clang__)
    1497             : #pragma clang diagnostic push
    1498             : #pragma clang diagnostic ignored "-Wmissing-braces"
    1499             : #endif
    1500             : static const JSPropertySpec sAttributes_specs[] = {
    1501             :   { "extension", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &extension_getterinfo, nullptr, nullptr },
    1502             :   { "allFrames", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &allFrames_getterinfo, nullptr, nullptr },
    1503             :   { "matchAboutBlank", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &matchAboutBlank_getterinfo, nullptr, nullptr },
    1504             :   { "runAt", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &runAt_getterinfo, nullptr, nullptr },
    1505             :   { "frameID", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &frameID_getterinfo, nullptr, nullptr },
    1506             :   { "matches", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &matches_getterinfo, nullptr, nullptr },
    1507             :   { "excludeMatches", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &excludeMatches_getterinfo, nullptr, nullptr },
    1508             :   { "includeGlobs", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &includeGlobs_getterinfo, nullptr, nullptr },
    1509             :   { "excludeGlobs", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &excludeGlobs_getterinfo, nullptr, nullptr },
    1510             :   { "cssPaths", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &cssPaths_getterinfo, nullptr, nullptr },
    1511             :   { "jsPaths", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &jsPaths_getterinfo, nullptr, nullptr },
    1512             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
    1513             : };
    1514             : #if defined(__clang__)
    1515             : #pragma clang diagnostic pop
    1516             : #endif
    1517             : 
    1518             : 
    1519             : // Can't be const because the pref-enabled boolean needs to be writable
    1520             : static Prefable<const JSPropertySpec> sAttributes[] = {
    1521             :   { nullptr, &sAttributes_specs[0] },
    1522             :   { nullptr, nullptr }
    1523             : };
    1524             : 
    1525             : 
    1526             : static const NativePropertiesN<2> sNativeProperties = {
    1527             :   false, 0,
    1528             :   false, 0,
    1529             :   true,  0 /* sMethods */,
    1530             :   true,  1 /* sAttributes */,
    1531             :   false, 0,
    1532             :   false, 0,
    1533             :   false, 0,
    1534             :   -1,
    1535             :   0,
    1536             :   nullptr,
    1537             :   {
    1538             :     { sMethods, nullptr },
    1539             :     { sAttributes, nullptr }
    1540             :   }
    1541             : };
    1542             : 
    1543             : static bool
    1544           0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
    1545             : {
    1546           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    1547           0 :   JS::Rooted<JSObject*> obj(cx, &args.callee());
    1548           0 :   if (!args.isConstructing()) {
    1549             :     // XXXbz wish I could get the name from the callee instead of
    1550             :     // Adding more relocations
    1551           0 :     return ThrowConstructorWithoutNew(cx, "WebExtensionContentScript");
    1552             :   }
    1553             : 
    1554           0 :   GlobalObject global(cx, obj);
    1555           0 :   if (global.Failed()) {
    1556           0 :     return false;
    1557             :   }
    1558             : 
    1559           0 :   JS::Rooted<JSObject*> desiredProto(cx);
    1560           0 :   if (!GetDesiredProto(cx, args, &desiredProto)) {
    1561           0 :     return false;
    1562             :   }
    1563             : 
    1564           0 :   if (MOZ_UNLIKELY(args.length() < 2)) {
    1565           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "WebExtensionContentScript");
    1566             :   }
    1567           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    1568           0 :   NonNull<mozilla::extensions::WebExtensionPolicy> arg0;
    1569           0 :   if (args[0].isObject()) {
    1570             :     {
    1571           0 :       nsresult rv = UnwrapObject<prototypes::id::WebExtensionPolicy, mozilla::extensions::WebExtensionPolicy>(args[0], arg0);
    1572           0 :       if (NS_FAILED(rv)) {
    1573           0 :         ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of WebExtensionContentScript.constructor", "WebExtensionPolicy");
    1574           0 :         return false;
    1575             :       }
    1576             :     }
    1577             :   } else {
    1578           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of WebExtensionContentScript.constructor");
    1579           0 :     return false;
    1580             :   }
    1581           0 :   binding_detail::FastWebExtensionContentScriptInit arg1;
    1582           0 :   if (!arg1.Init(cx, args[1],  "Argument 2 of WebExtensionContentScript.constructor", false)) {
    1583           0 :     return false;
    1584             :   }
    1585           0 :   Maybe<JSAutoCompartment> ac;
    1586           0 :   if (objIsXray) {
    1587           0 :     obj = js::CheckedUnwrap(obj);
    1588           0 :     if (!obj) {
    1589           0 :       return false;
    1590             :     }
    1591           0 :     ac.emplace(cx, obj);
    1592           0 :     if (!JS_WrapObject(cx, &desiredProto)) {
    1593           0 :       return false;
    1594             :     }
    1595             :   }
    1596           0 :   binding_detail::FastErrorResult rv;
    1597           0 :   auto result(StrongOrRawPtr<mozilla::extensions::WebExtensionContentScript>(mozilla::extensions::WebExtensionContentScript::Constructor(global, NonNullHelper(arg0), Constify(arg1), rv)));
    1598           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1599           0 :     return false;
    1600             :   }
    1601           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1602             :   static_assert(!IsPointer<decltype(result)>::value,
    1603             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
    1604           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
    1605           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1606           0 :     return false;
    1607             :   }
    1608           0 :   return true;
    1609             : }
    1610             : 
    1611             : static const js::ClassOps sInterfaceObjectClassOps = {
    1612             :     nullptr,               /* addProperty */
    1613             :     nullptr,               /* delProperty */
    1614             :     nullptr,               /* getProperty */
    1615             :     nullptr,               /* setProperty */
    1616             :     nullptr,               /* enumerate */
    1617             :     nullptr,               /* newEnumerate */
    1618             :     nullptr,               /* resolve */
    1619             :     nullptr,               /* mayResolve */
    1620             :     nullptr,               /* finalize */
    1621             :     _constructor, /* call */
    1622             :     nullptr,               /* hasInstance */
    1623             :     _constructor, /* construct */
    1624             :     nullptr,               /* trace */
    1625             : };
    1626             : 
    1627             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
    1628             :   {
    1629             :     "Function",
    1630             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
    1631             :     &sInterfaceObjectClassOps,
    1632             :     JS_NULL_CLASS_SPEC,
    1633             :     JS_NULL_CLASS_EXT,
    1634             :     &sInterfaceObjectClassObjectOps
    1635             :   },
    1636             :   eInterface,
    1637             :   true,
    1638             :   prototypes::id::WebExtensionContentScript,
    1639             :   PrototypeTraits<prototypes::id::WebExtensionContentScript>::Depth,
    1640             :   &sEmptyNativePropertyHooks,
    1641             :   "function WebExtensionContentScript() {\n    [native code]\n}",
    1642             :   JS::GetRealmFunctionPrototype
    1643             : };
    1644             : 
    1645             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
    1646             :   {
    1647             :     "WebExtensionContentScriptPrototype",
    1648             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    1649             :     JS_NULL_CLASS_OPS,
    1650             :     JS_NULL_CLASS_SPEC,
    1651             :     JS_NULL_CLASS_EXT,
    1652             :     JS_NULL_OBJECT_OPS
    1653             :   },
    1654             :   eInterfacePrototype,
    1655             :   false,
    1656             :   prototypes::id::WebExtensionContentScript,
    1657             :   PrototypeTraits<prototypes::id::WebExtensionContentScript>::Depth,
    1658             :   &sEmptyNativePropertyHooks,
    1659             :   "[object WebExtensionContentScriptPrototype]",
    1660             :   JS::GetRealmObjectPrototype
    1661             : };
    1662             : 
    1663             : bool
    1664           0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
    1665             : {
    1666           0 :   return nsContentUtils::ThreadsafeIsSystemCaller(aCx);
    1667             : }
    1668             : 
    1669             : static const js::ClassOps sClassOps = {
    1670             :   _addProperty, /* addProperty */
    1671             :   nullptr,               /* delProperty */
    1672             :   nullptr,               /* getProperty */
    1673             :   nullptr,               /* setProperty */
    1674             :   nullptr,               /* enumerate */
    1675             :   nullptr, /* newEnumerate */
    1676             :   nullptr, /* resolve */
    1677             :   nullptr, /* mayResolve */
    1678             :   _finalize, /* finalize */
    1679             :   nullptr, /* call */
    1680             :   nullptr,               /* hasInstance */
    1681             :   nullptr,               /* construct */
    1682             :   nullptr, /* trace */
    1683             : };
    1684             : 
    1685             : static const js::ClassExtension sClassExtension = {
    1686             :   nullptr, /* weakmapKeyDelegateOp */
    1687             :   _objectMoved /* objectMovedOp */
    1688             : };
    1689             : 
    1690             : static const DOMJSClass sClass = {
    1691             :   { "WebExtensionContentScript",
    1692             :     JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(5),
    1693             :     &sClassOps,
    1694             :     JS_NULL_CLASS_SPEC,
    1695             :     &sClassExtension,
    1696             :     JS_NULL_OBJECT_OPS
    1697             :   },
    1698             :   { prototypes::id::WebExtensionContentScript, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
    1699             :   IsBaseOf<nsISupports, mozilla::extensions::WebExtensionContentScript >::value,
    1700             :   &sEmptyNativePropertyHooks,
    1701             :   FindAssociatedGlobalForNative<mozilla::extensions::WebExtensionContentScript>::Get,
    1702             :   GetProtoObjectHandle,
    1703             :   GetCCParticipant<mozilla::extensions::WebExtensionContentScript>::Get()
    1704             : };
    1705             : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
    1706             :               "Must have the right minimal number of reserved slots.");
    1707             : static_assert(5 >= 5,
    1708             :               "Must have enough reserved slots.");
    1709             : 
    1710             : const JSClass*
    1711           0 : GetJSClass()
    1712             : {
    1713           0 :   return sClass.ToJSClass();
    1714             : }
    1715             : 
    1716             : bool
    1717           0 : Wrap(JSContext* aCx, mozilla::extensions::WebExtensionContentScript* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
    1718             : {
    1719             :   MOZ_ASSERT(static_cast<mozilla::extensions::WebExtensionContentScript*>(aObject) ==
    1720             :              reinterpret_cast<mozilla::extensions::WebExtensionContentScript*>(aObject),
    1721             :              "Multiple inheritance for mozilla::extensions::WebExtensionContentScript is broken.");
    1722           0 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
    1723           0 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
    1724           0 :   MOZ_ASSERT(!aCache->GetWrapper(),
    1725             :              "You should probably not be using Wrap() directly; use "
    1726             :              "GetOrCreateDOMReflector instead");
    1727             : 
    1728           0 :   MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
    1729             :              "nsISupports must be on our primary inheritance chain");
    1730             : 
    1731           0 :   JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
    1732           0 :   if (!global) {
    1733           0 :     return false;
    1734             :   }
    1735           0 :   MOZ_ASSERT(JS_IsGlobalObject(global));
    1736           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(global));
    1737             : 
    1738             :   // That might have ended up wrapping us already, due to the wonders
    1739             :   // of XBL.  Check for that, and bail out as needed.
    1740           0 :   aReflector.set(aCache->GetWrapper());
    1741           0 :   if (aReflector) {
    1742             : #ifdef DEBUG
    1743           0 :     binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
    1744             : #endif // DEBUG
    1745           0 :     return true;
    1746             :   }
    1747             : 
    1748           0 :   JSAutoCompartment ac(aCx, global);
    1749           0 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
    1750           0 :   if (!canonicalProto) {
    1751           0 :     return false;
    1752             :   }
    1753           0 :   JS::Rooted<JSObject*> proto(aCx);
    1754           0 :   if (aGivenProto) {
    1755           0 :     proto = aGivenProto;
    1756             :     // Unfortunately, while aGivenProto was in the compartment of aCx
    1757             :     // coming in, we changed compartments to that of "parent" so may need
    1758             :     // to wrap the proto here.
    1759           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
    1760           0 :       if (!JS_WrapObject(aCx, &proto)) {
    1761           0 :         return false;
    1762             :       }
    1763             :     }
    1764             :   } else {
    1765           0 :     proto = canonicalProto;
    1766             :   }
    1767             : 
    1768           0 :   BindingJSObjectCreator<mozilla::extensions::WebExtensionContentScript> creator(aCx);
    1769           0 :   creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
    1770           0 :   if (!aReflector) {
    1771           0 :     return false;
    1772             :   }
    1773             : 
    1774           0 :   aCache->SetWrapper(aReflector);
    1775           0 :   creator.InitializationSucceeded();
    1776             : 
    1777           0 :   MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
    1778             :              aCache->GetWrapperPreserveColor() == aReflector);
    1779             :   // If proto != canonicalProto, we have to preserve our wrapper;
    1780             :   // otherwise we won't be able to properly recreate it later, since
    1781             :   // we won't know what proto to use.  Note that we don't check
    1782             :   // aGivenProto here, since it's entirely possible (and even
    1783             :   // somewhat common) to have a non-null aGivenProto which is the
    1784             :   // same as canonicalProto.
    1785           0 :   if (proto != canonicalProto) {
    1786           0 :     PreserveWrapper(aObject);
    1787             :   }
    1788             : 
    1789           0 :   return true;
    1790             : }
    1791             : 
    1792             : void
    1793           0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    1794             : {
    1795           0 :   JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
    1796           0 :   if (!parentProto) {
    1797           0 :     return;
    1798             :   }
    1799             : 
    1800           0 :   JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
    1801           0 :   if (!constructorProto) {
    1802           0 :     return;
    1803             :   }
    1804             : 
    1805           0 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::WebExtensionContentScript);
    1806           0 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::WebExtensionContentScript);
    1807           0 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    1808             :                               &sPrototypeClass.mBase, protoCache,
    1809             :                               constructorProto, &sInterfaceObjectClass.mBase, 2, nullptr,
    1810             :                               interfaceCache,
    1811             :                               sNativeProperties.Upcast(),
    1812             :                               nullptr,
    1813             :                               "WebExtensionContentScript", aDefineOnGlobal,
    1814             :                               nullptr,
    1815           0 :                               false);
    1816             : }
    1817             : 
    1818             : JS::Handle<JSObject*>
    1819           0 : GetProtoObjectHandle(JSContext* aCx)
    1820             : {
    1821             :   /* Get the interface prototype object for this class.  This will create the
    1822             :      object as needed. */
    1823           0 :   bool aDefineOnGlobal = true;
    1824             : 
    1825             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    1826           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    1827           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    1828           0 :     return nullptr;
    1829             :   }
    1830             : 
    1831             :   /* Check to see whether the interface objects are already installed */
    1832           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    1833           0 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::WebExtensionContentScript)) {
    1834           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    1835           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    1836             :   }
    1837             : 
    1838             :   /*
    1839             :    * The object might _still_ be null, but that's OK.
    1840             :    *
    1841             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    1842             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    1843             :    * changed after they have been set.
    1844             :    *
    1845             :    * Calling address() avoids the read read barrier that does gray
    1846             :    * unmarking, but it's not possible for the object to be gray here.
    1847             :    */
    1848             : 
    1849           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::WebExtensionContentScript);
    1850           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    1851           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    1852             : }
    1853             : 
    1854             : JS::Handle<JSObject*>
    1855           0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
    1856             : {
    1857             :   /* Get the interface object for this class.  This will create the object as
    1858             :      needed. */
    1859             : 
    1860             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    1861           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    1862           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    1863           0 :     return nullptr;
    1864             :   }
    1865             : 
    1866             :   /* Check to see whether the interface objects are already installed */
    1867           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    1868           0 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::WebExtensionContentScript)) {
    1869           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    1870           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    1871             :   }
    1872             : 
    1873             :   /*
    1874             :    * The object might _still_ be null, but that's OK.
    1875             :    *
    1876             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    1877             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    1878             :    * changed after they have been set.
    1879             :    *
    1880             :    * Calling address() avoids the read read barrier that does gray
    1881             :    * unmarking, but it's not possible for the object to be gray here.
    1882             :    */
    1883             : 
    1884           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::WebExtensionContentScript);
    1885           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    1886           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    1887             : }
    1888             : 
    1889             : JSObject*
    1890           0 : GetConstructorObject(JSContext* aCx)
    1891             : {
    1892           0 :   return GetConstructorObjectHandle(aCx);
    1893             : }
    1894             : 
    1895             : } // namespace WebExtensionContentScriptBinding
    1896             : 
    1897             : 
    1898             : 
    1899             : } // namespace dom
    1900             : } // namespace mozilla

Generated by: LCOV version 1.13