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

          Line data    Source code
       1             : /* THIS FILE IS AUTOGENERATED FROM PaymentRequest.webidl BY Codegen.py - DO NOT EDIT */
       2             : 
       3             : #include "AtomList.h"
       4             : #include "EventHandlerBinding.h"
       5             : #include "EventTargetBinding.h"
       6             : #include "PaymentRequestBinding.h"
       7             : #include "WrapperFactory.h"
       8             : #include "jsapi.h"
       9             : #include "mozilla/OwningNonNull.h"
      10             : #include "mozilla/dom/BindingUtils.h"
      11             : #include "mozilla/dom/DOMJSClass.h"
      12             : #include "mozilla/dom/NonRefcountedDOMObject.h"
      13             : #include "mozilla/dom/Nullable.h"
      14             : #include "mozilla/dom/PaymentAddress.h"
      15             : #include "mozilla/dom/PaymentRequest.h"
      16             : #include "mozilla/dom/PrimitiveConversions.h"
      17             : #include "mozilla/dom/Promise.h"
      18             : #include "mozilla/dom/ScriptSettings.h"
      19             : #include "mozilla/dom/SimpleGlobalObject.h"
      20             : #include "mozilla/dom/ToJSValue.h"
      21             : #include "mozilla/dom/XrayExpandoClass.h"
      22             : 
      23             : namespace mozilla {
      24             : namespace dom {
      25             : 
      26             : namespace PaymentShippingTypeValues {
      27             : extern const EnumEntry strings[4] = {
      28             :   {"shipping", 8},
      29             :   {"delivery", 8},
      30             :   {"pickup", 6},
      31             :   { nullptr, 0 }
      32             : };
      33             : } // namespace PaymentShippingTypeValues
      34             : 
      35             : bool
      36           0 : ToJSValue(JSContext* aCx, PaymentShippingType aArgument, JS::MutableHandle<JS::Value> aValue)
      37             : {
      38           0 :   MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(PaymentShippingTypeValues::strings));
      39             :   JSString* resultStr =
      40           0 :     JS_NewStringCopyN(aCx, PaymentShippingTypeValues::strings[uint32_t(aArgument)].value,
      41           0 :                       PaymentShippingTypeValues::strings[uint32_t(aArgument)].length);
      42           0 :   if (!resultStr) {
      43           0 :     return false;
      44             :   }
      45           0 :   aValue.setString(resultStr);
      46           0 :   return true;
      47             : }
      48             : 
      49             : 
      50             : 
      51           0 : PaymentCurrencyAmount::PaymentCurrencyAmount()
      52             : {
      53             :   // Safe to pass a null context if we pass a null value
      54           0 :   Init(nullptr, JS::NullHandleValue);
      55           0 : }
      56             : 
      57             : 
      58             : 
      59             : bool
      60           0 : PaymentCurrencyAmount::InitIds(JSContext* cx, PaymentCurrencyAmountAtoms* atomsCache)
      61             : {
      62           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
      63             : 
      64             :   // Initialize these in reverse order so that any failure leaves the first one
      65             :   // uninitialized.
      66           0 :   if (!atomsCache->value_id.init(cx, "value") ||
      67           0 :       !atomsCache->currencySystem_id.init(cx, "currencySystem") ||
      68           0 :       !atomsCache->currency_id.init(cx, "currency")) {
      69           0 :     return false;
      70             :   }
      71           0 :   return true;
      72             : }
      73             : 
      74             : bool
      75           0 : PaymentCurrencyAmount::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
      76             : {
      77             :   // Passing a null JSContext is OK only if we're initing from null,
      78             :   // Since in that case we will not have to do any property gets
      79             :   // Also evaluate isNullOrUndefined in order to avoid false-positive
      80             :   // checkers by static analysis tools
      81           0 :   MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
      82           0 :   PaymentCurrencyAmountAtoms* atomsCache = nullptr;
      83           0 :   if (cx) {
      84           0 :     atomsCache = GetAtomCache<PaymentCurrencyAmountAtoms>(cx);
      85           0 :     if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
      86           0 :       return false;
      87             :     }
      88             :   }
      89             : 
      90           0 :   if (!IsConvertibleToDictionary(val)) {
      91           0 :     return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
      92             :   }
      93             : 
      94           0 :   bool isNull = val.isNullOrUndefined();
      95             :   // We only need these if !isNull, in which case we have |cx|.
      96           0 :   Maybe<JS::Rooted<JSObject *> > object;
      97           0 :   Maybe<JS::Rooted<JS::Value> > temp;
      98           0 :   if (!isNull) {
      99           0 :     MOZ_ASSERT(cx);
     100           0 :     object.emplace(cx, &val.toObject());
     101           0 :     temp.emplace(cx);
     102             :   }
     103           0 :   if (!isNull) {
     104           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->currency_id, temp.ptr())) {
     105           0 :       return false;
     106             :     }
     107             :   }
     108           0 :   if (!isNull && !temp->isUndefined()) {
     109           0 :     if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mCurrency)) {
     110           0 :       return false;
     111             :     }
     112           0 :     mIsAnyMemberPresent = true;
     113           0 :   } else if (cx) {
     114             :     // Don't error out if we have no cx.  In that
     115             :     // situation the caller is default-constructing us and we'll
     116             :     // just assume they know what they're doing.
     117           0 :     return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
     118           0 :                              "'currency' member of PaymentCurrencyAmount");
     119             :   }
     120             : 
     121           0 :   if (!isNull) {
     122           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->currencySystem_id, temp.ptr())) {
     123           0 :       return false;
     124             :     }
     125             :   }
     126           0 :   if (!isNull && !temp->isUndefined()) {
     127           0 :     if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mCurrencySystem)) {
     128           0 :       return false;
     129             :     }
     130             :   } else {
     131             :     static const char16_t data[] = { 'u', 'r', 'n', ':', 'i', 's', 'o', ':', 's', 't', 'd', ':', 'i', 's', 'o', ':', '4', '2', '1', '7', 0 };
     132           0 :     mCurrencySystem.Rebind(data, ArrayLength(data) - 1);
     133             :   }
     134           0 :   mIsAnyMemberPresent = true;
     135             : 
     136           0 :   if (!isNull) {
     137           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->value_id, temp.ptr())) {
     138           0 :       return false;
     139             :     }
     140             :   }
     141           0 :   if (!isNull && !temp->isUndefined()) {
     142           0 :     if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mValue)) {
     143           0 :       return false;
     144             :     }
     145           0 :     mIsAnyMemberPresent = true;
     146           0 :   } else if (cx) {
     147             :     // Don't error out if we have no cx.  In that
     148             :     // situation the caller is default-constructing us and we'll
     149             :     // just assume they know what they're doing.
     150           0 :     return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
     151           0 :                              "'value' member of PaymentCurrencyAmount");
     152             :   }
     153           0 :   return true;
     154             : }
     155             : 
     156             : bool
     157           0 : PaymentCurrencyAmount::Init(const nsAString& aJSON)
     158             : {
     159           0 :   AutoJSAPI jsapi;
     160           0 :   JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
     161           0 :   if (!cleanGlobal) {
     162           0 :     return false;
     163             :   }
     164           0 :   if (!jsapi.Init(cleanGlobal)) {
     165           0 :     return false;
     166             :   }
     167           0 :   JSContext* cx = jsapi.cx();
     168           0 :   JS::Rooted<JS::Value> json(cx);
     169           0 :   bool ok = ParseJSON(cx, aJSON, &json);
     170           0 :   NS_ENSURE_TRUE(ok, false);
     171           0 :   return Init(cx, json);
     172             : }
     173             : 
     174             : bool
     175           0 : PaymentCurrencyAmount::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
     176             : {
     177           0 :   PaymentCurrencyAmountAtoms* atomsCache = GetAtomCache<PaymentCurrencyAmountAtoms>(cx);
     178           0 :   if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     179           0 :     return false;
     180             :   }
     181             : 
     182           0 :   JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
     183           0 :   if (!obj) {
     184           0 :     return false;
     185             :   }
     186           0 :   rval.set(JS::ObjectValue(*obj));
     187             : 
     188             :   do {
     189             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     190           0 :     JS::Rooted<JS::Value> temp(cx);
     191           0 :     nsString const & currentValue = mCurrency;
     192           0 :     if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
     193           0 :       return false;
     194             :     }
     195           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->currency_id, temp, JSPROP_ENUMERATE)) {
     196           0 :       return false;
     197             :     }
     198           0 :     break;
     199             :   } while(0);
     200             : 
     201             :   do {
     202             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     203           0 :     JS::Rooted<JS::Value> temp(cx);
     204           0 :     nsString const & currentValue = mCurrencySystem;
     205           0 :     if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
     206           0 :       return false;
     207             :     }
     208           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->currencySystem_id, temp, JSPROP_ENUMERATE)) {
     209           0 :       return false;
     210             :     }
     211           0 :     break;
     212             :   } while(0);
     213             : 
     214             :   do {
     215             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     216           0 :     JS::Rooted<JS::Value> temp(cx);
     217           0 :     nsString const & currentValue = mValue;
     218           0 :     if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
     219           0 :       return false;
     220             :     }
     221           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->value_id, temp, JSPROP_ENUMERATE)) {
     222           0 :       return false;
     223             :     }
     224           0 :     break;
     225             :   } while(0);
     226             : 
     227           0 :   return true;
     228             : }
     229             : 
     230             : bool
     231           0 : PaymentCurrencyAmount::ToJSON(nsAString& aJSON) const
     232             : {
     233           0 :   AutoJSAPI jsapi;
     234           0 :   jsapi.Init();
     235           0 :   JSContext *cx = jsapi.cx();
     236             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
     237             :   // because we'll only be creating objects, in ways that have no
     238             :   // side-effects, followed by a call to JS::ToJSONMaybeSafely,
     239             :   // which likewise guarantees no side-effects for the sorts of
     240             :   // things we will pass it.
     241           0 :   JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
     242           0 :   JS::Rooted<JS::Value> val(cx);
     243           0 :   if (!ToObjectInternal(cx, &val)) {
     244           0 :     return false;
     245             :   }
     246           0 :   JS::Rooted<JSObject*> obj(cx, &val.toObject());
     247           0 :   return StringifyToJSON(cx, obj, aJSON);
     248             : }
     249             : 
     250             : void
     251           0 : PaymentCurrencyAmount::TraceDictionary(JSTracer* trc)
     252             : {
     253           0 : }
     254             : 
     255             : PaymentCurrencyAmount&
     256           0 : PaymentCurrencyAmount::operator=(const PaymentCurrencyAmount& aOther)
     257             : {
     258           0 :   mCurrency = aOther.mCurrency;
     259           0 :   mCurrencySystem = aOther.mCurrencySystem;
     260           0 :   mValue = aOther.mValue;
     261           0 :   return *this;
     262             : }
     263             : 
     264             : namespace binding_detail {
     265             : } // namespace binding_detail
     266             : 
     267             : 
     268             : 
     269           0 : PaymentMethodData::PaymentMethodData()
     270             : {
     271             :   // Safe to pass a null context if we pass a null value
     272           0 :   Init(nullptr, JS::NullHandleValue);
     273           0 : }
     274             : 
     275             : 
     276             : bool
     277           0 : PaymentMethodData::InitIds(JSContext* cx, PaymentMethodDataAtoms* atomsCache)
     278             : {
     279           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
     280             : 
     281             :   // Initialize these in reverse order so that any failure leaves the first one
     282             :   // uninitialized.
     283           0 :   if (!atomsCache->supportedMethods_id.init(cx, "supportedMethods") ||
     284           0 :       !atomsCache->data_id.init(cx, "data")) {
     285           0 :     return false;
     286             :   }
     287           0 :   return true;
     288             : }
     289             : 
     290             : bool
     291           0 : PaymentMethodData::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
     292             : {
     293             :   // Passing a null JSContext is OK only if we're initing from null,
     294             :   // Since in that case we will not have to do any property gets
     295             :   // Also evaluate isNullOrUndefined in order to avoid false-positive
     296             :   // checkers by static analysis tools
     297           0 :   MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
     298           0 :   PaymentMethodDataAtoms* atomsCache = nullptr;
     299           0 :   if (cx) {
     300           0 :     atomsCache = GetAtomCache<PaymentMethodDataAtoms>(cx);
     301           0 :     if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     302           0 :       return false;
     303             :     }
     304             :   }
     305             : 
     306           0 :   if (!IsConvertibleToDictionary(val)) {
     307           0 :     return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
     308             :   }
     309             : 
     310           0 :   bool isNull = val.isNullOrUndefined();
     311             :   // We only need these if !isNull, in which case we have |cx|.
     312           0 :   Maybe<JS::Rooted<JSObject *> > object;
     313           0 :   Maybe<JS::Rooted<JS::Value> > temp;
     314           0 :   if (!isNull) {
     315           0 :     MOZ_ASSERT(cx);
     316           0 :     object.emplace(cx, &val.toObject());
     317           0 :     temp.emplace(cx);
     318             :   }
     319           0 :   if (!isNull) {
     320           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->data_id, temp.ptr())) {
     321           0 :       return false;
     322             :     }
     323             :   }
     324           0 :   if (!isNull && !temp->isUndefined()) {
     325           0 :     mData.Construct();
     326           0 :     if (temp.ref().isObject()) {
     327             : #ifdef __clang__
     328             : #pragma clang diagnostic push
     329             : #pragma clang diagnostic ignored "-Wunreachable-code"
     330             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
     331             : #endif // __clang__
     332           0 :       if ((passedToJSImpl) && !CallerSubsumes(temp.ref())) {
     333           0 :         ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "'data' member of PaymentMethodData");
     334           0 :         return false;
     335             :       }
     336             : #ifdef __clang__
     337             : #pragma clang diagnostic pop
     338             : #endif // __clang__
     339           0 :       (mData.Value()) = &temp.ref().toObject();
     340             :     } else {
     341           0 :       ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'data' member of PaymentMethodData");
     342           0 :       return false;
     343             :     }
     344           0 :     mIsAnyMemberPresent = true;
     345             :   }
     346             : 
     347           0 :   if (!isNull) {
     348           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->supportedMethods_id, temp.ptr())) {
     349           0 :       return false;
     350             :     }
     351             :   }
     352           0 :   if (!isNull && !temp->isUndefined()) {
     353           0 :     if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mSupportedMethods)) {
     354           0 :       return false;
     355             :     }
     356           0 :     mIsAnyMemberPresent = true;
     357           0 :   } else if (cx) {
     358             :     // Don't error out if we have no cx.  In that
     359             :     // situation the caller is default-constructing us and we'll
     360             :     // just assume they know what they're doing.
     361           0 :     return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
     362           0 :                              "'supportedMethods' member of PaymentMethodData");
     363             :   }
     364           0 :   return true;
     365             : }
     366             : 
     367             : bool
     368           0 : PaymentMethodData::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
     369             : {
     370           0 :   PaymentMethodDataAtoms* atomsCache = GetAtomCache<PaymentMethodDataAtoms>(cx);
     371           0 :   if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     372           0 :     return false;
     373             :   }
     374             : 
     375           0 :   JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
     376           0 :   if (!obj) {
     377           0 :     return false;
     378             :   }
     379           0 :   rval.set(JS::ObjectValue(*obj));
     380             : 
     381           0 :   if (mData.WasPassed()) {
     382             :     do {
     383             :       // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     384           0 :       JS::Rooted<JS::Value> temp(cx);
     385           0 :       JSObject* const & currentValue = mData.InternalValue();
     386           0 :       JS::ExposeObjectToActiveJS(currentValue);
     387           0 :       temp.setObject(*currentValue);
     388           0 :       if (!MaybeWrapObjectValue(cx, &temp)) {
     389           0 :         return false;
     390             :       }
     391           0 :       if (!JS_DefinePropertyById(cx, obj, atomsCache->data_id, temp, JSPROP_ENUMERATE)) {
     392           0 :         return false;
     393             :       }
     394           0 :       break;
     395             :     } while(0);
     396             :   }
     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 :     nsString const & currentValue = mSupportedMethods;
     402           0 :     if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
     403           0 :       return false;
     404             :     }
     405           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->supportedMethods_id, temp, JSPROP_ENUMERATE)) {
     406           0 :       return false;
     407             :     }
     408           0 :     break;
     409             :   } while(0);
     410             : 
     411           0 :   return true;
     412             : }
     413             : 
     414             : void
     415           0 : PaymentMethodData::TraceDictionary(JSTracer* trc)
     416             : {
     417           0 :   if (mData.WasPassed()) {
     418           0 :     JS::UnsafeTraceRoot(trc, &mData.Value(), "PaymentMethodData.mData");
     419             :   }
     420           0 : }
     421             : 
     422             : namespace binding_detail {
     423             : } // namespace binding_detail
     424             : 
     425             : 
     426             : 
     427           0 : PaymentOptions::PaymentOptions()
     428             : {
     429             :   // Safe to pass a null context if we pass a null value
     430           0 :   Init(nullptr, JS::NullHandleValue);
     431           0 : }
     432             : 
     433             : 
     434             : 
     435             : bool
     436           0 : PaymentOptions::InitIds(JSContext* cx, PaymentOptionsAtoms* atomsCache)
     437             : {
     438           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
     439             : 
     440             :   // Initialize these in reverse order so that any failure leaves the first one
     441             :   // uninitialized.
     442           0 :   if (!atomsCache->shippingType_id.init(cx, "shippingType") ||
     443           0 :       !atomsCache->requestShipping_id.init(cx, "requestShipping") ||
     444           0 :       !atomsCache->requestPayerPhone_id.init(cx, "requestPayerPhone") ||
     445           0 :       !atomsCache->requestPayerName_id.init(cx, "requestPayerName") ||
     446           0 :       !atomsCache->requestPayerEmail_id.init(cx, "requestPayerEmail")) {
     447           0 :     return false;
     448             :   }
     449           0 :   return true;
     450             : }
     451             : 
     452             : bool
     453           0 : PaymentOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
     454             : {
     455             :   // Passing a null JSContext is OK only if we're initing from null,
     456             :   // Since in that case we will not have to do any property gets
     457             :   // Also evaluate isNullOrUndefined in order to avoid false-positive
     458             :   // checkers by static analysis tools
     459           0 :   MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
     460           0 :   PaymentOptionsAtoms* atomsCache = nullptr;
     461           0 :   if (cx) {
     462           0 :     atomsCache = GetAtomCache<PaymentOptionsAtoms>(cx);
     463           0 :     if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     464           0 :       return false;
     465             :     }
     466             :   }
     467             : 
     468           0 :   if (!IsConvertibleToDictionary(val)) {
     469           0 :     return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
     470             :   }
     471             : 
     472           0 :   bool isNull = val.isNullOrUndefined();
     473             :   // We only need these if !isNull, in which case we have |cx|.
     474           0 :   Maybe<JS::Rooted<JSObject *> > object;
     475           0 :   Maybe<JS::Rooted<JS::Value> > temp;
     476           0 :   if (!isNull) {
     477           0 :     MOZ_ASSERT(cx);
     478           0 :     object.emplace(cx, &val.toObject());
     479           0 :     temp.emplace(cx);
     480             :   }
     481           0 :   if (!isNull) {
     482           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->requestPayerEmail_id, temp.ptr())) {
     483           0 :       return false;
     484             :     }
     485             :   }
     486           0 :   if (!isNull && !temp->isUndefined()) {
     487           0 :     if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mRequestPayerEmail)) {
     488           0 :       return false;
     489             :     }
     490             :   } else {
     491           0 :     mRequestPayerEmail = false;
     492             :   }
     493           0 :   mIsAnyMemberPresent = true;
     494             : 
     495           0 :   if (!isNull) {
     496           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->requestPayerName_id, temp.ptr())) {
     497           0 :       return false;
     498             :     }
     499             :   }
     500           0 :   if (!isNull && !temp->isUndefined()) {
     501           0 :     if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mRequestPayerName)) {
     502           0 :       return false;
     503             :     }
     504             :   } else {
     505           0 :     mRequestPayerName = false;
     506             :   }
     507           0 :   mIsAnyMemberPresent = true;
     508             : 
     509           0 :   if (!isNull) {
     510           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->requestPayerPhone_id, temp.ptr())) {
     511           0 :       return false;
     512             :     }
     513             :   }
     514           0 :   if (!isNull && !temp->isUndefined()) {
     515           0 :     if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mRequestPayerPhone)) {
     516           0 :       return false;
     517             :     }
     518             :   } else {
     519           0 :     mRequestPayerPhone = false;
     520             :   }
     521           0 :   mIsAnyMemberPresent = true;
     522             : 
     523           0 :   if (!isNull) {
     524           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->requestShipping_id, temp.ptr())) {
     525           0 :       return false;
     526             :     }
     527             :   }
     528           0 :   if (!isNull && !temp->isUndefined()) {
     529           0 :     if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mRequestShipping)) {
     530           0 :       return false;
     531             :     }
     532             :   } else {
     533           0 :     mRequestShipping = false;
     534             :   }
     535           0 :   mIsAnyMemberPresent = true;
     536             : 
     537           0 :   if (!isNull) {
     538           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->shippingType_id, temp.ptr())) {
     539           0 :       return false;
     540             :     }
     541             :   }
     542           0 :   if (!isNull && !temp->isUndefined()) {
     543             :     {
     544             :       int index;
     545           0 :       if (!FindEnumStringIndex<true>(cx, temp.ref(), PaymentShippingTypeValues::strings, "PaymentShippingType", "'shippingType' member of PaymentOptions", &index)) {
     546           0 :         return false;
     547             :       }
     548           0 :       MOZ_ASSERT(index >= 0);
     549           0 :       mShippingType = static_cast<PaymentShippingType>(index);
     550             :     }
     551             :   } else {
     552           0 :     mShippingType = PaymentShippingType::Shipping;
     553             :   }
     554           0 :   mIsAnyMemberPresent = true;
     555           0 :   return true;
     556             : }
     557             : 
     558             : bool
     559           0 : PaymentOptions::Init(const nsAString& aJSON)
     560             : {
     561           0 :   AutoJSAPI jsapi;
     562           0 :   JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
     563           0 :   if (!cleanGlobal) {
     564           0 :     return false;
     565             :   }
     566           0 :   if (!jsapi.Init(cleanGlobal)) {
     567           0 :     return false;
     568             :   }
     569           0 :   JSContext* cx = jsapi.cx();
     570           0 :   JS::Rooted<JS::Value> json(cx);
     571           0 :   bool ok = ParseJSON(cx, aJSON, &json);
     572           0 :   NS_ENSURE_TRUE(ok, false);
     573           0 :   return Init(cx, json);
     574             : }
     575             : 
     576             : bool
     577           0 : PaymentOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
     578             : {
     579           0 :   PaymentOptionsAtoms* atomsCache = GetAtomCache<PaymentOptionsAtoms>(cx);
     580           0 :   if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     581           0 :     return false;
     582             :   }
     583             : 
     584           0 :   JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
     585           0 :   if (!obj) {
     586           0 :     return false;
     587             :   }
     588           0 :   rval.set(JS::ObjectValue(*obj));
     589             : 
     590             :   do {
     591             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     592           0 :     JS::Rooted<JS::Value> temp(cx);
     593           0 :     bool const & currentValue = mRequestPayerEmail;
     594           0 :     temp.setBoolean(currentValue);
     595           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->requestPayerEmail_id, temp, JSPROP_ENUMERATE)) {
     596           0 :       return false;
     597             :     }
     598           0 :     break;
     599             :   } while(0);
     600             : 
     601             :   do {
     602             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     603           0 :     JS::Rooted<JS::Value> temp(cx);
     604           0 :     bool const & currentValue = mRequestPayerName;
     605           0 :     temp.setBoolean(currentValue);
     606           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->requestPayerName_id, temp, JSPROP_ENUMERATE)) {
     607           0 :       return false;
     608             :     }
     609           0 :     break;
     610             :   } while(0);
     611             : 
     612             :   do {
     613             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     614           0 :     JS::Rooted<JS::Value> temp(cx);
     615           0 :     bool const & currentValue = mRequestPayerPhone;
     616           0 :     temp.setBoolean(currentValue);
     617           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->requestPayerPhone_id, temp, JSPROP_ENUMERATE)) {
     618           0 :       return false;
     619             :     }
     620           0 :     break;
     621             :   } while(0);
     622             : 
     623             :   do {
     624             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     625           0 :     JS::Rooted<JS::Value> temp(cx);
     626           0 :     bool const & currentValue = mRequestShipping;
     627           0 :     temp.setBoolean(currentValue);
     628           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->requestShipping_id, temp, JSPROP_ENUMERATE)) {
     629           0 :       return false;
     630             :     }
     631           0 :     break;
     632             :   } while(0);
     633             : 
     634             :   do {
     635             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     636           0 :     JS::Rooted<JS::Value> temp(cx);
     637           0 :     PaymentShippingType const & currentValue = mShippingType;
     638           0 :     if (!ToJSValue(cx, currentValue, &temp)) {
     639           0 :       return false;
     640             :     }
     641           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->shippingType_id, temp, JSPROP_ENUMERATE)) {
     642           0 :       return false;
     643             :     }
     644           0 :     break;
     645             :   } while(0);
     646             : 
     647           0 :   return true;
     648             : }
     649             : 
     650             : bool
     651           0 : PaymentOptions::ToJSON(nsAString& aJSON) const
     652             : {
     653           0 :   AutoJSAPI jsapi;
     654           0 :   jsapi.Init();
     655           0 :   JSContext *cx = jsapi.cx();
     656             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
     657             :   // because we'll only be creating objects, in ways that have no
     658             :   // side-effects, followed by a call to JS::ToJSONMaybeSafely,
     659             :   // which likewise guarantees no side-effects for the sorts of
     660             :   // things we will pass it.
     661           0 :   JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
     662           0 :   JS::Rooted<JS::Value> val(cx);
     663           0 :   if (!ToObjectInternal(cx, &val)) {
     664           0 :     return false;
     665             :   }
     666           0 :   JS::Rooted<JSObject*> obj(cx, &val.toObject());
     667           0 :   return StringifyToJSON(cx, obj, aJSON);
     668             : }
     669             : 
     670             : void
     671           0 : PaymentOptions::TraceDictionary(JSTracer* trc)
     672             : {
     673           0 : }
     674             : 
     675             : PaymentOptions&
     676           0 : PaymentOptions::operator=(const PaymentOptions& aOther)
     677             : {
     678           0 :   mRequestPayerEmail = aOther.mRequestPayerEmail;
     679           0 :   mRequestPayerName = aOther.mRequestPayerName;
     680           0 :   mRequestPayerPhone = aOther.mRequestPayerPhone;
     681           0 :   mRequestShipping = aOther.mRequestShipping;
     682           0 :   mShippingType = aOther.mShippingType;
     683           0 :   return *this;
     684             : }
     685             : 
     686             : namespace binding_detail {
     687             : } // namespace binding_detail
     688             : 
     689             : 
     690             : 
     691           0 : PaymentItem::PaymentItem()
     692           0 :   : mAmount(FastDictionaryInitializer())
     693             : {
     694             :   // Safe to pass a null context if we pass a null value
     695           0 :   Init(nullptr, JS::NullHandleValue);
     696           0 : }
     697             : 
     698             : 
     699             : 
     700             : bool
     701           0 : PaymentItem::InitIds(JSContext* cx, PaymentItemAtoms* atomsCache)
     702             : {
     703           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
     704             : 
     705             :   // Initialize these in reverse order so that any failure leaves the first one
     706             :   // uninitialized.
     707           0 :   if (!atomsCache->pending_id.init(cx, "pending") ||
     708           0 :       !atomsCache->label_id.init(cx, "label") ||
     709           0 :       !atomsCache->amount_id.init(cx, "amount")) {
     710           0 :     return false;
     711             :   }
     712           0 :   return true;
     713             : }
     714             : 
     715             : bool
     716           0 : PaymentItem::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
     717             : {
     718             :   // Passing a null JSContext is OK only if we're initing from null,
     719             :   // Since in that case we will not have to do any property gets
     720             :   // Also evaluate isNullOrUndefined in order to avoid false-positive
     721             :   // checkers by static analysis tools
     722           0 :   MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
     723           0 :   PaymentItemAtoms* atomsCache = nullptr;
     724           0 :   if (cx) {
     725           0 :     atomsCache = GetAtomCache<PaymentItemAtoms>(cx);
     726           0 :     if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     727           0 :       return false;
     728             :     }
     729             :   }
     730             : 
     731           0 :   if (!IsConvertibleToDictionary(val)) {
     732           0 :     return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
     733             :   }
     734             : 
     735           0 :   bool isNull = val.isNullOrUndefined();
     736             :   // We only need these if !isNull, in which case we have |cx|.
     737           0 :   Maybe<JS::Rooted<JSObject *> > object;
     738           0 :   Maybe<JS::Rooted<JS::Value> > temp;
     739           0 :   if (!isNull) {
     740           0 :     MOZ_ASSERT(cx);
     741           0 :     object.emplace(cx, &val.toObject());
     742           0 :     temp.emplace(cx);
     743             :   }
     744           0 :   if (!isNull) {
     745           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->amount_id, temp.ptr())) {
     746           0 :       return false;
     747             :     }
     748             :   }
     749           0 :   if (!isNull && !temp->isUndefined()) {
     750           0 :     if (!mAmount.Init(cx, temp.ref(),  "'amount' member of PaymentItem", passedToJSImpl)) {
     751           0 :       return false;
     752             :     }
     753           0 :     mIsAnyMemberPresent = true;
     754           0 :   } else if (cx) {
     755             :     // Don't error out if we have no cx.  In that
     756             :     // situation the caller is default-constructing us and we'll
     757             :     // just assume they know what they're doing.
     758           0 :     return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
     759           0 :                              "'amount' member of PaymentItem");
     760             :   }
     761             : 
     762           0 :   if (!isNull) {
     763           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->label_id, temp.ptr())) {
     764           0 :       return false;
     765             :     }
     766             :   }
     767           0 :   if (!isNull && !temp->isUndefined()) {
     768           0 :     if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mLabel)) {
     769           0 :       return false;
     770             :     }
     771           0 :     mIsAnyMemberPresent = true;
     772           0 :   } else if (cx) {
     773             :     // Don't error out if we have no cx.  In that
     774             :     // situation the caller is default-constructing us and we'll
     775             :     // just assume they know what they're doing.
     776           0 :     return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
     777           0 :                              "'label' member of PaymentItem");
     778             :   }
     779             : 
     780           0 :   if (!isNull) {
     781           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->pending_id, temp.ptr())) {
     782           0 :       return false;
     783             :     }
     784             :   }
     785           0 :   if (!isNull && !temp->isUndefined()) {
     786           0 :     if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mPending)) {
     787           0 :       return false;
     788             :     }
     789             :   } else {
     790           0 :     mPending = false;
     791             :   }
     792           0 :   mIsAnyMemberPresent = true;
     793           0 :   return true;
     794             : }
     795             : 
     796             : bool
     797           0 : PaymentItem::Init(const nsAString& aJSON)
     798             : {
     799           0 :   AutoJSAPI jsapi;
     800           0 :   JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
     801           0 :   if (!cleanGlobal) {
     802           0 :     return false;
     803             :   }
     804           0 :   if (!jsapi.Init(cleanGlobal)) {
     805           0 :     return false;
     806             :   }
     807           0 :   JSContext* cx = jsapi.cx();
     808           0 :   JS::Rooted<JS::Value> json(cx);
     809           0 :   bool ok = ParseJSON(cx, aJSON, &json);
     810           0 :   NS_ENSURE_TRUE(ok, false);
     811           0 :   return Init(cx, json);
     812             : }
     813             : 
     814             : bool
     815           0 : PaymentItem::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
     816             : {
     817           0 :   PaymentItemAtoms* atomsCache = GetAtomCache<PaymentItemAtoms>(cx);
     818           0 :   if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     819           0 :     return false;
     820             :   }
     821             : 
     822           0 :   JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
     823           0 :   if (!obj) {
     824           0 :     return false;
     825             :   }
     826           0 :   rval.set(JS::ObjectValue(*obj));
     827             : 
     828             :   do {
     829             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     830           0 :     JS::Rooted<JS::Value> temp(cx);
     831           0 :     PaymentCurrencyAmount const & currentValue = mAmount;
     832           0 :     if (!currentValue.ToObjectInternal(cx, &temp)) {
     833           0 :       return false;
     834             :     }
     835           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->amount_id, temp, JSPROP_ENUMERATE)) {
     836           0 :       return false;
     837             :     }
     838           0 :     break;
     839             :   } while(0);
     840             : 
     841             :   do {
     842             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     843           0 :     JS::Rooted<JS::Value> temp(cx);
     844           0 :     nsString const & currentValue = mLabel;
     845           0 :     if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
     846           0 :       return false;
     847             :     }
     848           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->label_id, temp, JSPROP_ENUMERATE)) {
     849           0 :       return false;
     850             :     }
     851           0 :     break;
     852             :   } while(0);
     853             : 
     854             :   do {
     855             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     856           0 :     JS::Rooted<JS::Value> temp(cx);
     857           0 :     bool const & currentValue = mPending;
     858           0 :     temp.setBoolean(currentValue);
     859           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->pending_id, temp, JSPROP_ENUMERATE)) {
     860           0 :       return false;
     861             :     }
     862           0 :     break;
     863             :   } while(0);
     864             : 
     865           0 :   return true;
     866             : }
     867             : 
     868             : bool
     869           0 : PaymentItem::ToJSON(nsAString& aJSON) const
     870             : {
     871           0 :   AutoJSAPI jsapi;
     872           0 :   jsapi.Init();
     873           0 :   JSContext *cx = jsapi.cx();
     874             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
     875             :   // because we'll only be creating objects, in ways that have no
     876             :   // side-effects, followed by a call to JS::ToJSONMaybeSafely,
     877             :   // which likewise guarantees no side-effects for the sorts of
     878             :   // things we will pass it.
     879           0 :   JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
     880           0 :   JS::Rooted<JS::Value> val(cx);
     881           0 :   if (!ToObjectInternal(cx, &val)) {
     882           0 :     return false;
     883             :   }
     884           0 :   JS::Rooted<JSObject*> obj(cx, &val.toObject());
     885           0 :   return StringifyToJSON(cx, obj, aJSON);
     886             : }
     887             : 
     888             : void
     889           0 : PaymentItem::TraceDictionary(JSTracer* trc)
     890             : {
     891           0 : }
     892             : 
     893             : PaymentItem&
     894           0 : PaymentItem::operator=(const PaymentItem& aOther)
     895             : {
     896           0 :   mAmount = aOther.mAmount;
     897           0 :   mLabel = aOther.mLabel;
     898           0 :   mPending = aOther.mPending;
     899           0 :   return *this;
     900             : }
     901             : 
     902             : namespace binding_detail {
     903             : } // namespace binding_detail
     904             : 
     905             : 
     906             : 
     907           0 : PaymentShippingOption::PaymentShippingOption()
     908           0 :   : mAmount(FastDictionaryInitializer())
     909             : {
     910             :   // Safe to pass a null context if we pass a null value
     911           0 :   Init(nullptr, JS::NullHandleValue);
     912           0 : }
     913             : 
     914             : 
     915             : 
     916             : bool
     917           0 : PaymentShippingOption::InitIds(JSContext* cx, PaymentShippingOptionAtoms* atomsCache)
     918             : {
     919           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
     920             : 
     921             :   // Initialize these in reverse order so that any failure leaves the first one
     922             :   // uninitialized.
     923           0 :   if (!atomsCache->selected_id.init(cx, "selected") ||
     924           0 :       !atomsCache->label_id.init(cx, "label") ||
     925           0 :       !atomsCache->id_id.init(cx, "id") ||
     926           0 :       !atomsCache->amount_id.init(cx, "amount")) {
     927           0 :     return false;
     928             :   }
     929           0 :   return true;
     930             : }
     931             : 
     932             : bool
     933           0 : PaymentShippingOption::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
     934             : {
     935             :   // Passing a null JSContext is OK only if we're initing from null,
     936             :   // Since in that case we will not have to do any property gets
     937             :   // Also evaluate isNullOrUndefined in order to avoid false-positive
     938             :   // checkers by static analysis tools
     939           0 :   MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
     940           0 :   PaymentShippingOptionAtoms* atomsCache = nullptr;
     941           0 :   if (cx) {
     942           0 :     atomsCache = GetAtomCache<PaymentShippingOptionAtoms>(cx);
     943           0 :     if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     944           0 :       return false;
     945             :     }
     946             :   }
     947             : 
     948           0 :   if (!IsConvertibleToDictionary(val)) {
     949           0 :     return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
     950             :   }
     951             : 
     952           0 :   bool isNull = val.isNullOrUndefined();
     953             :   // We only need these if !isNull, in which case we have |cx|.
     954           0 :   Maybe<JS::Rooted<JSObject *> > object;
     955           0 :   Maybe<JS::Rooted<JS::Value> > temp;
     956           0 :   if (!isNull) {
     957           0 :     MOZ_ASSERT(cx);
     958           0 :     object.emplace(cx, &val.toObject());
     959           0 :     temp.emplace(cx);
     960             :   }
     961           0 :   if (!isNull) {
     962           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->amount_id, temp.ptr())) {
     963           0 :       return false;
     964             :     }
     965             :   }
     966           0 :   if (!isNull && !temp->isUndefined()) {
     967           0 :     if (!mAmount.Init(cx, temp.ref(),  "'amount' member of PaymentShippingOption", passedToJSImpl)) {
     968           0 :       return false;
     969             :     }
     970           0 :     mIsAnyMemberPresent = true;
     971           0 :   } else if (cx) {
     972             :     // Don't error out if we have no cx.  In that
     973             :     // situation the caller is default-constructing us and we'll
     974             :     // just assume they know what they're doing.
     975           0 :     return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
     976           0 :                              "'amount' member of PaymentShippingOption");
     977             :   }
     978             : 
     979           0 :   if (!isNull) {
     980           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->id_id, temp.ptr())) {
     981           0 :       return false;
     982             :     }
     983             :   }
     984           0 :   if (!isNull && !temp->isUndefined()) {
     985           0 :     if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mId)) {
     986           0 :       return false;
     987             :     }
     988           0 :     mIsAnyMemberPresent = true;
     989           0 :   } else if (cx) {
     990             :     // Don't error out if we have no cx.  In that
     991             :     // situation the caller is default-constructing us and we'll
     992             :     // just assume they know what they're doing.
     993           0 :     return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
     994           0 :                              "'id' member of PaymentShippingOption");
     995             :   }
     996             : 
     997           0 :   if (!isNull) {
     998           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->label_id, temp.ptr())) {
     999           0 :       return false;
    1000             :     }
    1001             :   }
    1002           0 :   if (!isNull && !temp->isUndefined()) {
    1003           0 :     if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mLabel)) {
    1004           0 :       return false;
    1005             :     }
    1006           0 :     mIsAnyMemberPresent = true;
    1007           0 :   } else if (cx) {
    1008             :     // Don't error out if we have no cx.  In that
    1009             :     // situation the caller is default-constructing us and we'll
    1010             :     // just assume they know what they're doing.
    1011           0 :     return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
    1012           0 :                              "'label' member of PaymentShippingOption");
    1013             :   }
    1014             : 
    1015           0 :   if (!isNull) {
    1016           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->selected_id, temp.ptr())) {
    1017           0 :       return false;
    1018             :     }
    1019             :   }
    1020           0 :   if (!isNull && !temp->isUndefined()) {
    1021           0 :     if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mSelected)) {
    1022           0 :       return false;
    1023             :     }
    1024             :   } else {
    1025           0 :     mSelected = false;
    1026             :   }
    1027           0 :   mIsAnyMemberPresent = true;
    1028           0 :   return true;
    1029             : }
    1030             : 
    1031             : bool
    1032           0 : PaymentShippingOption::Init(const nsAString& aJSON)
    1033             : {
    1034           0 :   AutoJSAPI jsapi;
    1035           0 :   JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
    1036           0 :   if (!cleanGlobal) {
    1037           0 :     return false;
    1038             :   }
    1039           0 :   if (!jsapi.Init(cleanGlobal)) {
    1040           0 :     return false;
    1041             :   }
    1042           0 :   JSContext* cx = jsapi.cx();
    1043           0 :   JS::Rooted<JS::Value> json(cx);
    1044           0 :   bool ok = ParseJSON(cx, aJSON, &json);
    1045           0 :   NS_ENSURE_TRUE(ok, false);
    1046           0 :   return Init(cx, json);
    1047             : }
    1048             : 
    1049             : bool
    1050           0 : PaymentShippingOption::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
    1051             : {
    1052           0 :   PaymentShippingOptionAtoms* atomsCache = GetAtomCache<PaymentShippingOptionAtoms>(cx);
    1053           0 :   if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
    1054           0 :     return false;
    1055             :   }
    1056             : 
    1057           0 :   JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
    1058           0 :   if (!obj) {
    1059           0 :     return false;
    1060             :   }
    1061           0 :   rval.set(JS::ObjectValue(*obj));
    1062             : 
    1063             :   do {
    1064             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    1065           0 :     JS::Rooted<JS::Value> temp(cx);
    1066           0 :     PaymentCurrencyAmount const & currentValue = mAmount;
    1067           0 :     if (!currentValue.ToObjectInternal(cx, &temp)) {
    1068           0 :       return false;
    1069             :     }
    1070           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->amount_id, temp, JSPROP_ENUMERATE)) {
    1071           0 :       return false;
    1072             :     }
    1073           0 :     break;
    1074             :   } while(0);
    1075             : 
    1076             :   do {
    1077             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    1078           0 :     JS::Rooted<JS::Value> temp(cx);
    1079           0 :     nsString const & currentValue = mId;
    1080           0 :     if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
    1081           0 :       return false;
    1082             :     }
    1083           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->id_id, temp, JSPROP_ENUMERATE)) {
    1084           0 :       return false;
    1085             :     }
    1086           0 :     break;
    1087             :   } while(0);
    1088             : 
    1089             :   do {
    1090             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    1091           0 :     JS::Rooted<JS::Value> temp(cx);
    1092           0 :     nsString const & currentValue = mLabel;
    1093           0 :     if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
    1094           0 :       return false;
    1095             :     }
    1096           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->label_id, temp, JSPROP_ENUMERATE)) {
    1097           0 :       return false;
    1098             :     }
    1099           0 :     break;
    1100             :   } while(0);
    1101             : 
    1102             :   do {
    1103             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    1104           0 :     JS::Rooted<JS::Value> temp(cx);
    1105           0 :     bool const & currentValue = mSelected;
    1106           0 :     temp.setBoolean(currentValue);
    1107           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->selected_id, temp, JSPROP_ENUMERATE)) {
    1108           0 :       return false;
    1109             :     }
    1110           0 :     break;
    1111             :   } while(0);
    1112             : 
    1113           0 :   return true;
    1114             : }
    1115             : 
    1116             : bool
    1117           0 : PaymentShippingOption::ToJSON(nsAString& aJSON) const
    1118             : {
    1119           0 :   AutoJSAPI jsapi;
    1120           0 :   jsapi.Init();
    1121           0 :   JSContext *cx = jsapi.cx();
    1122             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
    1123             :   // because we'll only be creating objects, in ways that have no
    1124             :   // side-effects, followed by a call to JS::ToJSONMaybeSafely,
    1125             :   // which likewise guarantees no side-effects for the sorts of
    1126             :   // things we will pass it.
    1127           0 :   JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    1128           0 :   JS::Rooted<JS::Value> val(cx);
    1129           0 :   if (!ToObjectInternal(cx, &val)) {
    1130           0 :     return false;
    1131             :   }
    1132           0 :   JS::Rooted<JSObject*> obj(cx, &val.toObject());
    1133           0 :   return StringifyToJSON(cx, obj, aJSON);
    1134             : }
    1135             : 
    1136             : void
    1137           0 : PaymentShippingOption::TraceDictionary(JSTracer* trc)
    1138             : {
    1139           0 : }
    1140             : 
    1141             : PaymentShippingOption&
    1142           0 : PaymentShippingOption::operator=(const PaymentShippingOption& aOther)
    1143             : {
    1144           0 :   mAmount = aOther.mAmount;
    1145           0 :   mId = aOther.mId;
    1146           0 :   mLabel = aOther.mLabel;
    1147           0 :   mSelected = aOther.mSelected;
    1148           0 :   return *this;
    1149             : }
    1150             : 
    1151             : namespace binding_detail {
    1152             : } // namespace binding_detail
    1153             : 
    1154             : 
    1155             : 
    1156           0 : PaymentDetailsModifier::PaymentDetailsModifier()
    1157           0 :   : mTotal(FastDictionaryInitializer())
    1158             : {
    1159             :   // Safe to pass a null context if we pass a null value
    1160           0 :   Init(nullptr, JS::NullHandleValue);
    1161           0 : }
    1162             : 
    1163             : 
    1164             : bool
    1165           0 : PaymentDetailsModifier::InitIds(JSContext* cx, PaymentDetailsModifierAtoms* atomsCache)
    1166             : {
    1167           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
    1168             : 
    1169             :   // Initialize these in reverse order so that any failure leaves the first one
    1170             :   // uninitialized.
    1171           0 :   if (!atomsCache->total_id.init(cx, "total") ||
    1172           0 :       !atomsCache->supportedMethods_id.init(cx, "supportedMethods") ||
    1173           0 :       !atomsCache->data_id.init(cx, "data") ||
    1174           0 :       !atomsCache->additionalDisplayItems_id.init(cx, "additionalDisplayItems")) {
    1175           0 :     return false;
    1176             :   }
    1177           0 :   return true;
    1178             : }
    1179             : 
    1180             : bool
    1181           0 : PaymentDetailsModifier::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
    1182             : {
    1183             :   // Passing a null JSContext is OK only if we're initing from null,
    1184             :   // Since in that case we will not have to do any property gets
    1185             :   // Also evaluate isNullOrUndefined in order to avoid false-positive
    1186             :   // checkers by static analysis tools
    1187           0 :   MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
    1188           0 :   PaymentDetailsModifierAtoms* atomsCache = nullptr;
    1189           0 :   if (cx) {
    1190           0 :     atomsCache = GetAtomCache<PaymentDetailsModifierAtoms>(cx);
    1191           0 :     if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
    1192           0 :       return false;
    1193             :     }
    1194             :   }
    1195             : 
    1196           0 :   if (!IsConvertibleToDictionary(val)) {
    1197           0 :     return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
    1198             :   }
    1199             : 
    1200           0 :   bool isNull = val.isNullOrUndefined();
    1201             :   // We only need these if !isNull, in which case we have |cx|.
    1202           0 :   Maybe<JS::Rooted<JSObject *> > object;
    1203           0 :   Maybe<JS::Rooted<JS::Value> > temp;
    1204           0 :   if (!isNull) {
    1205           0 :     MOZ_ASSERT(cx);
    1206           0 :     object.emplace(cx, &val.toObject());
    1207           0 :     temp.emplace(cx);
    1208             :   }
    1209           0 :   if (!isNull) {
    1210           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->additionalDisplayItems_id, temp.ptr())) {
    1211           0 :       return false;
    1212             :     }
    1213             :   }
    1214           0 :   if (!isNull && !temp->isUndefined()) {
    1215           0 :     mAdditionalDisplayItems.Construct();
    1216           0 :     if (temp.ref().isObject()) {
    1217           0 :       JS::ForOfIterator iter(cx);
    1218           0 :       if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
    1219           0 :         return false;
    1220             :       }
    1221           0 :       if (!iter.valueIsIterable()) {
    1222           0 :         ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'additionalDisplayItems' member of PaymentDetailsModifier");
    1223           0 :         return false;
    1224             :       }
    1225           0 :       Sequence<PaymentItem> &arr = (mAdditionalDisplayItems.Value());
    1226           0 :       JS::Rooted<JS::Value> temp(cx);
    1227             :       while (true) {
    1228             :         bool done;
    1229           0 :         if (!iter.next(&temp, &done)) {
    1230           0 :           return false;
    1231             :         }
    1232           0 :         if (done) {
    1233           0 :           break;
    1234             :         }
    1235           0 :         PaymentItem* slotPtr = arr.AppendElement(mozilla::fallible);
    1236           0 :         if (!slotPtr) {
    1237           0 :           JS_ReportOutOfMemory(cx);
    1238           0 :           return false;
    1239             :         }
    1240           0 :         PaymentItem& slot = *slotPtr;
    1241           0 :         if (!slot.Init(cx, temp,  "Element of 'additionalDisplayItems' member of PaymentDetailsModifier", passedToJSImpl)) {
    1242           0 :           return false;
    1243             :         }
    1244           0 :       }
    1245             :     } else {
    1246           0 :       ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'additionalDisplayItems' member of PaymentDetailsModifier");
    1247           0 :       return false;
    1248             :     }
    1249           0 :     mIsAnyMemberPresent = true;
    1250             :   }
    1251             : 
    1252           0 :   if (!isNull) {
    1253           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->data_id, temp.ptr())) {
    1254           0 :       return false;
    1255             :     }
    1256             :   }
    1257           0 :   if (!isNull && !temp->isUndefined()) {
    1258           0 :     mData.Construct();
    1259           0 :     if (temp.ref().isObject()) {
    1260             : #ifdef __clang__
    1261             : #pragma clang diagnostic push
    1262             : #pragma clang diagnostic ignored "-Wunreachable-code"
    1263             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    1264             : #endif // __clang__
    1265           0 :       if ((passedToJSImpl) && !CallerSubsumes(temp.ref())) {
    1266           0 :         ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "'data' member of PaymentDetailsModifier");
    1267           0 :         return false;
    1268             :       }
    1269             : #ifdef __clang__
    1270             : #pragma clang diagnostic pop
    1271             : #endif // __clang__
    1272           0 :       (mData.Value()) = &temp.ref().toObject();
    1273             :     } else {
    1274           0 :       ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'data' member of PaymentDetailsModifier");
    1275           0 :       return false;
    1276             :     }
    1277           0 :     mIsAnyMemberPresent = true;
    1278             :   }
    1279             : 
    1280           0 :   if (!isNull) {
    1281           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->supportedMethods_id, temp.ptr())) {
    1282           0 :       return false;
    1283             :     }
    1284             :   }
    1285           0 :   if (!isNull && !temp->isUndefined()) {
    1286           0 :     if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mSupportedMethods)) {
    1287           0 :       return false;
    1288             :     }
    1289           0 :     mIsAnyMemberPresent = true;
    1290           0 :   } else if (cx) {
    1291             :     // Don't error out if we have no cx.  In that
    1292             :     // situation the caller is default-constructing us and we'll
    1293             :     // just assume they know what they're doing.
    1294           0 :     return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
    1295           0 :                              "'supportedMethods' member of PaymentDetailsModifier");
    1296             :   }
    1297             : 
    1298           0 :   if (!isNull) {
    1299           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->total_id, temp.ptr())) {
    1300           0 :       return false;
    1301             :     }
    1302             :   }
    1303           0 :   if (!mTotal.Init(cx, (!isNull && !temp->isUndefined()) ? temp.ref() : JS::NullHandleValue,  "'total' member of PaymentDetailsModifier", passedToJSImpl)) {
    1304           0 :     return false;
    1305             :   }
    1306           0 :   mIsAnyMemberPresent = true;
    1307           0 :   return true;
    1308             : }
    1309             : 
    1310             : bool
    1311           0 : PaymentDetailsModifier::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
    1312             : {
    1313           0 :   PaymentDetailsModifierAtoms* atomsCache = GetAtomCache<PaymentDetailsModifierAtoms>(cx);
    1314           0 :   if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
    1315           0 :     return false;
    1316             :   }
    1317             : 
    1318           0 :   JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
    1319           0 :   if (!obj) {
    1320           0 :     return false;
    1321             :   }
    1322           0 :   rval.set(JS::ObjectValue(*obj));
    1323             : 
    1324           0 :   if (mAdditionalDisplayItems.WasPassed()) {
    1325             :     do {
    1326             :       // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    1327           0 :       JS::Rooted<JS::Value> temp(cx);
    1328           0 :       Sequence<PaymentItem> const & currentValue = mAdditionalDisplayItems.InternalValue();
    1329             : 
    1330           0 :       uint32_t length = currentValue.Length();
    1331           0 :       JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
    1332           0 :       if (!returnArray) {
    1333           0 :         return false;
    1334             :       }
    1335             :       // Scope for 'tmp'
    1336             :       {
    1337           0 :         JS::Rooted<JS::Value> tmp(cx);
    1338           0 :         for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
    1339             :           // Control block to let us common up the JS_DefineElement calls when there
    1340             :           // are different ways to succeed at wrapping the object.
    1341             :           do {
    1342           0 :             if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
    1343           0 :               return false;
    1344             :             }
    1345           0 :             break;
    1346             :           } while (0);
    1347           0 :           if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
    1348             :                                 JSPROP_ENUMERATE)) {
    1349           0 :             return false;
    1350             :           }
    1351             :         }
    1352             :       }
    1353           0 :       temp.setObject(*returnArray);
    1354           0 :       if (!JS_DefinePropertyById(cx, obj, atomsCache->additionalDisplayItems_id, temp, JSPROP_ENUMERATE)) {
    1355           0 :         return false;
    1356             :       }
    1357           0 :       break;
    1358             :     } while(0);
    1359             :   }
    1360             : 
    1361           0 :   if (mData.WasPassed()) {
    1362             :     do {
    1363             :       // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    1364           0 :       JS::Rooted<JS::Value> temp(cx);
    1365           0 :       JSObject* const & currentValue = mData.InternalValue();
    1366           0 :       JS::ExposeObjectToActiveJS(currentValue);
    1367           0 :       temp.setObject(*currentValue);
    1368           0 :       if (!MaybeWrapObjectValue(cx, &temp)) {
    1369           0 :         return false;
    1370             :       }
    1371           0 :       if (!JS_DefinePropertyById(cx, obj, atomsCache->data_id, temp, JSPROP_ENUMERATE)) {
    1372           0 :         return false;
    1373             :       }
    1374           0 :       break;
    1375             :     } while(0);
    1376             :   }
    1377             : 
    1378             :   do {
    1379             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    1380           0 :     JS::Rooted<JS::Value> temp(cx);
    1381           0 :     nsString const & currentValue = mSupportedMethods;
    1382           0 :     if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
    1383           0 :       return false;
    1384             :     }
    1385           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->supportedMethods_id, temp, JSPROP_ENUMERATE)) {
    1386           0 :       return false;
    1387             :     }
    1388           0 :     break;
    1389             :   } while(0);
    1390             : 
    1391             :   do {
    1392             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    1393           0 :     JS::Rooted<JS::Value> temp(cx);
    1394           0 :     PaymentItem const & currentValue = mTotal;
    1395           0 :     if (!currentValue.ToObjectInternal(cx, &temp)) {
    1396           0 :       return false;
    1397             :     }
    1398           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->total_id, temp, JSPROP_ENUMERATE)) {
    1399           0 :       return false;
    1400             :     }
    1401           0 :     break;
    1402             :   } while(0);
    1403             : 
    1404           0 :   return true;
    1405             : }
    1406             : 
    1407             : void
    1408           0 : PaymentDetailsModifier::TraceDictionary(JSTracer* trc)
    1409             : {
    1410           0 :   if (mData.WasPassed()) {
    1411           0 :     JS::UnsafeTraceRoot(trc, &mData.Value(), "PaymentDetailsModifier.mData");
    1412             :   }
    1413           0 : }
    1414             : 
    1415             : namespace binding_detail {
    1416             : } // namespace binding_detail
    1417             : 
    1418             : 
    1419             : 
    1420           0 : PaymentDetailsBase::PaymentDetailsBase()
    1421             : {
    1422             :   // Safe to pass a null context if we pass a null value
    1423           0 :   Init(nullptr, JS::NullHandleValue);
    1424           0 : }
    1425             : 
    1426             : 
    1427             : bool
    1428           0 : PaymentDetailsBase::InitIds(JSContext* cx, PaymentDetailsBaseAtoms* atomsCache)
    1429             : {
    1430           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
    1431             : 
    1432             :   // Initialize these in reverse order so that any failure leaves the first one
    1433             :   // uninitialized.
    1434           0 :   if (!atomsCache->shippingOptions_id.init(cx, "shippingOptions") ||
    1435           0 :       !atomsCache->modifiers_id.init(cx, "modifiers") ||
    1436           0 :       !atomsCache->displayItems_id.init(cx, "displayItems")) {
    1437           0 :     return false;
    1438             :   }
    1439           0 :   return true;
    1440             : }
    1441             : 
    1442             : bool
    1443           0 : PaymentDetailsBase::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
    1444             : {
    1445             :   // Passing a null JSContext is OK only if we're initing from null,
    1446             :   // Since in that case we will not have to do any property gets
    1447             :   // Also evaluate isNullOrUndefined in order to avoid false-positive
    1448             :   // checkers by static analysis tools
    1449           0 :   MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
    1450           0 :   PaymentDetailsBaseAtoms* atomsCache = nullptr;
    1451           0 :   if (cx) {
    1452           0 :     atomsCache = GetAtomCache<PaymentDetailsBaseAtoms>(cx);
    1453           0 :     if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
    1454           0 :       return false;
    1455             :     }
    1456             :   }
    1457             : 
    1458           0 :   if (!IsConvertibleToDictionary(val)) {
    1459           0 :     return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
    1460             :   }
    1461             : 
    1462           0 :   bool isNull = val.isNullOrUndefined();
    1463             :   // We only need these if !isNull, in which case we have |cx|.
    1464           0 :   Maybe<JS::Rooted<JSObject *> > object;
    1465           0 :   Maybe<JS::Rooted<JS::Value> > temp;
    1466           0 :   if (!isNull) {
    1467           0 :     MOZ_ASSERT(cx);
    1468           0 :     object.emplace(cx, &val.toObject());
    1469           0 :     temp.emplace(cx);
    1470             :   }
    1471           0 :   if (!isNull) {
    1472           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->displayItems_id, temp.ptr())) {
    1473           0 :       return false;
    1474             :     }
    1475             :   }
    1476           0 :   if (!isNull && !temp->isUndefined()) {
    1477           0 :     mDisplayItems.Construct();
    1478           0 :     if (temp.ref().isObject()) {
    1479           0 :       JS::ForOfIterator iter(cx);
    1480           0 :       if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
    1481           0 :         return false;
    1482             :       }
    1483           0 :       if (!iter.valueIsIterable()) {
    1484           0 :         ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'displayItems' member of PaymentDetailsBase");
    1485           0 :         return false;
    1486             :       }
    1487           0 :       Sequence<PaymentItem> &arr = (mDisplayItems.Value());
    1488           0 :       JS::Rooted<JS::Value> temp(cx);
    1489             :       while (true) {
    1490             :         bool done;
    1491           0 :         if (!iter.next(&temp, &done)) {
    1492           0 :           return false;
    1493             :         }
    1494           0 :         if (done) {
    1495           0 :           break;
    1496             :         }
    1497           0 :         PaymentItem* slotPtr = arr.AppendElement(mozilla::fallible);
    1498           0 :         if (!slotPtr) {
    1499           0 :           JS_ReportOutOfMemory(cx);
    1500           0 :           return false;
    1501             :         }
    1502           0 :         PaymentItem& slot = *slotPtr;
    1503           0 :         if (!slot.Init(cx, temp,  "Element of 'displayItems' member of PaymentDetailsBase", passedToJSImpl)) {
    1504           0 :           return false;
    1505             :         }
    1506           0 :       }
    1507             :     } else {
    1508           0 :       ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'displayItems' member of PaymentDetailsBase");
    1509           0 :       return false;
    1510             :     }
    1511           0 :     mIsAnyMemberPresent = true;
    1512             :   }
    1513             : 
    1514           0 :   if (!isNull) {
    1515           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->modifiers_id, temp.ptr())) {
    1516           0 :       return false;
    1517             :     }
    1518             :   }
    1519           0 :   if (!isNull && !temp->isUndefined()) {
    1520           0 :     mModifiers.Construct();
    1521           0 :     if (temp.ref().isObject()) {
    1522           0 :       JS::ForOfIterator iter(cx);
    1523           0 :       if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
    1524           0 :         return false;
    1525             :       }
    1526           0 :       if (!iter.valueIsIterable()) {
    1527           0 :         ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'modifiers' member of PaymentDetailsBase");
    1528           0 :         return false;
    1529             :       }
    1530           0 :       Sequence<PaymentDetailsModifier> &arr = (mModifiers.Value());
    1531           0 :       JS::Rooted<JS::Value> temp(cx);
    1532             :       while (true) {
    1533             :         bool done;
    1534           0 :         if (!iter.next(&temp, &done)) {
    1535           0 :           return false;
    1536             :         }
    1537           0 :         if (done) {
    1538           0 :           break;
    1539             :         }
    1540           0 :         PaymentDetailsModifier* slotPtr = arr.AppendElement(mozilla::fallible);
    1541           0 :         if (!slotPtr) {
    1542           0 :           JS_ReportOutOfMemory(cx);
    1543           0 :           return false;
    1544             :         }
    1545           0 :         PaymentDetailsModifier& slot = *slotPtr;
    1546           0 :         if (!slot.Init(cx, temp,  "Element of 'modifiers' member of PaymentDetailsBase", passedToJSImpl)) {
    1547           0 :           return false;
    1548             :         }
    1549           0 :       }
    1550             :     } else {
    1551           0 :       ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'modifiers' member of PaymentDetailsBase");
    1552           0 :       return false;
    1553             :     }
    1554           0 :     mIsAnyMemberPresent = true;
    1555             :   }
    1556             : 
    1557           0 :   if (!isNull) {
    1558           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->shippingOptions_id, temp.ptr())) {
    1559           0 :       return false;
    1560             :     }
    1561             :   }
    1562           0 :   if (!isNull && !temp->isUndefined()) {
    1563           0 :     mShippingOptions.Construct();
    1564           0 :     if (temp.ref().isObject()) {
    1565           0 :       JS::ForOfIterator iter(cx);
    1566           0 :       if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
    1567           0 :         return false;
    1568             :       }
    1569           0 :       if (!iter.valueIsIterable()) {
    1570           0 :         ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'shippingOptions' member of PaymentDetailsBase");
    1571           0 :         return false;
    1572             :       }
    1573           0 :       Sequence<PaymentShippingOption> &arr = (mShippingOptions.Value());
    1574           0 :       JS::Rooted<JS::Value> temp(cx);
    1575             :       while (true) {
    1576             :         bool done;
    1577           0 :         if (!iter.next(&temp, &done)) {
    1578           0 :           return false;
    1579             :         }
    1580           0 :         if (done) {
    1581           0 :           break;
    1582             :         }
    1583           0 :         PaymentShippingOption* slotPtr = arr.AppendElement(mozilla::fallible);
    1584           0 :         if (!slotPtr) {
    1585           0 :           JS_ReportOutOfMemory(cx);
    1586           0 :           return false;
    1587             :         }
    1588           0 :         PaymentShippingOption& slot = *slotPtr;
    1589           0 :         if (!slot.Init(cx, temp,  "Element of 'shippingOptions' member of PaymentDetailsBase", passedToJSImpl)) {
    1590           0 :           return false;
    1591             :         }
    1592           0 :       }
    1593             :     } else {
    1594           0 :       ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'shippingOptions' member of PaymentDetailsBase");
    1595           0 :       return false;
    1596             :     }
    1597           0 :     mIsAnyMemberPresent = true;
    1598             :   }
    1599           0 :   return true;
    1600             : }
    1601             : 
    1602             : bool
    1603           0 : PaymentDetailsBase::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
    1604             : {
    1605           0 :   PaymentDetailsBaseAtoms* atomsCache = GetAtomCache<PaymentDetailsBaseAtoms>(cx);
    1606           0 :   if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
    1607           0 :     return false;
    1608             :   }
    1609             : 
    1610           0 :   JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
    1611           0 :   if (!obj) {
    1612           0 :     return false;
    1613             :   }
    1614           0 :   rval.set(JS::ObjectValue(*obj));
    1615             : 
    1616           0 :   if (mDisplayItems.WasPassed()) {
    1617             :     do {
    1618             :       // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    1619           0 :       JS::Rooted<JS::Value> temp(cx);
    1620           0 :       Sequence<PaymentItem> const & currentValue = mDisplayItems.InternalValue();
    1621             : 
    1622           0 :       uint32_t length = currentValue.Length();
    1623           0 :       JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
    1624           0 :       if (!returnArray) {
    1625           0 :         return false;
    1626             :       }
    1627             :       // Scope for 'tmp'
    1628             :       {
    1629           0 :         JS::Rooted<JS::Value> tmp(cx);
    1630           0 :         for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
    1631             :           // Control block to let us common up the JS_DefineElement calls when there
    1632             :           // are different ways to succeed at wrapping the object.
    1633             :           do {
    1634           0 :             if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
    1635           0 :               return false;
    1636             :             }
    1637           0 :             break;
    1638             :           } while (0);
    1639           0 :           if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
    1640             :                                 JSPROP_ENUMERATE)) {
    1641           0 :             return false;
    1642             :           }
    1643             :         }
    1644             :       }
    1645           0 :       temp.setObject(*returnArray);
    1646           0 :       if (!JS_DefinePropertyById(cx, obj, atomsCache->displayItems_id, temp, JSPROP_ENUMERATE)) {
    1647           0 :         return false;
    1648             :       }
    1649           0 :       break;
    1650             :     } while(0);
    1651             :   }
    1652             : 
    1653           0 :   if (mModifiers.WasPassed()) {
    1654             :     do {
    1655             :       // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    1656           0 :       JS::Rooted<JS::Value> temp(cx);
    1657           0 :       Sequence<PaymentDetailsModifier> const & currentValue = mModifiers.InternalValue();
    1658             : 
    1659           0 :       uint32_t length = currentValue.Length();
    1660           0 :       JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
    1661           0 :       if (!returnArray) {
    1662           0 :         return false;
    1663             :       }
    1664             :       // Scope for 'tmp'
    1665             :       {
    1666           0 :         JS::Rooted<JS::Value> tmp(cx);
    1667           0 :         for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
    1668             :           // Control block to let us common up the JS_DefineElement calls when there
    1669             :           // are different ways to succeed at wrapping the object.
    1670             :           do {
    1671           0 :             if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
    1672           0 :               return false;
    1673             :             }
    1674           0 :             break;
    1675             :           } while (0);
    1676           0 :           if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
    1677             :                                 JSPROP_ENUMERATE)) {
    1678           0 :             return false;
    1679             :           }
    1680             :         }
    1681             :       }
    1682           0 :       temp.setObject(*returnArray);
    1683           0 :       if (!JS_DefinePropertyById(cx, obj, atomsCache->modifiers_id, temp, JSPROP_ENUMERATE)) {
    1684           0 :         return false;
    1685             :       }
    1686           0 :       break;
    1687             :     } while(0);
    1688             :   }
    1689             : 
    1690           0 :   if (mShippingOptions.WasPassed()) {
    1691             :     do {
    1692             :       // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    1693           0 :       JS::Rooted<JS::Value> temp(cx);
    1694           0 :       Sequence<PaymentShippingOption> const & currentValue = mShippingOptions.InternalValue();
    1695             : 
    1696           0 :       uint32_t length = currentValue.Length();
    1697           0 :       JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
    1698           0 :       if (!returnArray) {
    1699           0 :         return false;
    1700             :       }
    1701             :       // Scope for 'tmp'
    1702             :       {
    1703           0 :         JS::Rooted<JS::Value> tmp(cx);
    1704           0 :         for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
    1705             :           // Control block to let us common up the JS_DefineElement calls when there
    1706             :           // are different ways to succeed at wrapping the object.
    1707             :           do {
    1708           0 :             if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
    1709           0 :               return false;
    1710             :             }
    1711           0 :             break;
    1712             :           } while (0);
    1713           0 :           if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
    1714             :                                 JSPROP_ENUMERATE)) {
    1715           0 :             return false;
    1716             :           }
    1717             :         }
    1718             :       }
    1719           0 :       temp.setObject(*returnArray);
    1720           0 :       if (!JS_DefinePropertyById(cx, obj, atomsCache->shippingOptions_id, temp, JSPROP_ENUMERATE)) {
    1721           0 :         return false;
    1722             :       }
    1723           0 :       break;
    1724             :     } while(0);
    1725             :   }
    1726             : 
    1727           0 :   return true;
    1728             : }
    1729             : 
    1730             : void
    1731           0 : PaymentDetailsBase::TraceDictionary(JSTracer* trc)
    1732             : {
    1733           0 :   if (mModifiers.WasPassed()) {
    1734           0 :     DoTraceSequence(trc, mModifiers.Value());
    1735             :   }
    1736           0 : }
    1737             : 
    1738             : namespace binding_detail {
    1739             : } // namespace binding_detail
    1740             : 
    1741             : 
    1742             : 
    1743           0 : PaymentDetailsInit::PaymentDetailsInit()
    1744           0 :   : PaymentDetailsBase(FastDictionaryInitializer()),
    1745           0 :     mTotal(FastDictionaryInitializer())
    1746             : {
    1747             :   // Safe to pass a null context if we pass a null value
    1748           0 :   Init(nullptr, JS::NullHandleValue);
    1749           0 : }
    1750             : 
    1751             : 
    1752             : bool
    1753           0 : PaymentDetailsInit::InitIds(JSContext* cx, PaymentDetailsInitAtoms* atomsCache)
    1754             : {
    1755           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
    1756             : 
    1757             :   // Initialize these in reverse order so that any failure leaves the first one
    1758             :   // uninitialized.
    1759           0 :   if (!atomsCache->total_id.init(cx, "total") ||
    1760           0 :       !atomsCache->id_id.init(cx, "id")) {
    1761           0 :     return false;
    1762             :   }
    1763           0 :   return true;
    1764             : }
    1765             : 
    1766             : bool
    1767           0 : PaymentDetailsInit::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
    1768             : {
    1769             :   // Passing a null JSContext is OK only if we're initing from null,
    1770             :   // Since in that case we will not have to do any property gets
    1771             :   // Also evaluate isNullOrUndefined in order to avoid false-positive
    1772             :   // checkers by static analysis tools
    1773           0 :   MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
    1774           0 :   PaymentDetailsInitAtoms* atomsCache = nullptr;
    1775           0 :   if (cx) {
    1776           0 :     atomsCache = GetAtomCache<PaymentDetailsInitAtoms>(cx);
    1777           0 :     if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
    1778           0 :       return false;
    1779             :     }
    1780             :   }
    1781             : 
    1782             :   // Per spec, we init the parent's members first
    1783           0 :   if (!PaymentDetailsBase::Init(cx, val)) {
    1784           0 :     return false;
    1785             :   }
    1786             : 
    1787           0 :   bool isNull = val.isNullOrUndefined();
    1788             :   // We only need these if !isNull, in which case we have |cx|.
    1789           0 :   Maybe<JS::Rooted<JSObject *> > object;
    1790           0 :   Maybe<JS::Rooted<JS::Value> > temp;
    1791           0 :   if (!isNull) {
    1792           0 :     MOZ_ASSERT(cx);
    1793           0 :     object.emplace(cx, &val.toObject());
    1794           0 :     temp.emplace(cx);
    1795             :   }
    1796           0 :   if (!isNull) {
    1797           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->id_id, temp.ptr())) {
    1798           0 :       return false;
    1799             :     }
    1800             :   }
    1801           0 :   if (!isNull && !temp->isUndefined()) {
    1802           0 :     mId.Construct();
    1803           0 :     if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mId.Value()))) {
    1804           0 :       return false;
    1805             :     }
    1806           0 :     mIsAnyMemberPresent = true;
    1807             :   }
    1808             : 
    1809           0 :   if (!isNull) {
    1810           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->total_id, temp.ptr())) {
    1811           0 :       return false;
    1812             :     }
    1813             :   }
    1814           0 :   if (!isNull && !temp->isUndefined()) {
    1815           0 :     if (!mTotal.Init(cx, temp.ref(),  "'total' member of PaymentDetailsInit", passedToJSImpl)) {
    1816           0 :       return false;
    1817             :     }
    1818           0 :     mIsAnyMemberPresent = true;
    1819           0 :   } else if (cx) {
    1820             :     // Don't error out if we have no cx.  In that
    1821             :     // situation the caller is default-constructing us and we'll
    1822             :     // just assume they know what they're doing.
    1823           0 :     return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
    1824           0 :                              "'total' member of PaymentDetailsInit");
    1825             :   }
    1826           0 :   return true;
    1827             : }
    1828             : 
    1829             : bool
    1830           0 : PaymentDetailsInit::Init(const nsAString& aJSON)
    1831             : {
    1832           0 :   AutoJSAPI jsapi;
    1833           0 :   JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
    1834           0 :   if (!cleanGlobal) {
    1835           0 :     return false;
    1836             :   }
    1837           0 :   if (!jsapi.Init(cleanGlobal)) {
    1838           0 :     return false;
    1839             :   }
    1840           0 :   JSContext* cx = jsapi.cx();
    1841           0 :   JS::Rooted<JS::Value> json(cx);
    1842           0 :   bool ok = ParseJSON(cx, aJSON, &json);
    1843           0 :   NS_ENSURE_TRUE(ok, false);
    1844           0 :   return Init(cx, json);
    1845             : }
    1846             : 
    1847             : bool
    1848           0 : PaymentDetailsInit::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
    1849             : {
    1850           0 :   PaymentDetailsInitAtoms* atomsCache = GetAtomCache<PaymentDetailsInitAtoms>(cx);
    1851           0 :   if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
    1852           0 :     return false;
    1853             :   }
    1854             : 
    1855             :   // Per spec, we define the parent's members first
    1856           0 :   if (!PaymentDetailsBase::ToObjectInternal(cx, rval)) {
    1857           0 :     return false;
    1858             :   }
    1859           0 :   JS::Rooted<JSObject*> obj(cx, &rval.toObject());
    1860             : 
    1861           0 :   if (mId.WasPassed()) {
    1862             :     do {
    1863             :       // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    1864           0 :       JS::Rooted<JS::Value> temp(cx);
    1865           0 :       nsString const & currentValue = mId.InternalValue();
    1866           0 :       if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
    1867           0 :         return false;
    1868             :       }
    1869           0 :       if (!JS_DefinePropertyById(cx, obj, atomsCache->id_id, temp, JSPROP_ENUMERATE)) {
    1870           0 :         return false;
    1871             :       }
    1872           0 :       break;
    1873             :     } while(0);
    1874             :   }
    1875             : 
    1876             :   do {
    1877             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    1878           0 :     JS::Rooted<JS::Value> temp(cx);
    1879           0 :     PaymentItem const & currentValue = mTotal;
    1880           0 :     if (!currentValue.ToObjectInternal(cx, &temp)) {
    1881           0 :       return false;
    1882             :     }
    1883           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->total_id, temp, JSPROP_ENUMERATE)) {
    1884           0 :       return false;
    1885             :     }
    1886           0 :     break;
    1887             :   } while(0);
    1888             : 
    1889           0 :   return true;
    1890             : }
    1891             : 
    1892             : bool
    1893           0 : PaymentDetailsInit::ToJSON(nsAString& aJSON) const
    1894             : {
    1895           0 :   AutoJSAPI jsapi;
    1896           0 :   jsapi.Init();
    1897           0 :   JSContext *cx = jsapi.cx();
    1898             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
    1899             :   // because we'll only be creating objects, in ways that have no
    1900             :   // side-effects, followed by a call to JS::ToJSONMaybeSafely,
    1901             :   // which likewise guarantees no side-effects for the sorts of
    1902             :   // things we will pass it.
    1903           0 :   JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    1904           0 :   JS::Rooted<JS::Value> val(cx);
    1905           0 :   if (!ToObjectInternal(cx, &val)) {
    1906           0 :     return false;
    1907             :   }
    1908           0 :   JS::Rooted<JSObject*> obj(cx, &val.toObject());
    1909           0 :   return StringifyToJSON(cx, obj, aJSON);
    1910             : }
    1911             : 
    1912             : void
    1913           0 : PaymentDetailsInit::TraceDictionary(JSTracer* trc)
    1914             : {
    1915           0 :   PaymentDetailsBase::TraceDictionary(trc);
    1916           0 : }
    1917             : 
    1918             : namespace binding_detail {
    1919             : } // namespace binding_detail
    1920             : 
    1921             : 
    1922             : namespace PaymentRequestBinding {
    1923             : 
    1924             : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventTargetBinding::NativeType>::value,
    1925             :               "Can't inherit from an interface with a different ownership model.");
    1926             : 
    1927             : static bool
    1928           0 : show(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, const JSJitMethodCallArgs& args)
    1929             : {
    1930           0 :   binding_detail::FastErrorResult rv;
    1931           0 :   auto result(StrongOrRawPtr<Promise>(self->Show(rv)));
    1932           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1933           0 :     return false;
    1934             :   }
    1935           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1936             :   static_assert(!IsPointer<decltype(result)>::value,
    1937             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
    1938           0 :   if (!ToJSValue(cx, result, args.rval())) {
    1939           0 :     return false;
    1940             :   }
    1941           0 :   return true;
    1942             : }
    1943             : 
    1944             : static bool
    1945           0 : show_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, const JSJitMethodCallArgs& args)
    1946             : {
    1947             :   // Make sure to save the callee before someone maybe messes
    1948             :   // with rval().
    1949           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
    1950           0 :   bool ok = show(cx, obj, self, args);
    1951           0 :   if (ok) {
    1952           0 :     return true;
    1953             :   }
    1954           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
    1955           0 :                                    args.rval());
    1956             : }
    1957             : 
    1958             : static const JSJitInfo show_methodinfo = {
    1959             :   { (JSJitGetterOp)show_promiseWrapper },
    1960             :   { prototypes::id::PaymentRequest },
    1961             :   { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
    1962             :   JSJitInfo::Method,
    1963             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1964             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1965             :   false,  /* isInfallible. False in setters. */
    1966             :   false,  /* isMovable.  Not relevant for setters. */
    1967             :   false, /* isEliminatable.  Not relevant for setters. */
    1968             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1969             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1970             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1971             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1972             : };
    1973             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1974             : static_assert(0 < 1, "There is no slot for us");
    1975             : 
    1976             : static bool
    1977           0 : abort(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, const JSJitMethodCallArgs& args)
    1978             : {
    1979           0 :   binding_detail::FastErrorResult rv;
    1980           0 :   auto result(StrongOrRawPtr<Promise>(self->Abort(rv)));
    1981           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1982           0 :     return false;
    1983             :   }
    1984           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1985             :   static_assert(!IsPointer<decltype(result)>::value,
    1986             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
    1987           0 :   if (!ToJSValue(cx, result, args.rval())) {
    1988           0 :     return false;
    1989             :   }
    1990           0 :   return true;
    1991             : }
    1992             : 
    1993             : static bool
    1994           0 : abort_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, const JSJitMethodCallArgs& args)
    1995             : {
    1996             :   // Make sure to save the callee before someone maybe messes
    1997             :   // with rval().
    1998           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
    1999           0 :   bool ok = abort(cx, obj, self, args);
    2000           0 :   if (ok) {
    2001           0 :     return true;
    2002             :   }
    2003           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
    2004           0 :                                    args.rval());
    2005             : }
    2006             : 
    2007             : static const JSJitInfo abort_methodinfo = {
    2008             :   { (JSJitGetterOp)abort_promiseWrapper },
    2009             :   { prototypes::id::PaymentRequest },
    2010             :   { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
    2011             :   JSJitInfo::Method,
    2012             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2013             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    2014             :   false,  /* isInfallible. False in setters. */
    2015             :   false,  /* isMovable.  Not relevant for setters. */
    2016             :   false, /* isEliminatable.  Not relevant for setters. */
    2017             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2018             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2019             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2020             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2021             : };
    2022             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2023             : static_assert(0 < 1, "There is no slot for us");
    2024             : 
    2025             : static bool
    2026           0 : canMakePayment(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, const JSJitMethodCallArgs& args)
    2027             : {
    2028           0 :   binding_detail::FastErrorResult rv;
    2029           0 :   auto result(StrongOrRawPtr<Promise>(self->CanMakePayment(rv)));
    2030           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2031           0 :     return false;
    2032             :   }
    2033           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2034             :   static_assert(!IsPointer<decltype(result)>::value,
    2035             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
    2036           0 :   if (!ToJSValue(cx, result, args.rval())) {
    2037           0 :     return false;
    2038             :   }
    2039           0 :   return true;
    2040             : }
    2041             : 
    2042             : static bool
    2043           0 : canMakePayment_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, const JSJitMethodCallArgs& args)
    2044             : {
    2045             :   // Make sure to save the callee before someone maybe messes
    2046             :   // with rval().
    2047           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
    2048           0 :   bool ok = canMakePayment(cx, obj, self, args);
    2049           0 :   if (ok) {
    2050           0 :     return true;
    2051             :   }
    2052           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
    2053           0 :                                    args.rval());
    2054             : }
    2055             : 
    2056             : static const JSJitInfo canMakePayment_methodinfo = {
    2057             :   { (JSJitGetterOp)canMakePayment_promiseWrapper },
    2058             :   { prototypes::id::PaymentRequest },
    2059             :   { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
    2060             :   JSJitInfo::Method,
    2061             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2062             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    2063             :   false,  /* isInfallible. False in setters. */
    2064             :   false,  /* isMovable.  Not relevant for setters. */
    2065             :   false, /* isEliminatable.  Not relevant for setters. */
    2066             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2067             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2068             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2069             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2070             : };
    2071             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2072             : static_assert(0 < 1, "There is no slot for us");
    2073             : 
    2074             : static bool
    2075           0 : get_id(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, JSJitGetterCallArgs args)
    2076             : {
    2077           0 :   DOMString result;
    2078           0 :   self->GetId(result);
    2079           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2080           0 :   if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    2081           0 :     return false;
    2082             :   }
    2083           0 :   return true;
    2084             : }
    2085             : 
    2086             : static const JSJitInfo id_getterinfo = {
    2087             :   { (JSJitGetterOp)get_id },
    2088             :   { prototypes::id::PaymentRequest },
    2089             :   { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
    2090             :   JSJitInfo::Getter,
    2091             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2092             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
    2093             :   false,  /* isInfallible. False in setters. */
    2094             :   false,  /* isMovable.  Not relevant for setters. */
    2095             :   false, /* isEliminatable.  Not relevant for setters. */
    2096             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2097             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2098             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2099             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2100             : };
    2101             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2102             : static_assert(0 < 1, "There is no slot for us");
    2103             : 
    2104             : static bool
    2105           0 : get_shippingAddress(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, JSJitGetterCallArgs args)
    2106             : {
    2107           0 :   auto result(StrongOrRawPtr<mozilla::dom::PaymentAddress>(self->GetShippingAddress()));
    2108           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2109           0 :   if (!result) {
    2110           0 :     args.rval().setNull();
    2111           0 :     return true;
    2112             :   }
    2113           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    2114           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    2115           0 :     return false;
    2116             :   }
    2117           0 :   return true;
    2118             : }
    2119             : 
    2120             : static const JSJitInfo shippingAddress_getterinfo = {
    2121             :   { (JSJitGetterOp)get_shippingAddress },
    2122             :   { prototypes::id::PaymentRequest },
    2123             :   { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
    2124             :   JSJitInfo::Getter,
    2125             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2126             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    2127             :   false,  /* isInfallible. False in setters. */
    2128             :   false,  /* isMovable.  Not relevant for setters. */
    2129             :   false, /* isEliminatable.  Not relevant for setters. */
    2130             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2131             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2132             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2133             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2134             : };
    2135             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2136             : static_assert(0 < 1, "There is no slot for us");
    2137             : 
    2138             : static bool
    2139           0 : get_shippingOption(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, JSJitGetterCallArgs args)
    2140             : {
    2141           0 :   DOMString result;
    2142           0 :   self->GetShippingOption(result);
    2143           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2144           0 :   if (!xpc::StringToJsval(cx, result, args.rval())) {
    2145           0 :     return false;
    2146             :   }
    2147           0 :   return true;
    2148             : }
    2149             : 
    2150             : static const JSJitInfo shippingOption_getterinfo = {
    2151             :   { (JSJitGetterOp)get_shippingOption },
    2152             :   { prototypes::id::PaymentRequest },
    2153             :   { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
    2154             :   JSJitInfo::Getter,
    2155             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2156             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    2157             :   false,  /* isInfallible. False in setters. */
    2158             :   false,  /* isMovable.  Not relevant for setters. */
    2159             :   false, /* isEliminatable.  Not relevant for setters. */
    2160             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2161             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2162             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2163             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2164             : };
    2165             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2166             : static_assert(0 < 1, "There is no slot for us");
    2167             : 
    2168             : static bool
    2169           0 : get_shippingType(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, JSJitGetterCallArgs args)
    2170             : {
    2171           0 :   Nullable<PaymentShippingType> result(self->GetShippingType());
    2172           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2173           0 :   if (result.IsNull()) {
    2174           0 :     args.rval().setNull();
    2175           0 :     return true;
    2176             :   } else {
    2177           0 :     if (!ToJSValue(cx, result.Value(), args.rval())) {
    2178           0 :       return false;
    2179             :     }
    2180           0 :     return true;
    2181             :   }
    2182             : }
    2183             : 
    2184             : static const JSJitInfo shippingType_getterinfo = {
    2185             :   { (JSJitGetterOp)get_shippingType },
    2186             :   { prototypes::id::PaymentRequest },
    2187             :   { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
    2188             :   JSJitInfo::Getter,
    2189             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2190             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    2191             :   false,  /* isInfallible. False in setters. */
    2192             :   false,  /* isMovable.  Not relevant for setters. */
    2193             :   false, /* isEliminatable.  Not relevant for setters. */
    2194             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2195             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2196             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2197             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2198             : };
    2199             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2200             : static_assert(0 < 1, "There is no slot for us");
    2201             : 
    2202             : static bool
    2203           0 : get_onshippingaddresschange(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, JSJitGetterCallArgs args)
    2204             : {
    2205           0 :   RefPtr<EventHandlerNonNull> result(self->GetOnshippingaddresschange());
    2206           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2207           0 :   if (result) {
    2208           0 :     args.rval().setObjectOrNull(GetCallbackFromCallbackObject(result));
    2209           0 :     if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
    2210           0 :       return false;
    2211             :     }
    2212           0 :     return true;
    2213             :   } else {
    2214           0 :     args.rval().setNull();
    2215           0 :     return true;
    2216             :   }
    2217             : }
    2218             : 
    2219             : static bool
    2220           0 : set_onshippingaddresschange(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, JSJitSetterCallArgs args)
    2221             : {
    2222           0 :   RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
    2223           0 :   if (args[0].isObject()) {
    2224             :     { // scope for tempRoot
    2225           0 :       JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
    2226           0 :       arg0 = new binding_detail::FastEventHandlerNonNull(tempRoot);
    2227             :     }
    2228             :   } else {
    2229           0 :     arg0 = nullptr;
    2230             :   }
    2231           0 :   self->SetOnshippingaddresschange(Constify(arg0));
    2232           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2233             : 
    2234           0 :   return true;
    2235             : }
    2236             : 
    2237             : static const JSJitInfo onshippingaddresschange_getterinfo = {
    2238             :   { (JSJitGetterOp)get_onshippingaddresschange },
    2239             :   { prototypes::id::PaymentRequest },
    2240             :   { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
    2241             :   JSJitInfo::Getter,
    2242             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2243             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    2244             :   false,  /* isInfallible. False in setters. */
    2245             :   false,  /* isMovable.  Not relevant for setters. */
    2246             :   false, /* isEliminatable.  Not relevant for setters. */
    2247             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2248             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2249             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2250             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2251             : };
    2252             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2253             : static_assert(0 < 1, "There is no slot for us");
    2254             : static const JSJitInfo onshippingaddresschange_setterinfo = {
    2255             :   { (JSJitGetterOp)set_onshippingaddresschange },
    2256             :   { prototypes::id::PaymentRequest },
    2257             :   { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
    2258             :   JSJitInfo::Setter,
    2259             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2260             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    2261             :   false,  /* isInfallible. False in setters. */
    2262             :   false,  /* isMovable.  Not relevant for setters. */
    2263             :   false, /* isEliminatable.  Not relevant for setters. */
    2264             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2265             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2266             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2267             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2268             : };
    2269             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2270             : static_assert(0 < 1, "There is no slot for us");
    2271             : 
    2272             : static bool
    2273           0 : get_onshippingoptionchange(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, JSJitGetterCallArgs args)
    2274             : {
    2275           0 :   RefPtr<EventHandlerNonNull> result(self->GetOnshippingoptionchange());
    2276           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2277           0 :   if (result) {
    2278           0 :     args.rval().setObjectOrNull(GetCallbackFromCallbackObject(result));
    2279           0 :     if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
    2280           0 :       return false;
    2281             :     }
    2282           0 :     return true;
    2283             :   } else {
    2284           0 :     args.rval().setNull();
    2285           0 :     return true;
    2286             :   }
    2287             : }
    2288             : 
    2289             : static bool
    2290           0 : set_onshippingoptionchange(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PaymentRequest* self, JSJitSetterCallArgs args)
    2291             : {
    2292           0 :   RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
    2293           0 :   if (args[0].isObject()) {
    2294             :     { // scope for tempRoot
    2295           0 :       JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
    2296           0 :       arg0 = new binding_detail::FastEventHandlerNonNull(tempRoot);
    2297             :     }
    2298             :   } else {
    2299           0 :     arg0 = nullptr;
    2300             :   }
    2301           0 :   self->SetOnshippingoptionchange(Constify(arg0));
    2302           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2303             : 
    2304           0 :   return true;
    2305             : }
    2306             : 
    2307             : static const JSJitInfo onshippingoptionchange_getterinfo = {
    2308             :   { (JSJitGetterOp)get_onshippingoptionchange },
    2309             :   { prototypes::id::PaymentRequest },
    2310             :   { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
    2311             :   JSJitInfo::Getter,
    2312             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2313             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    2314             :   false,  /* isInfallible. False in setters. */
    2315             :   false,  /* isMovable.  Not relevant for setters. */
    2316             :   false, /* isEliminatable.  Not relevant for setters. */
    2317             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2318             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2319             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2320             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2321             : };
    2322             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2323             : static_assert(0 < 1, "There is no slot for us");
    2324             : static const JSJitInfo onshippingoptionchange_setterinfo = {
    2325             :   { (JSJitGetterOp)set_onshippingoptionchange },
    2326             :   { prototypes::id::PaymentRequest },
    2327             :   { PrototypeTraits<prototypes::id::PaymentRequest>::Depth },
    2328             :   JSJitInfo::Setter,
    2329             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2330             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    2331             :   false,  /* isInfallible. False in setters. */
    2332             :   false,  /* isMovable.  Not relevant for setters. */
    2333             :   false, /* isEliminatable.  Not relevant for setters. */
    2334             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2335             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2336             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2337             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2338             : };
    2339             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2340             : static_assert(0 < 1, "There is no slot for us");
    2341             : 
    2342             : static bool
    2343           0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
    2344             : {
    2345           0 :   mozilla::dom::PaymentRequest* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PaymentRequest>(obj);
    2346             :   // We don't want to preserve if we don't have a wrapper, and we
    2347             :   // obviously can't preserve if we're not initialized.
    2348           0 :   if (self && self->GetWrapperPreserveColor()) {
    2349           0 :     PreserveWrapper(self);
    2350             :   }
    2351           0 :   return true;
    2352             : }
    2353             : 
    2354             : static void
    2355           0 : _finalize(js::FreeOp* fop, JSObject* obj)
    2356             : {
    2357           0 :   mozilla::dom::PaymentRequest* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PaymentRequest>(obj);
    2358           0 :   if (self) {
    2359           0 :     ClearWrapper(self, self, obj);
    2360           0 :     AddForDeferredFinalization<mozilla::dom::PaymentRequest>(self);
    2361             :   }
    2362           0 : }
    2363             : 
    2364             : static void
    2365           0 : _objectMoved(JSObject* obj, const JSObject* old)
    2366             : {
    2367           0 :   mozilla::dom::PaymentRequest* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PaymentRequest>(obj);
    2368           0 :   if (self) {
    2369           0 :     UpdateWrapper(self, self, obj, old);
    2370             :   }
    2371           0 : }
    2372             : 
    2373             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    2374             : #if defined(__clang__)
    2375             : #pragma clang diagnostic push
    2376             : #pragma clang diagnostic ignored "-Wmissing-braces"
    2377             : #endif
    2378             : static const JSFunctionSpec sMethods_specs[] = {
    2379             :   JS_FNSPEC("show", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&show_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    2380             :   JS_FNSPEC("abort", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&abort_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    2381             :   JS_FNSPEC("canMakePayment", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&canMakePayment_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    2382             :   JS_FS_END
    2383             : };
    2384             : #if defined(__clang__)
    2385             : #pragma clang diagnostic pop
    2386             : #endif
    2387             : 
    2388             : static PrefableDisablers sMethods_disablers0 = {
    2389             :   true, true, 0, nullptr
    2390             : };
    2391             : 
    2392             : // Can't be const because the pref-enabled boolean needs to be writable
    2393             : static Prefable<const JSFunctionSpec> sMethods[] = {
    2394             :   { &sMethods_disablers0, &sMethods_specs[0] },
    2395             :   { nullptr, nullptr }
    2396             : };
    2397             : 
    2398             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    2399             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    2400             : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    2401             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    2402             : 
    2403             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    2404             : #if defined(__clang__)
    2405             : #pragma clang diagnostic push
    2406             : #pragma clang diagnostic ignored "-Wmissing-braces"
    2407             : #endif
    2408             : static const JSPropertySpec sAttributes_specs[] = {
    2409             :   { "id", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &id_getterinfo, nullptr, nullptr },
    2410             :   { "shippingAddress", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &shippingAddress_getterinfo, nullptr, nullptr },
    2411             :   { "shippingOption", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &shippingOption_getterinfo, nullptr, nullptr },
    2412             :   { "shippingType", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &shippingType_getterinfo, nullptr, nullptr },
    2413             :   { "onshippingaddresschange", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &onshippingaddresschange_getterinfo, GenericBindingSetter, &onshippingaddresschange_setterinfo },
    2414             :   { "onshippingoptionchange", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &onshippingoptionchange_getterinfo, GenericBindingSetter, &onshippingoptionchange_setterinfo },
    2415             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
    2416             : };
    2417             : #if defined(__clang__)
    2418             : #pragma clang diagnostic pop
    2419             : #endif
    2420             : 
    2421             : static PrefableDisablers sAttributes_disablers0 = {
    2422             :   true, true, 0, nullptr
    2423             : };
    2424             : 
    2425             : // Can't be const because the pref-enabled boolean needs to be writable
    2426             : static Prefable<const JSPropertySpec> sAttributes[] = {
    2427             :   { &sAttributes_disablers0, &sAttributes_specs[0] },
    2428             :   { nullptr, nullptr }
    2429             : };
    2430             : 
    2431             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    2432             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    2433             : static_assert(6 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    2434             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    2435             : 
    2436             : 
    2437             : static uint16_t sNativeProperties_sortedPropertyIndices[9];
    2438             : static PropertyInfo sNativeProperties_propertyInfos[9];
    2439             : 
    2440             : static const NativePropertiesN<2> sNativeProperties = {
    2441             :   false, 0,
    2442             :   false, 0,
    2443             :   true,  0 /* sMethods */,
    2444             :   true,  1 /* sAttributes */,
    2445             :   false, 0,
    2446             :   false, 0,
    2447             :   false, 0,
    2448             :   -1,
    2449             :   9,
    2450             :   sNativeProperties_sortedPropertyIndices,
    2451             :   {
    2452             :     { sMethods, &sNativeProperties_propertyInfos[0] },
    2453             :     { sAttributes, &sNativeProperties_propertyInfos[3] }
    2454             :   }
    2455             : };
    2456             : static_assert(9 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
    2457             :     "We have a property info count that is oversized");
    2458             : 
    2459             : static bool
    2460           0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
    2461             : {
    2462           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    2463           0 :   JS::Rooted<JSObject*> obj(cx, &args.callee());
    2464           0 :   if (!args.isConstructing()) {
    2465             :     // XXXbz wish I could get the name from the callee instead of
    2466             :     // Adding more relocations
    2467           0 :     return ThrowConstructorWithoutNew(cx, "PaymentRequest");
    2468             :   }
    2469             : 
    2470           0 :   GlobalObject global(cx, obj);
    2471           0 :   if (global.Failed()) {
    2472           0 :     return false;
    2473             :   }
    2474             : 
    2475           0 :   JS::Rooted<JSObject*> desiredProto(cx);
    2476           0 :   if (!GetDesiredProto(cx, args, &desiredProto)) {
    2477           0 :     return false;
    2478             :   }
    2479             : 
    2480           0 :   if (MOZ_UNLIKELY(args.length() < 2)) {
    2481           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "PaymentRequest");
    2482             :   }
    2483           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2484           0 :   binding_detail::AutoSequence<PaymentMethodData> arg0;
    2485           0 :   SequenceRooter<PaymentMethodData> arg0_holder(cx, &arg0);
    2486           0 :   if (args[0].isObject()) {
    2487           0 :     JS::ForOfIterator iter(cx);
    2488           0 :     if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) {
    2489           0 :       return false;
    2490             :     }
    2491           0 :     if (!iter.valueIsIterable()) {
    2492           0 :       ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 1 of PaymentRequest.constructor");
    2493           0 :       return false;
    2494             :     }
    2495           0 :     binding_detail::AutoSequence<PaymentMethodData> &arr = arg0;
    2496           0 :     JS::Rooted<JS::Value> temp(cx);
    2497             :     while (true) {
    2498             :       bool done;
    2499           0 :       if (!iter.next(&temp, &done)) {
    2500           0 :         return false;
    2501             :       }
    2502           0 :       if (done) {
    2503           0 :         break;
    2504             :       }
    2505           0 :       PaymentMethodData* slotPtr = arr.AppendElement(mozilla::fallible);
    2506           0 :       if (!slotPtr) {
    2507           0 :         JS_ReportOutOfMemory(cx);
    2508           0 :         return false;
    2509             :       }
    2510           0 :       PaymentMethodData& slot = *slotPtr;
    2511           0 :       if (!slot.Init(cx, temp,  "Element of argument 1 of PaymentRequest.constructor", false)) {
    2512           0 :         return false;
    2513             :       }
    2514           0 :     }
    2515             :   } else {
    2516           0 :     ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 1 of PaymentRequest.constructor");
    2517           0 :     return false;
    2518             :   }
    2519           0 :   RootedDictionary<binding_detail::FastPaymentDetailsInit> arg1(cx);
    2520           0 :   if (!arg1.Init(cx, args[1],  "Argument 2 of PaymentRequest.constructor", false)) {
    2521           0 :     return false;
    2522             :   }
    2523           0 :   binding_detail::FastPaymentOptions arg2;
    2524           0 :   if (!arg2.Init(cx, (args.hasDefined(2)) ? args[2] : JS::NullHandleValue,  "Argument 3 of PaymentRequest.constructor", false)) {
    2525           0 :     return false;
    2526             :   }
    2527           0 :   Maybe<JSAutoCompartment> ac;
    2528           0 :   if (objIsXray) {
    2529           0 :     obj = js::CheckedUnwrap(obj);
    2530           0 :     if (!obj) {
    2531           0 :       return false;
    2532             :     }
    2533           0 :     ac.emplace(cx, obj);
    2534           0 :     if (!JS_WrapObject(cx, &desiredProto)) {
    2535           0 :       return false;
    2536             :     }
    2537           0 :     for (uint32_t indexName0 = 0; indexName0 < arg0.Length(); ++indexName0) {
    2538           0 :       if (arg0[indexName0].mData.WasPassed()) {
    2539           0 :         if (!JS_WrapObject(cx, JS::MutableHandle<JSObject*>::fromMarkedLocation(&arg0[indexName0].mData.Value()))) {
    2540           0 :           return false;
    2541             :         }
    2542             :       }
    2543             :     }
    2544           0 :     if (arg1.mModifiers.WasPassed()) {
    2545           0 :       for (uint32_t indexName0 = 0; indexName0 < arg1.mModifiers.Value().Length(); ++indexName0) {
    2546           0 :         if (arg1.mModifiers.Value()[indexName0].mData.WasPassed()) {
    2547           0 :           if (!JS_WrapObject(cx, JS::MutableHandle<JSObject*>::fromMarkedLocation(&arg1.mModifiers.Value()[indexName0].mData.Value()))) {
    2548           0 :             return false;
    2549             :           }
    2550             :         }
    2551             :       }
    2552             :     }
    2553             :   }
    2554           0 :   binding_detail::FastErrorResult rv;
    2555           0 :   auto result(StrongOrRawPtr<mozilla::dom::PaymentRequest>(mozilla::dom::PaymentRequest::Constructor(global, Constify(arg0), Constify(arg1), Constify(arg2), rv)));
    2556           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2557           0 :     return false;
    2558             :   }
    2559           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2560             :   static_assert(!IsPointer<decltype(result)>::value,
    2561             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
    2562           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
    2563           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    2564           0 :     return false;
    2565             :   }
    2566           0 :   return true;
    2567             : }
    2568             : 
    2569             : static const js::ClassOps sInterfaceObjectClassOps = {
    2570             :     nullptr,               /* addProperty */
    2571             :     nullptr,               /* delProperty */
    2572             :     nullptr,               /* getProperty */
    2573             :     nullptr,               /* setProperty */
    2574             :     nullptr,               /* enumerate */
    2575             :     nullptr,               /* newEnumerate */
    2576             :     nullptr,               /* resolve */
    2577             :     nullptr,               /* mayResolve */
    2578             :     nullptr,               /* finalize */
    2579             :     _constructor, /* call */
    2580             :     nullptr,               /* hasInstance */
    2581             :     _constructor, /* construct */
    2582             :     nullptr,               /* trace */
    2583             : };
    2584             : 
    2585             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
    2586             :   {
    2587             :     "Function",
    2588             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
    2589             :     &sInterfaceObjectClassOps,
    2590             :     JS_NULL_CLASS_SPEC,
    2591             :     JS_NULL_CLASS_EXT,
    2592             :     &sInterfaceObjectClassObjectOps
    2593             :   },
    2594             :   eInterface,
    2595             :   true,
    2596             :   prototypes::id::PaymentRequest,
    2597             :   PrototypeTraits<prototypes::id::PaymentRequest>::Depth,
    2598             :   sNativePropertyHooks,
    2599             :   "function PaymentRequest() {\n    [native code]\n}",
    2600             :   EventTargetBinding::GetConstructorObject
    2601             : };
    2602             : 
    2603             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
    2604             :   {
    2605             :     "PaymentRequestPrototype",
    2606             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    2607             :     JS_NULL_CLASS_OPS,
    2608             :     JS_NULL_CLASS_SPEC,
    2609             :     JS_NULL_CLASS_EXT,
    2610             :     JS_NULL_OBJECT_OPS
    2611             :   },
    2612             :   eInterfacePrototype,
    2613             :   false,
    2614             :   prototypes::id::PaymentRequest,
    2615             :   PrototypeTraits<prototypes::id::PaymentRequest>::Depth,
    2616             :   sNativePropertyHooks,
    2617             :   "[object PaymentRequestPrototype]",
    2618             :   EventTargetBinding::GetProtoObject
    2619             : };
    2620             : 
    2621             : bool
    2622           0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
    2623             : {
    2624           0 :   return mozilla::dom::PaymentRequest::PrefEnabled(aCx, aObj) &&
    2625           0 :          mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
    2626             : }
    2627             : 
    2628             : JSObject*
    2629           0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
    2630             : {
    2631           0 :   return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
    2632             : }
    2633             : 
    2634             : static const js::ClassOps sClassOps = {
    2635             :   _addProperty, /* addProperty */
    2636             :   nullptr,               /* delProperty */
    2637             :   nullptr,               /* getProperty */
    2638             :   nullptr,               /* setProperty */
    2639             :   nullptr,               /* enumerate */
    2640             :   nullptr, /* newEnumerate */
    2641             :   nullptr, /* resolve */
    2642             :   nullptr, /* mayResolve */
    2643             :   _finalize, /* finalize */
    2644             :   nullptr, /* call */
    2645             :   nullptr,               /* hasInstance */
    2646             :   nullptr,               /* construct */
    2647             :   nullptr, /* trace */
    2648             : };
    2649             : 
    2650             : static const js::ClassExtension sClassExtension = {
    2651             :   nullptr, /* weakmapKeyDelegateOp */
    2652             :   _objectMoved /* objectMovedOp */
    2653             : };
    2654             : 
    2655             : static const DOMJSClass sClass = {
    2656             :   { "PaymentRequest",
    2657             :     JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
    2658             :     &sClassOps,
    2659             :     JS_NULL_CLASS_SPEC,
    2660             :     &sClassExtension,
    2661             :     JS_NULL_OBJECT_OPS
    2662             :   },
    2663             :   { prototypes::id::EventTarget, prototypes::id::PaymentRequest, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
    2664             :   IsBaseOf<nsISupports, mozilla::dom::PaymentRequest >::value,
    2665             :   sNativePropertyHooks,
    2666             :   FindAssociatedGlobalForNative<mozilla::dom::PaymentRequest>::Get,
    2667             :   GetProtoObjectHandle,
    2668             :   GetCCParticipant<mozilla::dom::PaymentRequest>::Get()
    2669             : };
    2670             : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
    2671             :               "Must have the right minimal number of reserved slots.");
    2672             : static_assert(1 >= 1,
    2673             :               "Must have enough reserved slots.");
    2674             : 
    2675             : const JSClass*
    2676           0 : GetJSClass()
    2677             : {
    2678           0 :   return sClass.ToJSClass();
    2679             : }
    2680             : 
    2681             : bool
    2682           0 : Wrap(JSContext* aCx, mozilla::dom::PaymentRequest* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
    2683             : {
    2684             :   MOZ_ASSERT(static_cast<mozilla::dom::PaymentRequest*>(aObject) ==
    2685             :              reinterpret_cast<mozilla::dom::PaymentRequest*>(aObject),
    2686             :              "Multiple inheritance for mozilla::dom::PaymentRequest is broken.");
    2687             :   MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
    2688             :              reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
    2689             :              "Multiple inheritance for mozilla::dom::EventTarget is broken.");
    2690           0 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
    2691           0 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
    2692           0 :   MOZ_ASSERT(!aCache->GetWrapper(),
    2693             :              "You should probably not be using Wrap() directly; use "
    2694             :              "GetOrCreateDOMReflector instead");
    2695             : 
    2696           0 :   MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
    2697             :              "nsISupports must be on our primary inheritance chain");
    2698             : 
    2699           0 :   JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
    2700           0 :   if (!global) {
    2701           0 :     return false;
    2702             :   }
    2703           0 :   MOZ_ASSERT(JS_IsGlobalObject(global));
    2704           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(global));
    2705             : 
    2706             :   // That might have ended up wrapping us already, due to the wonders
    2707             :   // of XBL.  Check for that, and bail out as needed.
    2708           0 :   aReflector.set(aCache->GetWrapper());
    2709           0 :   if (aReflector) {
    2710             : #ifdef DEBUG
    2711           0 :     binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
    2712             : #endif // DEBUG
    2713           0 :     return true;
    2714             :   }
    2715             : 
    2716           0 :   JSAutoCompartment ac(aCx, global);
    2717           0 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
    2718           0 :   if (!canonicalProto) {
    2719           0 :     return false;
    2720             :   }
    2721           0 :   JS::Rooted<JSObject*> proto(aCx);
    2722           0 :   if (aGivenProto) {
    2723           0 :     proto = aGivenProto;
    2724             :     // Unfortunately, while aGivenProto was in the compartment of aCx
    2725             :     // coming in, we changed compartments to that of "parent" so may need
    2726             :     // to wrap the proto here.
    2727           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
    2728           0 :       if (!JS_WrapObject(aCx, &proto)) {
    2729           0 :         return false;
    2730             :       }
    2731             :     }
    2732             :   } else {
    2733           0 :     proto = canonicalProto;
    2734             :   }
    2735             : 
    2736           0 :   BindingJSObjectCreator<mozilla::dom::PaymentRequest> creator(aCx);
    2737           0 :   creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
    2738           0 :   if (!aReflector) {
    2739           0 :     return false;
    2740             :   }
    2741             : 
    2742           0 :   aCache->SetWrapper(aReflector);
    2743           0 :   creator.InitializationSucceeded();
    2744             : 
    2745           0 :   MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
    2746             :              aCache->GetWrapperPreserveColor() == aReflector);
    2747             :   // If proto != canonicalProto, we have to preserve our wrapper;
    2748             :   // otherwise we won't be able to properly recreate it later, since
    2749             :   // we won't know what proto to use.  Note that we don't check
    2750             :   // aGivenProto here, since it's entirely possible (and even
    2751             :   // somewhat common) to have a non-null aGivenProto which is the
    2752             :   // same as canonicalProto.
    2753           0 :   if (proto != canonicalProto) {
    2754           0 :     PreserveWrapper(aObject);
    2755             :   }
    2756             : 
    2757           0 :   return true;
    2758             : }
    2759             : 
    2760             : const NativePropertyHooks sNativePropertyHooks[] = { {
    2761             :   nullptr,
    2762             :   nullptr,
    2763             :   nullptr,
    2764             :   { sNativeProperties.Upcast(), nullptr },
    2765             :   prototypes::id::PaymentRequest,
    2766             :   constructors::id::PaymentRequest,
    2767             :   EventTargetBinding::sNativePropertyHooks,
    2768             :   &DefaultXrayExpandoObjectClass
    2769             : } };
    2770             : 
    2771             : void
    2772           0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    2773             : {
    2774           0 :   JS::Handle<JSObject*> parentProto(EventTargetBinding::GetProtoObjectHandle(aCx));
    2775           0 :   if (!parentProto) {
    2776           0 :     return;
    2777             :   }
    2778             : 
    2779           0 :   JS::Handle<JSObject*> constructorProto(EventTargetBinding::GetConstructorObjectHandle(aCx));
    2780           0 :   if (!constructorProto) {
    2781           0 :     return;
    2782             :   }
    2783             : 
    2784             :   static bool sIdsInited = false;
    2785           0 :   if (!sIdsInited && NS_IsMainThread()) {
    2786           0 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
    2787           0 :       return;
    2788             :     }
    2789           0 :     sIdsInited = true;
    2790             :   }
    2791             : 
    2792           0 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::PaymentRequest);
    2793           0 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::PaymentRequest);
    2794           0 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    2795             :                               &sPrototypeClass.mBase, protoCache,
    2796             :                               constructorProto, &sInterfaceObjectClass.mBase, 2, nullptr,
    2797             :                               interfaceCache,
    2798             :                               sNativeProperties.Upcast(),
    2799             :                               nullptr,
    2800             :                               "PaymentRequest", aDefineOnGlobal,
    2801             :                               nullptr,
    2802           0 :                               false);
    2803             : }
    2804             : 
    2805             : JS::Handle<JSObject*>
    2806           0 : GetProtoObjectHandle(JSContext* aCx)
    2807             : {
    2808             :   /* Get the interface prototype object for this class.  This will create the
    2809             :      object as needed. */
    2810           0 :   bool aDefineOnGlobal = true;
    2811             : 
    2812             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    2813           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    2814           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    2815           0 :     return nullptr;
    2816             :   }
    2817             : 
    2818             :   /* Check to see whether the interface objects are already installed */
    2819           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    2820           0 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::PaymentRequest)) {
    2821           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    2822           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    2823             :   }
    2824             : 
    2825             :   /*
    2826             :    * The object might _still_ be null, but that's OK.
    2827             :    *
    2828             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    2829             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    2830             :    * changed after they have been set.
    2831             :    *
    2832             :    * Calling address() avoids the read read barrier that does gray
    2833             :    * unmarking, but it's not possible for the object to be gray here.
    2834             :    */
    2835             : 
    2836           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::PaymentRequest);
    2837           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    2838           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    2839             : }
    2840             : 
    2841             : JS::Handle<JSObject*>
    2842           0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
    2843             : {
    2844             :   /* Get the interface object for this class.  This will create the object as
    2845             :      needed. */
    2846             : 
    2847             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    2848           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    2849           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    2850           0 :     return nullptr;
    2851             :   }
    2852             : 
    2853             :   /* Check to see whether the interface objects are already installed */
    2854           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    2855           0 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::PaymentRequest)) {
    2856           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    2857           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    2858             :   }
    2859             : 
    2860             :   /*
    2861             :    * The object might _still_ be null, but that's OK.
    2862             :    *
    2863             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    2864             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    2865             :    * changed after they have been set.
    2866             :    *
    2867             :    * Calling address() avoids the read read barrier that does gray
    2868             :    * unmarking, but it's not possible for the object to be gray here.
    2869             :    */
    2870             : 
    2871           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::PaymentRequest);
    2872           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    2873           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    2874             : }
    2875             : 
    2876             : JSObject*
    2877           0 : GetConstructorObject(JSContext* aCx)
    2878             : {
    2879           0 :   return GetConstructorObjectHandle(aCx);
    2880             : }
    2881             : 
    2882             : } // namespace PaymentRequestBinding
    2883             : 
    2884             : 
    2885             : 
    2886             : } // namespace dom
    2887             : } // namespace mozilla

Generated by: LCOV version 1.13