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

          Line data    Source code
       1             : /* THIS FILE IS AUTOGENERATED FROM SecureElement.webidl BY Codegen.py - DO NOT EDIT */
       2             : 
       3             : #include "AtomList.h"
       4             : #include "SecureElementBinding.h"
       5             : #include "WrapperFactory.h"
       6             : #include "XrayWrapper.h"
       7             : #include "jsapi.h"
       8             : #include "jsfriendapi.h"
       9             : #include "mozilla/OwningNonNull.h"
      10             : #include "mozilla/Preferences.h"
      11             : #include "mozilla/dom/BindingUtils.h"
      12             : #include "mozilla/dom/DOMJSClass.h"
      13             : #include "mozilla/dom/NonRefcountedDOMObject.h"
      14             : #include "mozilla/dom/Nullable.h"
      15             : #include "mozilla/dom/PrimitiveConversions.h"
      16             : #include "mozilla/dom/Promise.h"
      17             : #include "mozilla/dom/ScriptSettings.h"
      18             : #include "mozilla/dom/SimpleGlobalObject.h"
      19             : #include "mozilla/dom/ToJSValue.h"
      20             : #include "mozilla/dom/XrayExpandoClass.h"
      21             : #include "nsContentUtils.h"
      22             : #include "nsIGlobalObject.h"
      23             : 
      24             : namespace mozilla {
      25             : namespace dom {
      26             : 
      27             : namespace SETypeValues {
      28             : extern const EnumEntry strings[3] = {
      29             :   {"uicc", 4},
      30             :   {"eSE", 3},
      31             :   { nullptr, 0 }
      32             : };
      33             : } // namespace SETypeValues
      34             : 
      35             : bool
      36           0 : ToJSValue(JSContext* aCx, SEType aArgument, JS::MutableHandle<JS::Value> aValue)
      37             : {
      38           0 :   MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(SETypeValues::strings));
      39             :   JSString* resultStr =
      40           0 :     JS_NewStringCopyN(aCx, SETypeValues::strings[uint32_t(aArgument)].value,
      41           0 :                       SETypeValues::strings[uint32_t(aArgument)].length);
      42           0 :   if (!resultStr) {
      43           0 :     return false;
      44             :   }
      45           0 :   aValue.setString(resultStr);
      46           0 :   return true;
      47             : }
      48             : 
      49             : 
      50             : namespace SEErrorValues {
      51             : extern const EnumEntry strings[9] = {
      52             :   {"SESecurityError", 15},
      53             :   {"SEIoError", 9},
      54             :   {"SEBadStateError", 15},
      55             :   {"SEInvalidChannelError", 21},
      56             :   {"SEInvalidApplicationError", 25},
      57             :   {"SENotPresentError", 17},
      58             :   {"SEIllegalParameterError", 23},
      59             :   {"SEGenericError", 14},
      60             :   { nullptr, 0 }
      61             : };
      62             : } // namespace SEErrorValues
      63             : 
      64             : bool
      65           0 : ToJSValue(JSContext* aCx, SEError aArgument, JS::MutableHandle<JS::Value> aValue)
      66             : {
      67           0 :   MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(SEErrorValues::strings));
      68             :   JSString* resultStr =
      69           0 :     JS_NewStringCopyN(aCx, SEErrorValues::strings[uint32_t(aArgument)].value,
      70           0 :                       SEErrorValues::strings[uint32_t(aArgument)].length);
      71           0 :   if (!resultStr) {
      72           0 :     return false;
      73             :   }
      74           0 :   aValue.setString(resultStr);
      75           0 :   return true;
      76             : }
      77             : 
      78             : 
      79             : namespace SEChannelTypeValues {
      80             : extern const EnumEntry strings[3] = {
      81             :   {"basic", 5},
      82             :   {"logical", 7},
      83             :   { nullptr, 0 }
      84             : };
      85             : } // namespace SEChannelTypeValues
      86             : 
      87             : bool
      88           0 : ToJSValue(JSContext* aCx, SEChannelType aArgument, JS::MutableHandle<JS::Value> aValue)
      89             : {
      90           0 :   MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(SEChannelTypeValues::strings));
      91             :   JSString* resultStr =
      92           0 :     JS_NewStringCopyN(aCx, SEChannelTypeValues::strings[uint32_t(aArgument)].value,
      93           0 :                       SEChannelTypeValues::strings[uint32_t(aArgument)].length);
      94           0 :   if (!resultStr) {
      95           0 :     return false;
      96             :   }
      97           0 :   aValue.setString(resultStr);
      98           0 :   return true;
      99             : }
     100             : 
     101             : 
     102             : 
     103           0 : SECommand::SECommand()
     104             : {
     105             :   // Safe to pass a null context if we pass a null value
     106           0 :   Init(nullptr, JS::NullHandleValue);
     107           0 : }
     108             : 
     109             : 
     110             : 
     111             : bool
     112           0 : SECommand::InitIds(JSContext* cx, SECommandAtoms* atomsCache)
     113             : {
     114           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
     115             : 
     116             :   // Initialize these in reverse order so that any failure leaves the first one
     117             :   // uninitialized.
     118           0 :   if (!atomsCache->p2_id.init(cx, "p2") ||
     119           0 :       !atomsCache->p1_id.init(cx, "p1") ||
     120           0 :       !atomsCache->le_id.init(cx, "le") ||
     121           0 :       !atomsCache->ins_id.init(cx, "ins") ||
     122           0 :       !atomsCache->data_id.init(cx, "data") ||
     123           0 :       !atomsCache->cla_id.init(cx, "cla")) {
     124           0 :     return false;
     125             :   }
     126           0 :   return true;
     127             : }
     128             : 
     129             : bool
     130           0 : SECommand::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
     131             : {
     132             :   // Passing a null JSContext is OK only if we're initing from null,
     133             :   // Since in that case we will not have to do any property gets
     134             :   // Also evaluate isNullOrUndefined in order to avoid false-positive
     135             :   // checkers by static analysis tools
     136           0 :   MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
     137           0 :   SECommandAtoms* atomsCache = nullptr;
     138           0 :   if (cx) {
     139           0 :     atomsCache = GetAtomCache<SECommandAtoms>(cx);
     140           0 :     if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     141           0 :       return false;
     142             :     }
     143             :   }
     144             : 
     145           0 :   if (!IsConvertibleToDictionary(val)) {
     146           0 :     return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
     147             :   }
     148             : 
     149           0 :   bool isNull = val.isNullOrUndefined();
     150             :   // We only need these if !isNull, in which case we have |cx|.
     151           0 :   Maybe<JS::Rooted<JSObject *> > object;
     152           0 :   Maybe<JS::Rooted<JS::Value> > temp;
     153           0 :   if (!isNull) {
     154           0 :     MOZ_ASSERT(cx);
     155           0 :     object.emplace(cx, &val.toObject());
     156           0 :     temp.emplace(cx);
     157             :   }
     158           0 :   if (!isNull) {
     159           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->cla_id, temp.ptr())) {
     160           0 :       return false;
     161             :     }
     162             :   }
     163           0 :   if (!isNull && !temp->isUndefined()) {
     164           0 :     if (!ValueToPrimitive<uint8_t, eDefault>(cx, temp.ref(), &mCla)) {
     165           0 :       return false;
     166             :     }
     167           0 :     mIsAnyMemberPresent = true;
     168           0 :   } else if (cx) {
     169             :     // Don't error out if we have no cx.  In that
     170             :     // situation the caller is default-constructing us and we'll
     171             :     // just assume they know what they're doing.
     172           0 :     return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
     173           0 :                              "'cla' member of SECommand");
     174             :   }
     175             : 
     176           0 :   if (!isNull) {
     177           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->data_id, temp.ptr())) {
     178           0 :       return false;
     179             :     }
     180             :   }
     181           0 :   if (!isNull && !temp->isUndefined()) {
     182           0 :     if (temp.ref().isObject()) {
     183           0 :       JS::ForOfIterator iter(cx);
     184           0 :       if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
     185           0 :         return false;
     186             :       }
     187           0 :       if (!iter.valueIsIterable()) {
     188           0 :         ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'data' member of SECommand");
     189           0 :         return false;
     190             :       }
     191           0 :       Sequence<uint8_t> &arr = mData.SetValue();
     192           0 :       JS::Rooted<JS::Value> temp(cx);
     193             :       while (true) {
     194             :         bool done;
     195           0 :         if (!iter.next(&temp, &done)) {
     196           0 :           return false;
     197             :         }
     198           0 :         if (done) {
     199           0 :           break;
     200             :         }
     201           0 :         uint8_t* slotPtr = arr.AppendElement(mozilla::fallible);
     202           0 :         if (!slotPtr) {
     203           0 :           JS_ReportOutOfMemory(cx);
     204           0 :           return false;
     205             :         }
     206           0 :         uint8_t& slot = *slotPtr;
     207           0 :         if (!ValueToPrimitive<uint8_t, eDefault>(cx, temp, &slot)) {
     208           0 :           return false;
     209             :         }
     210           0 :       }
     211           0 :     } else if (temp.ref().isNullOrUndefined()) {
     212           0 :       mData.SetNull();
     213             :     } else {
     214           0 :       ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'data' member of SECommand");
     215           0 :       return false;
     216             :     }
     217             :   } else {
     218           0 :     mData.SetNull();
     219             :   }
     220           0 :   mIsAnyMemberPresent = true;
     221             : 
     222           0 :   if (!isNull) {
     223           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->ins_id, temp.ptr())) {
     224           0 :       return false;
     225             :     }
     226             :   }
     227           0 :   if (!isNull && !temp->isUndefined()) {
     228           0 :     if (!ValueToPrimitive<uint8_t, eDefault>(cx, temp.ref(), &mIns)) {
     229           0 :       return false;
     230             :     }
     231           0 :     mIsAnyMemberPresent = true;
     232           0 :   } else if (cx) {
     233             :     // Don't error out if we have no cx.  In that
     234             :     // situation the caller is default-constructing us and we'll
     235             :     // just assume they know what they're doing.
     236           0 :     return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
     237           0 :                              "'ins' member of SECommand");
     238             :   }
     239             : 
     240           0 :   if (!isNull) {
     241           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->le_id, temp.ptr())) {
     242           0 :       return false;
     243             :     }
     244             :   }
     245           0 :   if (!isNull && !temp->isUndefined()) {
     246           0 :     if (!ValueToPrimitive<int16_t, eDefault>(cx, temp.ref(), &mLe)) {
     247           0 :       return false;
     248             :     }
     249             :   } else {
     250           0 :     mLe = -1;
     251             :   }
     252           0 :   mIsAnyMemberPresent = true;
     253             : 
     254           0 :   if (!isNull) {
     255           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->p1_id, temp.ptr())) {
     256           0 :       return false;
     257             :     }
     258             :   }
     259           0 :   if (!isNull && !temp->isUndefined()) {
     260           0 :     if (!ValueToPrimitive<uint8_t, eDefault>(cx, temp.ref(), &mP1)) {
     261           0 :       return false;
     262             :     }
     263           0 :     mIsAnyMemberPresent = true;
     264           0 :   } else if (cx) {
     265             :     // Don't error out if we have no cx.  In that
     266             :     // situation the caller is default-constructing us and we'll
     267             :     // just assume they know what they're doing.
     268           0 :     return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
     269           0 :                              "'p1' member of SECommand");
     270             :   }
     271             : 
     272           0 :   if (!isNull) {
     273           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->p2_id, temp.ptr())) {
     274           0 :       return false;
     275             :     }
     276             :   }
     277           0 :   if (!isNull && !temp->isUndefined()) {
     278           0 :     if (!ValueToPrimitive<uint8_t, eDefault>(cx, temp.ref(), &mP2)) {
     279           0 :       return false;
     280             :     }
     281           0 :     mIsAnyMemberPresent = true;
     282           0 :   } else if (cx) {
     283             :     // Don't error out if we have no cx.  In that
     284             :     // situation the caller is default-constructing us and we'll
     285             :     // just assume they know what they're doing.
     286           0 :     return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
     287           0 :                              "'p2' member of SECommand");
     288             :   }
     289           0 :   return true;
     290             : }
     291             : 
     292             : bool
     293           0 : SECommand::Init(const nsAString& aJSON)
     294             : {
     295           0 :   AutoJSAPI jsapi;
     296           0 :   JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
     297           0 :   if (!cleanGlobal) {
     298           0 :     return false;
     299             :   }
     300           0 :   if (!jsapi.Init(cleanGlobal)) {
     301           0 :     return false;
     302             :   }
     303           0 :   JSContext* cx = jsapi.cx();
     304           0 :   JS::Rooted<JS::Value> json(cx);
     305           0 :   bool ok = ParseJSON(cx, aJSON, &json);
     306           0 :   NS_ENSURE_TRUE(ok, false);
     307           0 :   return Init(cx, json);
     308             : }
     309             : 
     310             : bool
     311           0 : SECommand::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
     312             : {
     313           0 :   SECommandAtoms* atomsCache = GetAtomCache<SECommandAtoms>(cx);
     314           0 :   if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     315           0 :     return false;
     316             :   }
     317             : 
     318           0 :   JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
     319           0 :   if (!obj) {
     320           0 :     return false;
     321             :   }
     322           0 :   rval.set(JS::ObjectValue(*obj));
     323             : 
     324             :   do {
     325             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     326           0 :     JS::Rooted<JS::Value> temp(cx);
     327           0 :     uint8_t const & currentValue = mCla;
     328           0 :     temp.setInt32(int32_t(currentValue));
     329           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->cla_id, temp, JSPROP_ENUMERATE)) {
     330           0 :       return false;
     331             :     }
     332           0 :     break;
     333             :   } while(0);
     334             : 
     335             :   do {
     336             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     337           0 :     JS::Rooted<JS::Value> temp(cx);
     338           0 :     Nullable<Sequence<uint8_t>> const & currentValue = mData;
     339             : 
     340           0 :     if (currentValue.IsNull()) {
     341           0 :       temp.setNull();
     342           0 :       if (!JS_DefinePropertyById(cx, obj, atomsCache->data_id, temp, JSPROP_ENUMERATE)) {
     343           0 :         return false;
     344             :       }
     345           0 :       break;
     346             :     }
     347             : 
     348           0 :     uint32_t length = currentValue.Value().Length();
     349           0 :     JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
     350           0 :     if (!returnArray) {
     351           0 :       return false;
     352             :     }
     353             :     // Scope for 'tmp'
     354             :     {
     355           0 :       JS::Rooted<JS::Value> tmp(cx);
     356           0 :       for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
     357             :         // Control block to let us common up the JS_DefineElement calls when there
     358             :         // are different ways to succeed at wrapping the object.
     359             :         do {
     360           0 :           tmp.setInt32(int32_t(currentValue.Value()[sequenceIdx0]));
     361           0 :           break;
     362             :         } while (0);
     363           0 :         if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
     364             :                               JSPROP_ENUMERATE)) {
     365           0 :           return false;
     366             :         }
     367             :       }
     368             :     }
     369           0 :     temp.setObject(*returnArray);
     370           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->data_id, temp, JSPROP_ENUMERATE)) {
     371           0 :       return false;
     372             :     }
     373           0 :     break;
     374             :   } while(0);
     375             : 
     376             :   do {
     377             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     378           0 :     JS::Rooted<JS::Value> temp(cx);
     379           0 :     uint8_t const & currentValue = mIns;
     380           0 :     temp.setInt32(int32_t(currentValue));
     381           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->ins_id, temp, JSPROP_ENUMERATE)) {
     382           0 :       return false;
     383             :     }
     384           0 :     break;
     385             :   } while(0);
     386             : 
     387             :   do {
     388             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     389           0 :     JS::Rooted<JS::Value> temp(cx);
     390           0 :     int16_t const & currentValue = mLe;
     391           0 :     temp.setInt32(int32_t(currentValue));
     392           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->le_id, temp, JSPROP_ENUMERATE)) {
     393           0 :       return false;
     394             :     }
     395           0 :     break;
     396             :   } while(0);
     397             : 
     398             :   do {
     399             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     400           0 :     JS::Rooted<JS::Value> temp(cx);
     401           0 :     uint8_t const & currentValue = mP1;
     402           0 :     temp.setInt32(int32_t(currentValue));
     403           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->p1_id, temp, JSPROP_ENUMERATE)) {
     404           0 :       return false;
     405             :     }
     406           0 :     break;
     407             :   } while(0);
     408             : 
     409             :   do {
     410             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     411           0 :     JS::Rooted<JS::Value> temp(cx);
     412           0 :     uint8_t const & currentValue = mP2;
     413           0 :     temp.setInt32(int32_t(currentValue));
     414           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->p2_id, temp, JSPROP_ENUMERATE)) {
     415           0 :       return false;
     416             :     }
     417           0 :     break;
     418             :   } while(0);
     419             : 
     420           0 :   return true;
     421             : }
     422             : 
     423             : bool
     424           0 : SECommand::ToJSON(nsAString& aJSON) const
     425             : {
     426           0 :   AutoJSAPI jsapi;
     427           0 :   jsapi.Init();
     428           0 :   JSContext *cx = jsapi.cx();
     429             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
     430             :   // because we'll only be creating objects, in ways that have no
     431             :   // side-effects, followed by a call to JS::ToJSONMaybeSafely,
     432             :   // which likewise guarantees no side-effects for the sorts of
     433             :   // things we will pass it.
     434           0 :   JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
     435           0 :   JS::Rooted<JS::Value> val(cx);
     436           0 :   if (!ToObjectInternal(cx, &val)) {
     437           0 :     return false;
     438             :   }
     439           0 :   JS::Rooted<JSObject*> obj(cx, &val.toObject());
     440           0 :   return StringifyToJSON(cx, obj, aJSON);
     441             : }
     442             : 
     443             : void
     444           0 : SECommand::TraceDictionary(JSTracer* trc)
     445             : {
     446           0 : }
     447             : 
     448             : SECommand&
     449           0 : SECommand::operator=(const SECommand& aOther)
     450             : {
     451           0 :   mCla = aOther.mCla;
     452           0 :   mData = aOther.mData;
     453           0 :   mIns = aOther.mIns;
     454           0 :   mLe = aOther.mLe;
     455           0 :   mP1 = aOther.mP1;
     456           0 :   mP2 = aOther.mP2;
     457           0 :   return *this;
     458             : }
     459             : 
     460             : namespace binding_detail {
     461             : } // namespace binding_detail
     462             : 
     463             : 
     464             : namespace SEChannelBinding {
     465             : 
     466             : static bool
     467           0 : get_session(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEChannel* self, JSJitGetterCallArgs args)
     468             : {
     469           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
     470           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
     471           0 :   if (objIsXray) {
     472           0 :     unwrappedObj.emplace(cx, obj);
     473             :   }
     474           0 :   if (objIsXray) {
     475           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
     476           0 :     if (!unwrappedObj.ref()) {
     477           0 :       return false;
     478             :     }
     479             :   }
     480           0 :   binding_detail::FastErrorResult rv;
     481           0 :   auto result(StrongOrRawPtr<mozilla::dom::SESession>(self->GetSession(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
     482           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     483           0 :     return false;
     484             :   }
     485           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     486           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
     487           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     488           0 :     return false;
     489             :   }
     490           0 :   return true;
     491             : }
     492             : 
     493             : static const JSJitInfo session_getterinfo = {
     494             :   { (JSJitGetterOp)get_session },
     495             :   { prototypes::id::SEChannel },
     496             :   { PrototypeTraits<prototypes::id::SEChannel>::Depth },
     497             :   JSJitInfo::Getter,
     498             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     499             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     500             :   false,  /* isInfallible. False in setters. */
     501             :   false,  /* isMovable.  Not relevant for setters. */
     502             :   false, /* isEliminatable.  Not relevant for setters. */
     503             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     504             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     505             :   false,  /* isTypedMethod.  Only relevant for methods. */
     506             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     507             : };
     508             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     509             : static_assert(0 < 2, "There is no slot for us");
     510             : 
     511             : static bool
     512           0 : get_openResponse(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEChannel* self, JSJitGetterCallArgs args)
     513             : {
     514             :   // Have to either root across the getter call or reget after.
     515             :   bool isXray;
     516           0 :   JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
     517           0 :   if (!slotStorage) {
     518           0 :     return false;
     519             :   }
     520           0 :   const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 0) : (DOM_INSTANCE_RESERVED_SLOTS + 0);
     521           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
     522             :   {
     523             :     // Scope for cachedVal
     524           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
     525           0 :     if (!cachedVal.isUndefined()) {
     526           0 :       args.rval().set(cachedVal);
     527             :       // The cached value is in the compartment of slotStorage,
     528             :       // so wrap into the caller compartment as needed.
     529           0 :       return MaybeWrapNonDOMObjectOrNullValue(cx, args.rval());
     530             :     }
     531             :   }
     532             : 
     533           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
     534           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
     535           0 :   if (objIsXray) {
     536           0 :     unwrappedObj.emplace(cx, obj);
     537             :   }
     538           0 :   if (objIsXray) {
     539           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
     540           0 :     if (!unwrappedObj.ref()) {
     541           0 :       return false;
     542             :     }
     543             :   }
     544           0 :   binding_detail::FastErrorResult rv;
     545           0 :   JS::Rooted<JSObject*> result(cx);
     546           0 :   self->GetOpenResponse(&result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
     547           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     548           0 :     return false;
     549             :   }
     550           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     551             :   {
     552           0 :     JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
     553           0 :     JSAutoCompartment ac(cx, conversionScope);
     554             :     do { // block we break out of when done wrapping
     555           0 :       if (result) {
     556           0 :                     JS::ExposeObjectToActiveJS(result);
     557             :                   }
     558           0 :                   args.rval().setObjectOrNull(result);
     559           0 :       if (!MaybeWrapNonDOMObjectOrNullValue(cx, args.rval())) {
     560           0 :         return false;
     561             :       }
     562           0 :       break;
     563             :     } while (0);
     564             :   }
     565             :   { // And now store things in the compartment of our slotStorage.
     566           0 :     JSAutoCompartment ac(cx, slotStorage);
     567             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
     568           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
     569           0 :     if (!MaybeWrapNonDOMObjectOrNullValue(cx, &storedVal)) {
     570           0 :       return false;
     571             :     }
     572           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
     573           0 :     if (!isXray) {
     574             :       // In the Xray case we don't need to do this, because getting the
     575             :       // expando object already preserved our wrapper.
     576           0 :       PreserveWrapper(self);
     577             :     }
     578             :   }
     579             :   // And now make sure args.rval() is in the caller compartment
     580           0 :   return MaybeWrapNonDOMObjectOrNullValue(cx, args.rval());
     581             : }
     582             : 
     583             : static const JSJitInfo openResponse_getterinfo = {
     584             :   { (JSJitGetterOp)get_openResponse },
     585             :   { prototypes::id::SEChannel },
     586             :   { PrototypeTraits<prototypes::id::SEChannel>::Depth },
     587             :   JSJitInfo::Getter,
     588             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
     589             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
     590             :   false,  /* isInfallible. False in setters. */
     591             :   false,  /* isMovable.  Not relevant for setters. */
     592             :   false, /* isEliminatable.  Not relevant for setters. */
     593             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     594             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
     595             :   false,  /* isTypedMethod.  Only relevant for methods. */
     596             :   (DOM_INSTANCE_RESERVED_SLOTS + 0)   /* Reserved slot index, if we're stored in a slot, else 0. */
     597             : };
     598             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit");
     599             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 2, "There is no slot for us");
     600             : 
     601             : static bool
     602           0 : get_isClosed(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEChannel* self, JSJitGetterCallArgs args)
     603             : {
     604           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
     605           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
     606           0 :   if (objIsXray) {
     607           0 :     unwrappedObj.emplace(cx, obj);
     608             :   }
     609           0 :   if (objIsXray) {
     610           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
     611           0 :     if (!unwrappedObj.ref()) {
     612           0 :       return false;
     613             :     }
     614             :   }
     615           0 :   binding_detail::FastErrorResult rv;
     616           0 :   bool result(self->GetIsClosed(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
     617           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     618           0 :     return false;
     619             :   }
     620           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     621           0 :   args.rval().setBoolean(result);
     622           0 :   return true;
     623             : }
     624             : 
     625             : static const JSJitInfo isClosed_getterinfo = {
     626             :   { (JSJitGetterOp)get_isClosed },
     627             :   { prototypes::id::SEChannel },
     628             :   { PrototypeTraits<prototypes::id::SEChannel>::Depth },
     629             :   JSJitInfo::Getter,
     630             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     631             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
     632             :   false,  /* isInfallible. False in setters. */
     633             :   false,  /* isMovable.  Not relevant for setters. */
     634             :   false, /* isEliminatable.  Not relevant for setters. */
     635             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     636             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     637             :   false,  /* isTypedMethod.  Only relevant for methods. */
     638             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     639             : };
     640             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     641             : static_assert(0 < 2, "There is no slot for us");
     642             : 
     643             : static bool
     644           0 : get_type(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEChannel* self, JSJitGetterCallArgs args)
     645             : {
     646           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
     647           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
     648           0 :   if (objIsXray) {
     649           0 :     unwrappedObj.emplace(cx, obj);
     650             :   }
     651           0 :   if (objIsXray) {
     652           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
     653           0 :     if (!unwrappedObj.ref()) {
     654           0 :       return false;
     655             :     }
     656             :   }
     657           0 :   binding_detail::FastErrorResult rv;
     658           0 :   SEChannelType result(self->GetType(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
     659           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     660           0 :     return false;
     661             :   }
     662           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     663           0 :   if (!ToJSValue(cx, result, args.rval())) {
     664           0 :     return false;
     665             :   }
     666           0 :   return true;
     667             : }
     668             : 
     669             : static const JSJitInfo type_getterinfo = {
     670             :   { (JSJitGetterOp)get_type },
     671             :   { prototypes::id::SEChannel },
     672             :   { PrototypeTraits<prototypes::id::SEChannel>::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 < 2, "There is no slot for us");
     686             : 
     687             : static bool
     688           0 : transmit(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEChannel* self, const JSJitMethodCallArgs& args)
     689             : {
     690           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
     691           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
     692           0 :   if (objIsXray) {
     693           0 :     unwrappedObj.emplace(cx, obj);
     694             :   }
     695           0 :   binding_detail::FastSECommand arg0;
     696           0 :   if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue,  "Argument 1 of SEChannel.transmit", true)) {
     697           0 :     return false;
     698             :   }
     699           0 :   if (objIsXray) {
     700           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
     701           0 :     if (!unwrappedObj.ref()) {
     702           0 :       return false;
     703             :     }
     704             :   }
     705           0 :   binding_detail::FastErrorResult rv;
     706           0 :   auto result(StrongOrRawPtr<Promise>(self->Transmit(Constify(arg0), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
     707           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     708           0 :     return false;
     709             :   }
     710           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     711           0 :   if (!ToJSValue(cx, result, args.rval())) {
     712           0 :     return false;
     713             :   }
     714           0 :   return true;
     715             : }
     716             : 
     717             : static bool
     718           0 : transmit_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEChannel* self, const JSJitMethodCallArgs& args)
     719             : {
     720             :   // Make sure to save the callee before someone maybe messes
     721             :   // with rval().
     722           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
     723           0 :   bool ok = transmit(cx, obj, self, args);
     724           0 :   if (ok) {
     725           0 :     return true;
     726             :   }
     727           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
     728           0 :                                    args.rval());
     729             : }
     730             : 
     731             : static const JSJitInfo transmit_methodinfo = {
     732             :   { (JSJitGetterOp)transmit_promiseWrapper },
     733             :   { prototypes::id::SEChannel },
     734             :   { PrototypeTraits<prototypes::id::SEChannel>::Depth },
     735             :   JSJitInfo::Method,
     736             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     737             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     738             :   false,  /* isInfallible. False in setters. */
     739             :   false,  /* isMovable.  Not relevant for setters. */
     740             :   false, /* isEliminatable.  Not relevant for setters. */
     741             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     742             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     743             :   false,  /* isTypedMethod.  Only relevant for methods. */
     744             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     745             : };
     746             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     747             : static_assert(0 < 2, "There is no slot for us");
     748             : 
     749             : static bool
     750           0 : close(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEChannel* self, const JSJitMethodCallArgs& args)
     751             : {
     752           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
     753           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
     754           0 :   if (objIsXray) {
     755           0 :     unwrappedObj.emplace(cx, obj);
     756             :   }
     757           0 :   if (objIsXray) {
     758           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
     759           0 :     if (!unwrappedObj.ref()) {
     760           0 :       return false;
     761             :     }
     762             :   }
     763           0 :   binding_detail::FastErrorResult rv;
     764           0 :   auto result(StrongOrRawPtr<Promise>(self->Close(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
     765           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     766           0 :     return false;
     767             :   }
     768           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     769           0 :   if (!ToJSValue(cx, result, args.rval())) {
     770           0 :     return false;
     771             :   }
     772           0 :   return true;
     773             : }
     774             : 
     775             : static bool
     776           0 : close_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEChannel* self, const JSJitMethodCallArgs& args)
     777             : {
     778             :   // Make sure to save the callee before someone maybe messes
     779             :   // with rval().
     780           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
     781           0 :   bool ok = close(cx, obj, self, args);
     782           0 :   if (ok) {
     783           0 :     return true;
     784             :   }
     785           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
     786           0 :                                    args.rval());
     787             : }
     788             : 
     789             : static const JSJitInfo close_methodinfo = {
     790             :   { (JSJitGetterOp)close_promiseWrapper },
     791             :   { prototypes::id::SEChannel },
     792             :   { PrototypeTraits<prototypes::id::SEChannel>::Depth },
     793             :   JSJitInfo::Method,
     794             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     795             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     796             :   false,  /* isInfallible. False in setters. */
     797             :   false,  /* isMovable.  Not relevant for setters. */
     798             :   false, /* isEliminatable.  Not relevant for setters. */
     799             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     800             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     801             :   false,  /* isTypedMethod.  Only relevant for methods. */
     802             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     803             : };
     804             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     805             : static_assert(0 < 2, "There is no slot for us");
     806             : 
     807             : static bool
     808           0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
     809             : {
     810           0 :   mozilla::dom::SEChannel* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SEChannel>(obj);
     811             :   // We don't want to preserve if we don't have a wrapper, and we
     812             :   // obviously can't preserve if we're not initialized.
     813           0 :   if (self && self->GetWrapperPreserveColor()) {
     814           0 :     PreserveWrapper(self);
     815             :   }
     816           0 :   return true;
     817             : }
     818             : 
     819             : static void
     820           0 : _finalize(js::FreeOp* fop, JSObject* obj)
     821             : {
     822           0 :   mozilla::dom::SEChannel* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SEChannel>(obj);
     823           0 :   if (self) {
     824           0 :     ClearWrapper(self, self, obj);
     825           0 :     AddForDeferredFinalization<mozilla::dom::SEChannel>(self);
     826             :   }
     827           0 : }
     828             : 
     829             : static void
     830           0 : _objectMoved(JSObject* obj, const JSObject* old)
     831             : {
     832           0 :   mozilla::dom::SEChannel* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SEChannel>(obj);
     833           0 :   if (self) {
     834           0 :     UpdateWrapper(self, self, obj, old);
     835             :   }
     836           0 : }
     837             : 
     838             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
     839             : #if defined(__clang__)
     840             : #pragma clang diagnostic push
     841             : #pragma clang diagnostic ignored "-Wmissing-braces"
     842             : #endif
     843             : static const JSFunctionSpec sChromeStaticMethods_specs[] = {
     844             :   JS_FNSPEC("_create", SEChannel::_Create, nullptr, 2, 0, nullptr),
     845             :   JS_FS_END
     846             : };
     847             : #if defined(__clang__)
     848             : #pragma clang diagnostic pop
     849             : #endif
     850             : 
     851             : 
     852             : // Can't be const because the pref-enabled boolean needs to be writable
     853             : static Prefable<const JSFunctionSpec> sChromeStaticMethods[] = {
     854             :   { nullptr, &sChromeStaticMethods_specs[0] },
     855             :   { nullptr, nullptr }
     856             : };
     857             : 
     858             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
     859             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
     860             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
     861             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
     862             : 
     863             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
     864             : #if defined(__clang__)
     865             : #pragma clang diagnostic push
     866             : #pragma clang diagnostic ignored "-Wmissing-braces"
     867             : #endif
     868             : static const JSFunctionSpec sMethods_specs[] = {
     869             :   JS_FNSPEC("transmit", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&transmit_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
     870             :   JS_FNSPEC("close", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&close_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
     871             :   JS_FS_END
     872             : };
     873             : #if defined(__clang__)
     874             : #pragma clang diagnostic pop
     875             : #endif
     876             : 
     877             : 
     878             : // Can't be const because the pref-enabled boolean needs to be writable
     879             : static Prefable<const JSFunctionSpec> sMethods[] = {
     880             :   { nullptr, &sMethods_specs[0] },
     881             :   { nullptr, nullptr }
     882             : };
     883             : 
     884             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
     885             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
     886             : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
     887             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
     888             : 
     889             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
     890             : #if defined(__clang__)
     891             : #pragma clang diagnostic push
     892             : #pragma clang diagnostic ignored "-Wmissing-braces"
     893             : #endif
     894             : static const JSPropertySpec sAttributes_specs[] = {
     895             :   { "session", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &session_getterinfo, nullptr, nullptr },
     896             :   { "openResponse", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &openResponse_getterinfo, nullptr, nullptr },
     897             :   { "isClosed", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &isClosed_getterinfo, nullptr, nullptr },
     898             :   { "type", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &type_getterinfo, nullptr, nullptr },
     899             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
     900             : };
     901             : #if defined(__clang__)
     902             : #pragma clang diagnostic pop
     903             : #endif
     904             : 
     905             : 
     906             : // Can't be const because the pref-enabled boolean needs to be writable
     907             : static Prefable<const JSPropertySpec> sAttributes[] = {
     908             :   { nullptr, &sAttributes_specs[0] },
     909             :   { nullptr, nullptr }
     910             : };
     911             : 
     912             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
     913             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
     914             : static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
     915             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
     916             : 
     917             : 
     918             : static uint16_t sNativeProperties_sortedPropertyIndices[6];
     919             : static PropertyInfo sNativeProperties_propertyInfos[6];
     920             : 
     921             : static const NativePropertiesN<2> sNativeProperties = {
     922             :   false, 0,
     923             :   false, 0,
     924             :   true,  0 /* sMethods */,
     925             :   true,  1 /* sAttributes */,
     926             :   false, 0,
     927             :   false, 0,
     928             :   false, 0,
     929             :   -1,
     930             :   6,
     931             :   sNativeProperties_sortedPropertyIndices,
     932             :   {
     933             :     { sMethods, &sNativeProperties_propertyInfos[0] },
     934             :     { sAttributes, &sNativeProperties_propertyInfos[2] }
     935             :   }
     936             : };
     937             : static_assert(6 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
     938             :     "We have a property info count that is oversized");
     939             : 
     940             : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[1];
     941             : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[1];
     942             : 
     943             : static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
     944             :   true,  0 /* sChromeStaticMethods */,
     945             :   false, 0,
     946             :   false, 0,
     947             :   false, 0,
     948             :   false, 0,
     949             :   false, 0,
     950             :   false, 0,
     951             :   -1,
     952             :   1,
     953             :   sChromeOnlyNativeProperties_sortedPropertyIndices,
     954             :   {
     955             :     { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] }
     956             :   }
     957             : };
     958             : static_assert(1 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
     959             :     "We have a property info count that is oversized");
     960             : 
     961             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
     962             :   {
     963             :     "Function",
     964             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
     965             :     &sBoringInterfaceObjectClassClassOps,
     966             :     JS_NULL_CLASS_SPEC,
     967             :     JS_NULL_CLASS_EXT,
     968             :     &sInterfaceObjectClassObjectOps
     969             :   },
     970             :   eInterface,
     971             :   true,
     972             :   prototypes::id::SEChannel,
     973             :   PrototypeTraits<prototypes::id::SEChannel>::Depth,
     974             :   sNativePropertyHooks,
     975             :   "function SEChannel() {\n    [native code]\n}",
     976             :   JS::GetRealmFunctionPrototype
     977             : };
     978             : 
     979             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
     980             :   {
     981             :     "SEChannelPrototype",
     982             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
     983             :     JS_NULL_CLASS_OPS,
     984             :     JS_NULL_CLASS_SPEC,
     985             :     JS_NULL_CLASS_EXT,
     986             :     JS_NULL_OBJECT_OPS
     987             :   },
     988             :   eInterfacePrototype,
     989             :   false,
     990             :   prototypes::id::SEChannel,
     991             :   PrototypeTraits<prototypes::id::SEChannel>::Depth,
     992             :   sNativePropertyHooks,
     993             :   "[object SEChannelPrototype]",
     994             :   JS::GetRealmObjectPrototype
     995             : };
     996             : 
     997             : bool
     998           0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
     999             : {
    1000             :   static bool sPrefValue;
    1001             :   static bool sPrefCacheSetUp = false;
    1002           0 :   if (!sPrefCacheSetUp) {
    1003           0 :     sPrefCacheSetUp = true;
    1004           0 :     Preferences::AddBoolVarCache(&sPrefValue, "dom.secureelement.enabled");
    1005             :   }
    1006             : 
    1007           0 :   return sPrefValue &&
    1008           0 :          nsContentUtils::ThreadsafeIsSystemCaller(aCx);
    1009             : }
    1010             : 
    1011             : JSObject*
    1012           0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
    1013             : {
    1014           0 :   return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
    1015             : }
    1016             : 
    1017             : static const js::ClassOps sClassOps = {
    1018             :   _addProperty, /* addProperty */
    1019             :   nullptr,               /* delProperty */
    1020             :   nullptr,               /* getProperty */
    1021             :   nullptr,               /* setProperty */
    1022             :   nullptr,               /* enumerate */
    1023             :   nullptr, /* newEnumerate */
    1024             :   nullptr, /* resolve */
    1025             :   nullptr, /* mayResolve */
    1026             :   _finalize, /* finalize */
    1027             :   nullptr, /* call */
    1028             :   nullptr,               /* hasInstance */
    1029             :   nullptr,               /* construct */
    1030             :   nullptr, /* trace */
    1031             : };
    1032             : 
    1033             : static const js::ClassExtension sClassExtension = {
    1034             :   nullptr, /* weakmapKeyDelegateOp */
    1035             :   _objectMoved /* objectMovedOp */
    1036             : };
    1037             : 
    1038             : static const DOMJSClass sClass = {
    1039             :   { "SEChannel",
    1040             :     JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2),
    1041             :     &sClassOps,
    1042             :     JS_NULL_CLASS_SPEC,
    1043             :     &sClassExtension,
    1044             :     JS_NULL_OBJECT_OPS
    1045             :   },
    1046             :   { prototypes::id::SEChannel, 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 },
    1047             :   IsBaseOf<nsISupports, mozilla::dom::SEChannel >::value,
    1048             :   sNativePropertyHooks,
    1049             :   FindAssociatedGlobalForNative<mozilla::dom::SEChannel>::Get,
    1050             :   GetProtoObjectHandle,
    1051             :   GetCCParticipant<mozilla::dom::SEChannel>::Get()
    1052             : };
    1053             : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
    1054             :               "Must have the right minimal number of reserved slots.");
    1055             : static_assert(2 >= 2,
    1056             :               "Must have enough reserved slots.");
    1057             : 
    1058             : const JSClass*
    1059           0 : GetJSClass()
    1060             : {
    1061           0 :   return sClass.ToJSClass();
    1062             : }
    1063             : 
    1064             : bool
    1065           0 : Wrap(JSContext* aCx, mozilla::dom::SEChannel* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
    1066             : {
    1067             :   MOZ_ASSERT(static_cast<mozilla::dom::SEChannel*>(aObject) ==
    1068             :              reinterpret_cast<mozilla::dom::SEChannel*>(aObject),
    1069             :              "Multiple inheritance for mozilla::dom::SEChannel is broken.");
    1070           0 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
    1071           0 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
    1072           0 :   MOZ_ASSERT(!aCache->GetWrapper(),
    1073             :              "You should probably not be using Wrap() directly; use "
    1074             :              "GetOrCreateDOMReflector instead");
    1075             : 
    1076           0 :   MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
    1077             :              "nsISupports must be on our primary inheritance chain");
    1078             : 
    1079           0 :   JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
    1080           0 :   if (!global) {
    1081           0 :     return false;
    1082             :   }
    1083           0 :   MOZ_ASSERT(JS_IsGlobalObject(global));
    1084           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(global));
    1085             : 
    1086             :   // That might have ended up wrapping us already, due to the wonders
    1087             :   // of XBL.  Check for that, and bail out as needed.
    1088           0 :   aReflector.set(aCache->GetWrapper());
    1089           0 :   if (aReflector) {
    1090             : #ifdef DEBUG
    1091           0 :     binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
    1092             : #endif // DEBUG
    1093           0 :     return true;
    1094             :   }
    1095             : 
    1096           0 :   JSAutoCompartment ac(aCx, global);
    1097           0 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
    1098           0 :   if (!canonicalProto) {
    1099           0 :     return false;
    1100             :   }
    1101           0 :   JS::Rooted<JSObject*> proto(aCx);
    1102           0 :   if (aGivenProto) {
    1103           0 :     proto = aGivenProto;
    1104             :     // Unfortunately, while aGivenProto was in the compartment of aCx
    1105             :     // coming in, we changed compartments to that of "parent" so may need
    1106             :     // to wrap the proto here.
    1107           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
    1108           0 :       if (!JS_WrapObject(aCx, &proto)) {
    1109           0 :         return false;
    1110             :       }
    1111             :     }
    1112             :   } else {
    1113           0 :     proto = canonicalProto;
    1114             :   }
    1115             : 
    1116           0 :   BindingJSObjectCreator<mozilla::dom::SEChannel> creator(aCx);
    1117           0 :   creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
    1118           0 :   if (!aReflector) {
    1119           0 :     return false;
    1120             :   }
    1121             : 
    1122           0 :   aCache->SetWrapper(aReflector);
    1123           0 :   creator.InitializationSucceeded();
    1124             : 
    1125           0 :   MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
    1126             :              aCache->GetWrapperPreserveColor() == aReflector);
    1127             :   // If proto != canonicalProto, we have to preserve our wrapper;
    1128             :   // otherwise we won't be able to properly recreate it later, since
    1129             :   // we won't know what proto to use.  Note that we don't check
    1130             :   // aGivenProto here, since it's entirely possible (and even
    1131             :   // somewhat common) to have a non-null aGivenProto which is the
    1132             :   // same as canonicalProto.
    1133           0 :   if (proto != canonicalProto) {
    1134           0 :     PreserveWrapper(aObject);
    1135             :   }
    1136             : 
    1137           0 :   return true;
    1138             : }
    1139             : 
    1140             : // This may allocate too many slots, because we only really need
    1141             : // slots for our non-interface-typed members that we cache.  But
    1142             : // allocating slots only for those would make the slot index
    1143             : // computations much more complicated, so let's do this the simple
    1144             : // way for now.
    1145             : DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 1);
    1146             : 
    1147             : const NativePropertyHooks sNativePropertyHooks[] = { {
    1148             :   nullptr,
    1149             :   nullptr,
    1150             :   nullptr,
    1151             :   { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
    1152             :   prototypes::id::SEChannel,
    1153             :   constructors::id::SEChannel,
    1154             :   nullptr,
    1155             :   &sXrayExpandoObjectClass
    1156             : } };
    1157             : 
    1158             : void
    1159           0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    1160             : {
    1161           0 :   JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
    1162           0 :   if (!parentProto) {
    1163           0 :     return;
    1164             :   }
    1165             : 
    1166           0 :   JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
    1167           0 :   if (!constructorProto) {
    1168           0 :     return;
    1169             :   }
    1170             : 
    1171             :   static bool sIdsInited = false;
    1172           0 :   if (!sIdsInited && NS_IsMainThread()) {
    1173           0 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
    1174           0 :       return;
    1175             :     }
    1176           0 :     if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
    1177           0 :       return;
    1178             :     }
    1179           0 :     sIdsInited = true;
    1180             :   }
    1181             : 
    1182           0 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::SEChannel);
    1183           0 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::SEChannel);
    1184           0 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    1185             :                               &sPrototypeClass.mBase, protoCache,
    1186             :                               constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
    1187             :                               interfaceCache,
    1188             :                               sNativeProperties.Upcast(),
    1189           0 :                               nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
    1190             :                               "SEChannel", aDefineOnGlobal,
    1191             :                               nullptr,
    1192           0 :                               false);
    1193             : }
    1194             : 
    1195             : JS::Handle<JSObject*>
    1196           0 : GetProtoObjectHandle(JSContext* aCx)
    1197             : {
    1198             :   /* Get the interface prototype object for this class.  This will create the
    1199             :      object as needed. */
    1200           0 :   bool aDefineOnGlobal = true;
    1201             : 
    1202             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    1203           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    1204           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    1205           0 :     return nullptr;
    1206             :   }
    1207             : 
    1208             :   /* Check to see whether the interface objects are already installed */
    1209           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    1210           0 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::SEChannel)) {
    1211           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    1212           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    1213             :   }
    1214             : 
    1215             :   /*
    1216             :    * The object might _still_ be null, but that's OK.
    1217             :    *
    1218             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    1219             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    1220             :    * changed after they have been set.
    1221             :    *
    1222             :    * Calling address() avoids the read read barrier that does gray
    1223             :    * unmarking, but it's not possible for the object to be gray here.
    1224             :    */
    1225             : 
    1226           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::SEChannel);
    1227           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    1228           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    1229             : }
    1230             : 
    1231             : JS::Handle<JSObject*>
    1232           0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
    1233             : {
    1234             :   /* Get the interface object for this class.  This will create the object as
    1235             :      needed. */
    1236             : 
    1237             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    1238           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    1239           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    1240           0 :     return nullptr;
    1241             :   }
    1242             : 
    1243             :   /* Check to see whether the interface objects are already installed */
    1244           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    1245           0 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::SEChannel)) {
    1246           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    1247           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    1248             :   }
    1249             : 
    1250             :   /*
    1251             :    * The object might _still_ be null, but that's OK.
    1252             :    *
    1253             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    1254             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    1255             :    * changed after they have been set.
    1256             :    *
    1257             :    * Calling address() avoids the read read barrier that does gray
    1258             :    * unmarking, but it's not possible for the object to be gray here.
    1259             :    */
    1260             : 
    1261           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::SEChannel);
    1262           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    1263           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    1264             : }
    1265             : 
    1266             : JSObject*
    1267           0 : GetConstructorObject(JSContext* aCx)
    1268             : {
    1269           0 :   return GetConstructorObjectHandle(aCx);
    1270             : }
    1271             : 
    1272             : } // namespace SEChannelBinding
    1273             : 
    1274             : 
    1275             : 
    1276             : namespace SEReaderBinding {
    1277             : 
    1278             : static bool
    1279           0 : get_isSEPresent(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEReader* self, JSJitGetterCallArgs args)
    1280             : {
    1281           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    1282           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    1283           0 :   if (objIsXray) {
    1284           0 :     unwrappedObj.emplace(cx, obj);
    1285             :   }
    1286           0 :   if (objIsXray) {
    1287           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    1288           0 :     if (!unwrappedObj.ref()) {
    1289           0 :       return false;
    1290             :     }
    1291             :   }
    1292           0 :   binding_detail::FastErrorResult rv;
    1293           0 :   bool result(self->GetIsSEPresent(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
    1294           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1295           0 :     return false;
    1296             :   }
    1297           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1298           0 :   args.rval().setBoolean(result);
    1299           0 :   return true;
    1300             : }
    1301             : 
    1302             : static const JSJitInfo isSEPresent_getterinfo = {
    1303             :   { (JSJitGetterOp)get_isSEPresent },
    1304             :   { prototypes::id::SEReader },
    1305             :   { PrototypeTraits<prototypes::id::SEReader>::Depth },
    1306             :   JSJitInfo::Getter,
    1307             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1308             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    1309             :   false,  /* isInfallible. False in setters. */
    1310             :   false,  /* isMovable.  Not relevant for setters. */
    1311             :   false, /* isEliminatable.  Not relevant for setters. */
    1312             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1313             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1314             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1315             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1316             : };
    1317             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1318             : static_assert(0 < 1, "There is no slot for us");
    1319             : 
    1320             : static bool
    1321           0 : get_type(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEReader* self, JSJitGetterCallArgs args)
    1322             : {
    1323           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    1324           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    1325           0 :   if (objIsXray) {
    1326           0 :     unwrappedObj.emplace(cx, obj);
    1327             :   }
    1328           0 :   if (objIsXray) {
    1329           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    1330           0 :     if (!unwrappedObj.ref()) {
    1331           0 :       return false;
    1332             :     }
    1333             :   }
    1334           0 :   binding_detail::FastErrorResult rv;
    1335           0 :   SEType result(self->GetType(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
    1336           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1337           0 :     return false;
    1338             :   }
    1339           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1340           0 :   if (!ToJSValue(cx, result, args.rval())) {
    1341           0 :     return false;
    1342             :   }
    1343           0 :   return true;
    1344             : }
    1345             : 
    1346             : static const JSJitInfo type_getterinfo = {
    1347             :   { (JSJitGetterOp)get_type },
    1348             :   { prototypes::id::SEReader },
    1349             :   { PrototypeTraits<prototypes::id::SEReader>::Depth },
    1350             :   JSJitInfo::Getter,
    1351             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1352             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
    1353             :   false,  /* isInfallible. False in setters. */
    1354             :   false,  /* isMovable.  Not relevant for setters. */
    1355             :   false, /* isEliminatable.  Not relevant for setters. */
    1356             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1357             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1358             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1359             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1360             : };
    1361             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1362             : static_assert(0 < 1, "There is no slot for us");
    1363             : 
    1364             : static bool
    1365           0 : openSession(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEReader* self, const JSJitMethodCallArgs& args)
    1366             : {
    1367           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    1368           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    1369           0 :   if (objIsXray) {
    1370           0 :     unwrappedObj.emplace(cx, obj);
    1371             :   }
    1372           0 :   if (objIsXray) {
    1373           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    1374           0 :     if (!unwrappedObj.ref()) {
    1375           0 :       return false;
    1376             :     }
    1377             :   }
    1378           0 :   binding_detail::FastErrorResult rv;
    1379           0 :   auto result(StrongOrRawPtr<Promise>(self->OpenSession(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
    1380           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1381           0 :     return false;
    1382             :   }
    1383           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1384           0 :   if (!ToJSValue(cx, result, args.rval())) {
    1385           0 :     return false;
    1386             :   }
    1387           0 :   return true;
    1388             : }
    1389             : 
    1390             : static bool
    1391           0 : openSession_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEReader* self, const JSJitMethodCallArgs& args)
    1392             : {
    1393             :   // Make sure to save the callee before someone maybe messes
    1394             :   // with rval().
    1395           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
    1396           0 :   bool ok = openSession(cx, obj, self, args);
    1397           0 :   if (ok) {
    1398           0 :     return true;
    1399             :   }
    1400           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
    1401           0 :                                    args.rval());
    1402             : }
    1403             : 
    1404             : static const JSJitInfo openSession_methodinfo = {
    1405             :   { (JSJitGetterOp)openSession_promiseWrapper },
    1406             :   { prototypes::id::SEReader },
    1407             :   { PrototypeTraits<prototypes::id::SEReader>::Depth },
    1408             :   JSJitInfo::Method,
    1409             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1410             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1411             :   false,  /* isInfallible. False in setters. */
    1412             :   false,  /* isMovable.  Not relevant for setters. */
    1413             :   false, /* isEliminatable.  Not relevant for setters. */
    1414             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1415             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1416             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1417             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1418             : };
    1419             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1420             : static_assert(0 < 1, "There is no slot for us");
    1421             : 
    1422             : static bool
    1423           0 : closeAll(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEReader* self, const JSJitMethodCallArgs& args)
    1424             : {
    1425           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    1426           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    1427           0 :   if (objIsXray) {
    1428           0 :     unwrappedObj.emplace(cx, obj);
    1429             :   }
    1430           0 :   if (objIsXray) {
    1431           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    1432           0 :     if (!unwrappedObj.ref()) {
    1433           0 :       return false;
    1434             :     }
    1435             :   }
    1436           0 :   binding_detail::FastErrorResult rv;
    1437           0 :   auto result(StrongOrRawPtr<Promise>(self->CloseAll(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
    1438           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1439           0 :     return false;
    1440             :   }
    1441           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1442           0 :   if (!ToJSValue(cx, result, args.rval())) {
    1443           0 :     return false;
    1444             :   }
    1445           0 :   return true;
    1446             : }
    1447             : 
    1448             : static bool
    1449           0 : closeAll_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEReader* self, const JSJitMethodCallArgs& args)
    1450             : {
    1451             :   // Make sure to save the callee before someone maybe messes
    1452             :   // with rval().
    1453           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
    1454           0 :   bool ok = closeAll(cx, obj, self, args);
    1455           0 :   if (ok) {
    1456           0 :     return true;
    1457             :   }
    1458           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
    1459           0 :                                    args.rval());
    1460             : }
    1461             : 
    1462             : static const JSJitInfo closeAll_methodinfo = {
    1463             :   { (JSJitGetterOp)closeAll_promiseWrapper },
    1464             :   { prototypes::id::SEReader },
    1465             :   { PrototypeTraits<prototypes::id::SEReader>::Depth },
    1466             :   JSJitInfo::Method,
    1467             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1468             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1469             :   false,  /* isInfallible. False in setters. */
    1470             :   false,  /* isMovable.  Not relevant for setters. */
    1471             :   false, /* isEliminatable.  Not relevant for setters. */
    1472             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1473             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1474             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1475             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1476             : };
    1477             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1478             : static_assert(0 < 1, "There is no slot for us");
    1479             : 
    1480             : static bool
    1481           0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
    1482             : {
    1483           0 :   mozilla::dom::SEReader* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SEReader>(obj);
    1484             :   // We don't want to preserve if we don't have a wrapper, and we
    1485             :   // obviously can't preserve if we're not initialized.
    1486           0 :   if (self && self->GetWrapperPreserveColor()) {
    1487           0 :     PreserveWrapper(self);
    1488             :   }
    1489           0 :   return true;
    1490             : }
    1491             : 
    1492             : static void
    1493           0 : _finalize(js::FreeOp* fop, JSObject* obj)
    1494             : {
    1495           0 :   mozilla::dom::SEReader* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SEReader>(obj);
    1496           0 :   if (self) {
    1497           0 :     ClearWrapper(self, self, obj);
    1498           0 :     AddForDeferredFinalization<mozilla::dom::SEReader>(self);
    1499             :   }
    1500           0 : }
    1501             : 
    1502             : static void
    1503           0 : _objectMoved(JSObject* obj, const JSObject* old)
    1504             : {
    1505           0 :   mozilla::dom::SEReader* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SEReader>(obj);
    1506           0 :   if (self) {
    1507           0 :     UpdateWrapper(self, self, obj, old);
    1508             :   }
    1509           0 : }
    1510             : 
    1511             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    1512             : #if defined(__clang__)
    1513             : #pragma clang diagnostic push
    1514             : #pragma clang diagnostic ignored "-Wmissing-braces"
    1515             : #endif
    1516             : static const JSFunctionSpec sChromeStaticMethods_specs[] = {
    1517             :   JS_FNSPEC("_create", SEReader::_Create, nullptr, 2, 0, nullptr),
    1518             :   JS_FS_END
    1519             : };
    1520             : #if defined(__clang__)
    1521             : #pragma clang diagnostic pop
    1522             : #endif
    1523             : 
    1524             : 
    1525             : // Can't be const because the pref-enabled boolean needs to be writable
    1526             : static Prefable<const JSFunctionSpec> sChromeStaticMethods[] = {
    1527             :   { nullptr, &sChromeStaticMethods_specs[0] },
    1528             :   { nullptr, nullptr }
    1529             : };
    1530             : 
    1531             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    1532             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    1533             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    1534             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    1535             : 
    1536             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    1537             : #if defined(__clang__)
    1538             : #pragma clang diagnostic push
    1539             : #pragma clang diagnostic ignored "-Wmissing-braces"
    1540             : #endif
    1541             : static const JSFunctionSpec sMethods_specs[] = {
    1542             :   JS_FNSPEC("openSession", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&openSession_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    1543             :   JS_FNSPEC("closeAll", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&closeAll_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    1544             :   JS_FS_END
    1545             : };
    1546             : #if defined(__clang__)
    1547             : #pragma clang diagnostic pop
    1548             : #endif
    1549             : 
    1550             : 
    1551             : // Can't be const because the pref-enabled boolean needs to be writable
    1552             : static Prefable<const JSFunctionSpec> sMethods[] = {
    1553             :   { nullptr, &sMethods_specs[0] },
    1554             :   { nullptr, nullptr }
    1555             : };
    1556             : 
    1557             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    1558             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    1559             : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    1560             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    1561             : 
    1562             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    1563             : #if defined(__clang__)
    1564             : #pragma clang diagnostic push
    1565             : #pragma clang diagnostic ignored "-Wmissing-braces"
    1566             : #endif
    1567             : static const JSPropertySpec sAttributes_specs[] = {
    1568             :   { "isSEPresent", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &isSEPresent_getterinfo, nullptr, nullptr },
    1569             :   { "type", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &type_getterinfo, nullptr, nullptr },
    1570             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
    1571             : };
    1572             : #if defined(__clang__)
    1573             : #pragma clang diagnostic pop
    1574             : #endif
    1575             : 
    1576             : 
    1577             : // Can't be const because the pref-enabled boolean needs to be writable
    1578             : static Prefable<const JSPropertySpec> sAttributes[] = {
    1579             :   { nullptr, &sAttributes_specs[0] },
    1580             :   { nullptr, nullptr }
    1581             : };
    1582             : 
    1583             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    1584             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    1585             : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    1586             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    1587             : 
    1588             : 
    1589             : static uint16_t sNativeProperties_sortedPropertyIndices[4];
    1590             : static PropertyInfo sNativeProperties_propertyInfos[4];
    1591             : 
    1592             : static const NativePropertiesN<2> sNativeProperties = {
    1593             :   false, 0,
    1594             :   false, 0,
    1595             :   true,  0 /* sMethods */,
    1596             :   true,  1 /* sAttributes */,
    1597             :   false, 0,
    1598             :   false, 0,
    1599             :   false, 0,
    1600             :   -1,
    1601             :   4,
    1602             :   sNativeProperties_sortedPropertyIndices,
    1603             :   {
    1604             :     { sMethods, &sNativeProperties_propertyInfos[0] },
    1605             :     { sAttributes, &sNativeProperties_propertyInfos[2] }
    1606             :   }
    1607             : };
    1608             : static_assert(4 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
    1609             :     "We have a property info count that is oversized");
    1610             : 
    1611             : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[1];
    1612             : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[1];
    1613             : 
    1614             : static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
    1615             :   true,  0 /* sChromeStaticMethods */,
    1616             :   false, 0,
    1617             :   false, 0,
    1618             :   false, 0,
    1619             :   false, 0,
    1620             :   false, 0,
    1621             :   false, 0,
    1622             :   -1,
    1623             :   1,
    1624             :   sChromeOnlyNativeProperties_sortedPropertyIndices,
    1625             :   {
    1626             :     { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] }
    1627             :   }
    1628             : };
    1629             : static_assert(1 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
    1630             :     "We have a property info count that is oversized");
    1631             : 
    1632             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
    1633             :   {
    1634             :     "Function",
    1635             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
    1636             :     &sBoringInterfaceObjectClassClassOps,
    1637             :     JS_NULL_CLASS_SPEC,
    1638             :     JS_NULL_CLASS_EXT,
    1639             :     &sInterfaceObjectClassObjectOps
    1640             :   },
    1641             :   eInterface,
    1642             :   true,
    1643             :   prototypes::id::SEReader,
    1644             :   PrototypeTraits<prototypes::id::SEReader>::Depth,
    1645             :   sNativePropertyHooks,
    1646             :   "function SEReader() {\n    [native code]\n}",
    1647             :   JS::GetRealmFunctionPrototype
    1648             : };
    1649             : 
    1650             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
    1651             :   {
    1652             :     "SEReaderPrototype",
    1653             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    1654             :     JS_NULL_CLASS_OPS,
    1655             :     JS_NULL_CLASS_SPEC,
    1656             :     JS_NULL_CLASS_EXT,
    1657             :     JS_NULL_OBJECT_OPS
    1658             :   },
    1659             :   eInterfacePrototype,
    1660             :   false,
    1661             :   prototypes::id::SEReader,
    1662             :   PrototypeTraits<prototypes::id::SEReader>::Depth,
    1663             :   sNativePropertyHooks,
    1664             :   "[object SEReaderPrototype]",
    1665             :   JS::GetRealmObjectPrototype
    1666             : };
    1667             : 
    1668             : bool
    1669           0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
    1670             : {
    1671             :   static bool sPrefValue;
    1672             :   static bool sPrefCacheSetUp = false;
    1673           0 :   if (!sPrefCacheSetUp) {
    1674           0 :     sPrefCacheSetUp = true;
    1675           0 :     Preferences::AddBoolVarCache(&sPrefValue, "dom.secureelement.enabled");
    1676             :   }
    1677             : 
    1678           0 :   return sPrefValue &&
    1679           0 :          nsContentUtils::ThreadsafeIsSystemCaller(aCx);
    1680             : }
    1681             : 
    1682             : JSObject*
    1683           0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
    1684             : {
    1685           0 :   return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
    1686             : }
    1687             : 
    1688             : static const js::ClassOps sClassOps = {
    1689             :   _addProperty, /* addProperty */
    1690             :   nullptr,               /* delProperty */
    1691             :   nullptr,               /* getProperty */
    1692             :   nullptr,               /* setProperty */
    1693             :   nullptr,               /* enumerate */
    1694             :   nullptr, /* newEnumerate */
    1695             :   nullptr, /* resolve */
    1696             :   nullptr, /* mayResolve */
    1697             :   _finalize, /* finalize */
    1698             :   nullptr, /* call */
    1699             :   nullptr,               /* hasInstance */
    1700             :   nullptr,               /* construct */
    1701             :   nullptr, /* trace */
    1702             : };
    1703             : 
    1704             : static const js::ClassExtension sClassExtension = {
    1705             :   nullptr, /* weakmapKeyDelegateOp */
    1706             :   _objectMoved /* objectMovedOp */
    1707             : };
    1708             : 
    1709             : static const DOMJSClass sClass = {
    1710             :   { "SEReader",
    1711             :     JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
    1712             :     &sClassOps,
    1713             :     JS_NULL_CLASS_SPEC,
    1714             :     &sClassExtension,
    1715             :     JS_NULL_OBJECT_OPS
    1716             :   },
    1717             :   { prototypes::id::SEReader, 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 },
    1718             :   IsBaseOf<nsISupports, mozilla::dom::SEReader >::value,
    1719             :   sNativePropertyHooks,
    1720             :   FindAssociatedGlobalForNative<mozilla::dom::SEReader>::Get,
    1721             :   GetProtoObjectHandle,
    1722             :   GetCCParticipant<mozilla::dom::SEReader>::Get()
    1723             : };
    1724             : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
    1725             :               "Must have the right minimal number of reserved slots.");
    1726             : static_assert(1 >= 1,
    1727             :               "Must have enough reserved slots.");
    1728             : 
    1729             : const JSClass*
    1730           0 : GetJSClass()
    1731             : {
    1732           0 :   return sClass.ToJSClass();
    1733             : }
    1734             : 
    1735             : bool
    1736           0 : Wrap(JSContext* aCx, mozilla::dom::SEReader* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
    1737             : {
    1738             :   MOZ_ASSERT(static_cast<mozilla::dom::SEReader*>(aObject) ==
    1739             :              reinterpret_cast<mozilla::dom::SEReader*>(aObject),
    1740             :              "Multiple inheritance for mozilla::dom::SEReader is broken.");
    1741           0 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
    1742           0 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
    1743           0 :   MOZ_ASSERT(!aCache->GetWrapper(),
    1744             :              "You should probably not be using Wrap() directly; use "
    1745             :              "GetOrCreateDOMReflector instead");
    1746             : 
    1747           0 :   MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
    1748             :              "nsISupports must be on our primary inheritance chain");
    1749             : 
    1750           0 :   JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
    1751           0 :   if (!global) {
    1752           0 :     return false;
    1753             :   }
    1754           0 :   MOZ_ASSERT(JS_IsGlobalObject(global));
    1755           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(global));
    1756             : 
    1757             :   // That might have ended up wrapping us already, due to the wonders
    1758             :   // of XBL.  Check for that, and bail out as needed.
    1759           0 :   aReflector.set(aCache->GetWrapper());
    1760           0 :   if (aReflector) {
    1761             : #ifdef DEBUG
    1762           0 :     binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
    1763             : #endif // DEBUG
    1764           0 :     return true;
    1765             :   }
    1766             : 
    1767           0 :   JSAutoCompartment ac(aCx, global);
    1768           0 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
    1769           0 :   if (!canonicalProto) {
    1770           0 :     return false;
    1771             :   }
    1772           0 :   JS::Rooted<JSObject*> proto(aCx);
    1773           0 :   if (aGivenProto) {
    1774           0 :     proto = aGivenProto;
    1775             :     // Unfortunately, while aGivenProto was in the compartment of aCx
    1776             :     // coming in, we changed compartments to that of "parent" so may need
    1777             :     // to wrap the proto here.
    1778           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
    1779           0 :       if (!JS_WrapObject(aCx, &proto)) {
    1780           0 :         return false;
    1781             :       }
    1782             :     }
    1783             :   } else {
    1784           0 :     proto = canonicalProto;
    1785             :   }
    1786             : 
    1787           0 :   BindingJSObjectCreator<mozilla::dom::SEReader> creator(aCx);
    1788           0 :   creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
    1789           0 :   if (!aReflector) {
    1790           0 :     return false;
    1791             :   }
    1792             : 
    1793           0 :   aCache->SetWrapper(aReflector);
    1794           0 :   creator.InitializationSucceeded();
    1795             : 
    1796           0 :   MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
    1797             :              aCache->GetWrapperPreserveColor() == aReflector);
    1798             :   // If proto != canonicalProto, we have to preserve our wrapper;
    1799             :   // otherwise we won't be able to properly recreate it later, since
    1800             :   // we won't know what proto to use.  Note that we don't check
    1801             :   // aGivenProto here, since it's entirely possible (and even
    1802             :   // somewhat common) to have a non-null aGivenProto which is the
    1803             :   // same as canonicalProto.
    1804           0 :   if (proto != canonicalProto) {
    1805           0 :     PreserveWrapper(aObject);
    1806             :   }
    1807             : 
    1808           0 :   return true;
    1809             : }
    1810             : 
    1811             : const NativePropertyHooks sNativePropertyHooks[] = { {
    1812             :   nullptr,
    1813             :   nullptr,
    1814             :   nullptr,
    1815             :   { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
    1816             :   prototypes::id::SEReader,
    1817             :   constructors::id::SEReader,
    1818             :   nullptr,
    1819             :   &DefaultXrayExpandoObjectClass
    1820             : } };
    1821             : 
    1822             : void
    1823           0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    1824             : {
    1825           0 :   JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
    1826           0 :   if (!parentProto) {
    1827           0 :     return;
    1828             :   }
    1829             : 
    1830           0 :   JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
    1831           0 :   if (!constructorProto) {
    1832           0 :     return;
    1833             :   }
    1834             : 
    1835             :   static bool sIdsInited = false;
    1836           0 :   if (!sIdsInited && NS_IsMainThread()) {
    1837           0 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
    1838           0 :       return;
    1839             :     }
    1840           0 :     if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
    1841           0 :       return;
    1842             :     }
    1843           0 :     sIdsInited = true;
    1844             :   }
    1845             : 
    1846           0 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::SEReader);
    1847           0 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::SEReader);
    1848           0 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    1849             :                               &sPrototypeClass.mBase, protoCache,
    1850             :                               constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
    1851             :                               interfaceCache,
    1852             :                               sNativeProperties.Upcast(),
    1853           0 :                               nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
    1854             :                               "SEReader", aDefineOnGlobal,
    1855             :                               nullptr,
    1856           0 :                               false);
    1857             : }
    1858             : 
    1859             : JS::Handle<JSObject*>
    1860           0 : GetProtoObjectHandle(JSContext* aCx)
    1861             : {
    1862             :   /* Get the interface prototype object for this class.  This will create the
    1863             :      object as needed. */
    1864           0 :   bool aDefineOnGlobal = true;
    1865             : 
    1866             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    1867           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    1868           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    1869           0 :     return nullptr;
    1870             :   }
    1871             : 
    1872             :   /* Check to see whether the interface objects are already installed */
    1873           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    1874           0 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::SEReader)) {
    1875           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    1876           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    1877             :   }
    1878             : 
    1879             :   /*
    1880             :    * The object might _still_ be null, but that's OK.
    1881             :    *
    1882             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    1883             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    1884             :    * changed after they have been set.
    1885             :    *
    1886             :    * Calling address() avoids the read read barrier that does gray
    1887             :    * unmarking, but it's not possible for the object to be gray here.
    1888             :    */
    1889             : 
    1890           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::SEReader);
    1891           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    1892           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    1893             : }
    1894             : 
    1895             : JS::Handle<JSObject*>
    1896           0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
    1897             : {
    1898             :   /* Get the interface object for this class.  This will create the object as
    1899             :      needed. */
    1900             : 
    1901             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    1902           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    1903           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    1904           0 :     return nullptr;
    1905             :   }
    1906             : 
    1907             :   /* Check to see whether the interface objects are already installed */
    1908           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    1909           0 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::SEReader)) {
    1910           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    1911           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    1912             :   }
    1913             : 
    1914             :   /*
    1915             :    * The object might _still_ be null, but that's OK.
    1916             :    *
    1917             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    1918             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    1919             :    * changed after they have been set.
    1920             :    *
    1921             :    * Calling address() avoids the read read barrier that does gray
    1922             :    * unmarking, but it's not possible for the object to be gray here.
    1923             :    */
    1924             : 
    1925           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::SEReader);
    1926           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    1927           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    1928             : }
    1929             : 
    1930             : JSObject*
    1931           0 : GetConstructorObject(JSContext* aCx)
    1932             : {
    1933           0 :   return GetConstructorObjectHandle(aCx);
    1934             : }
    1935             : 
    1936             : } // namespace SEReaderBinding
    1937             : 
    1938             : 
    1939             : 
    1940             : namespace SEResponseBinding {
    1941             : 
    1942             : static bool
    1943           0 : get_channel(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEResponse* self, JSJitGetterCallArgs args)
    1944             : {
    1945           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    1946           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    1947           0 :   if (objIsXray) {
    1948           0 :     unwrappedObj.emplace(cx, obj);
    1949             :   }
    1950           0 :   if (objIsXray) {
    1951           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    1952           0 :     if (!unwrappedObj.ref()) {
    1953           0 :       return false;
    1954             :     }
    1955             :   }
    1956           0 :   binding_detail::FastErrorResult rv;
    1957           0 :   auto result(StrongOrRawPtr<mozilla::dom::SEChannel>(self->GetChannel(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
    1958           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1959           0 :     return false;
    1960             :   }
    1961           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1962           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    1963           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1964           0 :     return false;
    1965             :   }
    1966           0 :   return true;
    1967             : }
    1968             : 
    1969             : static const JSJitInfo channel_getterinfo = {
    1970             :   { (JSJitGetterOp)get_channel },
    1971             :   { prototypes::id::SEResponse },
    1972             :   { PrototypeTraits<prototypes::id::SEResponse>::Depth },
    1973             :   JSJitInfo::Getter,
    1974             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    1975             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1976             :   false,  /* isInfallible. False in setters. */
    1977             :   false,  /* isMovable.  Not relevant for setters. */
    1978             :   false, /* isEliminatable.  Not relevant for setters. */
    1979             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1980             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1981             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1982             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1983             : };
    1984             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1985             : static_assert(0 < 2, "There is no slot for us");
    1986             : 
    1987             : static bool
    1988           0 : get_sw1(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEResponse* self, JSJitGetterCallArgs args)
    1989             : {
    1990           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    1991           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    1992           0 :   if (objIsXray) {
    1993           0 :     unwrappedObj.emplace(cx, obj);
    1994             :   }
    1995           0 :   if (objIsXray) {
    1996           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    1997           0 :     if (!unwrappedObj.ref()) {
    1998           0 :       return false;
    1999             :     }
    2000             :   }
    2001           0 :   binding_detail::FastErrorResult rv;
    2002           0 :   uint8_t result(self->GetSw1(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
    2003           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2004           0 :     return false;
    2005             :   }
    2006           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2007           0 :   args.rval().setInt32(int32_t(result));
    2008           0 :   return true;
    2009             : }
    2010             : 
    2011             : static const JSJitInfo sw1_getterinfo = {
    2012             :   { (JSJitGetterOp)get_sw1 },
    2013             :   { prototypes::id::SEResponse },
    2014             :   { PrototypeTraits<prototypes::id::SEResponse>::Depth },
    2015             :   JSJitInfo::Getter,
    2016             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    2017             :   JSVAL_TYPE_INT32,  /* returnType.  Not relevant for setters. */
    2018             :   false,  /* isInfallible. False in setters. */
    2019             :   false,  /* isMovable.  Not relevant for setters. */
    2020             :   false, /* isEliminatable.  Not relevant for setters. */
    2021             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2022             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2023             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2024             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2025             : };
    2026             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2027             : static_assert(0 < 2, "There is no slot for us");
    2028             : 
    2029             : static bool
    2030           0 : get_sw2(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEResponse* self, JSJitGetterCallArgs args)
    2031             : {
    2032           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2033           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2034           0 :   if (objIsXray) {
    2035           0 :     unwrappedObj.emplace(cx, obj);
    2036             :   }
    2037           0 :   if (objIsXray) {
    2038           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2039           0 :     if (!unwrappedObj.ref()) {
    2040           0 :       return false;
    2041             :     }
    2042             :   }
    2043           0 :   binding_detail::FastErrorResult rv;
    2044           0 :   uint8_t result(self->GetSw2(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
    2045           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2046           0 :     return false;
    2047             :   }
    2048           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2049           0 :   args.rval().setInt32(int32_t(result));
    2050           0 :   return true;
    2051             : }
    2052             : 
    2053             : static const JSJitInfo sw2_getterinfo = {
    2054             :   { (JSJitGetterOp)get_sw2 },
    2055             :   { prototypes::id::SEResponse },
    2056             :   { PrototypeTraits<prototypes::id::SEResponse>::Depth },
    2057             :   JSJitInfo::Getter,
    2058             :   JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
    2059             :   JSVAL_TYPE_INT32,  /* returnType.  Not relevant for setters. */
    2060             :   false,  /* isInfallible. False in setters. */
    2061             :   false,  /* isMovable.  Not relevant for setters. */
    2062             :   false, /* isEliminatable.  Not relevant for setters. */
    2063             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2064             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2065             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2066             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2067             : };
    2068             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2069             : static_assert(0 < 2, "There is no slot for us");
    2070             : 
    2071             : static bool
    2072           0 : get_data(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SEResponse* self, JSJitGetterCallArgs args)
    2073             : {
    2074             :   // Have to either root across the getter call or reget after.
    2075             :   bool isXray;
    2076           0 :   JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
    2077           0 :   if (!slotStorage) {
    2078           0 :     return false;
    2079             :   }
    2080           0 :   const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 0) : (DOM_INSTANCE_RESERVED_SLOTS + 0);
    2081           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    2082             :   {
    2083             :     // Scope for cachedVal
    2084           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    2085           0 :     if (!cachedVal.isUndefined()) {
    2086           0 :       args.rval().set(cachedVal);
    2087             :       // The cached value is in the compartment of slotStorage,
    2088             :       // so wrap into the caller compartment as needed.
    2089           0 :       return MaybeWrapNonDOMObjectOrNullValue(cx, args.rval());
    2090             :     }
    2091             :   }
    2092             : 
    2093           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2094           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2095           0 :   if (objIsXray) {
    2096           0 :     unwrappedObj.emplace(cx, obj);
    2097             :   }
    2098           0 :   if (objIsXray) {
    2099           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2100           0 :     if (!unwrappedObj.ref()) {
    2101           0 :       return false;
    2102             :     }
    2103             :   }
    2104           0 :   binding_detail::FastErrorResult rv;
    2105           0 :   Nullable<nsTArray<uint8_t>> result;
    2106           0 :   self->GetData(result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    2107           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2108           0 :     return false;
    2109             :   }
    2110           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2111             :   {
    2112           0 :     JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
    2113           0 :     JSAutoCompartment ac(cx, conversionScope);
    2114             :     do { // block we break out of when done wrapping
    2115             : 
    2116           0 :       if (result.IsNull()) {
    2117           0 :         args.rval().setNull();
    2118           0 :         break;
    2119             :       }
    2120             : 
    2121           0 :       uint32_t length = result.Value().Length();
    2122           0 :       JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
    2123           0 :       if (!returnArray) {
    2124           0 :         return false;
    2125             :       }
    2126             :       // Scope for 'tmp'
    2127             :       {
    2128           0 :         JS::Rooted<JS::Value> tmp(cx);
    2129           0 :         for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
    2130             :           // Control block to let us common up the JS_DefineElement calls when there
    2131             :           // are different ways to succeed at wrapping the object.
    2132             :           do {
    2133           0 :             tmp.setInt32(int32_t(result.Value()[sequenceIdx0]));
    2134           0 :             break;
    2135             :           } while (0);
    2136           0 :           if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
    2137             :                                 JSPROP_ENUMERATE)) {
    2138           0 :             return false;
    2139             :           }
    2140             :         }
    2141             :       }
    2142           0 :       args.rval().setObject(*returnArray);
    2143           0 :       break;
    2144             :     } while (0);
    2145             :   }
    2146             :   { // And now store things in the compartment of our slotStorage.
    2147           0 :     JSAutoCompartment ac(cx, slotStorage);
    2148             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    2149           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    2150           0 :     if (!MaybeWrapNonDOMObjectOrNullValue(cx, &storedVal)) {
    2151           0 :       return false;
    2152             :     }
    2153           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    2154           0 :     if (!isXray) {
    2155             :       // In the Xray case we don't need to do this, because getting the
    2156             :       // expando object already preserved our wrapper.
    2157           0 :       PreserveWrapper(self);
    2158             :     }
    2159             :   }
    2160             :   // And now make sure args.rval() is in the caller compartment
    2161           0 :   return MaybeWrapNonDOMObjectOrNullValue(cx, args.rval());
    2162             : }
    2163             : 
    2164             : static const JSJitInfo data_getterinfo = {
    2165             :   { (JSJitGetterOp)get_data },
    2166             :   { prototypes::id::SEResponse },
    2167             :   { PrototypeTraits<prototypes::id::SEResponse>::Depth },
    2168             :   JSJitInfo::Getter,
    2169             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    2170             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    2171             :   false,  /* isInfallible. False in setters. */
    2172             :   false,  /* isMovable.  Not relevant for setters. */
    2173             :   false, /* isEliminatable.  Not relevant for setters. */
    2174             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2175             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2176             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2177             :   (DOM_INSTANCE_RESERVED_SLOTS + 0)   /* Reserved slot index, if we're stored in a slot, else 0. */
    2178             : };
    2179             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit");
    2180             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 2, "There is no slot for us");
    2181             : 
    2182             : static bool
    2183           0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
    2184             : {
    2185           0 :   mozilla::dom::SEResponse* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SEResponse>(obj);
    2186             :   // We don't want to preserve if we don't have a wrapper, and we
    2187             :   // obviously can't preserve if we're not initialized.
    2188           0 :   if (self && self->GetWrapperPreserveColor()) {
    2189           0 :     PreserveWrapper(self);
    2190             :   }
    2191           0 :   return true;
    2192             : }
    2193             : 
    2194             : static void
    2195           0 : _finalize(js::FreeOp* fop, JSObject* obj)
    2196             : {
    2197           0 :   mozilla::dom::SEResponse* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SEResponse>(obj);
    2198           0 :   if (self) {
    2199           0 :     ClearWrapper(self, self, obj);
    2200           0 :     AddForDeferredFinalization<mozilla::dom::SEResponse>(self);
    2201             :   }
    2202           0 : }
    2203             : 
    2204             : static void
    2205           0 : _objectMoved(JSObject* obj, const JSObject* old)
    2206             : {
    2207           0 :   mozilla::dom::SEResponse* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SEResponse>(obj);
    2208           0 :   if (self) {
    2209           0 :     UpdateWrapper(self, self, obj, old);
    2210             :   }
    2211           0 : }
    2212             : 
    2213             : static bool
    2214           0 : _ClearCachedDataValue(JSContext* cx, unsigned argc, JS::Value* vp)
    2215             : {
    2216           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    2217           0 :   if (!args.thisv().isObject()) {
    2218           0 :     return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "SEResponse");
    2219             :   }
    2220           0 :   JS::Rooted<JSObject*> obj(cx, &args.thisv().toObject());
    2221             : 
    2222             :   mozilla::dom::SEResponse* self;
    2223           0 :   JS::Rooted<JS::Value> rootSelf(cx, JS::ObjectValue(*obj));
    2224             :   {
    2225           0 :     nsresult rv = UnwrapObject<prototypes::id::SEResponse, mozilla::dom::SEResponse>(&rootSelf, self);
    2226           0 :     if (NS_FAILED(rv)) {
    2227           0 :       return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "SEResponse");
    2228             :     }
    2229             :   }
    2230           0 :   SEResponseBinding::ClearCachedDataValue(self);
    2231           0 :   args.rval().setUndefined();
    2232           0 :   return true;
    2233             : }
    2234             : 
    2235             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    2236             : #if defined(__clang__)
    2237             : #pragma clang diagnostic push
    2238             : #pragma clang diagnostic ignored "-Wmissing-braces"
    2239             : #endif
    2240             : static const JSFunctionSpec sChromeStaticMethods_specs[] = {
    2241             :   JS_FNSPEC("_create", SEResponse::_Create, nullptr, 2, 0, nullptr),
    2242             :   JS_FS_END
    2243             : };
    2244             : #if defined(__clang__)
    2245             : #pragma clang diagnostic pop
    2246             : #endif
    2247             : 
    2248             : 
    2249             : // Can't be const because the pref-enabled boolean needs to be writable
    2250             : static Prefable<const JSFunctionSpec> sChromeStaticMethods[] = {
    2251             :   { nullptr, &sChromeStaticMethods_specs[0] },
    2252             :   { nullptr, nullptr }
    2253             : };
    2254             : 
    2255             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    2256             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    2257             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    2258             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    2259             : 
    2260             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    2261             : #if defined(__clang__)
    2262             : #pragma clang diagnostic push
    2263             : #pragma clang diagnostic ignored "-Wmissing-braces"
    2264             : #endif
    2265             : static const JSFunctionSpec sChromeMethods_specs[] = {
    2266             :   JS_FNSPEC("_clearCachedDataValue", _ClearCachedDataValue, nullptr, 0, 0, nullptr),
    2267             :   JS_FS_END
    2268             : };
    2269             : #if defined(__clang__)
    2270             : #pragma clang diagnostic pop
    2271             : #endif
    2272             : 
    2273             : 
    2274             : // Can't be const because the pref-enabled boolean needs to be writable
    2275             : static Prefable<const JSFunctionSpec> sChromeMethods[] = {
    2276             :   { nullptr, &sChromeMethods_specs[0] },
    2277             :   { nullptr, nullptr }
    2278             : };
    2279             : 
    2280             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    2281             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    2282             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    2283             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    2284             : 
    2285             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    2286             : #if defined(__clang__)
    2287             : #pragma clang diagnostic push
    2288             : #pragma clang diagnostic ignored "-Wmissing-braces"
    2289             : #endif
    2290             : static const JSPropertySpec sAttributes_specs[] = {
    2291             :   { "channel", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &channel_getterinfo, nullptr, nullptr },
    2292             :   { "sw1", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &sw1_getterinfo, nullptr, nullptr },
    2293             :   { "sw2", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &sw2_getterinfo, nullptr, nullptr },
    2294             :   { "data", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &data_getterinfo, nullptr, nullptr },
    2295             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
    2296             : };
    2297             : #if defined(__clang__)
    2298             : #pragma clang diagnostic pop
    2299             : #endif
    2300             : 
    2301             : 
    2302             : // Can't be const because the pref-enabled boolean needs to be writable
    2303             : static Prefable<const JSPropertySpec> sAttributes[] = {
    2304             :   { nullptr, &sAttributes_specs[0] },
    2305             :   { nullptr, nullptr }
    2306             : };
    2307             : 
    2308             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    2309             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    2310             : static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    2311             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    2312             : 
    2313             : 
    2314             : static uint16_t sNativeProperties_sortedPropertyIndices[4];
    2315             : static PropertyInfo sNativeProperties_propertyInfos[4];
    2316             : 
    2317             : static const NativePropertiesN<1> sNativeProperties = {
    2318             :   false, 0,
    2319             :   false, 0,
    2320             :   false, 0,
    2321             :   true,  0 /* sAttributes */,
    2322             :   false, 0,
    2323             :   false, 0,
    2324             :   false, 0,
    2325             :   -1,
    2326             :   4,
    2327             :   sNativeProperties_sortedPropertyIndices,
    2328             :   {
    2329             :     { sAttributes, &sNativeProperties_propertyInfos[0] }
    2330             :   }
    2331             : };
    2332             : static_assert(4 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
    2333             :     "We have a property info count that is oversized");
    2334             : 
    2335             : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[2];
    2336             : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[2];
    2337             : 
    2338             : static const NativePropertiesN<2> sChromeOnlyNativeProperties = {
    2339             :   true,  0 /* sChromeStaticMethods */,
    2340             :   false, 0,
    2341             :   true,  1 /* sChromeMethods */,
    2342             :   false, 0,
    2343             :   false, 0,
    2344             :   false, 0,
    2345             :   false, 0,
    2346             :   -1,
    2347             :   2,
    2348             :   sChromeOnlyNativeProperties_sortedPropertyIndices,
    2349             :   {
    2350             :     { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] },
    2351             :     { sChromeMethods, &sChromeOnlyNativeProperties_propertyInfos[1] }
    2352             :   }
    2353             : };
    2354             : static_assert(2 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
    2355             :     "We have a property info count that is oversized");
    2356             : 
    2357             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
    2358             :   {
    2359             :     "Function",
    2360             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
    2361             :     &sBoringInterfaceObjectClassClassOps,
    2362             :     JS_NULL_CLASS_SPEC,
    2363             :     JS_NULL_CLASS_EXT,
    2364             :     &sInterfaceObjectClassObjectOps
    2365             :   },
    2366             :   eInterface,
    2367             :   true,
    2368             :   prototypes::id::SEResponse,
    2369             :   PrototypeTraits<prototypes::id::SEResponse>::Depth,
    2370             :   sNativePropertyHooks,
    2371             :   "function SEResponse() {\n    [native code]\n}",
    2372             :   JS::GetRealmFunctionPrototype
    2373             : };
    2374             : 
    2375             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
    2376             :   {
    2377             :     "SEResponsePrototype",
    2378             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    2379             :     JS_NULL_CLASS_OPS,
    2380             :     JS_NULL_CLASS_SPEC,
    2381             :     JS_NULL_CLASS_EXT,
    2382             :     JS_NULL_OBJECT_OPS
    2383             :   },
    2384             :   eInterfacePrototype,
    2385             :   false,
    2386             :   prototypes::id::SEResponse,
    2387             :   PrototypeTraits<prototypes::id::SEResponse>::Depth,
    2388             :   sNativePropertyHooks,
    2389             :   "[object SEResponsePrototype]",
    2390             :   JS::GetRealmObjectPrototype
    2391             : };
    2392             : 
    2393             : bool
    2394           0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
    2395             : {
    2396             :   static bool sPrefValue;
    2397             :   static bool sPrefCacheSetUp = false;
    2398           0 :   if (!sPrefCacheSetUp) {
    2399           0 :     sPrefCacheSetUp = true;
    2400           0 :     Preferences::AddBoolVarCache(&sPrefValue, "dom.secureelement.enabled");
    2401             :   }
    2402             : 
    2403           0 :   return sPrefValue &&
    2404           0 :          nsContentUtils::ThreadsafeIsSystemCaller(aCx);
    2405             : }
    2406             : 
    2407             : JSObject*
    2408           0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
    2409             : {
    2410           0 :   return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
    2411             : }
    2412             : 
    2413             : static const js::ClassOps sClassOps = {
    2414             :   _addProperty, /* addProperty */
    2415             :   nullptr,               /* delProperty */
    2416             :   nullptr,               /* getProperty */
    2417             :   nullptr,               /* setProperty */
    2418             :   nullptr,               /* enumerate */
    2419             :   nullptr, /* newEnumerate */
    2420             :   nullptr, /* resolve */
    2421             :   nullptr, /* mayResolve */
    2422             :   _finalize, /* finalize */
    2423             :   nullptr, /* call */
    2424             :   nullptr,               /* hasInstance */
    2425             :   nullptr,               /* construct */
    2426             :   nullptr, /* trace */
    2427             : };
    2428             : 
    2429             : static const js::ClassExtension sClassExtension = {
    2430             :   nullptr, /* weakmapKeyDelegateOp */
    2431             :   _objectMoved /* objectMovedOp */
    2432             : };
    2433             : 
    2434             : static const DOMJSClass sClass = {
    2435             :   { "SEResponse",
    2436             :     JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2),
    2437             :     &sClassOps,
    2438             :     JS_NULL_CLASS_SPEC,
    2439             :     &sClassExtension,
    2440             :     JS_NULL_OBJECT_OPS
    2441             :   },
    2442             :   { prototypes::id::SEResponse, 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 },
    2443             :   IsBaseOf<nsISupports, mozilla::dom::SEResponse >::value,
    2444             :   sNativePropertyHooks,
    2445             :   FindAssociatedGlobalForNative<mozilla::dom::SEResponse>::Get,
    2446             :   GetProtoObjectHandle,
    2447             :   GetCCParticipant<mozilla::dom::SEResponse>::Get()
    2448             : };
    2449             : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
    2450             :               "Must have the right minimal number of reserved slots.");
    2451             : static_assert(2 >= 2,
    2452             :               "Must have enough reserved slots.");
    2453             : 
    2454             : const JSClass*
    2455           0 : GetJSClass()
    2456             : {
    2457           0 :   return sClass.ToJSClass();
    2458             : }
    2459             : 
    2460             : bool
    2461           0 : Wrap(JSContext* aCx, mozilla::dom::SEResponse* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
    2462             : {
    2463             :   MOZ_ASSERT(static_cast<mozilla::dom::SEResponse*>(aObject) ==
    2464             :              reinterpret_cast<mozilla::dom::SEResponse*>(aObject),
    2465             :              "Multiple inheritance for mozilla::dom::SEResponse is broken.");
    2466           0 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
    2467           0 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
    2468           0 :   MOZ_ASSERT(!aCache->GetWrapper(),
    2469             :              "You should probably not be using Wrap() directly; use "
    2470             :              "GetOrCreateDOMReflector instead");
    2471             : 
    2472           0 :   MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
    2473             :              "nsISupports must be on our primary inheritance chain");
    2474             : 
    2475           0 :   JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
    2476           0 :   if (!global) {
    2477           0 :     return false;
    2478             :   }
    2479           0 :   MOZ_ASSERT(JS_IsGlobalObject(global));
    2480           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(global));
    2481             : 
    2482             :   // That might have ended up wrapping us already, due to the wonders
    2483             :   // of XBL.  Check for that, and bail out as needed.
    2484           0 :   aReflector.set(aCache->GetWrapper());
    2485           0 :   if (aReflector) {
    2486             : #ifdef DEBUG
    2487           0 :     binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
    2488             : #endif // DEBUG
    2489           0 :     return true;
    2490             :   }
    2491             : 
    2492           0 :   JSAutoCompartment ac(aCx, global);
    2493           0 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
    2494           0 :   if (!canonicalProto) {
    2495           0 :     return false;
    2496             :   }
    2497           0 :   JS::Rooted<JSObject*> proto(aCx);
    2498           0 :   if (aGivenProto) {
    2499           0 :     proto = aGivenProto;
    2500             :     // Unfortunately, while aGivenProto was in the compartment of aCx
    2501             :     // coming in, we changed compartments to that of "parent" so may need
    2502             :     // to wrap the proto here.
    2503           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
    2504           0 :       if (!JS_WrapObject(aCx, &proto)) {
    2505           0 :         return false;
    2506             :       }
    2507             :     }
    2508             :   } else {
    2509           0 :     proto = canonicalProto;
    2510             :   }
    2511             : 
    2512           0 :   BindingJSObjectCreator<mozilla::dom::SEResponse> creator(aCx);
    2513           0 :   creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
    2514           0 :   if (!aReflector) {
    2515           0 :     return false;
    2516             :   }
    2517             : 
    2518           0 :   aCache->SetWrapper(aReflector);
    2519           0 :   creator.InitializationSucceeded();
    2520             : 
    2521           0 :   MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
    2522             :              aCache->GetWrapperPreserveColor() == aReflector);
    2523             :   // If proto != canonicalProto, we have to preserve our wrapper;
    2524             :   // otherwise we won't be able to properly recreate it later, since
    2525             :   // we won't know what proto to use.  Note that we don't check
    2526             :   // aGivenProto here, since it's entirely possible (and even
    2527             :   // somewhat common) to have a non-null aGivenProto which is the
    2528             :   // same as canonicalProto.
    2529           0 :   if (proto != canonicalProto) {
    2530           0 :     PreserveWrapper(aObject);
    2531             :   }
    2532             : 
    2533           0 :   return true;
    2534             : }
    2535             : 
    2536             : // This may allocate too many slots, because we only really need
    2537             : // slots for our non-interface-typed members that we cache.  But
    2538             : // allocating slots only for those would make the slot index
    2539             : // computations much more complicated, so let's do this the simple
    2540             : // way for now.
    2541             : DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 1);
    2542             : 
    2543             : const NativePropertyHooks sNativePropertyHooks[] = { {
    2544             :   nullptr,
    2545             :   nullptr,
    2546             :   nullptr,
    2547             :   { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
    2548             :   prototypes::id::SEResponse,
    2549             :   constructors::id::SEResponse,
    2550             :   nullptr,
    2551             :   &sXrayExpandoObjectClass
    2552             : } };
    2553             : 
    2554             : void
    2555           0 : ClearCachedDataValue(mozilla::dom::SEResponse* aObject)
    2556             : {
    2557             :   JSObject* obj;
    2558           0 :   obj = aObject->GetWrapper();
    2559           0 :   if (!obj) {
    2560           0 :     return;
    2561             :   }
    2562           0 :   js::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), JS::UndefinedValue());
    2563           0 :   xpc::ClearXrayExpandoSlots(obj, (xpc::JSSLOT_EXPANDO_COUNT + 0));
    2564             : }
    2565             : 
    2566             : void
    2567           0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    2568             : {
    2569           0 :   JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
    2570           0 :   if (!parentProto) {
    2571           0 :     return;
    2572             :   }
    2573             : 
    2574           0 :   JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
    2575           0 :   if (!constructorProto) {
    2576           0 :     return;
    2577             :   }
    2578             : 
    2579             :   static bool sIdsInited = false;
    2580           0 :   if (!sIdsInited && NS_IsMainThread()) {
    2581           0 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
    2582           0 :       return;
    2583             :     }
    2584           0 :     if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
    2585           0 :       return;
    2586             :     }
    2587           0 :     sIdsInited = true;
    2588             :   }
    2589             : 
    2590           0 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::SEResponse);
    2591           0 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::SEResponse);
    2592           0 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    2593             :                               &sPrototypeClass.mBase, protoCache,
    2594             :                               constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
    2595             :                               interfaceCache,
    2596             :                               sNativeProperties.Upcast(),
    2597           0 :                               nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
    2598             :                               "SEResponse", aDefineOnGlobal,
    2599             :                               nullptr,
    2600           0 :                               false);
    2601             : }
    2602             : 
    2603             : JS::Handle<JSObject*>
    2604           0 : GetProtoObjectHandle(JSContext* aCx)
    2605             : {
    2606             :   /* Get the interface prototype object for this class.  This will create the
    2607             :      object as needed. */
    2608           0 :   bool aDefineOnGlobal = true;
    2609             : 
    2610             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    2611           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    2612           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    2613           0 :     return nullptr;
    2614             :   }
    2615             : 
    2616             :   /* Check to see whether the interface objects are already installed */
    2617           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    2618           0 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::SEResponse)) {
    2619           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    2620           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    2621             :   }
    2622             : 
    2623             :   /*
    2624             :    * The object might _still_ be null, but that's OK.
    2625             :    *
    2626             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    2627             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    2628             :    * changed after they have been set.
    2629             :    *
    2630             :    * Calling address() avoids the read read barrier that does gray
    2631             :    * unmarking, but it's not possible for the object to be gray here.
    2632             :    */
    2633             : 
    2634           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::SEResponse);
    2635           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    2636           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    2637             : }
    2638             : 
    2639             : JS::Handle<JSObject*>
    2640           0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
    2641             : {
    2642             :   /* Get the interface object for this class.  This will create the object as
    2643             :      needed. */
    2644             : 
    2645             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    2646           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    2647           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    2648           0 :     return nullptr;
    2649             :   }
    2650             : 
    2651             :   /* Check to see whether the interface objects are already installed */
    2652           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    2653           0 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::SEResponse)) {
    2654           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    2655           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    2656             :   }
    2657             : 
    2658             :   /*
    2659             :    * The object might _still_ be null, but that's OK.
    2660             :    *
    2661             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    2662             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    2663             :    * changed after they have been set.
    2664             :    *
    2665             :    * Calling address() avoids the read read barrier that does gray
    2666             :    * unmarking, but it's not possible for the object to be gray here.
    2667             :    */
    2668             : 
    2669           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::SEResponse);
    2670           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    2671           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    2672             : }
    2673             : 
    2674             : JSObject*
    2675           0 : GetConstructorObject(JSContext* aCx)
    2676             : {
    2677           0 :   return GetConstructorObjectHandle(aCx);
    2678             : }
    2679             : 
    2680             : } // namespace SEResponseBinding
    2681             : 
    2682             : 
    2683             : 
    2684             : namespace SESessionBinding {
    2685             : 
    2686             : static bool
    2687           0 : get_reader(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SESession* self, JSJitGetterCallArgs args)
    2688             : {
    2689           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2690           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2691           0 :   if (objIsXray) {
    2692           0 :     unwrappedObj.emplace(cx, obj);
    2693             :   }
    2694           0 :   if (objIsXray) {
    2695           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2696           0 :     if (!unwrappedObj.ref()) {
    2697           0 :       return false;
    2698             :     }
    2699             :   }
    2700           0 :   binding_detail::FastErrorResult rv;
    2701           0 :   auto result(StrongOrRawPtr<mozilla::dom::SEReader>(self->GetReader(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
    2702           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2703           0 :     return false;
    2704             :   }
    2705           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2706           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    2707           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    2708           0 :     return false;
    2709             :   }
    2710           0 :   return true;
    2711             : }
    2712             : 
    2713             : static const JSJitInfo reader_getterinfo = {
    2714             :   { (JSJitGetterOp)get_reader },
    2715             :   { prototypes::id::SESession },
    2716             :   { PrototypeTraits<prototypes::id::SESession>::Depth },
    2717             :   JSJitInfo::Getter,
    2718             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2719             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    2720             :   false,  /* isInfallible. False in setters. */
    2721             :   false,  /* isMovable.  Not relevant for setters. */
    2722             :   false, /* isEliminatable.  Not relevant for setters. */
    2723             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2724             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2725             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2726             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2727             : };
    2728             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2729             : static_assert(0 < 1, "There is no slot for us");
    2730             : 
    2731             : static bool
    2732           0 : get_isClosed(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SESession* self, JSJitGetterCallArgs args)
    2733             : {
    2734           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2735           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2736           0 :   if (objIsXray) {
    2737           0 :     unwrappedObj.emplace(cx, obj);
    2738             :   }
    2739           0 :   if (objIsXray) {
    2740           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2741           0 :     if (!unwrappedObj.ref()) {
    2742           0 :       return false;
    2743             :     }
    2744             :   }
    2745           0 :   binding_detail::FastErrorResult rv;
    2746           0 :   bool result(self->GetIsClosed(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
    2747           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2748           0 :     return false;
    2749             :   }
    2750           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2751           0 :   args.rval().setBoolean(result);
    2752           0 :   return true;
    2753             : }
    2754             : 
    2755             : static const JSJitInfo isClosed_getterinfo = {
    2756             :   { (JSJitGetterOp)get_isClosed },
    2757             :   { prototypes::id::SESession },
    2758             :   { PrototypeTraits<prototypes::id::SESession>::Depth },
    2759             :   JSJitInfo::Getter,
    2760             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2761             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    2762             :   false,  /* isInfallible. False in setters. */
    2763             :   false,  /* isMovable.  Not relevant for setters. */
    2764             :   false, /* isEliminatable.  Not relevant for setters. */
    2765             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2766             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2767             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2768             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2769             : };
    2770             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2771             : static_assert(0 < 1, "There is no slot for us");
    2772             : 
    2773             : static bool
    2774           0 : openLogicalChannel(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SESession* self, const JSJitMethodCallArgs& args)
    2775             : {
    2776           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    2777           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SESession.openLogicalChannel");
    2778             :   }
    2779           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2780           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2781           0 :   if (objIsXray) {
    2782           0 :     unwrappedObj.emplace(cx, obj);
    2783             :   }
    2784           0 :   RootedTypedArray<Nullable<Uint8Array>> arg0(cx);
    2785           0 :   if (args[0].isObject()) {
    2786           0 :     if (!arg0.SetValue().Init(&args[0].toObject())) {
    2787           0 :       ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of SESession.openLogicalChannel", "Uint8ArrayOrNull");
    2788           0 :       return false;
    2789             :     }
    2790           0 :   } else if (args[0].isNullOrUndefined()) {
    2791           0 :     arg0.SetNull();
    2792             :   } else {
    2793           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of SESession.openLogicalChannel");
    2794           0 :     return false;
    2795             :   }
    2796           0 :   if (objIsXray) {
    2797           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2798           0 :     if (!unwrappedObj.ref()) {
    2799           0 :       return false;
    2800             :     }
    2801             :   }
    2802           0 :   binding_detail::FastErrorResult rv;
    2803           0 :   auto result(StrongOrRawPtr<Promise>(self->OpenLogicalChannel(Constify(arg0), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
    2804           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2805           0 :     return false;
    2806             :   }
    2807           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2808           0 :   if (!ToJSValue(cx, result, args.rval())) {
    2809           0 :     return false;
    2810             :   }
    2811           0 :   return true;
    2812             : }
    2813             : 
    2814             : static bool
    2815           0 : openLogicalChannel_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SESession* self, const JSJitMethodCallArgs& args)
    2816             : {
    2817             :   // Make sure to save the callee before someone maybe messes
    2818             :   // with rval().
    2819           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
    2820           0 :   bool ok = openLogicalChannel(cx, obj, self, args);
    2821           0 :   if (ok) {
    2822           0 :     return true;
    2823             :   }
    2824           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
    2825           0 :                                    args.rval());
    2826             : }
    2827             : 
    2828             : static const JSJitInfo openLogicalChannel_methodinfo = {
    2829             :   { (JSJitGetterOp)openLogicalChannel_promiseWrapper },
    2830             :   { prototypes::id::SESession },
    2831             :   { PrototypeTraits<prototypes::id::SESession>::Depth },
    2832             :   JSJitInfo::Method,
    2833             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2834             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    2835             :   false,  /* isInfallible. False in setters. */
    2836             :   false,  /* isMovable.  Not relevant for setters. */
    2837             :   false, /* isEliminatable.  Not relevant for setters. */
    2838             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2839             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2840             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2841             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2842             : };
    2843             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2844             : static_assert(0 < 1, "There is no slot for us");
    2845             : 
    2846             : static bool
    2847           0 : closeAll(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SESession* self, const JSJitMethodCallArgs& args)
    2848             : {
    2849           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2850           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2851           0 :   if (objIsXray) {
    2852           0 :     unwrappedObj.emplace(cx, obj);
    2853             :   }
    2854           0 :   if (objIsXray) {
    2855           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2856           0 :     if (!unwrappedObj.ref()) {
    2857           0 :       return false;
    2858             :     }
    2859             :   }
    2860           0 :   binding_detail::FastErrorResult rv;
    2861           0 :   auto result(StrongOrRawPtr<Promise>(self->CloseAll(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
    2862           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2863           0 :     return false;
    2864             :   }
    2865           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2866           0 :   if (!ToJSValue(cx, result, args.rval())) {
    2867           0 :     return false;
    2868             :   }
    2869           0 :   return true;
    2870             : }
    2871             : 
    2872             : static bool
    2873           0 : closeAll_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SESession* self, const JSJitMethodCallArgs& args)
    2874             : {
    2875             :   // Make sure to save the callee before someone maybe messes
    2876             :   // with rval().
    2877           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
    2878           0 :   bool ok = closeAll(cx, obj, self, args);
    2879           0 :   if (ok) {
    2880           0 :     return true;
    2881             :   }
    2882           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
    2883           0 :                                    args.rval());
    2884             : }
    2885             : 
    2886             : static const JSJitInfo closeAll_methodinfo = {
    2887             :   { (JSJitGetterOp)closeAll_promiseWrapper },
    2888             :   { prototypes::id::SESession },
    2889             :   { PrototypeTraits<prototypes::id::SESession>::Depth },
    2890             :   JSJitInfo::Method,
    2891             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2892             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    2893             :   false,  /* isInfallible. False in setters. */
    2894             :   false,  /* isMovable.  Not relevant for setters. */
    2895             :   false, /* isEliminatable.  Not relevant for setters. */
    2896             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2897             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2898             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2899             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2900             : };
    2901             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2902             : static_assert(0 < 1, "There is no slot for us");
    2903             : 
    2904             : static bool
    2905           0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
    2906             : {
    2907           0 :   mozilla::dom::SESession* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SESession>(obj);
    2908             :   // We don't want to preserve if we don't have a wrapper, and we
    2909             :   // obviously can't preserve if we're not initialized.
    2910           0 :   if (self && self->GetWrapperPreserveColor()) {
    2911           0 :     PreserveWrapper(self);
    2912             :   }
    2913           0 :   return true;
    2914             : }
    2915             : 
    2916             : static void
    2917           0 : _finalize(js::FreeOp* fop, JSObject* obj)
    2918             : {
    2919           0 :   mozilla::dom::SESession* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SESession>(obj);
    2920           0 :   if (self) {
    2921           0 :     ClearWrapper(self, self, obj);
    2922           0 :     AddForDeferredFinalization<mozilla::dom::SESession>(self);
    2923             :   }
    2924           0 : }
    2925             : 
    2926             : static void
    2927           0 : _objectMoved(JSObject* obj, const JSObject* old)
    2928             : {
    2929           0 :   mozilla::dom::SESession* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SESession>(obj);
    2930           0 :   if (self) {
    2931           0 :     UpdateWrapper(self, self, obj, old);
    2932             :   }
    2933           0 : }
    2934             : 
    2935             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    2936             : #if defined(__clang__)
    2937             : #pragma clang diagnostic push
    2938             : #pragma clang diagnostic ignored "-Wmissing-braces"
    2939             : #endif
    2940             : static const JSFunctionSpec sChromeStaticMethods_specs[] = {
    2941             :   JS_FNSPEC("_create", SESession::_Create, nullptr, 2, 0, nullptr),
    2942             :   JS_FS_END
    2943             : };
    2944             : #if defined(__clang__)
    2945             : #pragma clang diagnostic pop
    2946             : #endif
    2947             : 
    2948             : 
    2949             : // Can't be const because the pref-enabled boolean needs to be writable
    2950             : static Prefable<const JSFunctionSpec> sChromeStaticMethods[] = {
    2951             :   { nullptr, &sChromeStaticMethods_specs[0] },
    2952             :   { nullptr, nullptr }
    2953             : };
    2954             : 
    2955             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    2956             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    2957             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    2958             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    2959             : 
    2960             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    2961             : #if defined(__clang__)
    2962             : #pragma clang diagnostic push
    2963             : #pragma clang diagnostic ignored "-Wmissing-braces"
    2964             : #endif
    2965             : static const JSFunctionSpec sMethods_specs[] = {
    2966             :   JS_FNSPEC("openLogicalChannel", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&openLogicalChannel_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    2967             :   JS_FNSPEC("closeAll", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&closeAll_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    2968             :   JS_FS_END
    2969             : };
    2970             : #if defined(__clang__)
    2971             : #pragma clang diagnostic pop
    2972             : #endif
    2973             : 
    2974             : 
    2975             : // Can't be const because the pref-enabled boolean needs to be writable
    2976             : static Prefable<const JSFunctionSpec> sMethods[] = {
    2977             :   { nullptr, &sMethods_specs[0] },
    2978             :   { nullptr, nullptr }
    2979             : };
    2980             : 
    2981             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    2982             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    2983             : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    2984             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    2985             : 
    2986             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    2987             : #if defined(__clang__)
    2988             : #pragma clang diagnostic push
    2989             : #pragma clang diagnostic ignored "-Wmissing-braces"
    2990             : #endif
    2991             : static const JSPropertySpec sAttributes_specs[] = {
    2992             :   { "reader", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &reader_getterinfo, nullptr, nullptr },
    2993             :   { "isClosed", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &isClosed_getterinfo, nullptr, nullptr },
    2994             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
    2995             : };
    2996             : #if defined(__clang__)
    2997             : #pragma clang diagnostic pop
    2998             : #endif
    2999             : 
    3000             : 
    3001             : // Can't be const because the pref-enabled boolean needs to be writable
    3002             : static Prefable<const JSPropertySpec> sAttributes[] = {
    3003             :   { nullptr, &sAttributes_specs[0] },
    3004             :   { nullptr, nullptr }
    3005             : };
    3006             : 
    3007             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    3008             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    3009             : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    3010             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    3011             : 
    3012             : 
    3013             : static uint16_t sNativeProperties_sortedPropertyIndices[4];
    3014             : static PropertyInfo sNativeProperties_propertyInfos[4];
    3015             : 
    3016             : static const NativePropertiesN<2> sNativeProperties = {
    3017             :   false, 0,
    3018             :   false, 0,
    3019             :   true,  0 /* sMethods */,
    3020             :   true,  1 /* sAttributes */,
    3021             :   false, 0,
    3022             :   false, 0,
    3023             :   false, 0,
    3024             :   -1,
    3025             :   4,
    3026             :   sNativeProperties_sortedPropertyIndices,
    3027             :   {
    3028             :     { sMethods, &sNativeProperties_propertyInfos[0] },
    3029             :     { sAttributes, &sNativeProperties_propertyInfos[2] }
    3030             :   }
    3031             : };
    3032             : static_assert(4 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
    3033             :     "We have a property info count that is oversized");
    3034             : 
    3035             : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[1];
    3036             : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[1];
    3037             : 
    3038             : static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
    3039             :   true,  0 /* sChromeStaticMethods */,
    3040             :   false, 0,
    3041             :   false, 0,
    3042             :   false, 0,
    3043             :   false, 0,
    3044             :   false, 0,
    3045             :   false, 0,
    3046             :   -1,
    3047             :   1,
    3048             :   sChromeOnlyNativeProperties_sortedPropertyIndices,
    3049             :   {
    3050             :     { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] }
    3051             :   }
    3052             : };
    3053             : static_assert(1 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
    3054             :     "We have a property info count that is oversized");
    3055             : 
    3056             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
    3057             :   {
    3058             :     "Function",
    3059             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
    3060             :     &sBoringInterfaceObjectClassClassOps,
    3061             :     JS_NULL_CLASS_SPEC,
    3062             :     JS_NULL_CLASS_EXT,
    3063             :     &sInterfaceObjectClassObjectOps
    3064             :   },
    3065             :   eInterface,
    3066             :   true,
    3067             :   prototypes::id::SESession,
    3068             :   PrototypeTraits<prototypes::id::SESession>::Depth,
    3069             :   sNativePropertyHooks,
    3070             :   "function SESession() {\n    [native code]\n}",
    3071             :   JS::GetRealmFunctionPrototype
    3072             : };
    3073             : 
    3074             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
    3075             :   {
    3076             :     "SESessionPrototype",
    3077             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    3078             :     JS_NULL_CLASS_OPS,
    3079             :     JS_NULL_CLASS_SPEC,
    3080             :     JS_NULL_CLASS_EXT,
    3081             :     JS_NULL_OBJECT_OPS
    3082             :   },
    3083             :   eInterfacePrototype,
    3084             :   false,
    3085             :   prototypes::id::SESession,
    3086             :   PrototypeTraits<prototypes::id::SESession>::Depth,
    3087             :   sNativePropertyHooks,
    3088             :   "[object SESessionPrototype]",
    3089             :   JS::GetRealmObjectPrototype
    3090             : };
    3091             : 
    3092             : bool
    3093           0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
    3094             : {
    3095             :   static bool sPrefValue;
    3096             :   static bool sPrefCacheSetUp = false;
    3097           0 :   if (!sPrefCacheSetUp) {
    3098           0 :     sPrefCacheSetUp = true;
    3099           0 :     Preferences::AddBoolVarCache(&sPrefValue, "dom.secureelement.enabled");
    3100             :   }
    3101             : 
    3102           0 :   return sPrefValue &&
    3103           0 :          nsContentUtils::ThreadsafeIsSystemCaller(aCx);
    3104             : }
    3105             : 
    3106             : JSObject*
    3107           0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
    3108             : {
    3109           0 :   return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
    3110             : }
    3111             : 
    3112             : static const js::ClassOps sClassOps = {
    3113             :   _addProperty, /* addProperty */
    3114             :   nullptr,               /* delProperty */
    3115             :   nullptr,               /* getProperty */
    3116             :   nullptr,               /* setProperty */
    3117             :   nullptr,               /* enumerate */
    3118             :   nullptr, /* newEnumerate */
    3119             :   nullptr, /* resolve */
    3120             :   nullptr, /* mayResolve */
    3121             :   _finalize, /* finalize */
    3122             :   nullptr, /* call */
    3123             :   nullptr,               /* hasInstance */
    3124             :   nullptr,               /* construct */
    3125             :   nullptr, /* trace */
    3126             : };
    3127             : 
    3128             : static const js::ClassExtension sClassExtension = {
    3129             :   nullptr, /* weakmapKeyDelegateOp */
    3130             :   _objectMoved /* objectMovedOp */
    3131             : };
    3132             : 
    3133             : static const DOMJSClass sClass = {
    3134             :   { "SESession",
    3135             :     JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
    3136             :     &sClassOps,
    3137             :     JS_NULL_CLASS_SPEC,
    3138             :     &sClassExtension,
    3139             :     JS_NULL_OBJECT_OPS
    3140             :   },
    3141             :   { prototypes::id::SESession, 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 },
    3142             :   IsBaseOf<nsISupports, mozilla::dom::SESession >::value,
    3143             :   sNativePropertyHooks,
    3144             :   FindAssociatedGlobalForNative<mozilla::dom::SESession>::Get,
    3145             :   GetProtoObjectHandle,
    3146             :   GetCCParticipant<mozilla::dom::SESession>::Get()
    3147             : };
    3148             : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
    3149             :               "Must have the right minimal number of reserved slots.");
    3150             : static_assert(1 >= 1,
    3151             :               "Must have enough reserved slots.");
    3152             : 
    3153             : const JSClass*
    3154           0 : GetJSClass()
    3155             : {
    3156           0 :   return sClass.ToJSClass();
    3157             : }
    3158             : 
    3159             : bool
    3160           0 : Wrap(JSContext* aCx, mozilla::dom::SESession* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
    3161             : {
    3162             :   MOZ_ASSERT(static_cast<mozilla::dom::SESession*>(aObject) ==
    3163             :              reinterpret_cast<mozilla::dom::SESession*>(aObject),
    3164             :              "Multiple inheritance for mozilla::dom::SESession is broken.");
    3165           0 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
    3166           0 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
    3167           0 :   MOZ_ASSERT(!aCache->GetWrapper(),
    3168             :              "You should probably not be using Wrap() directly; use "
    3169             :              "GetOrCreateDOMReflector instead");
    3170             : 
    3171           0 :   MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
    3172             :              "nsISupports must be on our primary inheritance chain");
    3173             : 
    3174           0 :   JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
    3175           0 :   if (!global) {
    3176           0 :     return false;
    3177             :   }
    3178           0 :   MOZ_ASSERT(JS_IsGlobalObject(global));
    3179           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(global));
    3180             : 
    3181             :   // That might have ended up wrapping us already, due to the wonders
    3182             :   // of XBL.  Check for that, and bail out as needed.
    3183           0 :   aReflector.set(aCache->GetWrapper());
    3184           0 :   if (aReflector) {
    3185             : #ifdef DEBUG
    3186           0 :     binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
    3187             : #endif // DEBUG
    3188           0 :     return true;
    3189             :   }
    3190             : 
    3191           0 :   JSAutoCompartment ac(aCx, global);
    3192           0 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
    3193           0 :   if (!canonicalProto) {
    3194           0 :     return false;
    3195             :   }
    3196           0 :   JS::Rooted<JSObject*> proto(aCx);
    3197           0 :   if (aGivenProto) {
    3198           0 :     proto = aGivenProto;
    3199             :     // Unfortunately, while aGivenProto was in the compartment of aCx
    3200             :     // coming in, we changed compartments to that of "parent" so may need
    3201             :     // to wrap the proto here.
    3202           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
    3203           0 :       if (!JS_WrapObject(aCx, &proto)) {
    3204           0 :         return false;
    3205             :       }
    3206             :     }
    3207             :   } else {
    3208           0 :     proto = canonicalProto;
    3209             :   }
    3210             : 
    3211           0 :   BindingJSObjectCreator<mozilla::dom::SESession> creator(aCx);
    3212           0 :   creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
    3213           0 :   if (!aReflector) {
    3214           0 :     return false;
    3215             :   }
    3216             : 
    3217           0 :   aCache->SetWrapper(aReflector);
    3218           0 :   creator.InitializationSucceeded();
    3219             : 
    3220           0 :   MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
    3221             :              aCache->GetWrapperPreserveColor() == aReflector);
    3222             :   // If proto != canonicalProto, we have to preserve our wrapper;
    3223             :   // otherwise we won't be able to properly recreate it later, since
    3224             :   // we won't know what proto to use.  Note that we don't check
    3225             :   // aGivenProto here, since it's entirely possible (and even
    3226             :   // somewhat common) to have a non-null aGivenProto which is the
    3227             :   // same as canonicalProto.
    3228           0 :   if (proto != canonicalProto) {
    3229           0 :     PreserveWrapper(aObject);
    3230             :   }
    3231             : 
    3232           0 :   return true;
    3233             : }
    3234             : 
    3235             : const NativePropertyHooks sNativePropertyHooks[] = { {
    3236             :   nullptr,
    3237             :   nullptr,
    3238             :   nullptr,
    3239             :   { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
    3240             :   prototypes::id::SESession,
    3241             :   constructors::id::SESession,
    3242             :   nullptr,
    3243             :   &DefaultXrayExpandoObjectClass
    3244             : } };
    3245             : 
    3246             : void
    3247           0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    3248             : {
    3249           0 :   JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
    3250           0 :   if (!parentProto) {
    3251           0 :     return;
    3252             :   }
    3253             : 
    3254           0 :   JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
    3255           0 :   if (!constructorProto) {
    3256           0 :     return;
    3257             :   }
    3258             : 
    3259             :   static bool sIdsInited = false;
    3260           0 :   if (!sIdsInited && NS_IsMainThread()) {
    3261           0 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
    3262           0 :       return;
    3263             :     }
    3264           0 :     if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
    3265           0 :       return;
    3266             :     }
    3267           0 :     sIdsInited = true;
    3268             :   }
    3269             : 
    3270           0 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::SESession);
    3271           0 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::SESession);
    3272           0 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    3273             :                               &sPrototypeClass.mBase, protoCache,
    3274             :                               constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
    3275             :                               interfaceCache,
    3276             :                               sNativeProperties.Upcast(),
    3277           0 :                               nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
    3278             :                               "SESession", aDefineOnGlobal,
    3279             :                               nullptr,
    3280           0 :                               false);
    3281             : }
    3282             : 
    3283             : JS::Handle<JSObject*>
    3284           0 : GetProtoObjectHandle(JSContext* aCx)
    3285             : {
    3286             :   /* Get the interface prototype object for this class.  This will create the
    3287             :      object as needed. */
    3288           0 :   bool aDefineOnGlobal = true;
    3289             : 
    3290             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    3291           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    3292           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    3293           0 :     return nullptr;
    3294             :   }
    3295             : 
    3296             :   /* Check to see whether the interface objects are already installed */
    3297           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    3298           0 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::SESession)) {
    3299           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    3300           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    3301             :   }
    3302             : 
    3303             :   /*
    3304             :    * The object might _still_ be null, but that's OK.
    3305             :    *
    3306             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    3307             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    3308             :    * changed after they have been set.
    3309             :    *
    3310             :    * Calling address() avoids the read read barrier that does gray
    3311             :    * unmarking, but it's not possible for the object to be gray here.
    3312             :    */
    3313             : 
    3314           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::SESession);
    3315           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    3316           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    3317             : }
    3318             : 
    3319             : JS::Handle<JSObject*>
    3320           0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
    3321             : {
    3322             :   /* Get the interface object for this class.  This will create the object as
    3323             :      needed. */
    3324             : 
    3325             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    3326           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    3327           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    3328           0 :     return nullptr;
    3329             :   }
    3330             : 
    3331             :   /* Check to see whether the interface objects are already installed */
    3332           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    3333           0 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::SESession)) {
    3334           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    3335           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    3336             :   }
    3337             : 
    3338             :   /*
    3339             :    * The object might _still_ be null, but that's OK.
    3340             :    *
    3341             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    3342             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    3343             :    * changed after they have been set.
    3344             :    *
    3345             :    * Calling address() avoids the read read barrier that does gray
    3346             :    * unmarking, but it's not possible for the object to be gray here.
    3347             :    */
    3348             : 
    3349           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::SESession);
    3350           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    3351           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    3352             : }
    3353             : 
    3354             : JSObject*
    3355           0 : GetConstructorObject(JSContext* aCx)
    3356             : {
    3357           0 :   return GetConstructorObjectHandle(aCx);
    3358             : }
    3359             : 
    3360             : } // namespace SESessionBinding
    3361             : 
    3362             : 
    3363             : 
    3364             : already_AddRefed<Promise>
    3365           0 : SEChannelJSImpl::Transmit(const SECommand& command, ErrorResult& aRv, JSCompartment* aCompartment)
    3366             : {
    3367           0 :   CallSetup s(this, aRv, "SEChannel.transmit", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    3368           0 :   JSContext* cx = s.GetContext();
    3369           0 :   if (!cx) {
    3370           0 :     MOZ_ASSERT(aRv.Failed());
    3371           0 :     return nullptr;
    3372             :   }
    3373           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    3374           0 :   JS::AutoValueVector argv(cx);
    3375           0 :   if (!argv.resize(1)) {
    3376           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    3377           0 :     return nullptr;
    3378             :   }
    3379           0 :   unsigned argc = 1;
    3380             : 
    3381             :   do {
    3382           0 :     if (!command.ToObjectInternal(cx, argv[0])) {
    3383           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3384           0 :       return nullptr;
    3385             :     }
    3386           0 :     break;
    3387             :   } while (0);
    3388             : 
    3389           0 :   JS::Rooted<JS::Value> callable(cx);
    3390           0 :   SEChannelAtoms* atomsCache = GetAtomCache<SEChannelAtoms>(cx);
    3391           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    3392           0 :       !GetCallableProperty(cx, atomsCache->transmit_id, &callable)) {
    3393           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3394           0 :     return nullptr;
    3395             :   }
    3396           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    3397           0 :   if (!JS::Call(cx, thisValue, callable,
    3398           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    3399           0 :     aRv.NoteJSContextException(cx);
    3400           0 :     return nullptr;
    3401             :   }
    3402           0 :   RefPtr<Promise> rvalDecl;
    3403             :   { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
    3404             :     // etc.
    3405             : 
    3406           0 :     JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
    3407           0 :     if (!rval.isObject()) {
    3408           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SEChannel.transmit"));
    3409           0 :       return nullptr;
    3410             :     }
    3411           0 :     JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
    3412           0 :     if (!unwrappedVal) {
    3413             :       // A slight lie, but not much of one, for a dead object wrapper.
    3414           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SEChannel.transmit"));
    3415           0 :       return nullptr;
    3416             :     }
    3417           0 :     globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
    3418           0 :     JSAutoCompartment ac(cx, globalObj);
    3419           0 :     GlobalObject promiseGlobal(cx, globalObj);
    3420           0 :     if (promiseGlobal.Failed()) {
    3421           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3422           0 :       return nullptr;
    3423             :     }
    3424             : 
    3425           0 :     JS::Rooted<JS::Value> valueToResolve(cx, rval);
    3426           0 :     if (!JS_WrapValue(cx, &valueToResolve)) {
    3427           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3428           0 :       return nullptr;
    3429             :     }
    3430           0 :     binding_detail::FastErrorResult promiseRv;
    3431             :     nsCOMPtr<nsIGlobalObject> global =
    3432           0 :       do_QueryInterface(promiseGlobal.GetAsSupports());
    3433           0 :     if (!global) {
    3434           0 :       promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
    3435           0 :       MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
    3436           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3437           0 :       return nullptr;
    3438             :     }
    3439           0 :     rvalDecl = Promise::Resolve(global, cx, valueToResolve,
    3440           0 :                                     promiseRv);
    3441           0 :     if (promiseRv.MaybeSetPendingException(cx)) {
    3442           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3443           0 :       return nullptr;
    3444             :     }
    3445             :   }
    3446           0 :   return rvalDecl.forget();
    3447             : }
    3448             : 
    3449             : already_AddRefed<Promise>
    3450           0 : SEChannelJSImpl::Close(ErrorResult& aRv, JSCompartment* aCompartment)
    3451             : {
    3452           0 :   CallSetup s(this, aRv, "SEChannel.close", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    3453           0 :   JSContext* cx = s.GetContext();
    3454           0 :   if (!cx) {
    3455           0 :     MOZ_ASSERT(aRv.Failed());
    3456           0 :     return nullptr;
    3457             :   }
    3458           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    3459             : 
    3460           0 :   JS::Rooted<JS::Value> callable(cx);
    3461           0 :   SEChannelAtoms* atomsCache = GetAtomCache<SEChannelAtoms>(cx);
    3462           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    3463           0 :       !GetCallableProperty(cx, atomsCache->close_id, &callable)) {
    3464           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3465           0 :     return nullptr;
    3466             :   }
    3467           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    3468           0 :   if (!JS::Call(cx, thisValue, callable,
    3469           0 :                 JS::HandleValueArray::empty(), &rval)) {
    3470           0 :     aRv.NoteJSContextException(cx);
    3471           0 :     return nullptr;
    3472             :   }
    3473           0 :   RefPtr<Promise> rvalDecl;
    3474             :   { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
    3475             :     // etc.
    3476             : 
    3477           0 :     JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
    3478           0 :     if (!rval.isObject()) {
    3479           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SEChannel.close"));
    3480           0 :       return nullptr;
    3481             :     }
    3482           0 :     JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
    3483           0 :     if (!unwrappedVal) {
    3484             :       // A slight lie, but not much of one, for a dead object wrapper.
    3485           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SEChannel.close"));
    3486           0 :       return nullptr;
    3487             :     }
    3488           0 :     globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
    3489           0 :     JSAutoCompartment ac(cx, globalObj);
    3490           0 :     GlobalObject promiseGlobal(cx, globalObj);
    3491           0 :     if (promiseGlobal.Failed()) {
    3492           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3493           0 :       return nullptr;
    3494             :     }
    3495             : 
    3496           0 :     JS::Rooted<JS::Value> valueToResolve(cx, rval);
    3497           0 :     if (!JS_WrapValue(cx, &valueToResolve)) {
    3498           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3499           0 :       return nullptr;
    3500             :     }
    3501           0 :     binding_detail::FastErrorResult promiseRv;
    3502             :     nsCOMPtr<nsIGlobalObject> global =
    3503           0 :       do_QueryInterface(promiseGlobal.GetAsSupports());
    3504           0 :     if (!global) {
    3505           0 :       promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
    3506           0 :       MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
    3507           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3508           0 :       return nullptr;
    3509             :     }
    3510           0 :     rvalDecl = Promise::Resolve(global, cx, valueToResolve,
    3511           0 :                                     promiseRv);
    3512           0 :     if (promiseRv.MaybeSetPendingException(cx)) {
    3513           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3514           0 :       return nullptr;
    3515             :     }
    3516             :   }
    3517           0 :   return rvalDecl.forget();
    3518             : }
    3519             : 
    3520             : bool
    3521           0 : SEChannelJSImpl::InitIds(JSContext* cx, SEChannelAtoms* atomsCache)
    3522             : {
    3523           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
    3524             : 
    3525             :   // Initialize these in reverse order so that any failure leaves the first one
    3526             :   // uninitialized.
    3527           0 :   if (!atomsCache->close_id.init(cx, "close") ||
    3528           0 :       !atomsCache->transmit_id.init(cx, "transmit") ||
    3529           0 :       !atomsCache->type_id.init(cx, "type") ||
    3530           0 :       !atomsCache->isClosed_id.init(cx, "isClosed") ||
    3531           0 :       !atomsCache->openResponse_id.init(cx, "openResponse") ||
    3532           0 :       !atomsCache->session_id.init(cx, "session")) {
    3533           0 :     return false;
    3534             :   }
    3535           0 :   return true;
    3536             : }
    3537             : 
    3538             : 
    3539             : already_AddRefed<SESession>
    3540           0 : SEChannelJSImpl::GetSession(ErrorResult& aRv, JSCompartment* aCompartment)
    3541             : {
    3542           0 :   CallSetup s(this, aRv, "SEChannel.session", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    3543           0 :   JSContext* cx = s.GetContext();
    3544           0 :   if (!cx) {
    3545           0 :     MOZ_ASSERT(aRv.Failed());
    3546           0 :     return nullptr;
    3547             :   }
    3548           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    3549             : 
    3550           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    3551           0 :   SEChannelAtoms* atomsCache = GetAtomCache<SEChannelAtoms>(cx);
    3552           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    3553           0 :       !JS_GetPropertyById(cx, callback, atomsCache->session_id, &rval)) {
    3554           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3555           0 :     return nullptr;
    3556             :   }
    3557           0 :   RefPtr<mozilla::dom::SESession> rvalDecl;
    3558           0 :   if (rval.isObject()) {
    3559             :     static_assert(IsRefcounted<mozilla::dom::SESession>::value, "We can only store refcounted classes.");{
    3560           0 :       nsresult rv = UnwrapObject<prototypes::id::SESession, mozilla::dom::SESession>(rval, rvalDecl);
    3561           0 :       if (NS_FAILED(rv)) {
    3562             :         // Be careful to not wrap random DOM objects here, even if
    3563             :         // they're wrapped in opaque security wrappers for some reason.
    3564             :         // XXXbz Wish we could check for a JS-implemented object
    3565             :         // that already has a content reflection...
    3566           0 :         if (!IsDOMObject(js::UncheckedUnwrap(&rval.toObject()))) {
    3567           0 :           nsCOMPtr<nsIGlobalObject> contentGlobal;
    3568           0 :           JS::Handle<JSObject*> callback = CallbackOrNull();
    3569           0 :           if (!callback ||
    3570           0 :               !GetContentGlobalForJSImplementedObject(cx, callback, getter_AddRefs(contentGlobal))) {
    3571           0 :             aRv.Throw(NS_ERROR_UNEXPECTED);
    3572           0 :             return nullptr;
    3573             :           }
    3574           0 :           JS::Rooted<JSObject*> jsImplSourceObj(cx, &rval.toObject());
    3575           0 :           rvalDecl = new mozilla::dom::SESession(jsImplSourceObj, contentGlobal);
    3576             :         } else {
    3577           0 :           ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Return value of SEChannel.session", "SESession");
    3578           0 :           aRv.Throw(NS_ERROR_UNEXPECTED);
    3579           0 :           return nullptr;
    3580             :         }
    3581             :       }
    3582             :     }
    3583             :   } else {
    3584           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of SEChannel.session");
    3585           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3586           0 :     return nullptr;
    3587             :   }
    3588           0 :   return rvalDecl.forget();
    3589             : }
    3590             : 
    3591             : void
    3592           0 : SEChannelJSImpl::GetOpenResponse(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    3593             : {
    3594           0 :   CallSetup s(this, aRv, "SEChannel.openResponse", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    3595           0 :   JSContext* cx = s.GetContext();
    3596           0 :   if (!cx) {
    3597           0 :     MOZ_ASSERT(aRv.Failed());
    3598           0 :     return;
    3599             :   }
    3600           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    3601             : 
    3602           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    3603           0 :   SEChannelAtoms* atomsCache = GetAtomCache<SEChannelAtoms>(cx);
    3604           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    3605           0 :       !JS_GetPropertyById(cx, callback, atomsCache->openResponse_id, &rval)) {
    3606           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3607           0 :     return;
    3608             :   }
    3609           0 :   RootedTypedArray<Nullable<Uint8Array>> rvalDecl(cx);
    3610           0 :   if (rval.isObject()) {
    3611           0 :     if (!rvalDecl.SetValue().Init(&rval.toObject())) {
    3612           0 :       ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Return value of SEChannel.openResponse", "Uint8ArrayOrNull");
    3613           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3614           0 :       return;
    3615             :     }
    3616           0 :   } else if (rval.isNullOrUndefined()) {
    3617           0 :     rvalDecl.SetNull();
    3618             :   } else {
    3619           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of SEChannel.openResponse");
    3620           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3621           0 :     return;
    3622             :   }
    3623           0 :   aRetVal.set(rvalDecl.IsNull() ? nullptr : rvalDecl.Value().Obj());
    3624             : }
    3625             : 
    3626             : bool
    3627           0 : SEChannelJSImpl::GetIsClosed(ErrorResult& aRv, JSCompartment* aCompartment)
    3628             : {
    3629           0 :   CallSetup s(this, aRv, "SEChannel.isClosed", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    3630           0 :   JSContext* cx = s.GetContext();
    3631           0 :   if (!cx) {
    3632           0 :     MOZ_ASSERT(aRv.Failed());
    3633           0 :     return bool(0);
    3634             :   }
    3635           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    3636             : 
    3637           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    3638           0 :   SEChannelAtoms* atomsCache = GetAtomCache<SEChannelAtoms>(cx);
    3639           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    3640           0 :       !JS_GetPropertyById(cx, callback, atomsCache->isClosed_id, &rval)) {
    3641           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3642           0 :     return bool(0);
    3643             :   }
    3644             :   bool rvalDecl;
    3645           0 :   if (!ValueToPrimitive<bool, eDefault>(cx, rval, &rvalDecl)) {
    3646           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3647           0 :     return bool(0);
    3648             :   }
    3649           0 :   return rvalDecl;
    3650             : }
    3651             : 
    3652             : SEChannelType
    3653           0 : SEChannelJSImpl::GetType(ErrorResult& aRv, JSCompartment* aCompartment)
    3654             : {
    3655           0 :   CallSetup s(this, aRv, "SEChannel.type", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    3656           0 :   JSContext* cx = s.GetContext();
    3657           0 :   if (!cx) {
    3658           0 :     MOZ_ASSERT(aRv.Failed());
    3659           0 :     return SEChannelType(0);
    3660             :   }
    3661           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    3662             : 
    3663           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    3664           0 :   SEChannelAtoms* atomsCache = GetAtomCache<SEChannelAtoms>(cx);
    3665           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    3666           0 :       !JS_GetPropertyById(cx, callback, atomsCache->type_id, &rval)) {
    3667           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3668           0 :     return SEChannelType(0);
    3669             :   }
    3670             :   SEChannelType rvalDecl;
    3671             :   {
    3672             :     int index;
    3673           0 :     if (!FindEnumStringIndex<true>(cx, rval, SEChannelTypeValues::strings, "SEChannelType", "Return value of SEChannel.type", &index)) {
    3674           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3675           0 :       return SEChannelType(0);
    3676             :     }
    3677           0 :     MOZ_ASSERT(index >= 0);
    3678           0 :     rvalDecl = static_cast<SEChannelType>(index);
    3679             :   }
    3680           0 :   return rvalDecl;
    3681             : }
    3682             : 
    3683             : 
    3684             : NS_IMPL_CYCLE_COLLECTION_CLASS(SEChannel)
    3685           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(SEChannel)
    3686           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mImpl)
    3687           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
    3688           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
    3689           0 :   tmp->ClearWeakReferences();
    3690           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
    3691           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(SEChannel)
    3692           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImpl)
    3693           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
    3694           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
    3695           0 : NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(SEChannel)
    3696           0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(SEChannel)
    3697           0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(SEChannel)
    3698           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SEChannel)
    3699           0 :   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
    3700           0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
    3701           0 :   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
    3702           0 : NS_INTERFACE_MAP_END
    3703             : 
    3704           0 : SEChannel::SEChannel(JS::Handle<JSObject*> aJSImplObject, nsIGlobalObject* aParent)
    3705           0 :   : mImpl(new SEChannelJSImpl(nullptr, aJSImplObject, /* aIncumbentGlobal = */ nullptr)),
    3706           0 :     mParent(aParent)
    3707             : {
    3708           0 : }
    3709             : 
    3710             : 
    3711           0 : SEChannel::~SEChannel()
    3712             : {
    3713           0 : }
    3714             : 
    3715             : nsISupports*
    3716           0 : SEChannel::GetParentObject() const
    3717             : {
    3718           0 :   return mParent;
    3719             : }
    3720             : 
    3721             : JSObject*
    3722           0 : SEChannel::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
    3723             : {
    3724           0 :   JS::Rooted<JSObject*> obj(aCx, SEChannelBinding::Wrap(aCx, this, aGivenProto));
    3725           0 :   if (!obj) {
    3726           0 :     return nullptr;
    3727             :   }
    3728             : 
    3729             :   // Now define it on our chrome object
    3730           0 :   JSAutoCompartment ac(aCx, mImpl->CallbackOrNull());
    3731           0 :   if (!JS_WrapObject(aCx, &obj)) {
    3732           0 :     return nullptr;
    3733             :   }
    3734           0 :   if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
    3735           0 :     return nullptr;
    3736             :   }
    3737           0 :   return obj;
    3738             : }
    3739             : 
    3740             : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
    3741             : already_AddRefed<SESession>
    3742           0 : SEChannel::GetSession(ErrorResult& aRv, JSCompartment* aCompartment) const
    3743             : {
    3744           0 :   return mImpl->GetSession(aRv, aCompartment);
    3745             : }
    3746             : 
    3747             : void
    3748           0 : SEChannel::GetOpenResponse(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment) const
    3749             : {
    3750           0 :   return mImpl->GetOpenResponse(aRetVal, aRv, aCompartment);
    3751             : }
    3752             : 
    3753             : bool
    3754           0 : SEChannel::GetIsClosed(ErrorResult& aRv, JSCompartment* aCompartment) const
    3755             : {
    3756           0 :   return mImpl->GetIsClosed(aRv, aCompartment);
    3757             : }
    3758             : 
    3759             : SEChannelType
    3760           0 : SEChannel::GetType(ErrorResult& aRv, JSCompartment* aCompartment) const
    3761             : {
    3762           0 :   return mImpl->GetType(aRv, aCompartment);
    3763             : }
    3764             : 
    3765             : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
    3766             : already_AddRefed<Promise>
    3767           0 : SEChannel::Transmit(const SECommand& command, ErrorResult& aRv, JSCompartment* aCompartment)
    3768             : {
    3769           0 :   return mImpl->Transmit(command, aRv, aCompartment);
    3770             : }
    3771             : 
    3772             : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
    3773             : already_AddRefed<Promise>
    3774           0 : SEChannel::Close(ErrorResult& aRv, JSCompartment* aCompartment)
    3775             : {
    3776           0 :   return mImpl->Close(aRv, aCompartment);
    3777             : }
    3778             : 
    3779             : bool
    3780           0 : SEChannel::_Create(JSContext* cx, unsigned argc, JS::Value* vp)
    3781             : {
    3782           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    3783           0 :   if (args.length() < 2) {
    3784           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SEChannel._create");
    3785             :   }
    3786           0 :   if (!args[0].isObject()) {
    3787           0 :     return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of SEChannel._create");
    3788             :   }
    3789           0 :   if (!args[1].isObject()) {
    3790           0 :     return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of SEChannel._create");
    3791             :   }
    3792             : 
    3793             :   // GlobalObject will go through wrappers as needed for us, and
    3794             :   // is simpler than the right UnwrapArg incantation.
    3795           0 :   GlobalObject global(cx, &args[0].toObject());
    3796           0 :   if (global.Failed()) {
    3797           0 :     return false;
    3798             :   }
    3799           0 :   nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports());
    3800           0 :   MOZ_ASSERT(globalHolder);
    3801           0 :   JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
    3802           0 :   RefPtr<SEChannel> impl = new SEChannel(arg, globalHolder);
    3803           0 :   MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
    3804           0 :   return GetOrCreateDOMReflector(cx, impl, args.rval());
    3805             : }
    3806             : 
    3807             : 
    3808             : already_AddRefed<Promise>
    3809           0 : SEReaderJSImpl::OpenSession(ErrorResult& aRv, JSCompartment* aCompartment)
    3810             : {
    3811           0 :   CallSetup s(this, aRv, "SEReader.openSession", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    3812           0 :   JSContext* cx = s.GetContext();
    3813           0 :   if (!cx) {
    3814           0 :     MOZ_ASSERT(aRv.Failed());
    3815           0 :     return nullptr;
    3816             :   }
    3817           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    3818             : 
    3819           0 :   JS::Rooted<JS::Value> callable(cx);
    3820           0 :   SEReaderAtoms* atomsCache = GetAtomCache<SEReaderAtoms>(cx);
    3821           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    3822           0 :       !GetCallableProperty(cx, atomsCache->openSession_id, &callable)) {
    3823           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3824           0 :     return nullptr;
    3825             :   }
    3826           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    3827           0 :   if (!JS::Call(cx, thisValue, callable,
    3828           0 :                 JS::HandleValueArray::empty(), &rval)) {
    3829           0 :     aRv.NoteJSContextException(cx);
    3830           0 :     return nullptr;
    3831             :   }
    3832           0 :   RefPtr<Promise> rvalDecl;
    3833             :   { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
    3834             :     // etc.
    3835             : 
    3836           0 :     JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
    3837           0 :     if (!rval.isObject()) {
    3838           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SEReader.openSession"));
    3839           0 :       return nullptr;
    3840             :     }
    3841           0 :     JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
    3842           0 :     if (!unwrappedVal) {
    3843             :       // A slight lie, but not much of one, for a dead object wrapper.
    3844           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SEReader.openSession"));
    3845           0 :       return nullptr;
    3846             :     }
    3847           0 :     globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
    3848           0 :     JSAutoCompartment ac(cx, globalObj);
    3849           0 :     GlobalObject promiseGlobal(cx, globalObj);
    3850           0 :     if (promiseGlobal.Failed()) {
    3851           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3852           0 :       return nullptr;
    3853             :     }
    3854             : 
    3855           0 :     JS::Rooted<JS::Value> valueToResolve(cx, rval);
    3856           0 :     if (!JS_WrapValue(cx, &valueToResolve)) {
    3857           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3858           0 :       return nullptr;
    3859             :     }
    3860           0 :     binding_detail::FastErrorResult promiseRv;
    3861             :     nsCOMPtr<nsIGlobalObject> global =
    3862           0 :       do_QueryInterface(promiseGlobal.GetAsSupports());
    3863           0 :     if (!global) {
    3864           0 :       promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
    3865           0 :       MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
    3866           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3867           0 :       return nullptr;
    3868             :     }
    3869           0 :     rvalDecl = Promise::Resolve(global, cx, valueToResolve,
    3870           0 :                                     promiseRv);
    3871           0 :     if (promiseRv.MaybeSetPendingException(cx)) {
    3872           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3873           0 :       return nullptr;
    3874             :     }
    3875             :   }
    3876           0 :   return rvalDecl.forget();
    3877             : }
    3878             : 
    3879             : already_AddRefed<Promise>
    3880           0 : SEReaderJSImpl::CloseAll(ErrorResult& aRv, JSCompartment* aCompartment)
    3881             : {
    3882           0 :   CallSetup s(this, aRv, "SEReader.closeAll", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    3883           0 :   JSContext* cx = s.GetContext();
    3884           0 :   if (!cx) {
    3885           0 :     MOZ_ASSERT(aRv.Failed());
    3886           0 :     return nullptr;
    3887             :   }
    3888           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    3889             : 
    3890           0 :   JS::Rooted<JS::Value> callable(cx);
    3891           0 :   SEReaderAtoms* atomsCache = GetAtomCache<SEReaderAtoms>(cx);
    3892           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    3893           0 :       !GetCallableProperty(cx, atomsCache->closeAll_id, &callable)) {
    3894           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3895           0 :     return nullptr;
    3896             :   }
    3897           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    3898           0 :   if (!JS::Call(cx, thisValue, callable,
    3899           0 :                 JS::HandleValueArray::empty(), &rval)) {
    3900           0 :     aRv.NoteJSContextException(cx);
    3901           0 :     return nullptr;
    3902             :   }
    3903           0 :   RefPtr<Promise> rvalDecl;
    3904             :   { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
    3905             :     // etc.
    3906             : 
    3907           0 :     JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
    3908           0 :     if (!rval.isObject()) {
    3909           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SEReader.closeAll"));
    3910           0 :       return nullptr;
    3911             :     }
    3912           0 :     JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
    3913           0 :     if (!unwrappedVal) {
    3914             :       // A slight lie, but not much of one, for a dead object wrapper.
    3915           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SEReader.closeAll"));
    3916           0 :       return nullptr;
    3917             :     }
    3918           0 :     globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
    3919           0 :     JSAutoCompartment ac(cx, globalObj);
    3920           0 :     GlobalObject promiseGlobal(cx, globalObj);
    3921           0 :     if (promiseGlobal.Failed()) {
    3922           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3923           0 :       return nullptr;
    3924             :     }
    3925             : 
    3926           0 :     JS::Rooted<JS::Value> valueToResolve(cx, rval);
    3927           0 :     if (!JS_WrapValue(cx, &valueToResolve)) {
    3928           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3929           0 :       return nullptr;
    3930             :     }
    3931           0 :     binding_detail::FastErrorResult promiseRv;
    3932             :     nsCOMPtr<nsIGlobalObject> global =
    3933           0 :       do_QueryInterface(promiseGlobal.GetAsSupports());
    3934           0 :     if (!global) {
    3935           0 :       promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
    3936           0 :       MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
    3937           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3938           0 :       return nullptr;
    3939             :     }
    3940           0 :     rvalDecl = Promise::Resolve(global, cx, valueToResolve,
    3941           0 :                                     promiseRv);
    3942           0 :     if (promiseRv.MaybeSetPendingException(cx)) {
    3943           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3944           0 :       return nullptr;
    3945             :     }
    3946             :   }
    3947           0 :   return rvalDecl.forget();
    3948             : }
    3949             : 
    3950             : bool
    3951           0 : SEReaderJSImpl::InitIds(JSContext* cx, SEReaderAtoms* atomsCache)
    3952             : {
    3953           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
    3954             : 
    3955             :   // Initialize these in reverse order so that any failure leaves the first one
    3956             :   // uninitialized.
    3957           0 :   if (!atomsCache->closeAll_id.init(cx, "closeAll") ||
    3958           0 :       !atomsCache->openSession_id.init(cx, "openSession") ||
    3959           0 :       !atomsCache->type_id.init(cx, "type") ||
    3960           0 :       !atomsCache->isSEPresent_id.init(cx, "isSEPresent")) {
    3961           0 :     return false;
    3962             :   }
    3963           0 :   return true;
    3964             : }
    3965             : 
    3966             : 
    3967             : bool
    3968           0 : SEReaderJSImpl::GetIsSEPresent(ErrorResult& aRv, JSCompartment* aCompartment)
    3969             : {
    3970           0 :   CallSetup s(this, aRv, "SEReader.isSEPresent", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    3971           0 :   JSContext* cx = s.GetContext();
    3972           0 :   if (!cx) {
    3973           0 :     MOZ_ASSERT(aRv.Failed());
    3974           0 :     return bool(0);
    3975             :   }
    3976           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    3977             : 
    3978           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    3979           0 :   SEReaderAtoms* atomsCache = GetAtomCache<SEReaderAtoms>(cx);
    3980           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    3981           0 :       !JS_GetPropertyById(cx, callback, atomsCache->isSEPresent_id, &rval)) {
    3982           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3983           0 :     return bool(0);
    3984             :   }
    3985             :   bool rvalDecl;
    3986           0 :   if (!ValueToPrimitive<bool, eDefault>(cx, rval, &rvalDecl)) {
    3987           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3988           0 :     return bool(0);
    3989             :   }
    3990           0 :   return rvalDecl;
    3991             : }
    3992             : 
    3993             : SEType
    3994           0 : SEReaderJSImpl::GetType(ErrorResult& aRv, JSCompartment* aCompartment)
    3995             : {
    3996           0 :   CallSetup s(this, aRv, "SEReader.type", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    3997           0 :   JSContext* cx = s.GetContext();
    3998           0 :   if (!cx) {
    3999           0 :     MOZ_ASSERT(aRv.Failed());
    4000           0 :     return SEType(0);
    4001             :   }
    4002           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    4003             : 
    4004           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    4005           0 :   SEReaderAtoms* atomsCache = GetAtomCache<SEReaderAtoms>(cx);
    4006           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    4007           0 :       !JS_GetPropertyById(cx, callback, atomsCache->type_id, &rval)) {
    4008           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4009           0 :     return SEType(0);
    4010             :   }
    4011             :   SEType rvalDecl;
    4012             :   {
    4013             :     int index;
    4014           0 :     if (!FindEnumStringIndex<true>(cx, rval, SETypeValues::strings, "SEType", "Return value of SEReader.type", &index)) {
    4015           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    4016           0 :       return SEType(0);
    4017             :     }
    4018           0 :     MOZ_ASSERT(index >= 0);
    4019           0 :     rvalDecl = static_cast<SEType>(index);
    4020             :   }
    4021           0 :   return rvalDecl;
    4022             : }
    4023             : 
    4024             : 
    4025             : NS_IMPL_CYCLE_COLLECTION_CLASS(SEReader)
    4026           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(SEReader)
    4027           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mImpl)
    4028           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
    4029           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
    4030           0 :   tmp->ClearWeakReferences();
    4031           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
    4032           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(SEReader)
    4033           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImpl)
    4034           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
    4035           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
    4036           0 : NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(SEReader)
    4037           0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(SEReader)
    4038           0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(SEReader)
    4039           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SEReader)
    4040           0 :   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
    4041           0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
    4042           0 :   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
    4043           0 : NS_INTERFACE_MAP_END
    4044             : 
    4045           0 : SEReader::SEReader(JS::Handle<JSObject*> aJSImplObject, nsIGlobalObject* aParent)
    4046           0 :   : mImpl(new SEReaderJSImpl(nullptr, aJSImplObject, /* aIncumbentGlobal = */ nullptr)),
    4047           0 :     mParent(aParent)
    4048             : {
    4049           0 : }
    4050             : 
    4051             : 
    4052           0 : SEReader::~SEReader()
    4053             : {
    4054           0 : }
    4055             : 
    4056             : nsISupports*
    4057           0 : SEReader::GetParentObject() const
    4058             : {
    4059           0 :   return mParent;
    4060             : }
    4061             : 
    4062             : JSObject*
    4063           0 : SEReader::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
    4064             : {
    4065           0 :   JS::Rooted<JSObject*> obj(aCx, SEReaderBinding::Wrap(aCx, this, aGivenProto));
    4066           0 :   if (!obj) {
    4067           0 :     return nullptr;
    4068             :   }
    4069             : 
    4070             :   // Now define it on our chrome object
    4071           0 :   JSAutoCompartment ac(aCx, mImpl->CallbackOrNull());
    4072           0 :   if (!JS_WrapObject(aCx, &obj)) {
    4073           0 :     return nullptr;
    4074             :   }
    4075           0 :   if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
    4076           0 :     return nullptr;
    4077             :   }
    4078           0 :   return obj;
    4079             : }
    4080             : 
    4081             : bool
    4082           0 : SEReader::GetIsSEPresent(ErrorResult& aRv, JSCompartment* aCompartment) const
    4083             : {
    4084           0 :   return mImpl->GetIsSEPresent(aRv, aCompartment);
    4085             : }
    4086             : 
    4087             : SEType
    4088           0 : SEReader::GetType(ErrorResult& aRv, JSCompartment* aCompartment) const
    4089             : {
    4090           0 :   return mImpl->GetType(aRv, aCompartment);
    4091             : }
    4092             : 
    4093             : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
    4094             : already_AddRefed<Promise>
    4095           0 : SEReader::OpenSession(ErrorResult& aRv, JSCompartment* aCompartment)
    4096             : {
    4097           0 :   return mImpl->OpenSession(aRv, aCompartment);
    4098             : }
    4099             : 
    4100             : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
    4101             : already_AddRefed<Promise>
    4102           0 : SEReader::CloseAll(ErrorResult& aRv, JSCompartment* aCompartment)
    4103             : {
    4104           0 :   return mImpl->CloseAll(aRv, aCompartment);
    4105             : }
    4106             : 
    4107             : bool
    4108           0 : SEReader::_Create(JSContext* cx, unsigned argc, JS::Value* vp)
    4109             : {
    4110           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    4111           0 :   if (args.length() < 2) {
    4112           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SEReader._create");
    4113             :   }
    4114           0 :   if (!args[0].isObject()) {
    4115           0 :     return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of SEReader._create");
    4116             :   }
    4117           0 :   if (!args[1].isObject()) {
    4118           0 :     return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of SEReader._create");
    4119             :   }
    4120             : 
    4121             :   // GlobalObject will go through wrappers as needed for us, and
    4122             :   // is simpler than the right UnwrapArg incantation.
    4123           0 :   GlobalObject global(cx, &args[0].toObject());
    4124           0 :   if (global.Failed()) {
    4125           0 :     return false;
    4126             :   }
    4127           0 :   nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports());
    4128           0 :   MOZ_ASSERT(globalHolder);
    4129           0 :   JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
    4130           0 :   RefPtr<SEReader> impl = new SEReader(arg, globalHolder);
    4131           0 :   MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
    4132           0 :   return GetOrCreateDOMReflector(cx, impl, args.rval());
    4133             : }
    4134             : 
    4135             : 
    4136             : bool
    4137           0 : SEResponseJSImpl::InitIds(JSContext* cx, SEResponseAtoms* atomsCache)
    4138             : {
    4139           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
    4140             : 
    4141             :   // Initialize these in reverse order so that any failure leaves the first one
    4142             :   // uninitialized.
    4143           0 :   if (!atomsCache->data_id.init(cx, "data") ||
    4144           0 :       !atomsCache->sw2_id.init(cx, "sw2") ||
    4145           0 :       !atomsCache->sw1_id.init(cx, "sw1") ||
    4146           0 :       !atomsCache->channel_id.init(cx, "channel")) {
    4147           0 :     return false;
    4148             :   }
    4149           0 :   return true;
    4150             : }
    4151             : 
    4152             : 
    4153             : already_AddRefed<SEChannel>
    4154           0 : SEResponseJSImpl::GetChannel(ErrorResult& aRv, JSCompartment* aCompartment)
    4155             : {
    4156           0 :   CallSetup s(this, aRv, "SEResponse.channel", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    4157           0 :   JSContext* cx = s.GetContext();
    4158           0 :   if (!cx) {
    4159           0 :     MOZ_ASSERT(aRv.Failed());
    4160           0 :     return nullptr;
    4161             :   }
    4162           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    4163             : 
    4164           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    4165           0 :   SEResponseAtoms* atomsCache = GetAtomCache<SEResponseAtoms>(cx);
    4166           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    4167           0 :       !JS_GetPropertyById(cx, callback, atomsCache->channel_id, &rval)) {
    4168           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4169           0 :     return nullptr;
    4170             :   }
    4171           0 :   RefPtr<mozilla::dom::SEChannel> rvalDecl;
    4172           0 :   if (rval.isObject()) {
    4173             :     static_assert(IsRefcounted<mozilla::dom::SEChannel>::value, "We can only store refcounted classes.");{
    4174           0 :       nsresult rv = UnwrapObject<prototypes::id::SEChannel, mozilla::dom::SEChannel>(rval, rvalDecl);
    4175           0 :       if (NS_FAILED(rv)) {
    4176             :         // Be careful to not wrap random DOM objects here, even if
    4177             :         // they're wrapped in opaque security wrappers for some reason.
    4178             :         // XXXbz Wish we could check for a JS-implemented object
    4179             :         // that already has a content reflection...
    4180           0 :         if (!IsDOMObject(js::UncheckedUnwrap(&rval.toObject()))) {
    4181           0 :           nsCOMPtr<nsIGlobalObject> contentGlobal;
    4182           0 :           JS::Handle<JSObject*> callback = CallbackOrNull();
    4183           0 :           if (!callback ||
    4184           0 :               !GetContentGlobalForJSImplementedObject(cx, callback, getter_AddRefs(contentGlobal))) {
    4185           0 :             aRv.Throw(NS_ERROR_UNEXPECTED);
    4186           0 :             return nullptr;
    4187             :           }
    4188           0 :           JS::Rooted<JSObject*> jsImplSourceObj(cx, &rval.toObject());
    4189           0 :           rvalDecl = new mozilla::dom::SEChannel(jsImplSourceObj, contentGlobal);
    4190             :         } else {
    4191           0 :           ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Return value of SEResponse.channel", "SEChannel");
    4192           0 :           aRv.Throw(NS_ERROR_UNEXPECTED);
    4193           0 :           return nullptr;
    4194             :         }
    4195             :       }
    4196             :     }
    4197             :   } else {
    4198           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of SEResponse.channel");
    4199           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4200           0 :     return nullptr;
    4201             :   }
    4202           0 :   return rvalDecl.forget();
    4203             : }
    4204             : 
    4205             : uint8_t
    4206           0 : SEResponseJSImpl::GetSw1(ErrorResult& aRv, JSCompartment* aCompartment)
    4207             : {
    4208           0 :   CallSetup s(this, aRv, "SEResponse.sw1", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    4209           0 :   JSContext* cx = s.GetContext();
    4210           0 :   if (!cx) {
    4211           0 :     MOZ_ASSERT(aRv.Failed());
    4212           0 :     return uint8_t(0);
    4213             :   }
    4214           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    4215             : 
    4216           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    4217           0 :   SEResponseAtoms* atomsCache = GetAtomCache<SEResponseAtoms>(cx);
    4218           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    4219           0 :       !JS_GetPropertyById(cx, callback, atomsCache->sw1_id, &rval)) {
    4220           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4221           0 :     return uint8_t(0);
    4222             :   }
    4223             :   uint8_t rvalDecl;
    4224           0 :   if (!ValueToPrimitive<uint8_t, eDefault>(cx, rval, &rvalDecl)) {
    4225           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4226           0 :     return uint8_t(0);
    4227             :   }
    4228           0 :   return rvalDecl;
    4229             : }
    4230             : 
    4231             : uint8_t
    4232           0 : SEResponseJSImpl::GetSw2(ErrorResult& aRv, JSCompartment* aCompartment)
    4233             : {
    4234           0 :   CallSetup s(this, aRv, "SEResponse.sw2", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    4235           0 :   JSContext* cx = s.GetContext();
    4236           0 :   if (!cx) {
    4237           0 :     MOZ_ASSERT(aRv.Failed());
    4238           0 :     return uint8_t(0);
    4239             :   }
    4240           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    4241             : 
    4242           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    4243           0 :   SEResponseAtoms* atomsCache = GetAtomCache<SEResponseAtoms>(cx);
    4244           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    4245           0 :       !JS_GetPropertyById(cx, callback, atomsCache->sw2_id, &rval)) {
    4246           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4247           0 :     return uint8_t(0);
    4248             :   }
    4249             :   uint8_t rvalDecl;
    4250           0 :   if (!ValueToPrimitive<uint8_t, eDefault>(cx, rval, &rvalDecl)) {
    4251           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4252           0 :     return uint8_t(0);
    4253             :   }
    4254           0 :   return rvalDecl;
    4255             : }
    4256             : 
    4257             : void
    4258           0 : SEResponseJSImpl::GetData(Nullable<nsTArray<uint8_t>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    4259             : {
    4260           0 :   CallSetup s(this, aRv, "SEResponse.data", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    4261           0 :   JSContext* cx = s.GetContext();
    4262           0 :   if (!cx) {
    4263           0 :     MOZ_ASSERT(aRv.Failed());
    4264           0 :     return;
    4265             :   }
    4266           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    4267             : 
    4268           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    4269           0 :   SEResponseAtoms* atomsCache = GetAtomCache<SEResponseAtoms>(cx);
    4270           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    4271           0 :       !JS_GetPropertyById(cx, callback, atomsCache->data_id, &rval)) {
    4272           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4273           0 :     return;
    4274             :   }
    4275           0 :   Nullable<Sequence<uint8_t>> rvalDecl;
    4276           0 :   if (rval.isObject()) {
    4277           0 :     JS::ForOfIterator iter(cx);
    4278           0 :     if (!iter.init(rval, JS::ForOfIterator::AllowNonIterable)) {
    4279           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    4280           0 :       return;
    4281             :     }
    4282           0 :     if (!iter.valueIsIterable()) {
    4283           0 :       ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Return value of SEResponse.data");
    4284           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    4285           0 :       return;
    4286             :     }
    4287           0 :     Sequence<uint8_t> &arr = rvalDecl.SetValue();
    4288           0 :     JS::Rooted<JS::Value> temp(cx);
    4289             :     while (true) {
    4290             :       bool done;
    4291           0 :       if (!iter.next(&temp, &done)) {
    4292           0 :         aRv.Throw(NS_ERROR_UNEXPECTED);
    4293           0 :         return;
    4294             :       }
    4295           0 :       if (done) {
    4296           0 :         break;
    4297             :       }
    4298           0 :       uint8_t* slotPtr = arr.AppendElement(mozilla::fallible);
    4299           0 :       if (!slotPtr) {
    4300           0 :         JS_ReportOutOfMemory(cx);
    4301           0 :         aRv.Throw(NS_ERROR_UNEXPECTED);
    4302           0 :         return;
    4303             :       }
    4304           0 :       uint8_t& slot = *slotPtr;
    4305           0 :       if (!ValueToPrimitive<uint8_t, eDefault>(cx, temp, &slot)) {
    4306           0 :         aRv.Throw(NS_ERROR_UNEXPECTED);
    4307           0 :         return;
    4308             :       }
    4309           0 :     }
    4310           0 :   } else if (rval.isNullOrUndefined()) {
    4311           0 :     rvalDecl.SetNull();
    4312             :   } else {
    4313           0 :     ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Return value of SEResponse.data");
    4314           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4315           0 :     return;
    4316             :   }
    4317           0 :   if (rvalDecl.IsNull()) {
    4318           0 :     aRetVal.SetNull();
    4319             :   } else {
    4320           0 :     aRetVal.SetValue().SwapElements(rvalDecl.Value());
    4321             :   }
    4322             : }
    4323             : 
    4324             : 
    4325             : NS_IMPL_CYCLE_COLLECTION_CLASS(SEResponse)
    4326           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(SEResponse)
    4327           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mImpl)
    4328           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
    4329           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
    4330           0 :   tmp->ClearWeakReferences();
    4331           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
    4332           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(SEResponse)
    4333           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImpl)
    4334           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
    4335           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
    4336           0 : NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(SEResponse)
    4337           0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(SEResponse)
    4338           0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(SEResponse)
    4339           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SEResponse)
    4340           0 :   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
    4341           0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
    4342           0 :   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
    4343           0 : NS_INTERFACE_MAP_END
    4344             : 
    4345           0 : SEResponse::SEResponse(JS::Handle<JSObject*> aJSImplObject, nsIGlobalObject* aParent)
    4346           0 :   : mImpl(new SEResponseJSImpl(nullptr, aJSImplObject, /* aIncumbentGlobal = */ nullptr)),
    4347           0 :     mParent(aParent)
    4348             : {
    4349           0 : }
    4350             : 
    4351             : 
    4352           0 : SEResponse::~SEResponse()
    4353             : {
    4354           0 : }
    4355             : 
    4356             : nsISupports*
    4357           0 : SEResponse::GetParentObject() const
    4358             : {
    4359           0 :   return mParent;
    4360             : }
    4361             : 
    4362             : JSObject*
    4363           0 : SEResponse::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
    4364             : {
    4365           0 :   JS::Rooted<JSObject*> obj(aCx, SEResponseBinding::Wrap(aCx, this, aGivenProto));
    4366           0 :   if (!obj) {
    4367           0 :     return nullptr;
    4368             :   }
    4369             : 
    4370             :   // Now define it on our chrome object
    4371           0 :   JSAutoCompartment ac(aCx, mImpl->CallbackOrNull());
    4372           0 :   if (!JS_WrapObject(aCx, &obj)) {
    4373           0 :     return nullptr;
    4374             :   }
    4375           0 :   if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
    4376           0 :     return nullptr;
    4377             :   }
    4378           0 :   return obj;
    4379             : }
    4380             : 
    4381             : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
    4382             : already_AddRefed<SEChannel>
    4383           0 : SEResponse::GetChannel(ErrorResult& aRv, JSCompartment* aCompartment) const
    4384             : {
    4385           0 :   return mImpl->GetChannel(aRv, aCompartment);
    4386             : }
    4387             : 
    4388             : uint8_t
    4389           0 : SEResponse::GetSw1(ErrorResult& aRv, JSCompartment* aCompartment) const
    4390             : {
    4391           0 :   return mImpl->GetSw1(aRv, aCompartment);
    4392             : }
    4393             : 
    4394             : uint8_t
    4395           0 : SEResponse::GetSw2(ErrorResult& aRv, JSCompartment* aCompartment) const
    4396             : {
    4397           0 :   return mImpl->GetSw2(aRv, aCompartment);
    4398             : }
    4399             : 
    4400             : void
    4401           0 : SEResponse::GetData(Nullable<nsTArray<uint8_t>>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment) const
    4402             : {
    4403           0 :   return mImpl->GetData(aRetVal, aRv, aCompartment);
    4404             : }
    4405             : 
    4406             : bool
    4407           0 : SEResponse::_Create(JSContext* cx, unsigned argc, JS::Value* vp)
    4408             : {
    4409           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    4410           0 :   if (args.length() < 2) {
    4411           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SEResponse._create");
    4412             :   }
    4413           0 :   if (!args[0].isObject()) {
    4414           0 :     return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of SEResponse._create");
    4415             :   }
    4416           0 :   if (!args[1].isObject()) {
    4417           0 :     return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of SEResponse._create");
    4418             :   }
    4419             : 
    4420             :   // GlobalObject will go through wrappers as needed for us, and
    4421             :   // is simpler than the right UnwrapArg incantation.
    4422           0 :   GlobalObject global(cx, &args[0].toObject());
    4423           0 :   if (global.Failed()) {
    4424           0 :     return false;
    4425             :   }
    4426           0 :   nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports());
    4427           0 :   MOZ_ASSERT(globalHolder);
    4428           0 :   JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
    4429           0 :   RefPtr<SEResponse> impl = new SEResponse(arg, globalHolder);
    4430           0 :   MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
    4431           0 :   return GetOrCreateDOMReflector(cx, impl, args.rval());
    4432             : }
    4433             : 
    4434             : 
    4435             : already_AddRefed<Promise>
    4436           0 : SESessionJSImpl::OpenLogicalChannel(const Nullable<Uint8Array>& aid, ErrorResult& aRv, JSCompartment* aCompartment)
    4437             : {
    4438           0 :   CallSetup s(this, aRv, "SESession.openLogicalChannel", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    4439           0 :   JSContext* cx = s.GetContext();
    4440           0 :   if (!cx) {
    4441           0 :     MOZ_ASSERT(aRv.Failed());
    4442           0 :     return nullptr;
    4443             :   }
    4444           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    4445           0 :   JS::AutoValueVector argv(cx);
    4446           0 :   if (!argv.resize(1)) {
    4447           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    4448           0 :     return nullptr;
    4449             :   }
    4450           0 :   unsigned argc = 1;
    4451             : 
    4452             :   do {
    4453           0 :     if (aid.IsNull()) {
    4454           0 :       argv[0].setNull();
    4455           0 :       break;
    4456             :     }
    4457           0 :     argv[0].setObject(*aid.Value().Obj());
    4458           0 :     if (!MaybeWrapNonDOMObjectValue(cx, argv[0])) {
    4459           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    4460           0 :       return nullptr;
    4461             :     }
    4462           0 :     break;
    4463             :   } while (0);
    4464             : 
    4465           0 :   JS::Rooted<JS::Value> callable(cx);
    4466           0 :   SESessionAtoms* atomsCache = GetAtomCache<SESessionAtoms>(cx);
    4467           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    4468           0 :       !GetCallableProperty(cx, atomsCache->openLogicalChannel_id, &callable)) {
    4469           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4470           0 :     return nullptr;
    4471             :   }
    4472           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    4473           0 :   if (!JS::Call(cx, thisValue, callable,
    4474           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    4475           0 :     aRv.NoteJSContextException(cx);
    4476           0 :     return nullptr;
    4477             :   }
    4478           0 :   RefPtr<Promise> rvalDecl;
    4479             :   { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
    4480             :     // etc.
    4481             : 
    4482           0 :     JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
    4483           0 :     if (!rval.isObject()) {
    4484           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SESession.openLogicalChannel"));
    4485           0 :       return nullptr;
    4486             :     }
    4487           0 :     JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
    4488           0 :     if (!unwrappedVal) {
    4489             :       // A slight lie, but not much of one, for a dead object wrapper.
    4490           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SESession.openLogicalChannel"));
    4491           0 :       return nullptr;
    4492             :     }
    4493           0 :     globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
    4494           0 :     JSAutoCompartment ac(cx, globalObj);
    4495           0 :     GlobalObject promiseGlobal(cx, globalObj);
    4496           0 :     if (promiseGlobal.Failed()) {
    4497           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    4498           0 :       return nullptr;
    4499             :     }
    4500             : 
    4501           0 :     JS::Rooted<JS::Value> valueToResolve(cx, rval);
    4502           0 :     if (!JS_WrapValue(cx, &valueToResolve)) {
    4503           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    4504           0 :       return nullptr;
    4505             :     }
    4506           0 :     binding_detail::FastErrorResult promiseRv;
    4507             :     nsCOMPtr<nsIGlobalObject> global =
    4508           0 :       do_QueryInterface(promiseGlobal.GetAsSupports());
    4509           0 :     if (!global) {
    4510           0 :       promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
    4511           0 :       MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
    4512           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    4513           0 :       return nullptr;
    4514             :     }
    4515           0 :     rvalDecl = Promise::Resolve(global, cx, valueToResolve,
    4516           0 :                                     promiseRv);
    4517           0 :     if (promiseRv.MaybeSetPendingException(cx)) {
    4518           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    4519           0 :       return nullptr;
    4520             :     }
    4521             :   }
    4522           0 :   return rvalDecl.forget();
    4523             : }
    4524             : 
    4525             : already_AddRefed<Promise>
    4526           0 : SESessionJSImpl::CloseAll(ErrorResult& aRv, JSCompartment* aCompartment)
    4527             : {
    4528           0 :   CallSetup s(this, aRv, "SESession.closeAll", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    4529           0 :   JSContext* cx = s.GetContext();
    4530           0 :   if (!cx) {
    4531           0 :     MOZ_ASSERT(aRv.Failed());
    4532           0 :     return nullptr;
    4533             :   }
    4534           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    4535             : 
    4536           0 :   JS::Rooted<JS::Value> callable(cx);
    4537           0 :   SESessionAtoms* atomsCache = GetAtomCache<SESessionAtoms>(cx);
    4538           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    4539           0 :       !GetCallableProperty(cx, atomsCache->closeAll_id, &callable)) {
    4540           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4541           0 :     return nullptr;
    4542             :   }
    4543           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    4544           0 :   if (!JS::Call(cx, thisValue, callable,
    4545           0 :                 JS::HandleValueArray::empty(), &rval)) {
    4546           0 :     aRv.NoteJSContextException(cx);
    4547           0 :     return nullptr;
    4548             :   }
    4549           0 :   RefPtr<Promise> rvalDecl;
    4550             :   { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
    4551             :     // etc.
    4552             : 
    4553           0 :     JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
    4554           0 :     if (!rval.isObject()) {
    4555           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SESession.closeAll"));
    4556           0 :       return nullptr;
    4557             :     }
    4558           0 :     JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
    4559           0 :     if (!unwrappedVal) {
    4560             :       // A slight lie, but not much of one, for a dead object wrapper.
    4561           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of SESession.closeAll"));
    4562           0 :       return nullptr;
    4563             :     }
    4564           0 :     globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
    4565           0 :     JSAutoCompartment ac(cx, globalObj);
    4566           0 :     GlobalObject promiseGlobal(cx, globalObj);
    4567           0 :     if (promiseGlobal.Failed()) {
    4568           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    4569           0 :       return nullptr;
    4570             :     }
    4571             : 
    4572           0 :     JS::Rooted<JS::Value> valueToResolve(cx, rval);
    4573           0 :     if (!JS_WrapValue(cx, &valueToResolve)) {
    4574           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    4575           0 :       return nullptr;
    4576             :     }
    4577           0 :     binding_detail::FastErrorResult promiseRv;
    4578             :     nsCOMPtr<nsIGlobalObject> global =
    4579           0 :       do_QueryInterface(promiseGlobal.GetAsSupports());
    4580           0 :     if (!global) {
    4581           0 :       promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
    4582           0 :       MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
    4583           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    4584           0 :       return nullptr;
    4585             :     }
    4586           0 :     rvalDecl = Promise::Resolve(global, cx, valueToResolve,
    4587           0 :                                     promiseRv);
    4588           0 :     if (promiseRv.MaybeSetPendingException(cx)) {
    4589           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    4590           0 :       return nullptr;
    4591             :     }
    4592             :   }
    4593           0 :   return rvalDecl.forget();
    4594             : }
    4595             : 
    4596             : bool
    4597           0 : SESessionJSImpl::InitIds(JSContext* cx, SESessionAtoms* atomsCache)
    4598             : {
    4599           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
    4600             : 
    4601             :   // Initialize these in reverse order so that any failure leaves the first one
    4602             :   // uninitialized.
    4603           0 :   if (!atomsCache->closeAll_id.init(cx, "closeAll") ||
    4604           0 :       !atomsCache->openLogicalChannel_id.init(cx, "openLogicalChannel") ||
    4605           0 :       !atomsCache->isClosed_id.init(cx, "isClosed") ||
    4606           0 :       !atomsCache->reader_id.init(cx, "reader")) {
    4607           0 :     return false;
    4608             :   }
    4609           0 :   return true;
    4610             : }
    4611             : 
    4612             : 
    4613             : already_AddRefed<SEReader>
    4614           0 : SESessionJSImpl::GetReader(ErrorResult& aRv, JSCompartment* aCompartment)
    4615             : {
    4616           0 :   CallSetup s(this, aRv, "SESession.reader", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    4617           0 :   JSContext* cx = s.GetContext();
    4618           0 :   if (!cx) {
    4619           0 :     MOZ_ASSERT(aRv.Failed());
    4620           0 :     return nullptr;
    4621             :   }
    4622           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    4623             : 
    4624           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    4625           0 :   SESessionAtoms* atomsCache = GetAtomCache<SESessionAtoms>(cx);
    4626           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    4627           0 :       !JS_GetPropertyById(cx, callback, atomsCache->reader_id, &rval)) {
    4628           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4629           0 :     return nullptr;
    4630             :   }
    4631           0 :   RefPtr<mozilla::dom::SEReader> rvalDecl;
    4632           0 :   if (rval.isObject()) {
    4633             :     static_assert(IsRefcounted<mozilla::dom::SEReader>::value, "We can only store refcounted classes.");{
    4634           0 :       nsresult rv = UnwrapObject<prototypes::id::SEReader, mozilla::dom::SEReader>(rval, rvalDecl);
    4635           0 :       if (NS_FAILED(rv)) {
    4636             :         // Be careful to not wrap random DOM objects here, even if
    4637             :         // they're wrapped in opaque security wrappers for some reason.
    4638             :         // XXXbz Wish we could check for a JS-implemented object
    4639             :         // that already has a content reflection...
    4640           0 :         if (!IsDOMObject(js::UncheckedUnwrap(&rval.toObject()))) {
    4641           0 :           nsCOMPtr<nsIGlobalObject> contentGlobal;
    4642           0 :           JS::Handle<JSObject*> callback = CallbackOrNull();
    4643           0 :           if (!callback ||
    4644           0 :               !GetContentGlobalForJSImplementedObject(cx, callback, getter_AddRefs(contentGlobal))) {
    4645           0 :             aRv.Throw(NS_ERROR_UNEXPECTED);
    4646           0 :             return nullptr;
    4647             :           }
    4648           0 :           JS::Rooted<JSObject*> jsImplSourceObj(cx, &rval.toObject());
    4649           0 :           rvalDecl = new mozilla::dom::SEReader(jsImplSourceObj, contentGlobal);
    4650             :         } else {
    4651           0 :           ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Return value of SESession.reader", "SEReader");
    4652           0 :           aRv.Throw(NS_ERROR_UNEXPECTED);
    4653           0 :           return nullptr;
    4654             :         }
    4655             :       }
    4656             :     }
    4657             :   } else {
    4658           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of SESession.reader");
    4659           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4660           0 :     return nullptr;
    4661             :   }
    4662           0 :   return rvalDecl.forget();
    4663             : }
    4664             : 
    4665             : bool
    4666           0 : SESessionJSImpl::GetIsClosed(ErrorResult& aRv, JSCompartment* aCompartment)
    4667             : {
    4668           0 :   CallSetup s(this, aRv, "SESession.isClosed", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    4669           0 :   JSContext* cx = s.GetContext();
    4670           0 :   if (!cx) {
    4671           0 :     MOZ_ASSERT(aRv.Failed());
    4672           0 :     return bool(0);
    4673             :   }
    4674           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    4675             : 
    4676           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    4677           0 :   SESessionAtoms* atomsCache = GetAtomCache<SESessionAtoms>(cx);
    4678           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    4679           0 :       !JS_GetPropertyById(cx, callback, atomsCache->isClosed_id, &rval)) {
    4680           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4681           0 :     return bool(0);
    4682             :   }
    4683             :   bool rvalDecl;
    4684           0 :   if (!ValueToPrimitive<bool, eDefault>(cx, rval, &rvalDecl)) {
    4685           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4686           0 :     return bool(0);
    4687             :   }
    4688           0 :   return rvalDecl;
    4689             : }
    4690             : 
    4691             : 
    4692             : NS_IMPL_CYCLE_COLLECTION_CLASS(SESession)
    4693           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(SESession)
    4694           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mImpl)
    4695           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
    4696           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
    4697           0 :   tmp->ClearWeakReferences();
    4698           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
    4699           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(SESession)
    4700           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImpl)
    4701           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
    4702           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
    4703           0 : NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(SESession)
    4704           0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(SESession)
    4705           0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(SESession)
    4706           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SESession)
    4707           0 :   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
    4708           0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
    4709           0 :   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
    4710           0 : NS_INTERFACE_MAP_END
    4711             : 
    4712           0 : SESession::SESession(JS::Handle<JSObject*> aJSImplObject, nsIGlobalObject* aParent)
    4713           0 :   : mImpl(new SESessionJSImpl(nullptr, aJSImplObject, /* aIncumbentGlobal = */ nullptr)),
    4714           0 :     mParent(aParent)
    4715             : {
    4716           0 : }
    4717             : 
    4718             : 
    4719           0 : SESession::~SESession()
    4720             : {
    4721           0 : }
    4722             : 
    4723             : nsISupports*
    4724           0 : SESession::GetParentObject() const
    4725             : {
    4726           0 :   return mParent;
    4727             : }
    4728             : 
    4729             : JSObject*
    4730           0 : SESession::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
    4731             : {
    4732           0 :   JS::Rooted<JSObject*> obj(aCx, SESessionBinding::Wrap(aCx, this, aGivenProto));
    4733           0 :   if (!obj) {
    4734           0 :     return nullptr;
    4735             :   }
    4736             : 
    4737             :   // Now define it on our chrome object
    4738           0 :   JSAutoCompartment ac(aCx, mImpl->CallbackOrNull());
    4739           0 :   if (!JS_WrapObject(aCx, &obj)) {
    4740           0 :     return nullptr;
    4741             :   }
    4742           0 :   if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
    4743           0 :     return nullptr;
    4744             :   }
    4745           0 :   return obj;
    4746             : }
    4747             : 
    4748             : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
    4749             : already_AddRefed<SEReader>
    4750           0 : SESession::GetReader(ErrorResult& aRv, JSCompartment* aCompartment) const
    4751             : {
    4752           0 :   return mImpl->GetReader(aRv, aCompartment);
    4753             : }
    4754             : 
    4755             : bool
    4756           0 : SESession::GetIsClosed(ErrorResult& aRv, JSCompartment* aCompartment) const
    4757             : {
    4758           0 :   return mImpl->GetIsClosed(aRv, aCompartment);
    4759             : }
    4760             : 
    4761             : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
    4762             : already_AddRefed<Promise>
    4763           0 : SESession::OpenLogicalChannel(const Nullable<Uint8Array>& aid, ErrorResult& aRv, JSCompartment* aCompartment)
    4764             : {
    4765           0 :   return mImpl->OpenLogicalChannel(aid, aRv, aCompartment);
    4766             : }
    4767             : 
    4768             : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
    4769             : already_AddRefed<Promise>
    4770           0 : SESession::CloseAll(ErrorResult& aRv, JSCompartment* aCompartment)
    4771             : {
    4772           0 :   return mImpl->CloseAll(aRv, aCompartment);
    4773             : }
    4774             : 
    4775             : bool
    4776           0 : SESession::_Create(JSContext* cx, unsigned argc, JS::Value* vp)
    4777             : {
    4778           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    4779           0 :   if (args.length() < 2) {
    4780           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SESession._create");
    4781             :   }
    4782           0 :   if (!args[0].isObject()) {
    4783           0 :     return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of SESession._create");
    4784             :   }
    4785           0 :   if (!args[1].isObject()) {
    4786           0 :     return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of SESession._create");
    4787             :   }
    4788             : 
    4789             :   // GlobalObject will go through wrappers as needed for us, and
    4790             :   // is simpler than the right UnwrapArg incantation.
    4791           0 :   GlobalObject global(cx, &args[0].toObject());
    4792           0 :   if (global.Failed()) {
    4793           0 :     return false;
    4794             :   }
    4795           0 :   nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports());
    4796           0 :   MOZ_ASSERT(globalHolder);
    4797           0 :   JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
    4798           0 :   RefPtr<SESession> impl = new SESession(arg, globalHolder);
    4799           0 :   MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
    4800           0 :   return GetOrCreateDOMReflector(cx, impl, args.rval());
    4801             : }
    4802             : 
    4803             : 
    4804             : } // namespace dom
    4805             : } // namespace mozilla

Generated by: LCOV version 1.13