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

          Line data    Source code
       1             : /* THIS FILE IS AUTOGENERATED FROM Navigator.webidl BY Codegen.py - DO NOT EDIT */
       2             : 
       3             : #include "AddonManagerBinding.h"
       4             : #include "AtomList.h"
       5             : #include "DOMMediaStream.h"
       6             : #include "FetchBinding.h"
       7             : #include "FlyWebPublishBinding.h"
       8             : #include "MediaKeySystemAccessBinding.h"
       9             : #include "MediaStreamBinding.h"
      10             : #include "Navigator.h"
      11             : #include "NavigatorBinding.h"
      12             : #include "SecureElementManagerBinding.h"
      13             : #include "ServiceWorkerContainer.h"
      14             : #include "TCPSocket.h"
      15             : #include "TestJSImplGenBinding.h"
      16             : #include "WrapperFactory.h"
      17             : #include "XrayWrapper.h"
      18             : #include "mozilla/AddonManagerWebAPI.h"
      19             : #include "mozilla/OwningNonNull.h"
      20             : #include "mozilla/Preferences.h"
      21             : #include "mozilla/dom/BindingUtils.h"
      22             : #include "mozilla/dom/CredentialsContainer.h"
      23             : #include "mozilla/dom/DOMJSClass.h"
      24             : #include "mozilla/dom/DesktopNotification.h"
      25             : #include "mozilla/dom/Gamepad.h"
      26             : #include "mozilla/dom/GamepadServiceTest.h"
      27             : #include "mozilla/dom/MediaDevices.h"
      28             : #include "mozilla/dom/MediaStreamError.h"
      29             : #include "mozilla/dom/NonRefcountedDOMObject.h"
      30             : #include "mozilla/dom/Nullable.h"
      31             : #include "mozilla/dom/Permissions.h"
      32             : #include "mozilla/dom/PowerManager.h"
      33             : #include "mozilla/dom/Presentation.h"
      34             : #include "mozilla/dom/PrimitiveConversions.h"
      35             : #include "mozilla/dom/Promise.h"
      36             : #include "mozilla/dom/ServiceWorkerContainer.h"
      37             : #include "mozilla/dom/StorageManager.h"
      38             : #include "mozilla/dom/TCPSocket.h"
      39             : #include "mozilla/dom/ToJSValue.h"
      40             : #include "mozilla/dom/UnionConversions.h"
      41             : #include "mozilla/dom/VRDisplay.h"
      42             : #include "mozilla/dom/VRServiceTest.h"
      43             : #include "mozilla/dom/WakeLock.h"
      44             : #include "mozilla/dom/XrayExpandoClass.h"
      45             : #include "mozilla/dom/network/Connection.h"
      46             : #include "nsContentUtils.h"
      47             : #include "nsGeolocation.h"
      48             : #include "nsIDocument.h"
      49             : #include "nsISupports.h"
      50             : #include "nsIVariant.h"
      51             : #include "nsMimeTypeArray.h"
      52             : #include "nsPluginArray.h"
      53             : #include "xpcjsid.h"
      54             : 
      55             : namespace mozilla {
      56             : namespace dom {
      57             : 
      58             : void
      59           0 : NavigatorUserMediaSuccessCallback::Call(JSContext* cx, JS::Handle<JS::Value> aThisVal, DOMMediaStream& stream, ErrorResult& aRv)
      60             : {
      61           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
      62           0 :   JS::AutoValueVector argv(cx);
      63           0 :   if (!argv.resize(1)) {
      64           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
      65           0 :     return;
      66             :   }
      67           0 :   unsigned argc = 1;
      68             : 
      69             :   do {
      70           0 :     if (!GetOrCreateDOMReflector(cx, stream, argv[0])) {
      71           0 :       MOZ_ASSERT(true || JS_IsExceptionPending(cx));
      72           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
      73           0 :       return;
      74             :     }
      75           0 :     break;
      76             :   } while (0);
      77             : 
      78           0 :   JS::Rooted<JS::Value> callable(cx, JS::ObjectValue(*mCallback));
      79           0 :   if (!JS::Call(cx, aThisVal, callable,
      80           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
      81           0 :     aRv.NoteJSContextException(cx);
      82           0 :     return;
      83             :   }
      84             : }
      85             : 
      86             : 
      87             : 
      88             : void
      89           0 : NavigatorUserMediaErrorCallback::Call(JSContext* cx, JS::Handle<JS::Value> aThisVal, MediaStreamError& error, ErrorResult& aRv)
      90             : {
      91           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
      92           0 :   JS::AutoValueVector argv(cx);
      93           0 :   if (!argv.resize(1)) {
      94           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
      95           0 :     return;
      96             :   }
      97           0 :   unsigned argc = 1;
      98             : 
      99             :   do {
     100           0 :     if (!GetOrCreateDOMReflector(cx, error, argv[0])) {
     101           0 :       MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     102           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
     103           0 :       return;
     104             :     }
     105           0 :     break;
     106             :   } while (0);
     107             : 
     108           0 :   JS::Rooted<JS::Value> callable(cx, JS::ObjectValue(*mCallback));
     109           0 :   if (!JS::Call(cx, aThisVal, callable,
     110           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
     111           0 :     aRv.NoteJSContextException(cx);
     112           0 :     return;
     113             :   }
     114             : }
     115             : 
     116             : 
     117             : 
     118             : void
     119           0 : MozGetUserMediaDevicesSuccessCallback::Call(JSContext* cx, JS::Handle<JS::Value> aThisVal, nsIVariant* devices, ErrorResult& aRv)
     120             : {
     121           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
     122           0 :   JS::AutoValueVector argv(cx);
     123           0 :   if (!argv.resize(1)) {
     124           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     125           0 :     return;
     126             :   }
     127           0 :   unsigned argc = 1;
     128             : 
     129             :   do {
     130           0 :     if (!devices) {
     131           0 :       argv[0].setNull();
     132           0 :       break;
     133             :     }
     134           0 :     if (!WrapObject(cx, devices, &NS_GET_IID(nsIVariant), argv[0])) {
     135           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
     136           0 :       return;
     137             :     }
     138           0 :     break;
     139             :   } while (0);
     140             : 
     141           0 :   JS::Rooted<JS::Value> callable(cx, JS::ObjectValue(*mCallback));
     142           0 :   if (!JS::Call(cx, aThisVal, callable,
     143           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
     144           0 :     aRv.NoteJSContextException(cx);
     145           0 :     return;
     146             :   }
     147             : }
     148             : 
     149             : 
     150             : 
     151             : namespace binding_detail {
     152             : } // namespace binding_detail
     153             : 
     154             : 
     155             : namespace binding_detail {
     156             : } // namespace binding_detail
     157             : 
     158             : 
     159             : namespace binding_detail {
     160             : } // namespace binding_detail
     161             : 
     162             : 
     163             : namespace NavigatorBinding {
     164             : 
     165             : static bool
     166           0 : get_permissions(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
     167             : {
     168           0 :   binding_detail::FastErrorResult rv;
     169           0 :   auto result(StrongOrRawPtr<mozilla::dom::Permissions>(self->GetPermissions(rv)));
     170           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     171           0 :     return false;
     172             :   }
     173           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     174           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
     175           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     176           0 :     return false;
     177             :   }
     178           0 :   return true;
     179             : }
     180             : 
     181             : static const JSJitInfo permissions_getterinfo = {
     182             :   { (JSJitGetterOp)get_permissions },
     183             :   { prototypes::id::Navigator },
     184             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     185             :   JSJitInfo::Getter,
     186             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     187             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     188             :   false,  /* isInfallible. False in setters. */
     189             :   false,  /* isMovable.  Not relevant for setters. */
     190             :   false, /* isEliminatable.  Not relevant for setters. */
     191             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     192             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     193             :   false,  /* isTypedMethod.  Only relevant for methods. */
     194             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     195             : };
     196             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     197             : static_assert(0 < 16, "There is no slot for us");
     198             : 
     199             : static bool
     200           0 : get_mimeTypes(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
     201             : {
     202           0 :   binding_detail::FastErrorResult rv;
     203           0 :   auto result(StrongOrRawPtr<nsMimeTypeArray>(self->GetMimeTypes(rv)));
     204           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     205           0 :     return false;
     206             :   }
     207           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     208           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
     209           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     210           0 :     return false;
     211             :   }
     212           0 :   return true;
     213             : }
     214             : 
     215             : static const JSJitInfo mimeTypes_getterinfo = {
     216             :   { (JSJitGetterOp)get_mimeTypes },
     217             :   { prototypes::id::Navigator },
     218             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     219             :   JSJitInfo::Getter,
     220             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     221             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     222             :   false,  /* isInfallible. False in setters. */
     223             :   false,  /* isMovable.  Not relevant for setters. */
     224             :   false, /* isEliminatable.  Not relevant for setters. */
     225             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     226             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     227             :   false,  /* isTypedMethod.  Only relevant for methods. */
     228             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     229             : };
     230             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     231             : static_assert(0 < 16, "There is no slot for us");
     232             : 
     233             : static bool
     234           0 : get_plugins(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
     235             : {
     236           0 :   binding_detail::FastErrorResult rv;
     237           0 :   auto result(StrongOrRawPtr<nsPluginArray>(self->GetPlugins(rv)));
     238           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     239           0 :     return false;
     240             :   }
     241           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     242           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
     243           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     244           0 :     return false;
     245             :   }
     246           0 :   return true;
     247             : }
     248             : 
     249             : static const JSJitInfo plugins_getterinfo = {
     250             :   { (JSJitGetterOp)get_plugins },
     251             :   { prototypes::id::Navigator },
     252             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     253             :   JSJitInfo::Getter,
     254             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     255             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     256             :   false,  /* isInfallible. False in setters. */
     257             :   false,  /* isMovable.  Not relevant for setters. */
     258             :   false, /* isEliminatable.  Not relevant for setters. */
     259             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     260             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     261             :   false,  /* isTypedMethod.  Only relevant for methods. */
     262             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     263             : };
     264             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     265             : static_assert(0 < 16, "There is no slot for us");
     266             : 
     267             : static bool
     268           0 : get_doNotTrack(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
     269             : {
     270           0 :   DOMString result;
     271           0 :   self->GetDoNotTrack(result);
     272           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     273           0 :   if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
     274           0 :     return false;
     275             :   }
     276           0 :   return true;
     277             : }
     278             : 
     279             : static const JSJitInfo doNotTrack_getterinfo = {
     280             :   { (JSJitGetterOp)get_doNotTrack },
     281             :   { prototypes::id::Navigator },
     282             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     283             :   JSJitInfo::Getter,
     284             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     285             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
     286             :   false,  /* isInfallible. False in setters. */
     287             :   false,  /* isMovable.  Not relevant for setters. */
     288             :   false, /* isEliminatable.  Not relevant for setters. */
     289             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     290             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     291             :   false,  /* isTypedMethod.  Only relevant for methods. */
     292             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     293             : };
     294             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     295             : static_assert(0 < 16, "There is no slot for us");
     296             : 
     297             : static bool
     298           0 : getBattery(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
     299             : {
     300           0 :   binding_detail::FastErrorResult rv;
     301           0 :   auto result(StrongOrRawPtr<Promise>(self->GetBattery(rv)));
     302           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     303           0 :     return false;
     304             :   }
     305           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     306           0 :   if (!ToJSValue(cx, result, args.rval())) {
     307           0 :     return false;
     308             :   }
     309           0 :   return true;
     310             : }
     311             : 
     312             : static bool
     313           0 : getBattery_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
     314             : {
     315             :   // Make sure to save the callee before someone maybe messes
     316             :   // with rval().
     317           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
     318           0 :   bool ok = getBattery(cx, obj, self, args);
     319           0 :   if (ok) {
     320           0 :     return true;
     321             :   }
     322           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
     323           0 :                                    args.rval());
     324             : }
     325             : 
     326             : static const JSJitInfo getBattery_methodinfo = {
     327             :   { (JSJitGetterOp)getBattery_promiseWrapper },
     328             :   { prototypes::id::Navigator },
     329             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     330             :   JSJitInfo::Method,
     331             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     332             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     333             :   false,  /* isInfallible. False in setters. */
     334             :   false,  /* isMovable.  Not relevant for setters. */
     335             :   false, /* isEliminatable.  Not relevant for setters. */
     336             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     337             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     338             :   false,  /* isTypedMethod.  Only relevant for methods. */
     339             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     340             : };
     341             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     342             : static_assert(0 < 16, "There is no slot for us");
     343             : 
     344             : static bool
     345           0 : publishServer(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
     346             : {
     347           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
     348           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Navigator.publishServer");
     349             :   }
     350           0 :   binding_detail::FakeString arg0;
     351           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
     352           0 :     return false;
     353             :   }
     354           0 :   binding_detail::FastFlyWebPublishOptions arg1;
     355           0 :   if (!arg1.Init(cx, (args.hasDefined(1)) ? args[1] : JS::NullHandleValue,  "Argument 2 of Navigator.publishServer", false)) {
     356           0 :     return false;
     357             :   }
     358           0 :   binding_detail::FastErrorResult rv;
     359           0 :   auto result(StrongOrRawPtr<Promise>(self->PublishServer(NonNullHelper(Constify(arg0)), Constify(arg1), rv)));
     360           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     361           0 :     return false;
     362             :   }
     363           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     364             :   static_assert(!IsPointer<decltype(result)>::value,
     365             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
     366           0 :   if (!ToJSValue(cx, result, args.rval())) {
     367           0 :     return false;
     368             :   }
     369           0 :   return true;
     370             : }
     371             : 
     372             : static bool
     373           0 : publishServer_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
     374             : {
     375             :   // Make sure to save the callee before someone maybe messes
     376             :   // with rval().
     377           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
     378           0 :   bool ok = publishServer(cx, obj, self, args);
     379           0 :   if (ok) {
     380           0 :     return true;
     381             :   }
     382           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
     383           0 :                                    args.rval());
     384             : }
     385             : 
     386             : static const JSJitInfo publishServer_methodinfo = {
     387             :   { (JSJitGetterOp)publishServer_promiseWrapper },
     388             :   { prototypes::id::Navigator },
     389             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     390             :   JSJitInfo::Method,
     391             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     392             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     393             :   false,  /* isInfallible. False in setters. */
     394             :   false,  /* isMovable.  Not relevant for setters. */
     395             :   false, /* isEliminatable.  Not relevant for setters. */
     396             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     397             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     398             :   false,  /* isTypedMethod.  Only relevant for methods. */
     399             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     400             : };
     401             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     402             : static_assert(0 < 16, "There is no slot for us");
     403             : 
     404             : static bool
     405           0 : vibrate(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
     406             : {
     407           0 :   unsigned argcount = std::min(args.length(), 1u);
     408           0 :   switch (argcount) {
     409             :     case 1: {
     410           0 :       if (args[0].isObject()) {
     411             :         do {
     412           0 :           binding_detail::AutoSequence<uint32_t> arg0;
     413           0 :           JS::ForOfIterator iter(cx);
     414           0 :           if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) {
     415           0 :             return false;
     416             :           }
     417           0 :           if (!iter.valueIsIterable()) {
     418           0 :             break;
     419             :           }
     420           0 :           binding_detail::AutoSequence<uint32_t> &arr = arg0;
     421           0 :           JS::Rooted<JS::Value> temp(cx);
     422             :           while (true) {
     423             :             bool done;
     424           0 :             if (!iter.next(&temp, &done)) {
     425           0 :               return false;
     426             :             }
     427           0 :             if (done) {
     428           0 :               break;
     429             :             }
     430           0 :             uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
     431           0 :             if (!slotPtr) {
     432           0 :               JS_ReportOutOfMemory(cx);
     433           0 :               return false;
     434             :             }
     435           0 :             uint32_t& slot = *slotPtr;
     436           0 :             if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp, &slot)) {
     437           0 :               return false;
     438             :             }
     439           0 :           }
     440           0 :           bool result(self->Vibrate(Constify(arg0)));
     441           0 :           MOZ_ASSERT(!JS_IsExceptionPending(cx));
     442           0 :           args.rval().setBoolean(result);
     443           0 :           return true;
     444             :         } while (0);
     445             :       }
     446             :       uint32_t arg0;
     447           0 :       if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[0], &arg0)) {
     448           0 :         return false;
     449             :       }
     450           0 :       bool result(self->Vibrate(arg0));
     451           0 :       MOZ_ASSERT(!JS_IsExceptionPending(cx));
     452           0 :       args.rval().setBoolean(result);
     453           0 :       return true;
     454             :       break;
     455             :     }
     456             :     default: {
     457           0 :       return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Navigator.vibrate");
     458             :       break;
     459             :     }
     460             :   }
     461             :   MOZ_CRASH("We have an always-returning default case");
     462             :   return false;
     463             : }
     464             : 
     465             : static const JSJitInfo vibrate_methodinfo = {
     466             :   { (JSJitGetterOp)vibrate },
     467             :   { prototypes::id::Navigator },
     468             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     469             :   JSJitInfo::Method,
     470             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     471             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
     472             :   false,  /* isInfallible. False in setters. */
     473             :   false,  /* isMovable.  Not relevant for setters. */
     474             :   false, /* isEliminatable.  Not relevant for setters. */
     475             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     476             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     477             :   false,  /* isTypedMethod.  Only relevant for methods. */
     478             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     479             : };
     480             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     481             : static_assert(0 < 16, "There is no slot for us");
     482             : 
     483             : static bool
     484           0 : get_maxTouchPoints(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
     485             : {
     486           0 :   int32_t result(self->MaxTouchPoints());
     487           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     488           0 :   args.rval().setInt32(int32_t(result));
     489           0 :   return true;
     490             : }
     491             : 
     492             : static const JSJitInfo maxTouchPoints_getterinfo = {
     493             :   { (JSJitGetterOp)get_maxTouchPoints },
     494             :   { prototypes::id::Navigator },
     495             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     496             :   JSJitInfo::Getter,
     497             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     498             :   JSVAL_TYPE_INT32,  /* returnType.  Not relevant for setters. */
     499             :   true,  /* isInfallible. False in setters. */
     500             :   false,  /* isMovable.  Not relevant for setters. */
     501             :   false, /* isEliminatable.  Not relevant for setters. */
     502             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     503             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     504             :   false,  /* isTypedMethod.  Only relevant for methods. */
     505             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     506             : };
     507             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     508             : static_assert(0 < 16, "There is no slot for us");
     509             : 
     510             : static bool
     511           0 : setVibrationPermission(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
     512             : {
     513           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
     514           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Navigator.setVibrationPermission");
     515             :   }
     516             :   bool arg0;
     517           0 :   if (!ValueToPrimitive<bool, eDefault>(cx, args[0], &arg0)) {
     518           0 :     return false;
     519             :   }
     520             :   bool arg1;
     521           0 :   if (args.hasDefined(1)) {
     522           0 :     if (!ValueToPrimitive<bool, eDefault>(cx, args[1], &arg1)) {
     523           0 :       return false;
     524             :     }
     525             :   } else {
     526           0 :     arg1 = true;
     527             :   }
     528           0 :   self->SetVibrationPermission(arg0, arg1);
     529           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     530           0 :   args.rval().setUndefined();
     531           0 :   return true;
     532             : }
     533             : 
     534             : static const JSJitInfo setVibrationPermission_methodinfo = {
     535             :   { (JSJitGetterOp)setVibrationPermission },
     536             :   { prototypes::id::Navigator },
     537             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     538             :   JSJitInfo::Method,
     539             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     540             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
     541             :   false,  /* isInfallible. False in setters. */
     542             :   false,  /* isMovable.  Not relevant for setters. */
     543             :   false, /* isEliminatable.  Not relevant for setters. */
     544             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     545             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     546             :   false,  /* isTypedMethod.  Only relevant for methods. */
     547             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     548             : };
     549             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     550             : static_assert(0 < 16, "There is no slot for us");
     551             : 
     552             : static bool
     553           0 : get_oscpu(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
     554             : {
     555             :   // Have to either root across the getter call or reget after.
     556             :   bool isXray;
     557           0 :   JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
     558           0 :   if (!slotStorage) {
     559           0 :     return false;
     560             :   }
     561           0 :   const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 0) : (DOM_INSTANCE_RESERVED_SLOTS + 0);
     562           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
     563             :   {
     564             :     // Scope for cachedVal
     565           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
     566           0 :     if (!cachedVal.isUndefined()) {
     567           0 :       args.rval().set(cachedVal);
     568             :       // The cached value is in the compartment of slotStorage,
     569             :       // so wrap into the caller compartment as needed.
     570           0 :       return MaybeWrapValue(cx, args.rval());
     571             :     }
     572             :   }
     573             : 
     574           0 :   binding_detail::FastErrorResult rv;
     575           0 :   DOMString result;
     576           0 :   self->GetOscpu(result, nsContentUtils::IsSystemCaller(cx) ? CallerType::System : CallerType::NonSystem, rv);
     577           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     578           0 :     return false;
     579             :   }
     580           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     581             :   {
     582           0 :     JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
     583           0 :     JSAutoCompartment ac(cx, conversionScope);
     584             :     do { // block we break out of when done wrapping
     585           0 :       if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
     586           0 :         return false;
     587             :       }
     588           0 :       break;
     589             :     } while (0);
     590             :   }
     591             :   { // And now store things in the compartment of our slotStorage.
     592           0 :     JSAutoCompartment ac(cx, slotStorage);
     593             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
     594           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
     595           0 :     if (!MaybeWrapValue(cx, &storedVal)) {
     596           0 :       return false;
     597             :     }
     598           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
     599           0 :     if (!isXray) {
     600             :       // In the Xray case we don't need to do this, because getting the
     601             :       // expando object already preserved our wrapper.
     602           0 :       PreserveWrapper(self);
     603             :     }
     604             :   }
     605             :   // And now make sure args.rval() is in the caller compartment
     606           0 :   return MaybeWrapValue(cx, args.rval());
     607             : }
     608             : 
     609             : static const JSJitInfo oscpu_getterinfo = {
     610             :   { (JSJitGetterOp)get_oscpu },
     611             :   { prototypes::id::Navigator },
     612             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     613             :   JSJitInfo::Getter,
     614             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
     615             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
     616             :   false,  /* isInfallible. False in setters. */
     617             :   false,  /* isMovable.  Not relevant for setters. */
     618             :   false, /* isEliminatable.  Not relevant for setters. */
     619             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     620             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
     621             :   false,  /* isTypedMethod.  Only relevant for methods. */
     622             :   (DOM_INSTANCE_RESERVED_SLOTS + 0)   /* Reserved slot index, if we're stored in a slot, else 0. */
     623             : };
     624             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit");
     625             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 16, "There is no slot for us");
     626             : 
     627             : static bool
     628           0 : get_vendor(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
     629             : {
     630           0 :   DOMString result;
     631           0 :   self->GetVendor(result);
     632           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     633           0 :   if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
     634           0 :     return false;
     635             :   }
     636           0 :   return true;
     637             : }
     638             : 
     639             : static const JSJitInfo vendor_getterinfo = {
     640             :   { (JSJitGetterOp)get_vendor },
     641             :   { prototypes::id::Navigator },
     642             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     643             :   JSJitInfo::Getter,
     644             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     645             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
     646             :   false,  /* isInfallible. False in setters. */
     647             :   false,  /* isMovable.  Not relevant for setters. */
     648             :   false, /* isEliminatable.  Not relevant for setters. */
     649             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     650             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     651             :   false,  /* isTypedMethod.  Only relevant for methods. */
     652             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     653             : };
     654             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     655             : static_assert(0 < 16, "There is no slot for us");
     656             : 
     657             : static bool
     658           0 : get_vendorSub(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
     659             : {
     660           0 :   DOMString result;
     661           0 :   self->GetVendorSub(result);
     662           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     663           0 :   if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
     664           0 :     return false;
     665             :   }
     666           0 :   return true;
     667             : }
     668             : 
     669             : static const JSJitInfo vendorSub_getterinfo = {
     670             :   { (JSJitGetterOp)get_vendorSub },
     671             :   { prototypes::id::Navigator },
     672             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     673             :   JSJitInfo::Getter,
     674             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     675             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
     676             :   false,  /* isInfallible. False in setters. */
     677             :   false,  /* isMovable.  Not relevant for setters. */
     678             :   false, /* isEliminatable.  Not relevant for setters. */
     679             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     680             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     681             :   false,  /* isTypedMethod.  Only relevant for methods. */
     682             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     683             : };
     684             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     685             : static_assert(0 < 16, "There is no slot for us");
     686             : 
     687             : static bool
     688           0 : get_productSub(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
     689             : {
     690           0 :   DOMString result;
     691           0 :   self->GetProductSub(result);
     692           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     693           0 :   if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
     694           0 :     return false;
     695             :   }
     696           0 :   return true;
     697             : }
     698             : 
     699             : static const JSJitInfo productSub_getterinfo = {
     700             :   { (JSJitGetterOp)get_productSub },
     701             :   { prototypes::id::Navigator },
     702             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     703             :   JSJitInfo::Getter,
     704             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     705             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
     706             :   false,  /* isInfallible. False in setters. */
     707             :   false,  /* isMovable.  Not relevant for setters. */
     708             :   false, /* isEliminatable.  Not relevant for setters. */
     709             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     710             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     711             :   false,  /* isTypedMethod.  Only relevant for methods. */
     712             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     713             : };
     714             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     715             : static_assert(0 < 16, "There is no slot for us");
     716             : 
     717             : static bool
     718           0 : get_cookieEnabled(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
     719             : {
     720           0 :   bool result(self->CookieEnabled());
     721           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     722           0 :   args.rval().setBoolean(result);
     723           0 :   return true;
     724             : }
     725             : 
     726             : static const JSJitInfo cookieEnabled_getterinfo = {
     727             :   { (JSJitGetterOp)get_cookieEnabled },
     728             :   { prototypes::id::Navigator },
     729             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     730             :   JSJitInfo::Getter,
     731             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     732             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
     733             :   true,  /* isInfallible. False in setters. */
     734             :   false,  /* isMovable.  Not relevant for setters. */
     735             :   false, /* isEliminatable.  Not relevant for setters. */
     736             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     737             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     738             :   false,  /* isTypedMethod.  Only relevant for methods. */
     739             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     740             : };
     741             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     742             : static_assert(0 < 16, "There is no slot for us");
     743             : 
     744             : static bool
     745           0 : get_buildID(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
     746             : {
     747             :   // Have to either root across the getter call or reget after.
     748             :   bool isXray;
     749           0 :   JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
     750           0 :   if (!slotStorage) {
     751           0 :     return false;
     752             :   }
     753           0 :   const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 1) : (DOM_INSTANCE_RESERVED_SLOTS + 1);
     754           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
     755             :   {
     756             :     // Scope for cachedVal
     757           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
     758           0 :     if (!cachedVal.isUndefined()) {
     759           0 :       args.rval().set(cachedVal);
     760             :       // The cached value is in the compartment of slotStorage,
     761             :       // so wrap into the caller compartment as needed.
     762           0 :       return MaybeWrapValue(cx, args.rval());
     763             :     }
     764             :   }
     765             : 
     766           0 :   binding_detail::FastErrorResult rv;
     767           0 :   DOMString result;
     768           0 :   self->GetBuildID(result, nsContentUtils::IsSystemCaller(cx) ? CallerType::System : CallerType::NonSystem, rv);
     769           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     770           0 :     return false;
     771             :   }
     772           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     773             :   {
     774           0 :     JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
     775           0 :     JSAutoCompartment ac(cx, conversionScope);
     776             :     do { // block we break out of when done wrapping
     777           0 :       if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
     778           0 :         return false;
     779             :       }
     780           0 :       break;
     781             :     } while (0);
     782             :   }
     783             :   { // And now store things in the compartment of our slotStorage.
     784           0 :     JSAutoCompartment ac(cx, slotStorage);
     785             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
     786           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
     787           0 :     if (!MaybeWrapValue(cx, &storedVal)) {
     788           0 :       return false;
     789             :     }
     790           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
     791           0 :     if (!isXray) {
     792             :       // In the Xray case we don't need to do this, because getting the
     793             :       // expando object already preserved our wrapper.
     794           0 :       PreserveWrapper(self);
     795             :     }
     796             :   }
     797             :   // And now make sure args.rval() is in the caller compartment
     798           0 :   return MaybeWrapValue(cx, args.rval());
     799             : }
     800             : 
     801             : static const JSJitInfo buildID_getterinfo = {
     802             :   { (JSJitGetterOp)get_buildID },
     803             :   { prototypes::id::Navigator },
     804             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     805             :   JSJitInfo::Getter,
     806             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
     807             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
     808             :   false,  /* isInfallible. False in setters. */
     809             :   false,  /* isMovable.  Not relevant for setters. */
     810             :   false, /* isEliminatable.  Not relevant for setters. */
     811             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     812             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
     813             :   false,  /* isTypedMethod.  Only relevant for methods. */
     814             :   (DOM_INSTANCE_RESERVED_SLOTS + 1)   /* Reserved slot index, if we're stored in a slot, else 0. */
     815             : };
     816             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 1) <= JSJitInfo::maxSlotIndex, "We won't fit");
     817             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 1) < 16, "There is no slot for us");
     818             : 
     819             : static bool
     820           0 : get_mozPower(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
     821             : {
     822           0 :   if (!mozilla::dom::EnforceNotInPrerendering(cx, obj)) {
     823             :       // Return false from the JSNative in order to trigger
     824             :       // an uncatchable exception.
     825           0 :       MOZ_ASSERT(!JS_IsExceptionPending(cx));
     826           0 :       return false;
     827             :   }
     828           0 :   binding_detail::FastErrorResult rv;
     829           0 :   auto result(StrongOrRawPtr<mozilla::dom::PowerManager>(self->GetMozPower(rv)));
     830           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     831           0 :     return false;
     832             :   }
     833           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     834           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
     835           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     836           0 :     return false;
     837             :   }
     838           0 :   return true;
     839             : }
     840             : 
     841             : static const JSJitInfo mozPower_getterinfo = {
     842             :   { (JSJitGetterOp)get_mozPower },
     843             :   { prototypes::id::Navigator },
     844             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     845             :   JSJitInfo::Getter,
     846             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     847             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     848             :   false,  /* isInfallible. False in setters. */
     849             :   false,  /* isMovable.  Not relevant for setters. */
     850             :   false, /* isEliminatable.  Not relevant for setters. */
     851             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     852             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     853             :   false,  /* isTypedMethod.  Only relevant for methods. */
     854             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     855             : };
     856             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     857             : static_assert(0 < 16, "There is no slot for us");
     858             : 
     859             : static bool
     860           0 : javaEnabled(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
     861             : {
     862           0 :   binding_detail::FastErrorResult rv;
     863           0 :   bool result(self->JavaEnabled(nsContentUtils::IsSystemCaller(cx) ? CallerType::System : CallerType::NonSystem, rv));
     864           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     865           0 :     return false;
     866             :   }
     867           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     868           0 :   args.rval().setBoolean(result);
     869           0 :   return true;
     870             : }
     871             : 
     872             : static const JSJitInfo javaEnabled_methodinfo = {
     873             :   { (JSJitGetterOp)javaEnabled },
     874             :   { prototypes::id::Navigator },
     875             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     876             :   JSJitInfo::Method,
     877             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     878             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
     879             :   false,  /* isInfallible. False in setters. */
     880             :   false,  /* isMovable.  Not relevant for setters. */
     881             :   false, /* isEliminatable.  Not relevant for setters. */
     882             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     883             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     884             :   false,  /* isTypedMethod.  Only relevant for methods. */
     885             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     886             : };
     887             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     888             : static_assert(0 < 16, "There is no slot for us");
     889             : 
     890             : static bool
     891           0 : addIdleObserver(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
     892             : {
     893           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
     894           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Navigator.addIdleObserver");
     895             :   }
     896           0 :   RootedCallback<OwningNonNull<binding_detail::FastMozIdleObserver>> arg0(cx);
     897           0 :   if (args[0].isObject()) {
     898             :     { // scope for tempRoot
     899           0 :       JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
     900           0 :       arg0 = new binding_detail::FastMozIdleObserver(tempRoot);
     901             :     }
     902             :   } else {
     903           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of Navigator.addIdleObserver");
     904           0 :     return false;
     905             :   }
     906           0 :   binding_detail::FastErrorResult rv;
     907           0 :   self->AddIdleObserver(NonNullHelper(arg0), rv);
     908           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     909           0 :     return false;
     910             :   }
     911           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     912           0 :   args.rval().setUndefined();
     913           0 :   return true;
     914             : }
     915             : 
     916             : static const JSJitInfo addIdleObserver_methodinfo = {
     917             :   { (JSJitGetterOp)addIdleObserver },
     918             :   { prototypes::id::Navigator },
     919             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     920             :   JSJitInfo::Method,
     921             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     922             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
     923             :   false,  /* isInfallible. False in setters. */
     924             :   false,  /* isMovable.  Not relevant for setters. */
     925             :   false, /* isEliminatable.  Not relevant for setters. */
     926             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     927             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     928             :   false,  /* isTypedMethod.  Only relevant for methods. */
     929             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     930             : };
     931             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     932             : static_assert(0 < 16, "There is no slot for us");
     933             : 
     934             : static bool
     935           0 : removeIdleObserver(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
     936             : {
     937           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
     938           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Navigator.removeIdleObserver");
     939             :   }
     940           0 :   RootedCallback<OwningNonNull<binding_detail::FastMozIdleObserver>> arg0(cx);
     941           0 :   if (args[0].isObject()) {
     942             :     { // scope for tempRoot
     943           0 :       JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
     944           0 :       arg0 = new binding_detail::FastMozIdleObserver(tempRoot);
     945             :     }
     946             :   } else {
     947           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of Navigator.removeIdleObserver");
     948           0 :     return false;
     949             :   }
     950           0 :   binding_detail::FastErrorResult rv;
     951           0 :   self->RemoveIdleObserver(NonNullHelper(arg0), rv);
     952           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     953           0 :     return false;
     954             :   }
     955           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     956           0 :   args.rval().setUndefined();
     957           0 :   return true;
     958             : }
     959             : 
     960             : static const JSJitInfo removeIdleObserver_methodinfo = {
     961             :   { (JSJitGetterOp)removeIdleObserver },
     962             :   { prototypes::id::Navigator },
     963             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
     964             :   JSJitInfo::Method,
     965             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     966             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
     967             :   false,  /* isInfallible. False in setters. */
     968             :   false,  /* isMovable.  Not relevant for setters. */
     969             :   false, /* isEliminatable.  Not relevant for setters. */
     970             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     971             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     972             :   false,  /* isTypedMethod.  Only relevant for methods. */
     973             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     974             : };
     975             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     976             : static_assert(0 < 16, "There is no slot for us");
     977             : 
     978             : static bool
     979           0 : requestWakeLock(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
     980             : {
     981           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
     982           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Navigator.requestWakeLock");
     983             :   }
     984           0 :   if (!mozilla::dom::EnforceNotInPrerendering(cx, obj)) {
     985             :       // Return false from the JSNative in order to trigger
     986             :       // an uncatchable exception.
     987           0 :       MOZ_ASSERT(!JS_IsExceptionPending(cx));
     988           0 :       return false;
     989             :   }
     990           0 :   binding_detail::FakeString arg0;
     991           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
     992           0 :     return false;
     993             :   }
     994           0 :   binding_detail::FastErrorResult rv;
     995           0 :   auto result(StrongOrRawPtr<mozilla::dom::WakeLock>(self->RequestWakeLock(NonNullHelper(Constify(arg0)), rv)));
     996           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     997           0 :     return false;
     998             :   }
     999           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1000           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    1001           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1002           0 :     return false;
    1003             :   }
    1004           0 :   return true;
    1005             : }
    1006             : 
    1007             : static const JSJitInfo requestWakeLock_methodinfo = {
    1008             :   { (JSJitGetterOp)requestWakeLock },
    1009             :   { prototypes::id::Navigator },
    1010             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1011             :   JSJitInfo::Method,
    1012             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1013             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1014             :   false,  /* isInfallible. False in setters. */
    1015             :   false,  /* isMovable.  Not relevant for setters. */
    1016             :   false, /* isEliminatable.  Not relevant for setters. */
    1017             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1018             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1019             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1020             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1021             : };
    1022             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1023             : static_assert(0 < 16, "There is no slot for us");
    1024             : 
    1025             : static bool
    1026           0 : get_cpuHasSSE2(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    1027             : {
    1028           0 :   bool result(self->CpuHasSSE2());
    1029           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1030           0 :   args.rval().setBoolean(result);
    1031           0 :   return true;
    1032             : }
    1033             : 
    1034             : static const JSJitInfo cpuHasSSE2_getterinfo = {
    1035             :   { (JSJitGetterOp)get_cpuHasSSE2 },
    1036             :   { prototypes::id::Navigator },
    1037             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1038             :   JSJitInfo::Getter,
    1039             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1040             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    1041             :   true,  /* isInfallible. False in setters. */
    1042             :   false,  /* isMovable.  Not relevant for setters. */
    1043             :   false, /* isEliminatable.  Not relevant for setters. */
    1044             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1045             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1046             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1047             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1048             : };
    1049             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1050             : static_assert(0 < 16, "There is no slot for us");
    1051             : 
    1052             : static bool
    1053           0 : get_mozNotification(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    1054             : {
    1055           0 :   if (!mozilla::dom::EnforceNotInPrerendering(cx, obj)) {
    1056             :       // Return false from the JSNative in order to trigger
    1057             :       // an uncatchable exception.
    1058           0 :       MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1059           0 :       return false;
    1060             :   }
    1061           0 :   binding_detail::FastErrorResult rv;
    1062           0 :   auto result(StrongOrRawPtr<mozilla::dom::DesktopNotificationCenter>(self->GetMozNotification(rv)));
    1063           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1064           0 :     return false;
    1065             :   }
    1066           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1067           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    1068           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1069           0 :     return false;
    1070             :   }
    1071           0 :   return true;
    1072             : }
    1073             : 
    1074             : static const JSJitInfo mozNotification_getterinfo = {
    1075             :   { (JSJitGetterOp)get_mozNotification },
    1076             :   { prototypes::id::Navigator },
    1077             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1078             :   JSJitInfo::Getter,
    1079             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1080             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1081             :   false,  /* isInfallible. False in setters. */
    1082             :   false,  /* isMovable.  Not relevant for setters. */
    1083             :   false, /* isEliminatable.  Not relevant for setters. */
    1084             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1085             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1086             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1087             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1088             : };
    1089             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1090             : static_assert(0 < 16, "There is no slot for us");
    1091             : 
    1092             : static bool
    1093           0 : get_connection(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    1094             : {
    1095           0 :   binding_detail::FastErrorResult rv;
    1096           0 :   auto result(StrongOrRawPtr<mozilla::dom::network::Connection>(self->GetConnection(rv)));
    1097           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1098           0 :     return false;
    1099             :   }
    1100           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1101           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    1102           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1103           0 :     return false;
    1104             :   }
    1105           0 :   return true;
    1106             : }
    1107             : 
    1108             : static const JSJitInfo connection_getterinfo = {
    1109             :   { (JSJitGetterOp)get_connection },
    1110             :   { prototypes::id::Navigator },
    1111             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1112             :   JSJitInfo::Getter,
    1113             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1114             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1115             :   false,  /* isInfallible. False in setters. */
    1116             :   false,  /* isMovable.  Not relevant for setters. */
    1117             :   false, /* isEliminatable.  Not relevant for setters. */
    1118             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1119             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1120             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1121             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1122             : };
    1123             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1124             : static_assert(0 < 16, "There is no slot for us");
    1125             : 
    1126             : static bool
    1127           0 : getGamepads(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
    1128             : {
    1129           0 :   binding_detail::FastErrorResult rv;
    1130           0 :   nsTArray<StrongPtrForMember<mozilla::dom::Gamepad>::Type> result;
    1131           0 :   self->GetGamepads(result, rv);
    1132           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1133           0 :     return false;
    1134             :   }
    1135           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1136             : 
    1137           0 :   uint32_t length = result.Length();
    1138           0 :   JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
    1139           0 :   if (!returnArray) {
    1140           0 :     return false;
    1141             :   }
    1142             :   // Scope for 'tmp'
    1143             :   {
    1144           0 :     JS::Rooted<JS::Value> tmp(cx);
    1145           0 :     for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
    1146             :       // Control block to let us common up the JS_DefineElement calls when there
    1147             :       // are different ways to succeed at wrapping the object.
    1148             :       do {
    1149           0 :         if (!result[sequenceIdx0]) {
    1150           0 :           tmp.setNull();
    1151           0 :           break;
    1152             :         }
    1153           0 :         if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) {
    1154           0 :           MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1155           0 :           return false;
    1156             :         }
    1157           0 :         break;
    1158             :       } while (0);
    1159           0 :       if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
    1160             :                             JSPROP_ENUMERATE)) {
    1161           0 :         return false;
    1162             :       }
    1163             :     }
    1164             :   }
    1165           0 :   args.rval().setObject(*returnArray);
    1166           0 :   return true;
    1167             : }
    1168             : 
    1169             : static const JSJitInfo getGamepads_methodinfo = {
    1170             :   { (JSJitGetterOp)getGamepads },
    1171             :   { prototypes::id::Navigator },
    1172             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1173             :   JSJitInfo::Method,
    1174             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1175             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1176             :   false,  /* isInfallible. False in setters. */
    1177             :   false,  /* isMovable.  Not relevant for setters. */
    1178             :   false, /* isEliminatable.  Not relevant for setters. */
    1179             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1180             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1181             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1182             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1183             : };
    1184             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1185             : static_assert(0 < 16, "There is no slot for us");
    1186             : 
    1187             : static bool
    1188           0 : requestGamepadServiceTest(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
    1189             : {
    1190           0 :   auto result(StrongOrRawPtr<mozilla::dom::GamepadServiceTest>(self->RequestGamepadServiceTest()));
    1191           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1192           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    1193           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1194           0 :     return false;
    1195             :   }
    1196           0 :   return true;
    1197             : }
    1198             : 
    1199             : static const JSJitInfo requestGamepadServiceTest_methodinfo = {
    1200             :   { (JSJitGetterOp)requestGamepadServiceTest },
    1201             :   { prototypes::id::Navigator },
    1202             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1203             :   JSJitInfo::Method,
    1204             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1205             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1206             :   false,  /* isInfallible. False in setters. */
    1207             :   false,  /* isMovable.  Not relevant for setters. */
    1208             :   false, /* isEliminatable.  Not relevant for setters. */
    1209             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1210             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1211             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1212             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1213             : };
    1214             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1215             : static_assert(0 < 16, "There is no slot for us");
    1216             : 
    1217             : static bool
    1218           0 : getVRDisplays(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
    1219             : {
    1220           0 :   binding_detail::FastErrorResult rv;
    1221           0 :   auto result(StrongOrRawPtr<Promise>(self->GetVRDisplays(rv)));
    1222           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1223           0 :     return false;
    1224             :   }
    1225           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1226           0 :   if (!ToJSValue(cx, result, args.rval())) {
    1227           0 :     return false;
    1228             :   }
    1229           0 :   return true;
    1230             : }
    1231             : 
    1232             : static bool
    1233           0 : getVRDisplays_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
    1234             : {
    1235             :   // Make sure to save the callee before someone maybe messes
    1236             :   // with rval().
    1237           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
    1238           0 :   bool ok = getVRDisplays(cx, obj, self, args);
    1239           0 :   if (ok) {
    1240           0 :     return true;
    1241             :   }
    1242           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
    1243           0 :                                    args.rval());
    1244             : }
    1245             : 
    1246             : static const JSJitInfo getVRDisplays_methodinfo = {
    1247             :   { (JSJitGetterOp)getVRDisplays_promiseWrapper },
    1248             :   { prototypes::id::Navigator },
    1249             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1250             :   JSJitInfo::Method,
    1251             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1252             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1253             :   false,  /* isInfallible. False in setters. */
    1254             :   false,  /* isMovable.  Not relevant for setters. */
    1255             :   false, /* isEliminatable.  Not relevant for setters. */
    1256             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1257             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1258             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1259             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1260             : };
    1261             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1262             : static_assert(0 < 16, "There is no slot for us");
    1263             : 
    1264             : static bool
    1265           0 : get_activeVRDisplays(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    1266             : {
    1267             :   // Have to either root across the getter call or reget after.
    1268             :   bool isXray;
    1269           0 :   JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
    1270           0 :   if (!slotStorage) {
    1271           0 :     return false;
    1272             :   }
    1273           0 :   const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 2) : (DOM_INSTANCE_RESERVED_SLOTS + 2);
    1274           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    1275             :   {
    1276             :     // Scope for cachedVal
    1277           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    1278           0 :     if (!cachedVal.isUndefined()) {
    1279           0 :       args.rval().set(cachedVal);
    1280             :       // The cached value is in the compartment of slotStorage,
    1281             :       // so wrap into the caller compartment as needed.
    1282           0 :       return MaybeWrapNonDOMObjectValue(cx, args.rval());
    1283             :     }
    1284             :   }
    1285             : 
    1286           0 :   nsTArray<StrongPtrForMember<mozilla::dom::VRDisplay>::Type> result;
    1287           0 :   self->GetActiveVRDisplays(result);
    1288           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1289             :   {
    1290           0 :     JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
    1291           0 :     JSAutoCompartment ac(cx, conversionScope);
    1292             :     do { // block we break out of when done wrapping
    1293             : 
    1294           0 :       uint32_t length = result.Length();
    1295           0 :       JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
    1296           0 :       if (!returnArray) {
    1297           0 :         return false;
    1298             :       }
    1299             :       // Scope for 'tmp'
    1300             :       {
    1301           0 :         JS::Rooted<JS::Value> tmp(cx);
    1302           0 :         for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
    1303             :           // Control block to let us common up the JS_DefineElement calls when there
    1304             :           // are different ways to succeed at wrapping the object.
    1305             :           do {
    1306           0 :             if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) {
    1307           0 :               MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1308           0 :               return false;
    1309             :             }
    1310           0 :             break;
    1311             :           } while (0);
    1312           0 :           if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
    1313             :                                 JSPROP_ENUMERATE)) {
    1314           0 :             return false;
    1315             :           }
    1316             :         }
    1317             :       }
    1318           0 :       args.rval().setObject(*returnArray);
    1319           0 :       break;
    1320             :     } while (0);
    1321           0 :     JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
    1322           0 :     if (!JS_FreezeObject(cx, rvalObj)) {
    1323           0 :       return false;
    1324             :     }
    1325             :   }
    1326             :   { // And now store things in the compartment of our slotStorage.
    1327           0 :     JSAutoCompartment ac(cx, slotStorage);
    1328             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    1329           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    1330           0 :     if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
    1331           0 :       return false;
    1332             :     }
    1333           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    1334           0 :     if (!isXray) {
    1335             :       // In the Xray case we don't need to do this, because getting the
    1336             :       // expando object already preserved our wrapper.
    1337           0 :       PreserveWrapper(self);
    1338             :     }
    1339             :   }
    1340             :   // And now make sure args.rval() is in the caller compartment
    1341           0 :   return MaybeWrapNonDOMObjectValue(cx, args.rval());
    1342             : }
    1343             : 
    1344             : static const JSJitInfo activeVRDisplays_getterinfo = {
    1345             :   { (JSJitGetterOp)get_activeVRDisplays },
    1346             :   { prototypes::id::Navigator },
    1347             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1348             :   JSJitInfo::Getter,
    1349             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    1350             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1351             :   false,  /* isInfallible. False in setters. */
    1352             :   true,  /* isMovable.  Not relevant for setters. */
    1353             :   true, /* isEliminatable.  Not relevant for setters. */
    1354             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1355             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1356             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1357             :   (DOM_INSTANCE_RESERVED_SLOTS + 2)   /* Reserved slot index, if we're stored in a slot, else 0. */
    1358             : };
    1359             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 2) <= JSJitInfo::maxSlotIndex, "We won't fit");
    1360             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 2) < 16, "There is no slot for us");
    1361             : 
    1362             : static bool
    1363           0 : get_isWebVRContentDetected(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    1364             : {
    1365           0 :   bool result(self->IsWebVRContentDetected());
    1366           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1367           0 :   args.rval().setBoolean(result);
    1368           0 :   return true;
    1369             : }
    1370             : 
    1371             : static const JSJitInfo isWebVRContentDetected_getterinfo = {
    1372             :   { (JSJitGetterOp)get_isWebVRContentDetected },
    1373             :   { prototypes::id::Navigator },
    1374             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1375             :   JSJitInfo::Getter,
    1376             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1377             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    1378             :   true,  /* isInfallible. False in setters. */
    1379             :   false,  /* isMovable.  Not relevant for setters. */
    1380             :   false, /* isEliminatable.  Not relevant for setters. */
    1381             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1382             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1383             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1384             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1385             : };
    1386             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1387             : static_assert(0 < 16, "There is no slot for us");
    1388             : 
    1389             : static bool
    1390           0 : get_isWebVRContentPresenting(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    1391             : {
    1392           0 :   bool result(self->IsWebVRContentPresenting());
    1393           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1394           0 :   args.rval().setBoolean(result);
    1395           0 :   return true;
    1396             : }
    1397             : 
    1398             : static const JSJitInfo isWebVRContentPresenting_getterinfo = {
    1399             :   { (JSJitGetterOp)get_isWebVRContentPresenting },
    1400             :   { prototypes::id::Navigator },
    1401             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1402             :   JSJitInfo::Getter,
    1403             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1404             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    1405             :   true,  /* isInfallible. False in setters. */
    1406             :   false,  /* isMovable.  Not relevant for setters. */
    1407             :   false, /* isEliminatable.  Not relevant for setters. */
    1408             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1409             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1410             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1411             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1412             : };
    1413             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1414             : static_assert(0 < 16, "There is no slot for us");
    1415             : 
    1416             : static bool
    1417           0 : requestVRPresentation(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
    1418             : {
    1419           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    1420           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Navigator.requestVRPresentation");
    1421             :   }
    1422           0 :   NonNull<mozilla::dom::VRDisplay> arg0;
    1423           0 :   if (args[0].isObject()) {
    1424             :     {
    1425           0 :       nsresult rv = UnwrapObject<prototypes::id::VRDisplay, mozilla::dom::VRDisplay>(args[0], arg0);
    1426           0 :       if (NS_FAILED(rv)) {
    1427           0 :         ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of Navigator.requestVRPresentation", "VRDisplay");
    1428           0 :         return false;
    1429             :       }
    1430             :     }
    1431             :   } else {
    1432           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of Navigator.requestVRPresentation");
    1433           0 :     return false;
    1434             :   }
    1435           0 :   self->RequestVRPresentation(NonNullHelper(arg0));
    1436           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1437           0 :   args.rval().setUndefined();
    1438           0 :   return true;
    1439             : }
    1440             : 
    1441             : static const JSJitInfo requestVRPresentation_methodinfo = {
    1442             :   { (JSJitGetterOp)requestVRPresentation },
    1443             :   { prototypes::id::Navigator },
    1444             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1445             :   JSJitInfo::Method,
    1446             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1447             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    1448             :   false,  /* isInfallible. False in setters. */
    1449             :   false,  /* isMovable.  Not relevant for setters. */
    1450             :   false, /* isEliminatable.  Not relevant for setters. */
    1451             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1452             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1453             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1454             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1455             : };
    1456             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1457             : static_assert(0 < 16, "There is no slot for us");
    1458             : 
    1459             : static bool
    1460           0 : requestVRServiceTest(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
    1461             : {
    1462           0 :   auto result(StrongOrRawPtr<mozilla::dom::VRServiceTest>(self->RequestVRServiceTest()));
    1463           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1464           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    1465           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1466           0 :     return false;
    1467             :   }
    1468           0 :   return true;
    1469             : }
    1470             : 
    1471             : static const JSJitInfo requestVRServiceTest_methodinfo = {
    1472             :   { (JSJitGetterOp)requestVRServiceTest },
    1473             :   { prototypes::id::Navigator },
    1474             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1475             :   JSJitInfo::Method,
    1476             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1477             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1478             :   false,  /* isInfallible. False in setters. */
    1479             :   false,  /* isMovable.  Not relevant for setters. */
    1480             :   false, /* isEliminatable.  Not relevant for setters. */
    1481             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1482             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1483             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1484             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1485             : };
    1486             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1487             : static_assert(0 < 16, "There is no slot for us");
    1488             : 
    1489             : static bool
    1490           0 : get_mediaDevices(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    1491             : {
    1492           0 :   binding_detail::FastErrorResult rv;
    1493           0 :   auto result(StrongOrRawPtr<mozilla::dom::MediaDevices>(self->GetMediaDevices(rv)));
    1494           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1495           0 :     return false;
    1496             :   }
    1497           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1498           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    1499           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1500           0 :     return false;
    1501             :   }
    1502           0 :   return true;
    1503             : }
    1504             : 
    1505             : static const JSJitInfo mediaDevices_getterinfo = {
    1506             :   { (JSJitGetterOp)get_mediaDevices },
    1507             :   { prototypes::id::Navigator },
    1508             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1509             :   JSJitInfo::Getter,
    1510             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1511             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1512             :   false,  /* isInfallible. False in setters. */
    1513             :   false,  /* isMovable.  Not relevant for setters. */
    1514             :   false, /* isEliminatable.  Not relevant for setters. */
    1515             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1516             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1517             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1518             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1519             : };
    1520             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1521             : static_assert(0 < 16, "There is no slot for us");
    1522             : 
    1523             : static bool
    1524           0 : mozGetUserMedia(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
    1525             : {
    1526           0 :   if (MOZ_UNLIKELY(args.length() < 3)) {
    1527           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Navigator.mozGetUserMedia");
    1528             :   }
    1529           0 :   if (!mozilla::dom::EnforceNotInPrerendering(cx, obj)) {
    1530             :       // Return false from the JSNative in order to trigger
    1531             :       // an uncatchable exception.
    1532           0 :       MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1533           0 :       return false;
    1534             :   }
    1535           0 :   DeprecationWarning(cx, obj, nsIDocument::eNavigatorGetUserMedia);
    1536           0 :   binding_detail::FastMediaStreamConstraints arg0;
    1537           0 :   if (!arg0.Init(cx, args[0],  "Argument 1 of Navigator.mozGetUserMedia", false)) {
    1538           0 :     return false;
    1539             :   }
    1540           0 :   RootedCallback<OwningNonNull<binding_detail::FastNavigatorUserMediaSuccessCallback>> arg1(cx);
    1541           0 :   if (args[1].isObject()) {
    1542           0 :     if (JS::IsCallable(&args[1].toObject())) {
    1543             :     { // scope for tempRoot
    1544           0 :       JS::Rooted<JSObject*> tempRoot(cx, &args[1].toObject());
    1545           0 :       arg1 = new binding_detail::FastNavigatorUserMediaSuccessCallback(tempRoot);
    1546             :     }
    1547             :     } else {
    1548           0 :       ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "Argument 2 of Navigator.mozGetUserMedia");
    1549           0 :       return false;
    1550             :     }
    1551             :   } else {
    1552           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of Navigator.mozGetUserMedia");
    1553           0 :     return false;
    1554             :   }
    1555           0 :   RootedCallback<OwningNonNull<binding_detail::FastNavigatorUserMediaErrorCallback>> arg2(cx);
    1556           0 :   if (args[2].isObject()) {
    1557           0 :     if (JS::IsCallable(&args[2].toObject())) {
    1558             :     { // scope for tempRoot
    1559           0 :       JS::Rooted<JSObject*> tempRoot(cx, &args[2].toObject());
    1560           0 :       arg2 = new binding_detail::FastNavigatorUserMediaErrorCallback(tempRoot);
    1561             :     }
    1562             :     } else {
    1563           0 :       ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "Argument 3 of Navigator.mozGetUserMedia");
    1564           0 :       return false;
    1565             :     }
    1566             :   } else {
    1567           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 3 of Navigator.mozGetUserMedia");
    1568           0 :     return false;
    1569             :   }
    1570           0 :   binding_detail::FastErrorResult rv;
    1571           0 :   self->MozGetUserMedia(Constify(arg0), NonNullHelper(arg1), NonNullHelper(arg2), nsContentUtils::IsSystemCaller(cx) ? CallerType::System : CallerType::NonSystem, rv);
    1572           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1573           0 :     return false;
    1574             :   }
    1575           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1576           0 :   args.rval().setUndefined();
    1577           0 :   return true;
    1578             : }
    1579             : 
    1580             : static const JSJitInfo mozGetUserMedia_methodinfo = {
    1581             :   { (JSJitGetterOp)mozGetUserMedia },
    1582             :   { prototypes::id::Navigator },
    1583             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1584             :   JSJitInfo::Method,
    1585             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1586             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    1587             :   false,  /* isInfallible. False in setters. */
    1588             :   false,  /* isMovable.  Not relevant for setters. */
    1589             :   false, /* isEliminatable.  Not relevant for setters. */
    1590             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1591             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1592             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1593             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1594             : };
    1595             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1596             : static_assert(0 < 16, "There is no slot for us");
    1597             : 
    1598             : static bool
    1599           0 : mozGetUserMediaDevices(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
    1600             : {
    1601           0 :   if (MOZ_UNLIKELY(args.length() < 3)) {
    1602           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Navigator.mozGetUserMediaDevices");
    1603             :   }
    1604           0 :   binding_detail::FastMediaStreamConstraints arg0;
    1605           0 :   if (!arg0.Init(cx, args[0],  "Argument 1 of Navigator.mozGetUserMediaDevices", false)) {
    1606           0 :     return false;
    1607             :   }
    1608           0 :   RootedCallback<OwningNonNull<binding_detail::FastMozGetUserMediaDevicesSuccessCallback>> arg1(cx);
    1609           0 :   if (args[1].isObject()) {
    1610           0 :     if (JS::IsCallable(&args[1].toObject())) {
    1611             :     { // scope for tempRoot
    1612           0 :       JS::Rooted<JSObject*> tempRoot(cx, &args[1].toObject());
    1613           0 :       arg1 = new binding_detail::FastMozGetUserMediaDevicesSuccessCallback(tempRoot);
    1614             :     }
    1615             :     } else {
    1616           0 :       ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "Argument 2 of Navigator.mozGetUserMediaDevices");
    1617           0 :       return false;
    1618             :     }
    1619             :   } else {
    1620           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of Navigator.mozGetUserMediaDevices");
    1621           0 :     return false;
    1622             :   }
    1623           0 :   RootedCallback<OwningNonNull<binding_detail::FastNavigatorUserMediaErrorCallback>> arg2(cx);
    1624           0 :   if (args[2].isObject()) {
    1625           0 :     if (JS::IsCallable(&args[2].toObject())) {
    1626             :     { // scope for tempRoot
    1627           0 :       JS::Rooted<JSObject*> tempRoot(cx, &args[2].toObject());
    1628           0 :       arg2 = new binding_detail::FastNavigatorUserMediaErrorCallback(tempRoot);
    1629             :     }
    1630             :     } else {
    1631           0 :       ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "Argument 3 of Navigator.mozGetUserMediaDevices");
    1632           0 :       return false;
    1633             :     }
    1634             :   } else {
    1635           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 3 of Navigator.mozGetUserMediaDevices");
    1636           0 :     return false;
    1637             :   }
    1638             :   uint64_t arg3;
    1639           0 :   if (args.hasDefined(3)) {
    1640           0 :     if (!ValueToPrimitive<uint64_t, eDefault>(cx, args[3], &arg3)) {
    1641           0 :       return false;
    1642             :     }
    1643             :   } else {
    1644           0 :     arg3 = 0ULL;
    1645             :   }
    1646           0 :   binding_detail::FakeString arg4;
    1647           0 :   if (args.hasDefined(4)) {
    1648           0 :     if (!ConvertJSValueToString(cx, args[4], eStringify, eStringify, arg4)) {
    1649           0 :       return false;
    1650             :     }
    1651             :   } else {
    1652             :     static const char16_t data[] = { 0 };
    1653           0 :     arg4.Rebind(data, ArrayLength(data) - 1);
    1654             :   }
    1655           0 :   binding_detail::FastErrorResult rv;
    1656           0 :   self->MozGetUserMediaDevices(Constify(arg0), NonNullHelper(arg1), NonNullHelper(arg2), arg3, NonNullHelper(Constify(arg4)), rv);
    1657           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1658           0 :     return false;
    1659             :   }
    1660           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1661           0 :   args.rval().setUndefined();
    1662           0 :   return true;
    1663             : }
    1664             : 
    1665             : static const JSJitInfo mozGetUserMediaDevices_methodinfo = {
    1666             :   { (JSJitGetterOp)mozGetUserMediaDevices },
    1667             :   { prototypes::id::Navigator },
    1668             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1669             :   JSJitInfo::Method,
    1670             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1671             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    1672             :   false,  /* isInfallible. False in setters. */
    1673             :   false,  /* isMovable.  Not relevant for setters. */
    1674             :   false, /* isEliminatable.  Not relevant for setters. */
    1675             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1676             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1677             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1678             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1679             : };
    1680             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1681             : static_assert(0 < 16, "There is no slot for us");
    1682             : 
    1683             : static bool
    1684           0 : get_serviceWorker(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    1685             : {
    1686           0 :   auto result(StrongOrRawPtr<mozilla::dom::ServiceWorkerContainer>(self->ServiceWorker()));
    1687           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1688           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    1689           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1690           0 :     return false;
    1691             :   }
    1692           0 :   return true;
    1693             : }
    1694             : 
    1695             : static const JSJitInfo serviceWorker_getterinfo = {
    1696             :   { (JSJitGetterOp)get_serviceWorker },
    1697             :   { prototypes::id::Navigator },
    1698             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1699             :   JSJitInfo::Getter,
    1700             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    1701             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1702             :   false,  /* isInfallible. False in setters. */
    1703             :   true,  /* isMovable.  Not relevant for setters. */
    1704             :   true, /* isEliminatable.  Not relevant for setters. */
    1705             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1706             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1707             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1708             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1709             : };
    1710             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1711             : static_assert(0 < 16, "There is no slot for us");
    1712             : 
    1713             : static bool
    1714           0 : sendBeacon(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
    1715             : {
    1716           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    1717           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Navigator.sendBeacon");
    1718             :   }
    1719           0 :   binding_detail::FakeString arg0;
    1720           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    1721           0 :     return false;
    1722             :   }
    1723           0 :   Nullable<BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString > arg1;
    1724           0 :   Maybe<BlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVStringArgument> arg1_holder;
    1725           0 :   if (!(args.hasDefined(1)) || args[1].isNullOrUndefined()) {
    1726           0 :     arg1.SetNull();
    1727             :   } else {
    1728           0 :     arg1_holder.emplace(arg1.SetValue());
    1729             :     {
    1730           0 :       bool done = false, failed = false, tryNext;
    1731           0 :       if (args[1].isObject()) {
    1732           0 :         done = (failed = !arg1_holder.ref().TrySetToBlob(cx, args[1], tryNext, false)) || !tryNext ||
    1733           0 :                (failed = !arg1_holder.ref().TrySetToArrayBufferView(cx, args[1], tryNext, false)) || !tryNext ||
    1734           0 :                (failed = !arg1_holder.ref().TrySetToArrayBuffer(cx, args[1], tryNext, false)) || !tryNext ||
    1735           0 :                (failed = !arg1_holder.ref().TrySetToFormData(cx, args[1], tryNext, false)) || !tryNext ||
    1736           0 :                (failed = !arg1_holder.ref().TrySetToURLSearchParams(cx, args[1], tryNext, false)) || !tryNext;
    1737             : 
    1738             :       }
    1739           0 :       if (!done) {
    1740             :         do {
    1741           0 :           done = (failed = !arg1_holder.ref().TrySetToUSVString(cx, args[1], tryNext)) || !tryNext;
    1742           0 :           break;
    1743             :         } while (0);
    1744             :       }
    1745           0 :       if (failed) {
    1746           0 :         return false;
    1747             :       }
    1748           0 :       if (!done) {
    1749           0 :         ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 2 of Navigator.sendBeacon", "Blob, ArrayBufferView, ArrayBuffer, FormData, URLSearchParams");
    1750           0 :         return false;
    1751             :       }
    1752             :     }
    1753             :   }
    1754           0 :   binding_detail::FastErrorResult rv;
    1755           0 :   bool result(self->SendBeacon(NonNullHelper(Constify(arg0)), Constify(arg1), rv));
    1756           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1757           0 :     return false;
    1758             :   }
    1759           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1760           0 :   args.rval().setBoolean(result);
    1761           0 :   return true;
    1762             : }
    1763             : 
    1764             : static const JSJitInfo sendBeacon_methodinfo = {
    1765             :   { (JSJitGetterOp)sendBeacon },
    1766             :   { prototypes::id::Navigator },
    1767             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1768             :   JSJitInfo::Method,
    1769             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1770             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    1771             :   false,  /* isInfallible. False in setters. */
    1772             :   false,  /* isMovable.  Not relevant for setters. */
    1773             :   false, /* isEliminatable.  Not relevant for setters. */
    1774             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1775             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1776             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1777             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1778             : };
    1779             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1780             : static_assert(0 < 16, "There is no slot for us");
    1781             : 
    1782             : static bool
    1783           0 : get_presentation(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    1784             : {
    1785           0 :   binding_detail::FastErrorResult rv;
    1786           0 :   auto result(StrongOrRawPtr<mozilla::dom::Presentation>(self->GetPresentation(rv)));
    1787           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1788           0 :     return false;
    1789             :   }
    1790           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1791           0 :   if (!result) {
    1792           0 :     args.rval().setNull();
    1793           0 :     return true;
    1794             :   }
    1795           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    1796           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1797           0 :     return false;
    1798             :   }
    1799           0 :   return true;
    1800             : }
    1801             : 
    1802             : static const JSJitInfo presentation_getterinfo = {
    1803             :   { (JSJitGetterOp)get_presentation },
    1804             :   { prototypes::id::Navigator },
    1805             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1806             :   JSJitInfo::Getter,
    1807             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    1808             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    1809             :   false,  /* isInfallible. False in setters. */
    1810             :   false,  /* isMovable.  Not relevant for setters. */
    1811             :   false, /* isEliminatable.  Not relevant for setters. */
    1812             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1813             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1814             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1815             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1816             : };
    1817             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1818             : static_assert(0 < 16, "There is no slot for us");
    1819             : 
    1820             : static bool
    1821           0 : get_mozTCPSocket(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    1822             : {
    1823           0 :   auto result(StrongOrRawPtr<mozilla::dom::LegacyMozTCPSocket>(self->MozTCPSocket()));
    1824           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1825             :   static_assert(!IsPointer<decltype(result)>::value,
    1826             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
    1827           0 :   if (!WrapNewBindingNonWrapperCachedObject(cx, obj, result, args.rval())) {
    1828           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1829           0 :     return false;
    1830             :   }
    1831           0 :   return true;
    1832             : }
    1833             : 
    1834             : static const JSJitInfo mozTCPSocket_getterinfo = {
    1835             :   { (JSJitGetterOp)get_mozTCPSocket },
    1836             :   { prototypes::id::Navigator },
    1837             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1838             :   JSJitInfo::Getter,
    1839             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1840             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1841             :   false,  /* isInfallible. False in setters. */
    1842             :   false,  /* isMovable.  Not relevant for setters. */
    1843             :   false, /* isEliminatable.  Not relevant for setters. */
    1844             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1845             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1846             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1847             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1848             : };
    1849             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1850             : static_assert(0 < 16, "There is no slot for us");
    1851             : 
    1852             : static bool
    1853           0 : requestMediaKeySystemAccess(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
    1854             : {
    1855           0 :   if (MOZ_UNLIKELY(args.length() < 2)) {
    1856           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Navigator.requestMediaKeySystemAccess");
    1857             :   }
    1858           0 :   binding_detail::FakeString arg0;
    1859           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    1860           0 :     return false;
    1861             :   }
    1862           0 :   binding_detail::AutoSequence<MediaKeySystemConfiguration> arg1;
    1863           0 :   if (args[1].isObject()) {
    1864           0 :     JS::ForOfIterator iter(cx);
    1865           0 :     if (!iter.init(args[1], JS::ForOfIterator::AllowNonIterable)) {
    1866           0 :       return false;
    1867             :     }
    1868           0 :     if (!iter.valueIsIterable()) {
    1869           0 :       ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 2 of Navigator.requestMediaKeySystemAccess");
    1870           0 :       return false;
    1871             :     }
    1872           0 :     binding_detail::AutoSequence<MediaKeySystemConfiguration> &arr = arg1;
    1873           0 :     JS::Rooted<JS::Value> temp(cx);
    1874             :     while (true) {
    1875             :       bool done;
    1876           0 :       if (!iter.next(&temp, &done)) {
    1877           0 :         return false;
    1878             :       }
    1879           0 :       if (done) {
    1880           0 :         break;
    1881             :       }
    1882           0 :       MediaKeySystemConfiguration* slotPtr = arr.AppendElement(mozilla::fallible);
    1883           0 :       if (!slotPtr) {
    1884           0 :         JS_ReportOutOfMemory(cx);
    1885           0 :         return false;
    1886             :       }
    1887           0 :       MediaKeySystemConfiguration& slot = *slotPtr;
    1888           0 :       if (!slot.Init(cx, temp,  "Element of argument 2 of Navigator.requestMediaKeySystemAccess", false)) {
    1889           0 :         return false;
    1890             :       }
    1891           0 :     }
    1892             :   } else {
    1893           0 :     ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 2 of Navigator.requestMediaKeySystemAccess");
    1894           0 :     return false;
    1895             :   }
    1896           0 :   binding_detail::FastErrorResult rv;
    1897           0 :   auto result(StrongOrRawPtr<Promise>(self->RequestMediaKeySystemAccess(NonNullHelper(Constify(arg0)), Constify(arg1), rv)));
    1898           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1899           0 :     return false;
    1900             :   }
    1901           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1902             :   static_assert(!IsPointer<decltype(result)>::value,
    1903             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
    1904           0 :   if (!ToJSValue(cx, result, args.rval())) {
    1905           0 :     return false;
    1906             :   }
    1907           0 :   return true;
    1908             : }
    1909             : 
    1910             : static bool
    1911           0 : requestMediaKeySystemAccess_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
    1912             : {
    1913             :   // Make sure to save the callee before someone maybe messes
    1914             :   // with rval().
    1915           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
    1916           0 :   bool ok = requestMediaKeySystemAccess(cx, obj, self, args);
    1917           0 :   if (ok) {
    1918           0 :     return true;
    1919             :   }
    1920           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
    1921           0 :                                    args.rval());
    1922             : }
    1923             : 
    1924             : static const JSJitInfo requestMediaKeySystemAccess_methodinfo = {
    1925             :   { (JSJitGetterOp)requestMediaKeySystemAccess_promiseWrapper },
    1926             :   { prototypes::id::Navigator },
    1927             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1928             :   JSJitInfo::Method,
    1929             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1930             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1931             :   false,  /* isInfallible. False in setters. */
    1932             :   false,  /* isMovable.  Not relevant for setters. */
    1933             :   false, /* isEliminatable.  Not relevant for setters. */
    1934             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1935             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1936             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1937             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1938             : };
    1939             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1940             : static_assert(0 < 16, "There is no slot for us");
    1941             : 
    1942             : static bool
    1943           0 : get_mozE10sEnabled(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    1944             : {
    1945           0 :   bool result(self->MozE10sEnabled());
    1946           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1947           0 :   args.rval().setBoolean(result);
    1948           0 :   return true;
    1949             : }
    1950             : 
    1951             : static const JSJitInfo mozE10sEnabled_getterinfo = {
    1952             :   { (JSJitGetterOp)get_mozE10sEnabled },
    1953             :   { prototypes::id::Navigator },
    1954             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1955             :   JSJitInfo::Getter,
    1956             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1957             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    1958             :   true,  /* isInfallible. False in setters. */
    1959             :   false,  /* isMovable.  Not relevant for setters. */
    1960             :   false, /* isEliminatable.  Not relevant for setters. */
    1961             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1962             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1963             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1964             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1965             : };
    1966             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1967             : static_assert(0 < 16, "There is no slot for us");
    1968             : 
    1969             : static bool
    1970           0 : get_credentials(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    1971             : {
    1972           0 :   auto result(StrongOrRawPtr<mozilla::dom::CredentialsContainer>(self->Credentials()));
    1973           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1974           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    1975           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1976           0 :     return false;
    1977             :   }
    1978           0 :   return true;
    1979             : }
    1980             : 
    1981             : static const JSJitInfo credentials_getterinfo = {
    1982             :   { (JSJitGetterOp)get_credentials },
    1983             :   { prototypes::id::Navigator },
    1984             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    1985             :   JSJitInfo::Getter,
    1986             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    1987             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1988             :   false,  /* isInfallible. False in setters. */
    1989             :   true,  /* isMovable.  Not relevant for setters. */
    1990             :   true, /* isEliminatable.  Not relevant for setters. */
    1991             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1992             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1993             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1994             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1995             : };
    1996             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1997             : static_assert(0 < 16, "There is no slot for us");
    1998             : 
    1999             : static bool
    2000           0 : get_mozAddonManager(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    2001             : {
    2002             :   // Have to either root across the getter call or reget after.
    2003           0 :   JS::Rooted<JSObject*> slotStorage(cx, js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false));
    2004           0 :   MOZ_ASSERT(IsDOMObject(slotStorage));
    2005           0 :   const size_t slotIndex = (DOM_INSTANCE_RESERVED_SLOTS + 3);
    2006           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    2007             :   {
    2008             :     // Scope for cachedVal
    2009           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    2010           0 :     if (!cachedVal.isUndefined()) {
    2011           0 :       args.rval().set(cachedVal);
    2012             :       // The cached value is in the compartment of slotStorage,
    2013             :       // so wrap into the caller compartment as needed.
    2014           0 :       return MaybeWrapValue(cx, args.rval());
    2015             :     }
    2016             :   }
    2017             : 
    2018           0 :   binding_detail::FastErrorResult rv;
    2019           0 :   auto result(StrongOrRawPtr<mozilla::dom::AddonManager>(AddonManagerBinding::ConstructNavigatorObject(cx, slotStorage, rv)));
    2020           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2021           0 :     return false;
    2022             :   }
    2023           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2024             :   {
    2025           0 :     JS::Rooted<JSObject*> conversionScope(cx, slotStorage);
    2026           0 :     JSAutoCompartment ac(cx, conversionScope);
    2027             :     do { // block we break out of when done wrapping
    2028           0 :       if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    2029           0 :         MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    2030           0 :         return false;
    2031             :       }
    2032           0 :       break;
    2033             :     } while (0);
    2034             :   }
    2035             :   { // And now store things in the compartment of our slotStorage.
    2036           0 :     JSAutoCompartment ac(cx, slotStorage);
    2037             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    2038           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    2039           0 :     if (!MaybeWrapValue(cx, &storedVal)) {
    2040           0 :       return false;
    2041             :     }
    2042           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    2043           0 :     PreserveWrapper(self);
    2044             :   }
    2045             :   // And now make sure args.rval() is in the caller compartment
    2046           0 :   return MaybeWrapValue(cx, args.rval());
    2047             : }
    2048             : 
    2049             : static const JSJitInfo mozAddonManager_getterinfo = {
    2050             :   { (JSJitGetterOp)get_mozAddonManager },
    2051             :   { prototypes::id::Navigator },
    2052             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    2053             :   JSJitInfo::Getter,
    2054             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    2055             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    2056             :   false,  /* isInfallible. False in setters. */
    2057             :   false,  /* isMovable.  Not relevant for setters. */
    2058             :   false, /* isEliminatable.  Not relevant for setters. */
    2059             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2060             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2061             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2062             :   (DOM_INSTANCE_RESERVED_SLOTS + 3)   /* Reserved slot index, if we're stored in a slot, else 0. */
    2063             : };
    2064             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 3) <= JSJitInfo::maxSlotIndex, "We won't fit");
    2065             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 3) < 16, "There is no slot for us");
    2066             : 
    2067             : static bool
    2068           0 : get_seManager(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    2069             : {
    2070             :   // Have to either root across the getter call or reget after.
    2071           0 :   JS::Rooted<JSObject*> slotStorage(cx, js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false));
    2072           0 :   MOZ_ASSERT(IsDOMObject(slotStorage));
    2073           0 :   const size_t slotIndex = (DOM_INSTANCE_RESERVED_SLOTS + 4);
    2074           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    2075             :   {
    2076             :     // Scope for cachedVal
    2077           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    2078           0 :     if (!cachedVal.isUndefined()) {
    2079           0 :       args.rval().set(cachedVal);
    2080             :       // The cached value is in the compartment of slotStorage,
    2081             :       // so wrap into the caller compartment as needed.
    2082           0 :       return MaybeWrapValue(cx, args.rval());
    2083             :     }
    2084             :   }
    2085             : 
    2086           0 :   binding_detail::FastErrorResult rv;
    2087           0 :   auto result(StrongOrRawPtr<mozilla::dom::SEManager>(SEManagerBinding::ConstructNavigatorObject(cx, slotStorage, rv)));
    2088           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2089           0 :     return false;
    2090             :   }
    2091           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2092             :   {
    2093           0 :     JS::Rooted<JSObject*> conversionScope(cx, slotStorage);
    2094           0 :     JSAutoCompartment ac(cx, conversionScope);
    2095             :     do { // block we break out of when done wrapping
    2096           0 :       if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    2097           0 :         MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    2098           0 :         return false;
    2099             :       }
    2100           0 :       break;
    2101             :     } while (0);
    2102             :   }
    2103             :   { // And now store things in the compartment of our slotStorage.
    2104           0 :     JSAutoCompartment ac(cx, slotStorage);
    2105             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    2106           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    2107           0 :     if (!MaybeWrapValue(cx, &storedVal)) {
    2108           0 :       return false;
    2109             :     }
    2110           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    2111           0 :     PreserveWrapper(self);
    2112             :   }
    2113             :   // And now make sure args.rval() is in the caller compartment
    2114           0 :   return MaybeWrapValue(cx, args.rval());
    2115             : }
    2116             : 
    2117             : static const JSJitInfo seManager_getterinfo = {
    2118             :   { (JSJitGetterOp)get_seManager },
    2119             :   { prototypes::id::Navigator },
    2120             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    2121             :   JSJitInfo::Getter,
    2122             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    2123             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    2124             :   false,  /* isInfallible. False in setters. */
    2125             :   false,  /* isMovable.  Not relevant for setters. */
    2126             :   false, /* isEliminatable.  Not relevant for setters. */
    2127             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2128             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2129             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2130             :   (DOM_INSTANCE_RESERVED_SLOTS + 4)   /* Reserved slot index, if we're stored in a slot, else 0. */
    2131             : };
    2132             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 4) <= JSJitInfo::maxSlotIndex, "We won't fit");
    2133             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 4) < 16, "There is no slot for us");
    2134             : 
    2135             : static bool
    2136           0 : get_hardwareConcurrency(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    2137             : {
    2138           0 :   uint64_t result(self->HardwareConcurrency());
    2139           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2140           0 :   args.rval().set(JS_NumberValue(double(result)));
    2141           0 :   return true;
    2142             : }
    2143             : 
    2144             : static const JSJitInfo hardwareConcurrency_getterinfo = {
    2145             :   { (JSJitGetterOp)get_hardwareConcurrency },
    2146             :   { prototypes::id::Navigator },
    2147             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    2148             :   JSJitInfo::Getter,
    2149             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2150             :   JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
    2151             :   true,  /* isInfallible. False in setters. */
    2152             :   false,  /* isMovable.  Not relevant for setters. */
    2153             :   false, /* isEliminatable.  Not relevant for setters. */
    2154             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2155             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2156             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2157             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2158             : };
    2159             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2160             : static_assert(0 < 16, "There is no slot for us");
    2161             : 
    2162             : static bool
    2163           0 : registerProtocolHandler(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
    2164             : {
    2165           0 :   if (MOZ_UNLIKELY(args.length() < 3)) {
    2166           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Navigator.registerProtocolHandler");
    2167             :   }
    2168           0 :   binding_detail::FakeString arg0;
    2169           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    2170           0 :     return false;
    2171             :   }
    2172           0 :   binding_detail::FakeString arg1;
    2173           0 :   if (!ConvertJSValueToString(cx, args[1], eStringify, eStringify, arg1)) {
    2174           0 :     return false;
    2175             :   }
    2176           0 :   binding_detail::FakeString arg2;
    2177           0 :   if (!ConvertJSValueToString(cx, args[2], eStringify, eStringify, arg2)) {
    2178           0 :     return false;
    2179             :   }
    2180           0 :   binding_detail::FastErrorResult rv;
    2181           0 :   self->RegisterProtocolHandler(NonNullHelper(Constify(arg0)), NonNullHelper(Constify(arg1)), NonNullHelper(Constify(arg2)), rv);
    2182           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2183           0 :     return false;
    2184             :   }
    2185           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2186           0 :   args.rval().setUndefined();
    2187           0 :   return true;
    2188             : }
    2189             : 
    2190             : static const JSJitInfo registerProtocolHandler_methodinfo = {
    2191             :   { (JSJitGetterOp)registerProtocolHandler },
    2192             :   { prototypes::id::Navigator },
    2193             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    2194             :   JSJitInfo::Method,
    2195             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2196             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    2197             :   false,  /* isInfallible. False in setters. */
    2198             :   false,  /* isMovable.  Not relevant for setters. */
    2199             :   false, /* isEliminatable.  Not relevant for setters. */
    2200             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2201             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2202             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2203             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2204             : };
    2205             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2206             : static_assert(0 < 16, "There is no slot for us");
    2207             : 
    2208             : static bool
    2209           0 : registerContentHandler(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
    2210             : {
    2211           0 :   if (MOZ_UNLIKELY(args.length() < 3)) {
    2212           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Navigator.registerContentHandler");
    2213             :   }
    2214           0 :   binding_detail::FakeString arg0;
    2215           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    2216           0 :     return false;
    2217             :   }
    2218           0 :   binding_detail::FakeString arg1;
    2219           0 :   if (!ConvertJSValueToString(cx, args[1], eStringify, eStringify, arg1)) {
    2220           0 :     return false;
    2221             :   }
    2222           0 :   binding_detail::FakeString arg2;
    2223           0 :   if (!ConvertJSValueToString(cx, args[2], eStringify, eStringify, arg2)) {
    2224           0 :     return false;
    2225             :   }
    2226           0 :   binding_detail::FastErrorResult rv;
    2227           0 :   self->RegisterContentHandler(NonNullHelper(Constify(arg0)), NonNullHelper(Constify(arg1)), NonNullHelper(Constify(arg2)), rv);
    2228           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2229           0 :     return false;
    2230             :   }
    2231           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2232           0 :   args.rval().setUndefined();
    2233           0 :   return true;
    2234             : }
    2235             : 
    2236             : static const JSJitInfo registerContentHandler_methodinfo = {
    2237             :   { (JSJitGetterOp)registerContentHandler },
    2238             :   { prototypes::id::Navigator },
    2239             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    2240             :   JSJitInfo::Method,
    2241             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2242             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    2243             :   false,  /* isInfallible. False in setters. */
    2244             :   false,  /* isMovable.  Not relevant for setters. */
    2245             :   false, /* isEliminatable.  Not relevant for setters. */
    2246             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2247             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2248             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2249             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2250             : };
    2251             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2252             : static_assert(0 < 16, "There is no slot for us");
    2253             : 
    2254             : static bool
    2255           0 : get_geolocation(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    2256             : {
    2257           0 :   binding_detail::FastErrorResult rv;
    2258           0 :   auto result(StrongOrRawPtr<mozilla::dom::Geolocation>(self->GetGeolocation(rv)));
    2259           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2260           0 :     return false;
    2261             :   }
    2262           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2263           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    2264           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    2265           0 :     return false;
    2266             :   }
    2267           0 :   return true;
    2268             : }
    2269             : 
    2270             : static const JSJitInfo geolocation_getterinfo = {
    2271             :   { (JSJitGetterOp)get_geolocation },
    2272             :   { prototypes::id::Navigator },
    2273             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    2274             :   JSJitInfo::Getter,
    2275             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2276             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    2277             :   false,  /* isInfallible. False in setters. */
    2278             :   false,  /* isMovable.  Not relevant for setters. */
    2279             :   false, /* isEliminatable.  Not relevant for setters. */
    2280             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2281             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2282             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2283             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2284             : };
    2285             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2286             : static_assert(0 < 16, "There is no slot for us");
    2287             : 
    2288             : static bool
    2289           0 : get_appCodeName(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    2290             : {
    2291             :   // Have to either root across the getter call or reget after.
    2292             :   bool isXray;
    2293           0 :   JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
    2294           0 :   if (!slotStorage) {
    2295           0 :     return false;
    2296             :   }
    2297           0 :   const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 7) : (DOM_INSTANCE_RESERVED_SLOTS + 7);
    2298           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    2299             :   {
    2300             :     // Scope for cachedVal
    2301           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    2302           0 :     if (!cachedVal.isUndefined()) {
    2303           0 :       args.rval().set(cachedVal);
    2304             :       // The cached value is in the compartment of slotStorage,
    2305             :       // so wrap into the caller compartment as needed.
    2306           0 :       return MaybeWrapValue(cx, args.rval());
    2307             :     }
    2308             :   }
    2309             : 
    2310           0 :   DOMString result;
    2311           0 :   self->GetAppCodeName(result);
    2312           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2313             :   {
    2314           0 :     JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
    2315           0 :     JSAutoCompartment ac(cx, conversionScope);
    2316             :     do { // block we break out of when done wrapping
    2317           0 :       if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    2318           0 :         return false;
    2319             :       }
    2320           0 :       break;
    2321             :     } while (0);
    2322             :   }
    2323             :   { // And now store things in the compartment of our slotStorage.
    2324           0 :     JSAutoCompartment ac(cx, slotStorage);
    2325             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    2326           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    2327           0 :     if (!MaybeWrapValue(cx, &storedVal)) {
    2328           0 :       return false;
    2329             :     }
    2330           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    2331           0 :     if (!isXray) {
    2332             :       // In the Xray case we don't need to do this, because getting the
    2333             :       // expando object already preserved our wrapper.
    2334           0 :       PreserveWrapper(self);
    2335             :     }
    2336             :   }
    2337             :   // And now make sure args.rval() is in the caller compartment
    2338           0 :   return MaybeWrapValue(cx, args.rval());
    2339             : }
    2340             : 
    2341             : static const JSJitInfo appCodeName_getterinfo = {
    2342             :   { (JSJitGetterOp)get_appCodeName },
    2343             :   { prototypes::id::Navigator },
    2344             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    2345             :   JSJitInfo::Getter,
    2346             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    2347             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
    2348             :   false,  /* isInfallible. False in setters. */
    2349             :   true,  /* isMovable.  Not relevant for setters. */
    2350             :   true, /* isEliminatable.  Not relevant for setters. */
    2351             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2352             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2353             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2354             :   (DOM_INSTANCE_RESERVED_SLOTS + 7)   /* Reserved slot index, if we're stored in a slot, else 0. */
    2355             : };
    2356             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 7) <= JSJitInfo::maxSlotIndex, "We won't fit");
    2357             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 7) < 16, "There is no slot for us");
    2358             : 
    2359             : static bool
    2360           0 : get_appName(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    2361             : {
    2362             :   // Have to either root across the getter call or reget after.
    2363             :   bool isXray;
    2364           0 :   JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
    2365           0 :   if (!slotStorage) {
    2366           0 :     return false;
    2367             :   }
    2368           0 :   const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 8) : (DOM_INSTANCE_RESERVED_SLOTS + 8);
    2369           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    2370             :   {
    2371             :     // Scope for cachedVal
    2372           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    2373           0 :     if (!cachedVal.isUndefined()) {
    2374           0 :       args.rval().set(cachedVal);
    2375             :       // The cached value is in the compartment of slotStorage,
    2376             :       // so wrap into the caller compartment as needed.
    2377           0 :       return MaybeWrapValue(cx, args.rval());
    2378             :     }
    2379             :   }
    2380             : 
    2381           0 :   DOMString result;
    2382           0 :   self->GetAppName(result, nsContentUtils::IsSystemCaller(cx) ? CallerType::System : CallerType::NonSystem);
    2383           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2384             :   {
    2385           0 :     JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
    2386           0 :     JSAutoCompartment ac(cx, conversionScope);
    2387             :     do { // block we break out of when done wrapping
    2388           0 :       if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    2389           0 :         return false;
    2390             :       }
    2391           0 :       break;
    2392             :     } while (0);
    2393             :   }
    2394             :   { // And now store things in the compartment of our slotStorage.
    2395           0 :     JSAutoCompartment ac(cx, slotStorage);
    2396             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    2397           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    2398           0 :     if (!MaybeWrapValue(cx, &storedVal)) {
    2399           0 :       return false;
    2400             :     }
    2401           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    2402           0 :     if (!isXray) {
    2403             :       // In the Xray case we don't need to do this, because getting the
    2404             :       // expando object already preserved our wrapper.
    2405           0 :       PreserveWrapper(self);
    2406             :     }
    2407             :   }
    2408             :   // And now make sure args.rval() is in the caller compartment
    2409           0 :   return MaybeWrapValue(cx, args.rval());
    2410             : }
    2411             : 
    2412             : static const JSJitInfo appName_getterinfo = {
    2413             :   { (JSJitGetterOp)get_appName },
    2414             :   { prototypes::id::Navigator },
    2415             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    2416             :   JSJitInfo::Getter,
    2417             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    2418             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
    2419             :   false,  /* isInfallible. False in setters. */
    2420             :   true,  /* isMovable.  Not relevant for setters. */
    2421             :   true, /* isEliminatable.  Not relevant for setters. */
    2422             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2423             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2424             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2425             :   (DOM_INSTANCE_RESERVED_SLOTS + 8)   /* Reserved slot index, if we're stored in a slot, else 0. */
    2426             : };
    2427             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 8) <= JSJitInfo::maxSlotIndex, "We won't fit");
    2428             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 8) < 16, "There is no slot for us");
    2429             : 
    2430             : static bool
    2431           0 : get_appVersion(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    2432             : {
    2433             :   // Have to either root across the getter call or reget after.
    2434             :   bool isXray;
    2435           0 :   JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
    2436           0 :   if (!slotStorage) {
    2437           0 :     return false;
    2438             :   }
    2439           0 :   const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 9) : (DOM_INSTANCE_RESERVED_SLOTS + 9);
    2440           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    2441             :   {
    2442             :     // Scope for cachedVal
    2443           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    2444           0 :     if (!cachedVal.isUndefined()) {
    2445           0 :       args.rval().set(cachedVal);
    2446             :       // The cached value is in the compartment of slotStorage,
    2447             :       // so wrap into the caller compartment as needed.
    2448           0 :       return MaybeWrapValue(cx, args.rval());
    2449             :     }
    2450             :   }
    2451             : 
    2452           0 :   binding_detail::FastErrorResult rv;
    2453           0 :   DOMString result;
    2454           0 :   self->GetAppVersion(result, nsContentUtils::IsSystemCaller(cx) ? CallerType::System : CallerType::NonSystem, rv);
    2455           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2456           0 :     return false;
    2457             :   }
    2458           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2459             :   {
    2460           0 :     JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
    2461           0 :     JSAutoCompartment ac(cx, conversionScope);
    2462             :     do { // block we break out of when done wrapping
    2463           0 :       if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    2464           0 :         return false;
    2465             :       }
    2466           0 :       break;
    2467             :     } while (0);
    2468             :   }
    2469             :   { // And now store things in the compartment of our slotStorage.
    2470           0 :     JSAutoCompartment ac(cx, slotStorage);
    2471             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    2472           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    2473           0 :     if (!MaybeWrapValue(cx, &storedVal)) {
    2474           0 :       return false;
    2475             :     }
    2476           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    2477           0 :     if (!isXray) {
    2478             :       // In the Xray case we don't need to do this, because getting the
    2479             :       // expando object already preserved our wrapper.
    2480           0 :       PreserveWrapper(self);
    2481             :     }
    2482             :   }
    2483             :   // And now make sure args.rval() is in the caller compartment
    2484           0 :   return MaybeWrapValue(cx, args.rval());
    2485             : }
    2486             : 
    2487             : static const JSJitInfo appVersion_getterinfo = {
    2488             :   { (JSJitGetterOp)get_appVersion },
    2489             :   { prototypes::id::Navigator },
    2490             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    2491             :   JSJitInfo::Getter,
    2492             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    2493             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
    2494             :   false,  /* isInfallible. False in setters. */
    2495             :   false,  /* isMovable.  Not relevant for setters. */
    2496             :   false, /* isEliminatable.  Not relevant for setters. */
    2497             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2498             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2499             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2500             :   (DOM_INSTANCE_RESERVED_SLOTS + 9)   /* Reserved slot index, if we're stored in a slot, else 0. */
    2501             : };
    2502             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 9) <= JSJitInfo::maxSlotIndex, "We won't fit");
    2503             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 9) < 16, "There is no slot for us");
    2504             : 
    2505             : static bool
    2506           0 : get_platform(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    2507             : {
    2508             :   // Have to either root across the getter call or reget after.
    2509             :   bool isXray;
    2510           0 :   JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
    2511           0 :   if (!slotStorage) {
    2512           0 :     return false;
    2513             :   }
    2514           0 :   const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 10) : (DOM_INSTANCE_RESERVED_SLOTS + 10);
    2515           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    2516             :   {
    2517             :     // Scope for cachedVal
    2518           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    2519           0 :     if (!cachedVal.isUndefined()) {
    2520           0 :       args.rval().set(cachedVal);
    2521             :       // The cached value is in the compartment of slotStorage,
    2522             :       // so wrap into the caller compartment as needed.
    2523           0 :       return MaybeWrapValue(cx, args.rval());
    2524             :     }
    2525             :   }
    2526             : 
    2527           0 :   binding_detail::FastErrorResult rv;
    2528           0 :   DOMString result;
    2529           0 :   self->GetPlatform(result, nsContentUtils::IsSystemCaller(cx) ? CallerType::System : CallerType::NonSystem, rv);
    2530           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2531           0 :     return false;
    2532             :   }
    2533           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2534             :   {
    2535           0 :     JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
    2536           0 :     JSAutoCompartment ac(cx, conversionScope);
    2537             :     do { // block we break out of when done wrapping
    2538           0 :       if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    2539           0 :         return false;
    2540             :       }
    2541           0 :       break;
    2542             :     } while (0);
    2543             :   }
    2544             :   { // And now store things in the compartment of our slotStorage.
    2545           0 :     JSAutoCompartment ac(cx, slotStorage);
    2546             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    2547           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    2548           0 :     if (!MaybeWrapValue(cx, &storedVal)) {
    2549           0 :       return false;
    2550             :     }
    2551           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    2552           0 :     if (!isXray) {
    2553             :       // In the Xray case we don't need to do this, because getting the
    2554             :       // expando object already preserved our wrapper.
    2555           0 :       PreserveWrapper(self);
    2556             :     }
    2557             :   }
    2558             :   // And now make sure args.rval() is in the caller compartment
    2559           0 :   return MaybeWrapValue(cx, args.rval());
    2560             : }
    2561             : 
    2562             : static const JSJitInfo platform_getterinfo = {
    2563             :   { (JSJitGetterOp)get_platform },
    2564             :   { prototypes::id::Navigator },
    2565             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    2566             :   JSJitInfo::Getter,
    2567             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    2568             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
    2569             :   false,  /* isInfallible. False in setters. */
    2570             :   false,  /* isMovable.  Not relevant for setters. */
    2571             :   false, /* isEliminatable.  Not relevant for setters. */
    2572             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2573             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2574             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2575             :   (DOM_INSTANCE_RESERVED_SLOTS + 10)   /* Reserved slot index, if we're stored in a slot, else 0. */
    2576             : };
    2577             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 10) <= JSJitInfo::maxSlotIndex, "We won't fit");
    2578             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 10) < 16, "There is no slot for us");
    2579             : 
    2580             : static bool
    2581           0 : get_userAgent(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    2582             : {
    2583             :   // Have to either root across the getter call or reget after.
    2584             :   bool isXray;
    2585           0 :   JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
    2586           0 :   if (!slotStorage) {
    2587           0 :     return false;
    2588             :   }
    2589           0 :   const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 11) : (DOM_INSTANCE_RESERVED_SLOTS + 11);
    2590           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    2591             :   {
    2592             :     // Scope for cachedVal
    2593           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    2594           0 :     if (!cachedVal.isUndefined()) {
    2595           0 :       args.rval().set(cachedVal);
    2596             :       // The cached value is in the compartment of slotStorage,
    2597             :       // so wrap into the caller compartment as needed.
    2598           0 :       return MaybeWrapValue(cx, args.rval());
    2599             :     }
    2600             :   }
    2601             : 
    2602           0 :   binding_detail::FastErrorResult rv;
    2603           0 :   DOMString result;
    2604           0 :   self->GetUserAgent(result, nsContentUtils::IsSystemCaller(cx) ? CallerType::System : CallerType::NonSystem, rv);
    2605           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2606           0 :     return false;
    2607             :   }
    2608           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2609             :   {
    2610           0 :     JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
    2611           0 :     JSAutoCompartment ac(cx, conversionScope);
    2612             :     do { // block we break out of when done wrapping
    2613           0 :       if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    2614           0 :         return false;
    2615             :       }
    2616           0 :       break;
    2617             :     } while (0);
    2618             :   }
    2619             :   { // And now store things in the compartment of our slotStorage.
    2620           0 :     JSAutoCompartment ac(cx, slotStorage);
    2621             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    2622           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    2623           0 :     if (!MaybeWrapValue(cx, &storedVal)) {
    2624           0 :       return false;
    2625             :     }
    2626           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    2627           0 :     if (!isXray) {
    2628             :       // In the Xray case we don't need to do this, because getting the
    2629             :       // expando object already preserved our wrapper.
    2630           0 :       PreserveWrapper(self);
    2631             :     }
    2632             :   }
    2633             :   // And now make sure args.rval() is in the caller compartment
    2634           0 :   return MaybeWrapValue(cx, args.rval());
    2635             : }
    2636             : 
    2637             : static const JSJitInfo userAgent_getterinfo = {
    2638             :   { (JSJitGetterOp)get_userAgent },
    2639             :   { prototypes::id::Navigator },
    2640             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    2641             :   JSJitInfo::Getter,
    2642             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    2643             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
    2644             :   false,  /* isInfallible. False in setters. */
    2645             :   false,  /* isMovable.  Not relevant for setters. */
    2646             :   false, /* isEliminatable.  Not relevant for setters. */
    2647             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2648             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2649             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2650             :   (DOM_INSTANCE_RESERVED_SLOTS + 11)   /* Reserved slot index, if we're stored in a slot, else 0. */
    2651             : };
    2652             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 11) <= JSJitInfo::maxSlotIndex, "We won't fit");
    2653             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 11) < 16, "There is no slot for us");
    2654             : 
    2655             : static bool
    2656           0 : get_product(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    2657             : {
    2658             :   // Have to either root across the getter call or reget after.
    2659             :   bool isXray;
    2660           0 :   JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
    2661           0 :   if (!slotStorage) {
    2662           0 :     return false;
    2663             :   }
    2664           0 :   const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 12) : (DOM_INSTANCE_RESERVED_SLOTS + 12);
    2665           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    2666             :   {
    2667             :     // Scope for cachedVal
    2668           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    2669           0 :     if (!cachedVal.isUndefined()) {
    2670           0 :       args.rval().set(cachedVal);
    2671             :       // The cached value is in the compartment of slotStorage,
    2672             :       // so wrap into the caller compartment as needed.
    2673           0 :       return MaybeWrapValue(cx, args.rval());
    2674             :     }
    2675             :   }
    2676             : 
    2677           0 :   DOMString result;
    2678           0 :   self->GetProduct(result);
    2679           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2680             :   {
    2681           0 :     JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
    2682           0 :     JSAutoCompartment ac(cx, conversionScope);
    2683             :     do { // block we break out of when done wrapping
    2684           0 :       if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    2685           0 :         return false;
    2686             :       }
    2687           0 :       break;
    2688             :     } while (0);
    2689             :   }
    2690             :   { // And now store things in the compartment of our slotStorage.
    2691           0 :     JSAutoCompartment ac(cx, slotStorage);
    2692             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    2693           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    2694           0 :     if (!MaybeWrapValue(cx, &storedVal)) {
    2695           0 :       return false;
    2696             :     }
    2697           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    2698           0 :     if (!isXray) {
    2699             :       // In the Xray case we don't need to do this, because getting the
    2700             :       // expando object already preserved our wrapper.
    2701           0 :       PreserveWrapper(self);
    2702             :     }
    2703             :   }
    2704             :   // And now make sure args.rval() is in the caller compartment
    2705           0 :   return MaybeWrapValue(cx, args.rval());
    2706             : }
    2707             : 
    2708             : static const JSJitInfo product_getterinfo = {
    2709             :   { (JSJitGetterOp)get_product },
    2710             :   { prototypes::id::Navigator },
    2711             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    2712             :   JSJitInfo::Getter,
    2713             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    2714             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
    2715             :   false,  /* isInfallible. False in setters. */
    2716             :   true,  /* isMovable.  Not relevant for setters. */
    2717             :   true, /* isEliminatable.  Not relevant for setters. */
    2718             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2719             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2720             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2721             :   (DOM_INSTANCE_RESERVED_SLOTS + 12)   /* Reserved slot index, if we're stored in a slot, else 0. */
    2722             : };
    2723             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 12) <= JSJitInfo::maxSlotIndex, "We won't fit");
    2724             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 12) < 16, "There is no slot for us");
    2725             : 
    2726             : static bool
    2727           0 : taintEnabled(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, const JSJitMethodCallArgs& args)
    2728             : {
    2729           0 :   bool result(self->TaintEnabled());
    2730           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2731           0 :   args.rval().setBoolean(result);
    2732           0 :   return true;
    2733             : }
    2734             : 
    2735             : static const JSJitInfo taintEnabled_methodinfo = {
    2736             :   { (JSJitGetterOp)taintEnabled },
    2737             :   { prototypes::id::Navigator },
    2738             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    2739             :   JSJitInfo::Method,
    2740             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2741             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    2742             :   true,  /* isInfallible. False in setters. */
    2743             :   false,  /* isMovable.  Not relevant for setters. */
    2744             :   false, /* isEliminatable.  Not relevant for setters. */
    2745             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2746             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2747             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2748             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2749             : };
    2750             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2751             : static_assert(0 < 16, "There is no slot for us");
    2752             : 
    2753             : static bool
    2754           0 : get_language(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    2755             : {
    2756             :   // Have to either root across the getter call or reget after.
    2757             :   bool isXray;
    2758           0 :   JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
    2759           0 :   if (!slotStorage) {
    2760           0 :     return false;
    2761             :   }
    2762           0 :   const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 13) : (DOM_INSTANCE_RESERVED_SLOTS + 13);
    2763           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    2764             :   {
    2765             :     // Scope for cachedVal
    2766           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    2767           0 :     if (!cachedVal.isUndefined()) {
    2768           0 :       args.rval().set(cachedVal);
    2769             :       // The cached value is in the compartment of slotStorage,
    2770             :       // so wrap into the caller compartment as needed.
    2771           0 :       return MaybeWrapValue(cx, args.rval());
    2772             :     }
    2773             :   }
    2774             : 
    2775           0 :   DOMString result;
    2776           0 :   self->GetLanguage(result);
    2777           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2778             :   {
    2779           0 :     JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
    2780           0 :     JSAutoCompartment ac(cx, conversionScope);
    2781             :     do { // block we break out of when done wrapping
    2782           0 :       if (!xpc::StringToJsval(cx, result, args.rval())) {
    2783           0 :         return false;
    2784             :       }
    2785           0 :       break;
    2786             :     } while (0);
    2787             :   }
    2788             :   { // And now store things in the compartment of our slotStorage.
    2789           0 :     JSAutoCompartment ac(cx, slotStorage);
    2790             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    2791           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    2792           0 :     if (!MaybeWrapValue(cx, &storedVal)) {
    2793           0 :       return false;
    2794             :     }
    2795           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    2796           0 :     if (!isXray) {
    2797             :       // In the Xray case we don't need to do this, because getting the
    2798             :       // expando object already preserved our wrapper.
    2799           0 :       PreserveWrapper(self);
    2800             :     }
    2801             :   }
    2802             :   // And now make sure args.rval() is in the caller compartment
    2803           0 :   return MaybeWrapValue(cx, args.rval());
    2804             : }
    2805             : 
    2806             : static const JSJitInfo language_getterinfo = {
    2807             :   { (JSJitGetterOp)get_language },
    2808             :   { prototypes::id::Navigator },
    2809             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    2810             :   JSJitInfo::Getter,
    2811             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    2812             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    2813             :   false,  /* isInfallible. False in setters. */
    2814             :   true,  /* isMovable.  Not relevant for setters. */
    2815             :   true, /* isEliminatable.  Not relevant for setters. */
    2816             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2817             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2818             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2819             :   (DOM_INSTANCE_RESERVED_SLOTS + 13)   /* Reserved slot index, if we're stored in a slot, else 0. */
    2820             : };
    2821             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 13) <= JSJitInfo::maxSlotIndex, "We won't fit");
    2822             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 13) < 16, "There is no slot for us");
    2823             : 
    2824             : static bool
    2825           0 : get_languages(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    2826             : {
    2827             :   // Have to either root across the getter call or reget after.
    2828             :   bool isXray;
    2829           0 :   JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
    2830           0 :   if (!slotStorage) {
    2831           0 :     return false;
    2832             :   }
    2833           0 :   const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 14) : (DOM_INSTANCE_RESERVED_SLOTS + 14);
    2834           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    2835             :   {
    2836             :     // Scope for cachedVal
    2837           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    2838           0 :     if (!cachedVal.isUndefined()) {
    2839           0 :       args.rval().set(cachedVal);
    2840             :       // The cached value is in the compartment of slotStorage,
    2841             :       // so wrap into the caller compartment as needed.
    2842           0 :       return MaybeWrapNonDOMObjectValue(cx, args.rval());
    2843             :     }
    2844             :   }
    2845             : 
    2846           0 :   nsTArray<nsString> result;
    2847           0 :   self->GetLanguages(result);
    2848           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2849             :   {
    2850           0 :     JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
    2851           0 :     JSAutoCompartment ac(cx, conversionScope);
    2852             :     do { // block we break out of when done wrapping
    2853             : 
    2854           0 :       uint32_t length = result.Length();
    2855           0 :       JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
    2856           0 :       if (!returnArray) {
    2857           0 :         return false;
    2858             :       }
    2859             :       // Scope for 'tmp'
    2860             :       {
    2861           0 :         JS::Rooted<JS::Value> tmp(cx);
    2862           0 :         for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
    2863             :           // Control block to let us common up the JS_DefineElement calls when there
    2864             :           // are different ways to succeed at wrapping the object.
    2865             :           do {
    2866           0 :             if (!xpc::NonVoidStringToJsval(cx, result[sequenceIdx0], &tmp)) {
    2867           0 :               return false;
    2868             :             }
    2869           0 :             break;
    2870             :           } while (0);
    2871           0 :           if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
    2872             :                                 JSPROP_ENUMERATE)) {
    2873           0 :             return false;
    2874             :           }
    2875             :         }
    2876             :       }
    2877           0 :       args.rval().setObject(*returnArray);
    2878           0 :       break;
    2879             :     } while (0);
    2880           0 :     JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
    2881           0 :     if (!JS_FreezeObject(cx, rvalObj)) {
    2882           0 :       return false;
    2883             :     }
    2884             :   }
    2885             :   { // And now store things in the compartment of our slotStorage.
    2886           0 :     JSAutoCompartment ac(cx, slotStorage);
    2887             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    2888           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    2889           0 :     if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
    2890           0 :       return false;
    2891             :     }
    2892           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    2893           0 :     if (!isXray) {
    2894             :       // In the Xray case we don't need to do this, because getting the
    2895             :       // expando object already preserved our wrapper.
    2896           0 :       PreserveWrapper(self);
    2897             :     }
    2898             :   }
    2899             :   // And now make sure args.rval() is in the caller compartment
    2900           0 :   return MaybeWrapNonDOMObjectValue(cx, args.rval());
    2901             : }
    2902             : 
    2903             : static const JSJitInfo languages_getterinfo = {
    2904             :   { (JSJitGetterOp)get_languages },
    2905             :   { prototypes::id::Navigator },
    2906             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    2907             :   JSJitInfo::Getter,
    2908             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    2909             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    2910             :   false,  /* isInfallible. False in setters. */
    2911             :   true,  /* isMovable.  Not relevant for setters. */
    2912             :   true, /* isEliminatable.  Not relevant for setters. */
    2913             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2914             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2915             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2916             :   (DOM_INSTANCE_RESERVED_SLOTS + 14)   /* Reserved slot index, if we're stored in a slot, else 0. */
    2917             : };
    2918             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 14) <= JSJitInfo::maxSlotIndex, "We won't fit");
    2919             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 14) < 16, "There is no slot for us");
    2920             : 
    2921             : static bool
    2922           0 : get_onLine(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    2923             : {
    2924           0 :   bool result(self->OnLine());
    2925           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2926           0 :   args.rval().setBoolean(result);
    2927           0 :   return true;
    2928             : }
    2929             : 
    2930             : static const JSJitInfo onLine_getterinfo = {
    2931             :   { (JSJitGetterOp)get_onLine },
    2932             :   { prototypes::id::Navigator },
    2933             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    2934             :   JSJitInfo::Getter,
    2935             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2936             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    2937             :   true,  /* isInfallible. False in setters. */
    2938             :   false,  /* isMovable.  Not relevant for setters. */
    2939             :   false, /* isEliminatable.  Not relevant for setters. */
    2940             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2941             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2942             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2943             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2944             : };
    2945             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2946             : static_assert(0 < 16, "There is no slot for us");
    2947             : 
    2948             : static bool
    2949           0 : get_storage(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Navigator* self, JSJitGetterCallArgs args)
    2950             : {
    2951           0 :   auto result(StrongOrRawPtr<mozilla::dom::StorageManager>(self->Storage()));
    2952           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2953           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    2954           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    2955           0 :     return false;
    2956             :   }
    2957           0 :   return true;
    2958             : }
    2959             : 
    2960             : static const JSJitInfo storage_getterinfo = {
    2961             :   { (JSJitGetterOp)get_storage },
    2962             :   { prototypes::id::Navigator },
    2963             :   { PrototypeTraits<prototypes::id::Navigator>::Depth },
    2964             :   JSJitInfo::Getter,
    2965             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2966             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    2967             :   false,  /* isInfallible. False in setters. */
    2968             :   false,  /* isMovable.  Not relevant for setters. */
    2969             :   false, /* isEliminatable.  Not relevant for setters. */
    2970             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2971             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2972             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2973             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2974             : };
    2975             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2976             : static_assert(0 < 16, "There is no slot for us");
    2977             : 
    2978             : static bool
    2979           0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
    2980             : {
    2981           0 :   mozilla::dom::Navigator* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Navigator>(obj);
    2982             :   // We don't want to preserve if we don't have a wrapper, and we
    2983             :   // obviously can't preserve if we're not initialized.
    2984           0 :   if (self && self->GetWrapperPreserveColor()) {
    2985           0 :     PreserveWrapper(self);
    2986             :   }
    2987           0 :   return true;
    2988             : }
    2989             : 
    2990             : static void
    2991           0 : _finalize(js::FreeOp* fop, JSObject* obj)
    2992             : {
    2993           0 :   mozilla::dom::Navigator* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Navigator>(obj);
    2994           0 :   if (self) {
    2995           0 :     ClearWrapper(self, self, obj);
    2996           0 :     AddForDeferredFinalization<mozilla::dom::Navigator>(self);
    2997             :   }
    2998           0 : }
    2999             : 
    3000             : static void
    3001           0 : _objectMoved(JSObject* obj, const JSObject* old)
    3002             : {
    3003           0 :   mozilla::dom::Navigator* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Navigator>(obj);
    3004           0 :   if (self) {
    3005           0 :     UpdateWrapper(self, self, obj, old);
    3006             :   }
    3007           0 : }
    3008             : 
    3009             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    3010             : #if defined(__clang__)
    3011             : #pragma clang diagnostic push
    3012             : #pragma clang diagnostic ignored "-Wmissing-braces"
    3013             : #endif
    3014             : static const JSFunctionSpec sMethods_specs[] = {
    3015             :   JS_FNSPEC("publishServer", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&publishServer_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    3016             :   JS_FS_END,
    3017             :   JS_FNSPEC("vibrate", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&vibrate_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    3018             :   JS_FNSPEC("javaEnabled", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&javaEnabled_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    3019             :   JS_FS_END,
    3020             :   JS_FNSPEC("requestWakeLock", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&requestWakeLock_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    3021             :   JS_FS_END,
    3022             :   JS_FNSPEC("getGamepads", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&getGamepads_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    3023             :   JS_FS_END,
    3024             :   JS_FNSPEC("requestGamepadServiceTest", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&requestGamepadServiceTest_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    3025             :   JS_FS_END,
    3026             :   JS_FNSPEC("getVRDisplays", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&getVRDisplays_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    3027             :   JS_FS_END,
    3028             :   JS_FNSPEC("requestVRServiceTest", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&requestVRServiceTest_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    3029             :   JS_FS_END,
    3030             :   JS_FNSPEC("mozGetUserMedia", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&mozGetUserMedia_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
    3031             :   JS_FS_END,
    3032             :   JS_FNSPEC("sendBeacon", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&sendBeacon_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    3033             :   JS_FS_END,
    3034             :   JS_FNSPEC("requestMediaKeySystemAccess", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&requestMediaKeySystemAccess_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
    3035             :   JS_FS_END,
    3036             :   JS_FNSPEC("QueryInterface", QueryInterface, nullptr, 1, 0, nullptr),
    3037             :   JS_FS_END,
    3038             :   JS_FNSPEC("registerProtocolHandler", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&registerProtocolHandler_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
    3039             :   JS_FNSPEC("registerContentHandler", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&registerContentHandler_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
    3040             :   JS_FNSPEC("taintEnabled", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&taintEnabled_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    3041             :   JS_FS_END
    3042             : };
    3043             : #if defined(__clang__)
    3044             : #pragma clang diagnostic pop
    3045             : #endif
    3046             : 
    3047             : static PrefableDisablers sMethods_disablers0 = {
    3048             :   true, false, 0, nullptr
    3049             : };
    3050             : 
    3051             : static PrefableDisablers sMethods_disablers5 = {
    3052             :   true, false, 0, &Navigator::HasWakeLockSupport
    3053             : };
    3054             : 
    3055             : static PrefableDisablers sMethods_disablers7 = {
    3056             :   true, false, 0, nullptr
    3057             : };
    3058             : 
    3059             : static PrefableDisablers sMethods_disablers9 = {
    3060             :   true, false, 0, nullptr
    3061             : };
    3062             : 
    3063             : static PrefableDisablers sMethods_disablers11 = {
    3064             :   true, false, 0, nullptr
    3065             : };
    3066             : 
    3067             : static PrefableDisablers sMethods_disablers13 = {
    3068             :   true, false, 0, nullptr
    3069             : };
    3070             : 
    3071             : static PrefableDisablers sMethods_disablers15 = {
    3072             :   true, false, 0, &Navigator::HasUserMediaSupport
    3073             : };
    3074             : 
    3075             : static PrefableDisablers sMethods_disablers17 = {
    3076             :   true, false, 0, nullptr
    3077             : };
    3078             : 
    3079             : static PrefableDisablers sMethods_disablers21 = {
    3080             :   true, false, 0, &WantsQueryInterface<mozilla::dom::Navigator>::Enabled
    3081             : };
    3082             : 
    3083             : // Can't be const because the pref-enabled boolean needs to be writable
    3084             : static Prefable<const JSFunctionSpec> sMethods[] = {
    3085             :   { &sMethods_disablers0, &sMethods_specs[0] },
    3086             :   { nullptr, &sMethods_specs[2] },
    3087             :   { &sMethods_disablers5, &sMethods_specs[5] },
    3088             :   { &sMethods_disablers7, &sMethods_specs[7] },
    3089             :   { &sMethods_disablers9, &sMethods_specs[9] },
    3090             :   { &sMethods_disablers11, &sMethods_specs[11] },
    3091             :   { &sMethods_disablers13, &sMethods_specs[13] },
    3092             :   { &sMethods_disablers15, &sMethods_specs[15] },
    3093             :   { &sMethods_disablers17, &sMethods_specs[17] },
    3094             :   { nullptr, &sMethods_specs[19] },
    3095             :   { &sMethods_disablers21, &sMethods_specs[21] },
    3096             :   { nullptr, &sMethods_specs[23] },
    3097             :   { nullptr, nullptr }
    3098             : };
    3099             : 
    3100             : static_assert(12 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    3101             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    3102             : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    3103             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    3104             : 
    3105             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    3106             : #if defined(__clang__)
    3107             : #pragma clang diagnostic push
    3108             : #pragma clang diagnostic ignored "-Wmissing-braces"
    3109             : #endif
    3110             : static const JSFunctionSpec sChromeMethods_specs[] = {
    3111             :   JS_FNSPEC("getBattery", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&getBattery_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    3112             :   JS_FS_END,
    3113             :   JS_FNSPEC("setVibrationPermission", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&setVibrationPermission_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    3114             :   JS_FNSPEC("addIdleObserver", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&addIdleObserver_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    3115             :   JS_FNSPEC("removeIdleObserver", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&removeIdleObserver_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    3116             :   JS_FS_END,
    3117             :   JS_FNSPEC("requestVRPresentation", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&requestVRPresentation_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    3118             :   JS_FS_END,
    3119             :   JS_FNSPEC("mozGetUserMediaDevices", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&mozGetUserMediaDevices_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
    3120             :   JS_FS_END
    3121             : };
    3122             : #if defined(__clang__)
    3123             : #pragma clang diagnostic pop
    3124             : #endif
    3125             : 
    3126             : static PrefableDisablers sChromeMethods_disablers0 = {
    3127             :   true, false, 0, nullptr
    3128             : };
    3129             : 
    3130             : static PrefableDisablers sChromeMethods_disablers6 = {
    3131             :   true, false, 0, nullptr
    3132             : };
    3133             : 
    3134             : // Can't be const because the pref-enabled boolean needs to be writable
    3135             : static Prefable<const JSFunctionSpec> sChromeMethods[] = {
    3136             :   { &sChromeMethods_disablers0, &sChromeMethods_specs[0] },
    3137             :   { nullptr, &sChromeMethods_specs[2] },
    3138             :   { &sChromeMethods_disablers6, &sChromeMethods_specs[6] },
    3139             :   { nullptr, &sChromeMethods_specs[8] },
    3140             :   { nullptr, nullptr }
    3141             : };
    3142             : 
    3143             : static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    3144             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    3145             : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    3146             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    3147             : 
    3148             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    3149             : #if defined(__clang__)
    3150             : #pragma clang diagnostic push
    3151             : #pragma clang diagnostic ignored "-Wmissing-braces"
    3152             : #endif
    3153             : static const JSPropertySpec sAttributes_specs[] = {
    3154             :   { "permissions", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &permissions_getterinfo, nullptr, nullptr },
    3155             :   { "mimeTypes", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &mimeTypes_getterinfo, nullptr, nullptr },
    3156             :   { "plugins", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &plugins_getterinfo, nullptr, nullptr },
    3157             :   { "doNotTrack", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &doNotTrack_getterinfo, nullptr, nullptr },
    3158             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
    3159             :   { "maxTouchPoints", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &maxTouchPoints_getterinfo, nullptr, nullptr },
    3160             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
    3161             :   { "oscpu", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &oscpu_getterinfo, nullptr, nullptr },
    3162             :   { "vendor", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &vendor_getterinfo, nullptr, nullptr },
    3163             :   { "vendorSub", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &vendorSub_getterinfo, nullptr, nullptr },
    3164             :   { "productSub", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &productSub_getterinfo, nullptr, nullptr },
    3165             :   { "cookieEnabled", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &cookieEnabled_getterinfo, nullptr, nullptr },
    3166             :   { "buildID", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &buildID_getterinfo, nullptr, nullptr },
    3167             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
    3168             :   { "mozNotification", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &mozNotification_getterinfo, nullptr, nullptr },
    3169             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
    3170             :   { "connection", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &connection_getterinfo, nullptr, nullptr },
    3171             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
    3172             :   { "activeVRDisplays", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &activeVRDisplays_getterinfo, nullptr, nullptr },
    3173             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
    3174             :   { "mediaDevices", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &mediaDevices_getterinfo, nullptr, nullptr },
    3175             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
    3176             :   { "serviceWorker", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &serviceWorker_getterinfo, nullptr, nullptr },
    3177             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
    3178             :   { "presentation", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &presentation_getterinfo, nullptr, nullptr },
    3179             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
    3180             :   { "mozTCPSocket", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &mozTCPSocket_getterinfo, nullptr, nullptr },
    3181             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
    3182             :   { "mozE10sEnabled", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &mozE10sEnabled_getterinfo, nullptr, nullptr },
    3183             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
    3184             :   { "credentials", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &credentials_getterinfo, nullptr, nullptr },
    3185             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
    3186             :   { "mozAddonManager", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &mozAddonManager_getterinfo, nullptr, nullptr },
    3187             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
    3188             :   { "hardwareConcurrency", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &hardwareConcurrency_getterinfo, nullptr, nullptr },
    3189             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
    3190             :   { "geolocation", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &geolocation_getterinfo, nullptr, nullptr },
    3191             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
    3192             :   { "appCodeName", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &appCodeName_getterinfo, nullptr, nullptr },
    3193             :   { "appName", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &appName_getterinfo, nullptr, nullptr },
    3194             :   { "appVersion", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &appVersion_getterinfo, nullptr, nullptr },
    3195             :   { "platform", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &platform_getterinfo, nullptr, nullptr },
    3196             :   { "userAgent", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &userAgent_getterinfo, nullptr, nullptr },
    3197             :   { "product", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &product_getterinfo, nullptr, nullptr },
    3198             :   { "language", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &language_getterinfo, nullptr, nullptr },
    3199             :   { "languages", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &languages_getterinfo, nullptr, nullptr },
    3200             :   { "onLine", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &onLine_getterinfo, nullptr, nullptr },
    3201             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
    3202             :   { "storage", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &storage_getterinfo, nullptr, nullptr },
    3203             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
    3204             : };
    3205             : #if defined(__clang__)
    3206             : #pragma clang diagnostic pop
    3207             : #endif
    3208             : 
    3209             : static PrefableDisablers sAttributes_disablers5 = {
    3210             :   true, false, 0, nullptr
    3211             : };
    3212             : 
    3213             : static PrefableDisablers sAttributes_disablers14 = {
    3214             :   true, false, 0, nullptr
    3215             : };
    3216             : 
    3217             : static PrefableDisablers sAttributes_disablers16 = {
    3218             :   true, false, 0, nullptr
    3219             : };
    3220             : 
    3221             : static PrefableDisablers sAttributes_disablers18 = {
    3222             :   true, false, 0, nullptr
    3223             : };
    3224             : 
    3225             : static PrefableDisablers sAttributes_disablers20 = {
    3226             :   true, false, 0, &Navigator::HasUserMediaSupport
    3227             : };
    3228             : 
    3229             : static PrefableDisablers sAttributes_disablers22 = {
    3230             :   true, false, 0, &ServiceWorkerContainer::IsEnabled
    3231             : };
    3232             : 
    3233             : static PrefableDisablers sAttributes_disablers24 = {
    3234             :   true, false, 0, nullptr
    3235             : };
    3236             : 
    3237             : static PrefableDisablers sAttributes_disablers26 = {
    3238             :   true, false, 0, &mozilla::dom::TCPSocket::ShouldTCPSocketExist
    3239             : };
    3240             : 
    3241             : static PrefableDisablers sAttributes_disablers28 = {
    3242             :   true, false, 0, &Navigator::IsE10sEnabled
    3243             : };
    3244             : 
    3245             : static PrefableDisablers sAttributes_disablers30 = {
    3246             :   true, false, 0, nullptr
    3247             : };
    3248             : 
    3249             : static PrefableDisablers sAttributes_disablers32 = {
    3250             :   true, false, 0, &mozilla::AddonManagerWebAPI::IsAPIEnabled
    3251             : };
    3252             : 
    3253             : static PrefableDisablers sAttributes_disablers36 = {
    3254             :   true, false, 0, nullptr
    3255             : };
    3256             : 
    3257             : static PrefableDisablers sAttributes_disablers48 = {
    3258             :   true, true, 0, &mozilla::dom::StorageManager::PrefEnabled
    3259             : };
    3260             : 
    3261             : // Can't be const because the pref-enabled boolean needs to be writable
    3262             : static Prefable<const JSPropertySpec> sAttributes[] = {
    3263             :   { nullptr, &sAttributes_specs[0] },
    3264             :   { &sAttributes_disablers5, &sAttributes_specs[5] },
    3265             :   { nullptr, &sAttributes_specs[7] },
    3266             :   { &sAttributes_disablers14, &sAttributes_specs[14] },
    3267             :   { &sAttributes_disablers16, &sAttributes_specs[16] },
    3268             :   { &sAttributes_disablers18, &sAttributes_specs[18] },
    3269             :   { &sAttributes_disablers20, &sAttributes_specs[20] },
    3270             :   { &sAttributes_disablers22, &sAttributes_specs[22] },
    3271             :   { &sAttributes_disablers24, &sAttributes_specs[24] },
    3272             :   { &sAttributes_disablers26, &sAttributes_specs[26] },
    3273             :   { &sAttributes_disablers28, &sAttributes_specs[28] },
    3274             :   { &sAttributes_disablers30, &sAttributes_specs[30] },
    3275             :   { &sAttributes_disablers32, &sAttributes_specs[32] },
    3276             :   { nullptr, &sAttributes_specs[34] },
    3277             :   { &sAttributes_disablers36, &sAttributes_specs[36] },
    3278             :   { nullptr, &sAttributes_specs[38] },
    3279             :   { &sAttributes_disablers48, &sAttributes_specs[48] },
    3280             :   { nullptr, nullptr }
    3281             : };
    3282             : 
    3283             : static_assert(17 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    3284             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    3285             : static_assert(9 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    3286             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    3287             : 
    3288             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    3289             : #if defined(__clang__)
    3290             : #pragma clang diagnostic push
    3291             : #pragma clang diagnostic ignored "-Wmissing-braces"
    3292             : #endif
    3293             : static const JSPropertySpec sChromeAttributes_specs[] = {
    3294             :   { "mozPower", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &mozPower_getterinfo, nullptr, nullptr },
    3295             :   { "cpuHasSSE2", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &cpuHasSSE2_getterinfo, nullptr, nullptr },
    3296             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
    3297             :   { "isWebVRContentDetected", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &isWebVRContentDetected_getterinfo, nullptr, nullptr },
    3298             :   { "isWebVRContentPresenting", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &isWebVRContentPresenting_getterinfo, nullptr, nullptr },
    3299             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
    3300             :   { "seManager", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &seManager_getterinfo, nullptr, nullptr },
    3301             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
    3302             : };
    3303             : #if defined(__clang__)
    3304             : #pragma clang diagnostic pop
    3305             : #endif
    3306             : 
    3307             : static PrefableDisablers sChromeAttributes_disablers3 = {
    3308             :   true, false, 0, nullptr
    3309             : };
    3310             : 
    3311             : static PrefableDisablers sChromeAttributes_disablers6 = {
    3312             :   true, false, 0, nullptr
    3313             : };
    3314             : 
    3315             : // Can't be const because the pref-enabled boolean needs to be writable
    3316             : static Prefable<const JSPropertySpec> sChromeAttributes[] = {
    3317             :   { nullptr, &sChromeAttributes_specs[0] },
    3318             :   { &sChromeAttributes_disablers3, &sChromeAttributes_specs[3] },
    3319             :   { &sChromeAttributes_disablers6, &sChromeAttributes_specs[6] },
    3320             :   { nullptr, nullptr }
    3321             : };
    3322             : 
    3323             : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    3324             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    3325             : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    3326             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    3327             : 
    3328             : 
    3329             : static uint16_t sNativeProperties_sortedPropertyIndices[48];
    3330             : static PropertyInfo sNativeProperties_propertyInfos[48];
    3331             : 
    3332             : static const NativePropertiesN<2> sNativeProperties = {
    3333             :   false, 0,
    3334             :   false, 0,
    3335             :   true,  0 /* sMethods */,
    3336             :   true,  1 /* sAttributes */,
    3337             :   false, 0,
    3338             :   false, 0,
    3339             :   false, 0,
    3340             :   -1,
    3341             :   48,
    3342             :   sNativeProperties_sortedPropertyIndices,
    3343             :   {
    3344             :     { sMethods, &sNativeProperties_propertyInfos[0] },
    3345             :     { sAttributes, &sNativeProperties_propertyInfos[15] }
    3346             :   }
    3347             : };
    3348             : static_assert(48 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
    3349             :     "We have a property info count that is oversized");
    3350             : 
    3351             : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[11];
    3352             : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[11];
    3353             : 
    3354             : static const NativePropertiesN<2> sChromeOnlyNativeProperties = {
    3355             :   false, 0,
    3356             :   false, 0,
    3357             :   true,  0 /* sChromeMethods */,
    3358             :   true,  1 /* sChromeAttributes */,
    3359             :   false, 0,
    3360             :   false, 0,
    3361             :   false, 0,
    3362             :   -1,
    3363             :   11,
    3364             :   sChromeOnlyNativeProperties_sortedPropertyIndices,
    3365             :   {
    3366             :     { sChromeMethods, &sChromeOnlyNativeProperties_propertyInfos[0] },
    3367             :     { sChromeAttributes, &sChromeOnlyNativeProperties_propertyInfos[6] }
    3368             :   }
    3369             : };
    3370             : static_assert(11 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
    3371             :     "We have a property info count that is oversized");
    3372             : 
    3373             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
    3374             :   {
    3375             :     "Function",
    3376             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
    3377             :     &sBoringInterfaceObjectClassClassOps,
    3378             :     JS_NULL_CLASS_SPEC,
    3379             :     JS_NULL_CLASS_EXT,
    3380             :     &sInterfaceObjectClassObjectOps
    3381             :   },
    3382             :   eInterface,
    3383             :   true,
    3384             :   prototypes::id::Navigator,
    3385             :   PrototypeTraits<prototypes::id::Navigator>::Depth,
    3386             :   sNativePropertyHooks,
    3387             :   "function Navigator() {\n    [native code]\n}",
    3388             :   JS::GetRealmFunctionPrototype
    3389             : };
    3390             : 
    3391             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
    3392             :   {
    3393             :     "NavigatorPrototype",
    3394             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    3395             :     JS_NULL_CLASS_OPS,
    3396             :     JS_NULL_CLASS_SPEC,
    3397             :     JS_NULL_CLASS_EXT,
    3398             :     JS_NULL_OBJECT_OPS
    3399             :   },
    3400             :   eInterfacePrototype,
    3401             :   false,
    3402             :   prototypes::id::Navigator,
    3403             :   PrototypeTraits<prototypes::id::Navigator>::Depth,
    3404             :   sNativePropertyHooks,
    3405             :   "[object NavigatorPrototype]",
    3406             :   JS::GetRealmObjectPrototype
    3407             : };
    3408             : 
    3409             : JSObject*
    3410           0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
    3411             : {
    3412           0 :   return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
    3413             : }
    3414             : 
    3415             : static const js::ClassOps sClassOps = {
    3416             :   _addProperty, /* addProperty */
    3417             :   nullptr,               /* delProperty */
    3418             :   nullptr,               /* getProperty */
    3419             :   nullptr,               /* setProperty */
    3420             :   nullptr,               /* enumerate */
    3421             :   nullptr, /* newEnumerate */
    3422             :   nullptr, /* resolve */
    3423             :   nullptr, /* mayResolve */
    3424             :   _finalize, /* finalize */
    3425             :   nullptr, /* call */
    3426             :   nullptr,               /* hasInstance */
    3427             :   nullptr,               /* construct */
    3428             :   nullptr, /* trace */
    3429             : };
    3430             : 
    3431             : static const js::ClassExtension sClassExtension = {
    3432             :   nullptr, /* weakmapKeyDelegateOp */
    3433             :   _objectMoved /* objectMovedOp */
    3434             : };
    3435             : 
    3436             : static const DOMJSClass sClass = {
    3437             :   { "Navigator",
    3438             :     JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(16),
    3439             :     &sClassOps,
    3440             :     JS_NULL_CLASS_SPEC,
    3441             :     &sClassExtension,
    3442             :     JS_NULL_OBJECT_OPS
    3443             :   },
    3444             :   { prototypes::id::Navigator, 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 },
    3445             :   IsBaseOf<nsISupports, mozilla::dom::Navigator >::value,
    3446             :   sNativePropertyHooks,
    3447             :   FindAssociatedGlobalForNative<mozilla::dom::Navigator>::Get,
    3448             :   GetProtoObjectHandle,
    3449             :   GetCCParticipant<mozilla::dom::Navigator>::Get()
    3450             : };
    3451             : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
    3452             :               "Must have the right minimal number of reserved slots.");
    3453             : static_assert(16 >= 16,
    3454             :               "Must have enough reserved slots.");
    3455             : 
    3456             : const JSClass*
    3457           0 : GetJSClass()
    3458             : {
    3459           0 :   return sClass.ToJSClass();
    3460             : }
    3461             : 
    3462             : bool
    3463           0 : Wrap(JSContext* aCx, mozilla::dom::Navigator* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
    3464             : {
    3465             :   MOZ_ASSERT(static_cast<mozilla::dom::Navigator*>(aObject) ==
    3466             :              reinterpret_cast<mozilla::dom::Navigator*>(aObject),
    3467             :              "Multiple inheritance for mozilla::dom::Navigator is broken.");
    3468           0 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
    3469           0 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
    3470           0 :   MOZ_ASSERT(!aCache->GetWrapper(),
    3471             :              "You should probably not be using Wrap() directly; use "
    3472             :              "GetOrCreateDOMReflector instead");
    3473             : 
    3474           0 :   MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
    3475             :              "nsISupports must be on our primary inheritance chain");
    3476             : 
    3477           0 :   JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
    3478           0 :   if (!global) {
    3479           0 :     return false;
    3480             :   }
    3481           0 :   MOZ_ASSERT(JS_IsGlobalObject(global));
    3482           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(global));
    3483             : 
    3484             :   // That might have ended up wrapping us already, due to the wonders
    3485             :   // of XBL.  Check for that, and bail out as needed.
    3486           0 :   aReflector.set(aCache->GetWrapper());
    3487           0 :   if (aReflector) {
    3488             : #ifdef DEBUG
    3489           0 :     binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
    3490             : #endif // DEBUG
    3491           0 :     return true;
    3492             :   }
    3493             : 
    3494           0 :   JSAutoCompartment ac(aCx, global);
    3495           0 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
    3496           0 :   if (!canonicalProto) {
    3497           0 :     return false;
    3498             :   }
    3499           0 :   JS::Rooted<JSObject*> proto(aCx);
    3500           0 :   if (aGivenProto) {
    3501           0 :     proto = aGivenProto;
    3502             :     // Unfortunately, while aGivenProto was in the compartment of aCx
    3503             :     // coming in, we changed compartments to that of "parent" so may need
    3504             :     // to wrap the proto here.
    3505           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
    3506           0 :       if (!JS_WrapObject(aCx, &proto)) {
    3507           0 :         return false;
    3508             :       }
    3509             :     }
    3510             :   } else {
    3511           0 :     proto = canonicalProto;
    3512             :   }
    3513             : 
    3514           0 :   BindingJSObjectCreator<mozilla::dom::Navigator> creator(aCx);
    3515           0 :   creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
    3516           0 :   if (!aReflector) {
    3517           0 :     return false;
    3518             :   }
    3519             : 
    3520           0 :   aCache->SetWrapper(aReflector);
    3521           0 :   creator.InitializationSucceeded();
    3522             : 
    3523           0 :   MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
    3524             :              aCache->GetWrapperPreserveColor() == aReflector);
    3525             :   // If proto != canonicalProto, we have to preserve our wrapper;
    3526             :   // otherwise we won't be able to properly recreate it later, since
    3527             :   // we won't know what proto to use.  Note that we don't check
    3528             :   // aGivenProto here, since it's entirely possible (and even
    3529             :   // somewhat common) to have a non-null aGivenProto which is the
    3530             :   // same as canonicalProto.
    3531           0 :   if (proto != canonicalProto) {
    3532           0 :     PreserveWrapper(aObject);
    3533             :   }
    3534             : 
    3535           0 :   return true;
    3536             : }
    3537             : 
    3538             : // This may allocate too many slots, because we only really need
    3539             : // slots for our non-interface-typed members that we cache.  But
    3540             : // allocating slots only for those would make the slot index
    3541             : // computations much more complicated, so let's do this the simple
    3542             : // way for now.
    3543             : DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 15);
    3544             : 
    3545             : const NativePropertyHooks sNativePropertyHooks[] = { {
    3546             :   nullptr,
    3547             :   nullptr,
    3548             :   nullptr,
    3549             :   { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
    3550             :   prototypes::id::Navigator,
    3551             :   constructors::id::Navigator,
    3552             :   nullptr,
    3553             :   &sXrayExpandoObjectClass
    3554             : } };
    3555             : 
    3556             : void
    3557           0 : ClearCachedActiveVRDisplaysValue(mozilla::dom::Navigator* aObject)
    3558             : {
    3559             :   JSObject* obj;
    3560           0 :   obj = aObject->GetWrapper();
    3561           0 :   if (!obj) {
    3562           0 :     return;
    3563             :   }
    3564           0 :   js::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 2), JS::UndefinedValue());
    3565           0 :   xpc::ClearXrayExpandoSlots(obj, (xpc::JSSLOT_EXPANDO_COUNT + 2));
    3566             : }
    3567             : 
    3568             : void
    3569           0 : ClearCachedUserAgentValue(mozilla::dom::Navigator* aObject)
    3570             : {
    3571             :   JSObject* obj;
    3572           0 :   obj = aObject->GetWrapper();
    3573           0 :   if (!obj) {
    3574           0 :     return;
    3575             :   }
    3576           0 :   js::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 11), JS::UndefinedValue());
    3577           0 :   xpc::ClearXrayExpandoSlots(obj, (xpc::JSSLOT_EXPANDO_COUNT + 11));
    3578             : }
    3579             : 
    3580             : void
    3581           0 : ClearCachedLanguageValue(mozilla::dom::Navigator* aObject)
    3582             : {
    3583             :   JSObject* obj;
    3584           0 :   obj = aObject->GetWrapper();
    3585           0 :   if (!obj) {
    3586           0 :     return;
    3587             :   }
    3588           0 :   js::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 13), JS::UndefinedValue());
    3589           0 :   xpc::ClearXrayExpandoSlots(obj, (xpc::JSSLOT_EXPANDO_COUNT + 13));
    3590             : }
    3591             : 
    3592             : void
    3593           0 : ClearCachedLanguagesValue(mozilla::dom::Navigator* aObject)
    3594             : {
    3595             :   JSObject* obj;
    3596           0 :   obj = aObject->GetWrapper();
    3597           0 :   if (!obj) {
    3598           0 :     return;
    3599             :   }
    3600           0 :   js::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 14), JS::UndefinedValue());
    3601           0 :   xpc::ClearXrayExpandoSlots(obj, (xpc::JSSLOT_EXPANDO_COUNT + 14));
    3602             : }
    3603             : 
    3604             : void
    3605           0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    3606             : {
    3607           0 :   JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
    3608           0 :   if (!parentProto) {
    3609           0 :     return;
    3610             :   }
    3611             : 
    3612           0 :   JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
    3613           0 :   if (!constructorProto) {
    3614           0 :     return;
    3615             :   }
    3616             : 
    3617             :   static bool sIdsInited = false;
    3618           0 :   if (!sIdsInited && NS_IsMainThread()) {
    3619           0 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
    3620           0 :       return;
    3621             :     }
    3622           0 :     if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
    3623           0 :       return;
    3624             :     }
    3625           0 :     sIdsInited = true;
    3626             :   }
    3627             : 
    3628             :   static bool sPrefCachesInited = false;
    3629           0 :   if (!sPrefCachesInited && NS_IsMainThread()) {
    3630           0 :     sPrefCachesInited = true;
    3631           0 :     Preferences::AddBoolVarCache(&sMethods[0].disablers->enabled, "dom.flyweb.enabled");
    3632           0 :     Preferences::AddBoolVarCache(&sMethods[2].disablers->enabled, "dom.wakelock.enabled");
    3633           0 :     Preferences::AddBoolVarCache(&sMethods[3].disablers->enabled, "dom.gamepad.enabled");
    3634           0 :     Preferences::AddBoolVarCache(&sMethods[4].disablers->enabled, "dom.gamepad.test.enabled");
    3635           0 :     Preferences::AddBoolVarCache(&sMethods[5].disablers->enabled, "dom.vr.enabled");
    3636           0 :     Preferences::AddBoolVarCache(&sMethods[6].disablers->enabled, "dom.vr.test.enabled");
    3637           0 :     Preferences::AddBoolVarCache(&sMethods[8].disablers->enabled, "beacon.enabled");
    3638           0 :     Preferences::AddBoolVarCache(&sChromeMethods[0].disablers->enabled, "dom.battery.enabled");
    3639           0 :     Preferences::AddBoolVarCache(&sChromeMethods[2].disablers->enabled, "dom.vr.enabled");
    3640           0 :     Preferences::AddBoolVarCache(&sAttributes[1].disablers->enabled, "dom.w3c_pointer_events.enabled");
    3641           0 :     Preferences::AddBoolVarCache(&sAttributes[3].disablers->enabled, "notification.feature.enabled");
    3642           0 :     Preferences::AddBoolVarCache(&sAttributes[4].disablers->enabled, "dom.netinfo.enabled");
    3643           0 :     Preferences::AddBoolVarCache(&sAttributes[5].disablers->enabled, "dom.vr.enabled");
    3644           0 :     Preferences::AddBoolVarCache(&sAttributes[8].disablers->enabled, "dom.presentation.enabled");
    3645           0 :     Preferences::AddBoolVarCache(&sAttributes[11].disablers->enabled, "security.webauth.webauthn");
    3646           0 :     Preferences::AddBoolVarCache(&sAttributes[14].disablers->enabled, "geo.enabled");
    3647           0 :     Preferences::AddBoolVarCache(&sChromeAttributes[1].disablers->enabled, "dom.vr.enabled");
    3648           0 :     Preferences::AddBoolVarCache(&sChromeAttributes[2].disablers->enabled, "dom.secureelement.enabled");
    3649             :   }
    3650             : 
    3651           0 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::Navigator);
    3652           0 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::Navigator);
    3653           0 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    3654             :                               &sPrototypeClass.mBase, protoCache,
    3655             :                               constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
    3656             :                               interfaceCache,
    3657             :                               sNativeProperties.Upcast(),
    3658           0 :                               nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
    3659             :                               "Navigator", aDefineOnGlobal,
    3660             :                               nullptr,
    3661           0 :                               false);
    3662             : }
    3663             : 
    3664             : JS::Handle<JSObject*>
    3665           0 : GetProtoObjectHandle(JSContext* aCx)
    3666             : {
    3667             :   /* Get the interface prototype object for this class.  This will create the
    3668             :      object as needed. */
    3669           0 :   bool aDefineOnGlobal = true;
    3670             : 
    3671             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    3672           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    3673           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    3674           0 :     return nullptr;
    3675             :   }
    3676             : 
    3677             :   /* Check to see whether the interface objects are already installed */
    3678           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    3679           0 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::Navigator)) {
    3680           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    3681           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    3682             :   }
    3683             : 
    3684             :   /*
    3685             :    * The object might _still_ be null, but that's OK.
    3686             :    *
    3687             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    3688             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    3689             :    * changed after they have been set.
    3690             :    *
    3691             :    * Calling address() avoids the read read barrier that does gray
    3692             :    * unmarking, but it's not possible for the object to be gray here.
    3693             :    */
    3694             : 
    3695           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::Navigator);
    3696           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    3697           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    3698             : }
    3699             : 
    3700             : JS::Handle<JSObject*>
    3701           0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
    3702             : {
    3703             :   /* Get the interface object for this class.  This will create the object as
    3704             :      needed. */
    3705             : 
    3706             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    3707           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    3708           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    3709           0 :     return nullptr;
    3710             :   }
    3711             : 
    3712             :   /* Check to see whether the interface objects are already installed */
    3713           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    3714           0 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::Navigator)) {
    3715           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    3716           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    3717             :   }
    3718             : 
    3719             :   /*
    3720             :    * The object might _still_ be null, but that's OK.
    3721             :    *
    3722             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    3723             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    3724             :    * changed after they have been set.
    3725             :    *
    3726             :    * Calling address() avoids the read read barrier that does gray
    3727             :    * unmarking, but it's not possible for the object to be gray here.
    3728             :    */
    3729             : 
    3730           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::Navigator);
    3731           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    3732           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    3733             : }
    3734             : 
    3735             : JSObject*
    3736           0 : GetConstructorObject(JSContext* aCx)
    3737             : {
    3738           0 :   return GetConstructorObjectHandle(aCx);
    3739             : }
    3740             : 
    3741             : } // namespace NavigatorBinding
    3742             : 
    3743             : 
    3744             : 
    3745             : void
    3746           0 : MozIdleObserver::Onidle(ErrorResult& aRv, const char* aExecutionReason, ExceptionHandling aExceptionHandling, JSCompartment* aCompartment)
    3747             : {
    3748           0 :   CallSetup s(this, aRv, "MozIdleObserver.onidle", aExceptionHandling, aCompartment);
    3749           0 :   JSContext* cx = s.GetContext();
    3750           0 :   if (!cx) {
    3751           0 :     MOZ_ASSERT(aRv.Failed());
    3752           0 :     return;
    3753             :   }
    3754           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    3755             : 
    3756           0 :   JS::Rooted<JS::Value> callable(cx);
    3757           0 :   MozIdleObserverAtoms* atomsCache = GetAtomCache<MozIdleObserverAtoms>(cx);
    3758           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    3759           0 :       !GetCallableProperty(cx, atomsCache->onidle_id, &callable)) {
    3760           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3761           0 :     return;
    3762             :   }
    3763           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    3764           0 :   if (!JS::Call(cx, thisValue, callable,
    3765           0 :                 JS::HandleValueArray::empty(), &rval)) {
    3766           0 :     aRv.NoteJSContextException(cx);
    3767           0 :     return;
    3768             :   }
    3769             : }
    3770             : 
    3771             : void
    3772           0 : MozIdleObserver::Onactive(ErrorResult& aRv, const char* aExecutionReason, ExceptionHandling aExceptionHandling, JSCompartment* aCompartment)
    3773             : {
    3774           0 :   CallSetup s(this, aRv, "MozIdleObserver.onactive", aExceptionHandling, aCompartment);
    3775           0 :   JSContext* cx = s.GetContext();
    3776           0 :   if (!cx) {
    3777           0 :     MOZ_ASSERT(aRv.Failed());
    3778           0 :     return;
    3779             :   }
    3780           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    3781             : 
    3782           0 :   JS::Rooted<JS::Value> callable(cx);
    3783           0 :   MozIdleObserverAtoms* atomsCache = GetAtomCache<MozIdleObserverAtoms>(cx);
    3784           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    3785           0 :       !GetCallableProperty(cx, atomsCache->onactive_id, &callable)) {
    3786           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3787           0 :     return;
    3788             :   }
    3789           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    3790           0 :   if (!JS::Call(cx, thisValue, callable,
    3791           0 :                 JS::HandleValueArray::empty(), &rval)) {
    3792           0 :     aRv.NoteJSContextException(cx);
    3793           0 :     return;
    3794             :   }
    3795             : }
    3796             : 
    3797             : bool
    3798           0 : MozIdleObserver::InitIds(JSContext* cx, MozIdleObserverAtoms* atomsCache)
    3799             : {
    3800           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
    3801             : 
    3802             :   // Initialize these in reverse order so that any failure leaves the first one
    3803             :   // uninitialized.
    3804           0 :   if (!atomsCache->onactive_id.init(cx, "onactive") ||
    3805           0 :       !atomsCache->onidle_id.init(cx, "onidle") ||
    3806           0 :       !atomsCache->time_id.init(cx, "time")) {
    3807           0 :     return false;
    3808             :   }
    3809           0 :   return true;
    3810             : }
    3811             : 
    3812             : 
    3813             : uint32_t
    3814           0 : MozIdleObserver::GetTime(ErrorResult& aRv, const char* aExecutionReason, ExceptionHandling aExceptionHandling, JSCompartment* aCompartment)
    3815             : {
    3816           0 :   CallSetup s(this, aRv, "MozIdleObserver.time", aExceptionHandling, aCompartment);
    3817           0 :   JSContext* cx = s.GetContext();
    3818           0 :   if (!cx) {
    3819           0 :     MOZ_ASSERT(aRv.Failed());
    3820           0 :     return uint32_t(0);
    3821             :   }
    3822           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    3823             : 
    3824           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    3825           0 :   MozIdleObserverAtoms* atomsCache = GetAtomCache<MozIdleObserverAtoms>(cx);
    3826           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    3827           0 :       !JS_GetPropertyById(cx, callback, atomsCache->time_id, &rval)) {
    3828           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3829           0 :     return uint32_t(0);
    3830             :   }
    3831             :   uint32_t rvalDecl;
    3832           0 :   if (!ValueToPrimitive<uint32_t, eDefault>(cx, rval, &rvalDecl)) {
    3833           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3834           0 :     return uint32_t(0);
    3835             :   }
    3836           0 :   return rvalDecl;
    3837             : }
    3838             : 
    3839             : 
    3840             : namespace binding_detail {
    3841             : } // namespace binding_detail
    3842             : 
    3843             : 
    3844             : } // namespace dom
    3845             : } // namespace mozilla

Generated by: LCOV version 1.13