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

          Line data    Source code
       1             : /* THIS FILE IS AUTOGENERATED FROM TestInterfaceJSMaplikeSetlikeIterable.webidl BY Codegen.py - DO NOT EDIT */
       2             : 
       3             : #include "AtomList.h"
       4             : #include "TestInterfaceJSMaplikeSetlikeIterableBinding.h"
       5             : #include "WrapperFactory.h"
       6             : #include "XrayWrapper.h"
       7             : #include "mozilla/OwningNonNull.h"
       8             : #include "mozilla/Preferences.h"
       9             : #include "mozilla/dom/BindingUtils.h"
      10             : #include "mozilla/dom/DOMJSClass.h"
      11             : #include "mozilla/dom/DOMJSProxyHandler.h"
      12             : #include "mozilla/dom/IterableIterator.h"
      13             : #include "mozilla/dom/NonRefcountedDOMObject.h"
      14             : #include "mozilla/dom/PrimitiveConversions.h"
      15             : #include "mozilla/dom/TestInterfaceIterableDouble.h"
      16             : #include "mozilla/dom/TestInterfaceIterableDoubleUnion.h"
      17             : #include "mozilla/dom/TestInterfaceIterableSingle.h"
      18             : #include "mozilla/dom/TestInterfaceMaplike.h"
      19             : #include "mozilla/dom/TestInterfaceMaplikeObject.h"
      20             : #include "mozilla/dom/TestInterfaceSetlike.h"
      21             : #include "mozilla/dom/TestInterfaceSetlikeNode.h"
      22             : #include "mozilla/dom/ToJSValue.h"
      23             : #include "mozilla/dom/UnionConversions.h"
      24             : #include "mozilla/dom/XrayExpandoClass.h"
      25             : #include "nsContentUtils.h"
      26             : #include "nsIGlobalObject.h"
      27             : #include "nsINode.h"
      28             : 
      29             : namespace mozilla {
      30             : namespace dom {
      31             : 
      32             : bool
      33           0 : StringOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
      34             : {
      35           0 :   switch (mType) {
      36             :     case eUninitialized: {
      37           0 :       return false;
      38             :       break;
      39             :     }
      40             :     case eString: {
      41           0 :       if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
      42           0 :         return false;
      43             :       }
      44           0 :       return true;
      45             :       break;
      46             :     }
      47             :     case eLong: {
      48           0 :       rval.setInt32(int32_t(mValue.mLong.Value()));
      49           0 :       return true;
      50             :       break;
      51             :     }
      52             :     default: {
      53           0 :       return false;
      54             :       break;
      55             :     }
      56             :   }
      57             : 
      58             :   return false;
      59             : }
      60             : 
      61             : 
      62             : nsString&
      63           0 : OwningStringOrLong::RawSetAsString()
      64             : {
      65           0 :   if (mType == eString) {
      66           0 :     return mValue.mString.Value();
      67             :   }
      68           0 :   MOZ_ASSERT(mType == eUninitialized);
      69           0 :   mType = eString;
      70           0 :   return mValue.mString.SetValue();
      71             : }
      72             : 
      73             : nsString&
      74           0 : OwningStringOrLong::SetAsString()
      75             : {
      76           0 :   if (mType == eString) {
      77           0 :     return mValue.mString.Value();
      78             :   }
      79           0 :   Uninit();
      80           0 :   mType = eString;
      81           0 :   return mValue.mString.SetValue();
      82             : }
      83             : 
      84             : bool
      85           0 : OwningStringOrLong::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
      86             : {
      87           0 :   tryNext = false;
      88             :   { // scope for memberSlot
      89           0 :     nsString& memberSlot = RawSetAsString();
      90           0 :     if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
      91           0 :       return false;
      92             :     }
      93             :   }
      94           0 :   return true;
      95             : }
      96             : 
      97             : 
      98             : void
      99           0 : OwningStringOrLong::DestroyString()
     100             : {
     101           0 :   MOZ_ASSERT(IsString(), "Wrong type!");
     102           0 :   mValue.mString.Destroy();
     103           0 :   mType = eUninitialized;
     104           0 : }
     105             : 
     106             : 
     107             : 
     108             : 
     109             : int32_t&
     110           0 : OwningStringOrLong::RawSetAsLong()
     111             : {
     112           0 :   if (mType == eLong) {
     113           0 :     return mValue.mLong.Value();
     114             :   }
     115           0 :   MOZ_ASSERT(mType == eUninitialized);
     116           0 :   mType = eLong;
     117           0 :   return mValue.mLong.SetValue();
     118             : }
     119             : 
     120             : int32_t&
     121           0 : OwningStringOrLong::SetAsLong()
     122             : {
     123           0 :   if (mType == eLong) {
     124           0 :     return mValue.mLong.Value();
     125             :   }
     126           0 :   Uninit();
     127           0 :   mType = eLong;
     128           0 :   return mValue.mLong.SetValue();
     129             : }
     130             : 
     131             : bool
     132           0 : OwningStringOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
     133             : {
     134           0 :   tryNext = false;
     135             :   { // scope for memberSlot
     136           0 :     int32_t& memberSlot = RawSetAsLong();
     137           0 :     if (!ValueToPrimitive<int32_t, eDefault>(cx, value, &memberSlot)) {
     138           0 :       return false;
     139             :     }
     140             :   }
     141           0 :   return true;
     142             : }
     143             : 
     144             : void
     145           0 : OwningStringOrLong::DestroyLong()
     146             : {
     147           0 :   MOZ_ASSERT(IsLong(), "Wrong type!");
     148           0 :   mValue.mLong.Destroy();
     149           0 :   mType = eUninitialized;
     150           0 : }
     151             : 
     152             : 
     153             : 
     154             : 
     155             : void
     156           0 : OwningStringOrLong::Uninit()
     157             : {
     158           0 :   switch (mType) {
     159             :     case eUninitialized: {
     160           0 :       break;
     161             :     }
     162             :     case eString: {
     163           0 :       DestroyString();
     164           0 :       break;
     165             :     }
     166             :     case eLong: {
     167           0 :       DestroyLong();
     168           0 :       break;
     169             :     }
     170             :   }
     171           0 : }
     172             : 
     173             : bool
     174           0 : OwningStringOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
     175             : {
     176           0 :   switch (mType) {
     177             :     case eUninitialized: {
     178           0 :       return false;
     179             :       break;
     180             :     }
     181             :     case eString: {
     182           0 :       if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
     183           0 :         return false;
     184             :       }
     185           0 :       return true;
     186             :       break;
     187             :     }
     188             :     case eLong: {
     189           0 :       rval.setInt32(int32_t(mValue.mLong.Value()));
     190           0 :       return true;
     191             :       break;
     192             :     }
     193             :     default: {
     194           0 :       return false;
     195             :       break;
     196             :     }
     197             :   }
     198             : 
     199             :   return false;
     200             : }
     201             : 
     202             : void
     203           0 : OwningStringOrLong::TraceUnion(JSTracer* trc)
     204             : {
     205           0 : }
     206             : 
     207             : OwningStringOrLong&
     208           0 : OwningStringOrLong::operator=(const OwningStringOrLong& aOther)
     209             : {
     210           0 :   switch (aOther.mType) {
     211             :     case eUninitialized: {
     212           0 :       MOZ_ASSERT(mType == eUninitialized,
     213             :                  "We need to destroy ourselves?");
     214           0 :       break;
     215             :     }
     216             :     case eString: {
     217           0 :       SetAsString() = aOther.GetAsString();
     218           0 :       break;
     219             :     }
     220             :     case eLong: {
     221           0 :       SetAsLong() = aOther.GetAsLong();
     222           0 :       break;
     223             :     }
     224             :   }
     225           0 :   return *this;
     226             : }
     227             : 
     228             : 
     229             : namespace TestInterfaceIterableDoubleBinding {
     230             : 
     231             : static bool
     232           0 : entries(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceIterableDouble* self, const JSJitMethodCallArgs& args)
     233             : {
     234             :   typedef mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDouble> itrType;
     235             :   RefPtr<itrType> result(new itrType(self,
     236             :                                        itrType::IterableIteratorType::Entries,
     237           0 :                                        &TestInterfaceIterableDoubleIteratorBinding::Wrap));
     238             :   static_assert(!IsPointer<decltype(result)>::value,
     239             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
     240           0 :   if (!WrapNewBindingNonWrapperCachedObject(cx, obj, result, args.rval())) {
     241           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     242           0 :     return false;
     243             :   }
     244           0 :   return true;
     245             : }
     246             : 
     247             : static const JSJitInfo::ArgType entries_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
     248             : static const JSTypedMethodJitInfo entries_methodinfo = {
     249             :   {
     250             :     { (JSJitGetterOp)entries },
     251             :     { prototypes::id::TestInterfaceIterableDouble },
     252             :     { PrototypeTraits<prototypes::id::TestInterfaceIterableDouble>::Depth },
     253             :     JSJitInfo::Method,
     254             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     255             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     256             :     false,  /* isInfallible. False in setters. */
     257             :     false,  /* isMovable.  Not relevant for setters. */
     258             :     false, /* isEliminatable.  Not relevant for setters. */
     259             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
     260             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     261             :     true,  /* isTypedMethod.  Only relevant for methods. */
     262             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
     263             :   },
     264             :   entries_methodinfo_argTypes
     265             : };
     266             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     267             : static_assert(0 < 1, "There is no slot for us");
     268             : 
     269             : static bool
     270           0 : keys(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceIterableDouble* self, const JSJitMethodCallArgs& args)
     271             : {
     272             :   typedef mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDouble> itrType;
     273             :   RefPtr<itrType> result(new itrType(self,
     274             :                                        itrType::IterableIteratorType::Keys,
     275           0 :                                        &TestInterfaceIterableDoubleIteratorBinding::Wrap));
     276             :   static_assert(!IsPointer<decltype(result)>::value,
     277             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
     278           0 :   if (!WrapNewBindingNonWrapperCachedObject(cx, obj, result, args.rval())) {
     279           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     280           0 :     return false;
     281             :   }
     282           0 :   return true;
     283             : }
     284             : 
     285             : static const JSJitInfo::ArgType keys_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
     286             : static const JSTypedMethodJitInfo keys_methodinfo = {
     287             :   {
     288             :     { (JSJitGetterOp)keys },
     289             :     { prototypes::id::TestInterfaceIterableDouble },
     290             :     { PrototypeTraits<prototypes::id::TestInterfaceIterableDouble>::Depth },
     291             :     JSJitInfo::Method,
     292             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     293             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     294             :     false,  /* isInfallible. False in setters. */
     295             :     false,  /* isMovable.  Not relevant for setters. */
     296             :     false, /* isEliminatable.  Not relevant for setters. */
     297             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
     298             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     299             :     true,  /* isTypedMethod.  Only relevant for methods. */
     300             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
     301             :   },
     302             :   keys_methodinfo_argTypes
     303             : };
     304             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     305             : static_assert(0 < 1, "There is no slot for us");
     306             : 
     307             : static bool
     308           0 : values(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceIterableDouble* self, const JSJitMethodCallArgs& args)
     309             : {
     310             :   typedef mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDouble> itrType;
     311             :   RefPtr<itrType> result(new itrType(self,
     312             :                                        itrType::IterableIteratorType::Values,
     313           0 :                                        &TestInterfaceIterableDoubleIteratorBinding::Wrap));
     314             :   static_assert(!IsPointer<decltype(result)>::value,
     315             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
     316           0 :   if (!WrapNewBindingNonWrapperCachedObject(cx, obj, result, args.rval())) {
     317           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     318           0 :     return false;
     319             :   }
     320           0 :   return true;
     321             : }
     322             : 
     323             : static const JSJitInfo::ArgType values_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
     324             : static const JSTypedMethodJitInfo values_methodinfo = {
     325             :   {
     326             :     { (JSJitGetterOp)values },
     327             :     { prototypes::id::TestInterfaceIterableDouble },
     328             :     { PrototypeTraits<prototypes::id::TestInterfaceIterableDouble>::Depth },
     329             :     JSJitInfo::Method,
     330             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     331             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     332             :     false,  /* isInfallible. False in setters. */
     333             :     false,  /* isMovable.  Not relevant for setters. */
     334             :     false, /* isEliminatable.  Not relevant for setters. */
     335             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
     336             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     337             :     true,  /* isTypedMethod.  Only relevant for methods. */
     338             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
     339             :   },
     340             :   values_methodinfo_argTypes
     341             : };
     342             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     343             : static_assert(0 < 1, "There is no slot for us");
     344             : 
     345             : static bool
     346           0 : forEach(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceIterableDouble* self, const JSJitMethodCallArgs& args)
     347             : {
     348           0 :   JS::Rooted<JSObject*> arg0(cx);
     349           0 :   if (args.get(0).isObject()) {
     350           0 :     arg0 = &args.get(0).toObject();
     351             :   } else {
     352           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of TestInterfaceIterableDouble.forEach");
     353           0 :     return false;
     354             :   }
     355           0 :   JS::Rooted<JS::Value> arg1(cx);
     356           0 :   if (args.hasDefined(1)) {
     357           0 :     arg1 = args.get(1);
     358             :   } else {
     359           0 :     arg1 = JS::UndefinedValue();
     360             :   }
     361           0 :   if (!JS::IsCallable(arg0)) {
     362           0 :     ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "Argument 1 of TestInterfaceIterableDouble.forEach");
     363           0 :     return false;
     364             :   }
     365           0 :   JS::AutoValueArray<3> callArgs(cx);
     366           0 :   callArgs[2].setObject(*obj);
     367           0 :   JS::Rooted<JS::Value> ignoredReturnVal(cx);
     368           0 :   for (size_t i = 0; i < self->GetIterableLength(); ++i) {
     369           0 :     if (!ToJSValue(cx, self->GetValueAtIndex(i), callArgs[0])) {
     370           0 :       return false;
     371             :     }
     372           0 :     if (!ToJSValue(cx, self->GetKeyAtIndex(i), callArgs[1])) {
     373           0 :       return false;
     374             :     }
     375           0 :     if (!JS::Call(cx, arg1, arg0, JS::HandleValueArray(callArgs),
     376             :                   &ignoredReturnVal)) {
     377           0 :       return false;
     378             :     }
     379             :   }
     380           0 :   args.rval().setUndefined();
     381           0 :   return true;
     382             : }
     383             : 
     384             : static const JSJitInfo forEach_methodinfo = {
     385             :   { (JSJitGetterOp)forEach },
     386             :   { prototypes::id::TestInterfaceIterableDouble },
     387             :   { PrototypeTraits<prototypes::id::TestInterfaceIterableDouble>::Depth },
     388             :   JSJitInfo::Method,
     389             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     390             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
     391             :   false,  /* isInfallible. False in setters. */
     392             :   false,  /* isMovable.  Not relevant for setters. */
     393             :   false, /* isEliminatable.  Not relevant for setters. */
     394             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     395             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     396             :   false,  /* isTypedMethod.  Only relevant for methods. */
     397             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     398             : };
     399             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     400             : static_assert(0 < 1, "There is no slot for us");
     401             : 
     402             : static bool
     403           0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
     404             : {
     405           0 :   mozilla::dom::TestInterfaceIterableDouble* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceIterableDouble>(obj);
     406             :   // We don't want to preserve if we don't have a wrapper, and we
     407             :   // obviously can't preserve if we're not initialized.
     408           0 :   if (self && self->GetWrapperPreserveColor()) {
     409           0 :     PreserveWrapper(self);
     410             :   }
     411           0 :   return true;
     412             : }
     413             : 
     414             : static void
     415           0 : _finalize(js::FreeOp* fop, JSObject* obj)
     416             : {
     417           0 :   mozilla::dom::TestInterfaceIterableDouble* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceIterableDouble>(obj);
     418           0 :   if (self) {
     419           0 :     ClearWrapper(self, self, obj);
     420           0 :     AddForDeferredFinalization<mozilla::dom::TestInterfaceIterableDouble>(self);
     421             :   }
     422           0 : }
     423             : 
     424             : static void
     425           0 : _objectMoved(JSObject* obj, const JSObject* old)
     426             : {
     427           0 :   mozilla::dom::TestInterfaceIterableDouble* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceIterableDouble>(obj);
     428           0 :   if (self) {
     429           0 :     UpdateWrapper(self, self, obj, old);
     430             :   }
     431           0 : }
     432             : 
     433             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
     434             : #if defined(__clang__)
     435             : #pragma clang diagnostic push
     436             : #pragma clang diagnostic ignored "-Wmissing-braces"
     437             : #endif
     438             : static const JSFunctionSpec sMethods_specs[] = {
     439             :   JS_FNSPEC("entries", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&entries_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
     440             :   JS_FNSPEC("keys", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&keys_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
     441             :   JS_FNSPEC("values", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&values_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
     442             :   JS_FNSPEC("forEach", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&forEach_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
     443             :   JS_FS_END
     444             : };
     445             : #if defined(__clang__)
     446             : #pragma clang diagnostic pop
     447             : #endif
     448             : 
     449             : 
     450             : // Can't be const because the pref-enabled boolean needs to be writable
     451             : static Prefable<const JSFunctionSpec> sMethods[] = {
     452             :   { nullptr, &sMethods_specs[0] },
     453             :   { nullptr, nullptr }
     454             : };
     455             : 
     456             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
     457             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
     458             : static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
     459             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
     460             : 
     461             : 
     462             : static uint16_t sNativeProperties_sortedPropertyIndices[4];
     463             : static PropertyInfo sNativeProperties_propertyInfos[4];
     464             : 
     465             : static const NativePropertiesN<1> sNativeProperties = {
     466             :   false, 0,
     467             :   false, 0,
     468             :   true,  0 /* sMethods */,
     469             :   false, 0,
     470             :   false, 0,
     471             :   false, 0,
     472             :   false, 0,
     473             :   0,
     474             :   4,
     475             :   sNativeProperties_sortedPropertyIndices,
     476             :   {
     477             :     { sMethods, &sNativeProperties_propertyInfos[0] }
     478             :   }
     479             : };
     480             : static_assert(4 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
     481             :     "We have a property info count that is oversized");
     482             : 
     483             : static bool
     484           0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
     485             : {
     486           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
     487           0 :   JS::Rooted<JSObject*> obj(cx, &args.callee());
     488           0 :   if (!args.isConstructing()) {
     489             :     // XXXbz wish I could get the name from the callee instead of
     490             :     // Adding more relocations
     491           0 :     return ThrowConstructorWithoutNew(cx, "TestInterfaceIterableDouble");
     492             :   }
     493             : 
     494           0 :   GlobalObject global(cx, obj);
     495           0 :   if (global.Failed()) {
     496           0 :     return false;
     497             :   }
     498             : 
     499           0 :   JS::Rooted<JSObject*> desiredProto(cx);
     500           0 :   if (!GetDesiredProto(cx, args, &desiredProto)) {
     501           0 :     return false;
     502             :   }
     503             : 
     504           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
     505           0 :   Maybe<JSAutoCompartment> ac;
     506           0 :   if (objIsXray) {
     507           0 :     obj = js::CheckedUnwrap(obj);
     508           0 :     if (!obj) {
     509           0 :       return false;
     510             :     }
     511           0 :     ac.emplace(cx, obj);
     512           0 :     if (!JS_WrapObject(cx, &desiredProto)) {
     513           0 :       return false;
     514             :     }
     515             :   }
     516           0 :   binding_detail::FastErrorResult rv;
     517           0 :   auto result(StrongOrRawPtr<mozilla::dom::TestInterfaceIterableDouble>(mozilla::dom::TestInterfaceIterableDouble::Constructor(global, rv)));
     518           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     519           0 :     return false;
     520             :   }
     521           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     522             :   static_assert(!IsPointer<decltype(result)>::value,
     523             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
     524           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
     525           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     526           0 :     return false;
     527             :   }
     528           0 :   return true;
     529             : }
     530             : 
     531             : static const js::ClassOps sInterfaceObjectClassOps = {
     532             :     nullptr,               /* addProperty */
     533             :     nullptr,               /* delProperty */
     534             :     nullptr,               /* getProperty */
     535             :     nullptr,               /* setProperty */
     536             :     nullptr,               /* enumerate */
     537             :     nullptr,               /* newEnumerate */
     538             :     nullptr,               /* resolve */
     539             :     nullptr,               /* mayResolve */
     540             :     nullptr,               /* finalize */
     541             :     _constructor, /* call */
     542             :     nullptr,               /* hasInstance */
     543             :     _constructor, /* construct */
     544             :     nullptr,               /* trace */
     545             : };
     546             : 
     547             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
     548             :   {
     549             :     "Function",
     550             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
     551             :     &sInterfaceObjectClassOps,
     552             :     JS_NULL_CLASS_SPEC,
     553             :     JS_NULL_CLASS_EXT,
     554             :     &sInterfaceObjectClassObjectOps
     555             :   },
     556             :   eInterface,
     557             :   true,
     558             :   prototypes::id::TestInterfaceIterableDouble,
     559             :   PrototypeTraits<prototypes::id::TestInterfaceIterableDouble>::Depth,
     560             :   sNativePropertyHooks,
     561             :   "function TestInterfaceIterableDouble() {\n    [native code]\n}",
     562             :   JS::GetRealmFunctionPrototype
     563             : };
     564             : 
     565             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
     566             :   {
     567             :     "TestInterfaceIterableDoublePrototype",
     568             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
     569             :     JS_NULL_CLASS_OPS,
     570             :     JS_NULL_CLASS_SPEC,
     571             :     JS_NULL_CLASS_EXT,
     572             :     JS_NULL_OBJECT_OPS
     573             :   },
     574             :   eInterfacePrototype,
     575             :   false,
     576             :   prototypes::id::TestInterfaceIterableDouble,
     577             :   PrototypeTraits<prototypes::id::TestInterfaceIterableDouble>::Depth,
     578             :   sNativePropertyHooks,
     579             :   "[object TestInterfaceIterableDoublePrototype]",
     580             :   JS::GetRealmObjectPrototype
     581             : };
     582             : 
     583             : bool
     584           0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
     585             : {
     586             :   static bool sPrefValue;
     587             :   static bool sPrefCacheSetUp = false;
     588           0 :   if (!sPrefCacheSetUp) {
     589           0 :     sPrefCacheSetUp = true;
     590           0 :     Preferences::AddBoolVarCache(&sPrefValue, "dom.expose_test_interfaces");
     591             :   }
     592             : 
     593           0 :   return sPrefValue;
     594             : }
     595             : 
     596             : JSObject*
     597           0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
     598             : {
     599           0 :   return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
     600             : }
     601             : 
     602             : static const js::ClassOps sClassOps = {
     603             :   _addProperty, /* addProperty */
     604             :   nullptr,               /* delProperty */
     605             :   nullptr,               /* getProperty */
     606             :   nullptr,               /* setProperty */
     607             :   nullptr,               /* enumerate */
     608             :   nullptr, /* newEnumerate */
     609             :   nullptr, /* resolve */
     610             :   nullptr, /* mayResolve */
     611             :   _finalize, /* finalize */
     612             :   nullptr, /* call */
     613             :   nullptr,               /* hasInstance */
     614             :   nullptr,               /* construct */
     615             :   nullptr, /* trace */
     616             : };
     617             : 
     618             : static const js::ClassExtension sClassExtension = {
     619             :   nullptr, /* weakmapKeyDelegateOp */
     620             :   _objectMoved /* objectMovedOp */
     621             : };
     622             : 
     623             : static const DOMJSClass sClass = {
     624             :   { "TestInterfaceIterableDouble",
     625             :     JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
     626             :     &sClassOps,
     627             :     JS_NULL_CLASS_SPEC,
     628             :     &sClassExtension,
     629             :     JS_NULL_OBJECT_OPS
     630             :   },
     631             :   { prototypes::id::TestInterfaceIterableDouble, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
     632             :   IsBaseOf<nsISupports, mozilla::dom::TestInterfaceIterableDouble >::value,
     633             :   sNativePropertyHooks,
     634             :   FindAssociatedGlobalForNative<mozilla::dom::TestInterfaceIterableDouble>::Get,
     635             :   GetProtoObjectHandle,
     636             :   GetCCParticipant<mozilla::dom::TestInterfaceIterableDouble>::Get()
     637             : };
     638             : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
     639             :               "Must have the right minimal number of reserved slots.");
     640             : static_assert(1 >= 1,
     641             :               "Must have enough reserved slots.");
     642             : 
     643             : const JSClass*
     644           0 : GetJSClass()
     645             : {
     646           0 :   return sClass.ToJSClass();
     647             : }
     648             : 
     649             : bool
     650           0 : Wrap(JSContext* aCx, mozilla::dom::TestInterfaceIterableDouble* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
     651             : {
     652             :   MOZ_ASSERT(static_cast<mozilla::dom::TestInterfaceIterableDouble*>(aObject) ==
     653             :              reinterpret_cast<mozilla::dom::TestInterfaceIterableDouble*>(aObject),
     654             :              "Multiple inheritance for mozilla::dom::TestInterfaceIterableDouble is broken.");
     655           0 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
     656           0 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
     657           0 :   MOZ_ASSERT(!aCache->GetWrapper(),
     658             :              "You should probably not be using Wrap() directly; use "
     659             :              "GetOrCreateDOMReflector instead");
     660             : 
     661           0 :   MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
     662             :              "nsISupports must be on our primary inheritance chain");
     663             : 
     664           0 :   JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
     665           0 :   if (!global) {
     666           0 :     return false;
     667             :   }
     668           0 :   MOZ_ASSERT(JS_IsGlobalObject(global));
     669           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(global));
     670             : 
     671             :   // That might have ended up wrapping us already, due to the wonders
     672             :   // of XBL.  Check for that, and bail out as needed.
     673           0 :   aReflector.set(aCache->GetWrapper());
     674           0 :   if (aReflector) {
     675             : #ifdef DEBUG
     676           0 :     binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
     677             : #endif // DEBUG
     678           0 :     return true;
     679             :   }
     680             : 
     681           0 :   JSAutoCompartment ac(aCx, global);
     682           0 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
     683           0 :   if (!canonicalProto) {
     684           0 :     return false;
     685             :   }
     686           0 :   JS::Rooted<JSObject*> proto(aCx);
     687           0 :   if (aGivenProto) {
     688           0 :     proto = aGivenProto;
     689             :     // Unfortunately, while aGivenProto was in the compartment of aCx
     690             :     // coming in, we changed compartments to that of "parent" so may need
     691             :     // to wrap the proto here.
     692           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
     693           0 :       if (!JS_WrapObject(aCx, &proto)) {
     694           0 :         return false;
     695             :       }
     696             :     }
     697             :   } else {
     698           0 :     proto = canonicalProto;
     699             :   }
     700             : 
     701           0 :   BindingJSObjectCreator<mozilla::dom::TestInterfaceIterableDouble> creator(aCx);
     702           0 :   creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
     703           0 :   if (!aReflector) {
     704           0 :     return false;
     705             :   }
     706             : 
     707           0 :   aCache->SetWrapper(aReflector);
     708           0 :   creator.InitializationSucceeded();
     709             : 
     710           0 :   MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
     711             :              aCache->GetWrapperPreserveColor() == aReflector);
     712             :   // If proto != canonicalProto, we have to preserve our wrapper;
     713             :   // otherwise we won't be able to properly recreate it later, since
     714             :   // we won't know what proto to use.  Note that we don't check
     715             :   // aGivenProto here, since it's entirely possible (and even
     716             :   // somewhat common) to have a non-null aGivenProto which is the
     717             :   // same as canonicalProto.
     718           0 :   if (proto != canonicalProto) {
     719           0 :     PreserveWrapper(aObject);
     720             :   }
     721             : 
     722           0 :   return true;
     723             : }
     724             : 
     725             : const NativePropertyHooks sNativePropertyHooks[] = { {
     726             :   nullptr,
     727             :   nullptr,
     728             :   nullptr,
     729             :   { sNativeProperties.Upcast(), nullptr },
     730             :   prototypes::id::TestInterfaceIterableDouble,
     731             :   constructors::id::TestInterfaceIterableDouble,
     732             :   nullptr,
     733             :   &DefaultXrayExpandoObjectClass
     734             : } };
     735             : 
     736             : void
     737           0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
     738             : {
     739           0 :   JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
     740           0 :   if (!parentProto) {
     741           0 :     return;
     742             :   }
     743             : 
     744           0 :   JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
     745           0 :   if (!constructorProto) {
     746           0 :     return;
     747             :   }
     748             : 
     749             :   static bool sIdsInited = false;
     750           0 :   if (!sIdsInited && NS_IsMainThread()) {
     751           0 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
     752           0 :       return;
     753             :     }
     754           0 :     sIdsInited = true;
     755             :   }
     756             : 
     757           0 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::TestInterfaceIterableDouble);
     758           0 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::TestInterfaceIterableDouble);
     759           0 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
     760             :                               &sPrototypeClass.mBase, protoCache,
     761             :                               constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
     762             :                               interfaceCache,
     763             :                               sNativeProperties.Upcast(),
     764             :                               nullptr,
     765             :                               "TestInterfaceIterableDouble", aDefineOnGlobal,
     766             :                               nullptr,
     767           0 :                               false);
     768             : 
     769             :   // Set up aliases on the interface prototype object we just created.
     770           0 :   JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx);
     771           0 :   if (!proto) {
     772           0 :     *protoCache = nullptr;
     773           0 :     if (interfaceCache) {
     774           0 :       *interfaceCache = nullptr;
     775             :     }
     776           0 :     return;
     777             :   }
     778             : 
     779           0 :   JS::Rooted<JS::Value> aliasedVal(aCx);
     780             : 
     781           0 :   if (!JS_GetProperty(aCx, proto, "entries", &aliasedVal)) {
     782           0 :     *protoCache = nullptr;
     783           0 :     if (interfaceCache) {
     784           0 :       *interfaceCache = nullptr;
     785             :     }
     786           0 :     return;
     787             :   }
     788           0 :   JS::Rooted<jsid> iteratorId(aCx, SYMBOL_TO_JSID(JS::GetWellKnownSymbol(aCx, JS::SymbolCode::iterator)));
     789           0 :   if (!JS_DefinePropertyById(aCx, proto, iteratorId, aliasedVal, 0)) {
     790           0 :     *protoCache = nullptr;
     791           0 :     if (interfaceCache) {
     792           0 :       *interfaceCache = nullptr;
     793             :     }
     794           0 :     return;
     795             :   }
     796             : }
     797             : 
     798             : JS::Handle<JSObject*>
     799           0 : GetProtoObjectHandle(JSContext* aCx)
     800             : {
     801             :   /* Get the interface prototype object for this class.  This will create the
     802             :      object as needed. */
     803           0 :   bool aDefineOnGlobal = true;
     804             : 
     805             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
     806           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
     807           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
     808           0 :     return nullptr;
     809             :   }
     810             : 
     811             :   /* Check to see whether the interface objects are already installed */
     812           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
     813           0 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::TestInterfaceIterableDouble)) {
     814           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
     815           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
     816             :   }
     817             : 
     818             :   /*
     819             :    * The object might _still_ be null, but that's OK.
     820             :    *
     821             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
     822             :    * traced by TraceProtoAndIfaceCache() and its contents are never
     823             :    * changed after they have been set.
     824             :    *
     825             :    * Calling address() avoids the read read barrier that does gray
     826             :    * unmarking, but it's not possible for the object to be gray here.
     827             :    */
     828             : 
     829           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::TestInterfaceIterableDouble);
     830           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
     831           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
     832             : }
     833             : 
     834             : JS::Handle<JSObject*>
     835           0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
     836             : {
     837             :   /* Get the interface object for this class.  This will create the object as
     838             :      needed. */
     839             : 
     840             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
     841           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
     842           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
     843           0 :     return nullptr;
     844             :   }
     845             : 
     846             :   /* Check to see whether the interface objects are already installed */
     847           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
     848           0 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::TestInterfaceIterableDouble)) {
     849           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
     850           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
     851             :   }
     852             : 
     853             :   /*
     854             :    * The object might _still_ be null, but that's OK.
     855             :    *
     856             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
     857             :    * traced by TraceProtoAndIfaceCache() and its contents are never
     858             :    * changed after they have been set.
     859             :    *
     860             :    * Calling address() avoids the read read barrier that does gray
     861             :    * unmarking, but it's not possible for the object to be gray here.
     862             :    */
     863             : 
     864           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::TestInterfaceIterableDouble);
     865           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
     866           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
     867             : }
     868             : 
     869             : JSObject*
     870           0 : GetConstructorObject(JSContext* aCx)
     871             : {
     872           0 :   return GetConstructorObjectHandle(aCx);
     873             : }
     874             : 
     875             : } // namespace TestInterfaceIterableDoubleBinding
     876             : 
     877             : 
     878             : 
     879             : namespace TestInterfaceIterableDoubleIteratorBinding {
     880             : 
     881             : static bool
     882           0 : next(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDouble>* self, const JSJitMethodCallArgs& args)
     883             : {
     884           0 :   binding_detail::FastErrorResult rv;
     885           0 :   JS::Rooted<JSObject*> result(cx);
     886           0 :   self->Next(cx, &result, rv);
     887           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     888           0 :     return false;
     889             :   }
     890           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     891           0 :   JS::ExposeObjectToActiveJS(result);
     892           0 :   args.rval().setObject(*result);
     893           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
     894           0 :     return false;
     895             :   }
     896           0 :   return true;
     897             : }
     898             : 
     899             : static const JSJitInfo next_methodinfo = {
     900             :   { (JSJitGetterOp)next },
     901             :   { prototypes::id::TestInterfaceIterableDoubleIterator },
     902             :   { PrototypeTraits<prototypes::id::TestInterfaceIterableDoubleIterator>::Depth },
     903             :   JSJitInfo::Method,
     904             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     905             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     906             :   false,  /* isInfallible. False in setters. */
     907             :   false,  /* isMovable.  Not relevant for setters. */
     908             :   false, /* isEliminatable.  Not relevant for setters. */
     909             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     910             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     911             :   false,  /* isTypedMethod.  Only relevant for methods. */
     912             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     913             : };
     914             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     915             : static_assert(0 < 1, "There is no slot for us");
     916             : 
     917             : static void
     918           0 : _finalize(js::FreeOp* fop, JSObject* obj)
     919             : {
     920           0 :   mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDouble>* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDouble>>(obj);
     921           0 :   if (self) {
     922           0 :     AddForDeferredFinalization<mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDouble>>(self);
     923             :   }
     924           0 : }
     925             : 
     926             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
     927             : #if defined(__clang__)
     928             : #pragma clang diagnostic push
     929             : #pragma clang diagnostic ignored "-Wmissing-braces"
     930             : #endif
     931             : static const JSFunctionSpec sMethods_specs[] = {
     932             :   JS_FNSPEC("next", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&next_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
     933             :   JS_FS_END
     934             : };
     935             : #if defined(__clang__)
     936             : #pragma clang diagnostic pop
     937             : #endif
     938             : 
     939             : 
     940             : // Can't be const because the pref-enabled boolean needs to be writable
     941             : static Prefable<const JSFunctionSpec> sMethods[] = {
     942             :   { nullptr, &sMethods_specs[0] },
     943             :   { nullptr, nullptr }
     944             : };
     945             : 
     946             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
     947             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
     948             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
     949             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
     950             : 
     951             : 
     952             : static uint16_t sNativeProperties_sortedPropertyIndices[1];
     953             : static PropertyInfo sNativeProperties_propertyInfos[1];
     954             : 
     955             : static const NativePropertiesN<1> sNativeProperties = {
     956             :   false, 0,
     957             :   false, 0,
     958             :   true,  0 /* sMethods */,
     959             :   false, 0,
     960             :   false, 0,
     961             :   false, 0,
     962             :   false, 0,
     963             :   -1,
     964             :   1,
     965             :   sNativeProperties_sortedPropertyIndices,
     966             :   {
     967             :     { sMethods, &sNativeProperties_propertyInfos[0] }
     968             :   }
     969             : };
     970             : static_assert(1 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
     971             :     "We have a property info count that is oversized");
     972             : 
     973             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
     974             :   {
     975             :     "TestInterfaceIterableDoubleIteratorPrototype",
     976             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
     977             :     JS_NULL_CLASS_OPS,
     978             :     JS_NULL_CLASS_SPEC,
     979             :     JS_NULL_CLASS_EXT,
     980             :     JS_NULL_OBJECT_OPS
     981             :   },
     982             :   eInterfacePrototype,
     983             :   false,
     984             :   prototypes::id::TestInterfaceIterableDoubleIterator,
     985             :   PrototypeTraits<prototypes::id::TestInterfaceIterableDoubleIterator>::Depth,
     986             :   sNativePropertyHooks,
     987             :   "[object TestInterfaceIterableDoubleIteratorPrototype]",
     988             :   JS::GetRealmIteratorPrototype
     989             : };
     990             : 
     991             : static const js::ClassOps sClassOps = {
     992             :   nullptr, /* addProperty */
     993             :   nullptr,               /* delProperty */
     994             :   nullptr,               /* getProperty */
     995             :   nullptr,               /* setProperty */
     996             :   nullptr,               /* enumerate */
     997             :   nullptr, /* newEnumerate */
     998             :   nullptr, /* resolve */
     999             :   nullptr, /* mayResolve */
    1000             :   _finalize, /* finalize */
    1001             :   nullptr, /* call */
    1002             :   nullptr,               /* hasInstance */
    1003             :   nullptr,               /* construct */
    1004             :   nullptr, /* trace */
    1005             : };
    1006             : 
    1007             : static const js::ClassExtension sClassExtension = {
    1008             :   nullptr, /* weakmapKeyDelegateOp */
    1009             :   nullptr /* objectMovedOp */
    1010             : };
    1011             : 
    1012             : static const DOMJSClass sClass = {
    1013             :   { "TestInterfaceIterableDoubleIterator",
    1014             :     JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
    1015             :     &sClassOps,
    1016             :     JS_NULL_CLASS_SPEC,
    1017             :     &sClassExtension,
    1018             :     JS_NULL_OBJECT_OPS
    1019             :   },
    1020             :   { prototypes::id::TestInterfaceIterableDoubleIterator, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
    1021             :   IsBaseOf<nsISupports, mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDouble> >::value,
    1022             :   sNativePropertyHooks,
    1023             :   FindAssociatedGlobalForNative<mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDouble>>::Get,
    1024             :   GetProtoObjectHandle,
    1025             :   GetCCParticipant<mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDouble>>::Get()
    1026             : };
    1027             : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
    1028             :               "Must have the right minimal number of reserved slots.");
    1029             : static_assert(1 >= 1,
    1030             :               "Must have enough reserved slots.");
    1031             : 
    1032             : const JSClass*
    1033           0 : GetJSClass()
    1034             : {
    1035           0 :   return sClass.ToJSClass();
    1036             : }
    1037             : 
    1038             : bool
    1039           0 : Wrap(JSContext* aCx, mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDouble>* aObject, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
    1040             : {
    1041             :   MOZ_ASSERT(static_cast<mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDouble>*>(aObject) ==
    1042             :              reinterpret_cast<mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDouble>*>(aObject),
    1043             :              "Multiple inheritance for mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDouble> is broken.");
    1044           0 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
    1045           0 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
    1046             : 
    1047           0 :   JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
    1048           0 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
    1049           0 :   if (!canonicalProto) {
    1050           0 :     return false;
    1051             :   }
    1052           0 :   JS::Rooted<JSObject*> proto(aCx);
    1053           0 :   if (aGivenProto) {
    1054           0 :     proto = aGivenProto;
    1055             :     // Unfortunately, while aGivenProto was in the compartment of aCx
    1056             :     // coming in, we changed compartments to that of "parent" so may need
    1057             :     // to wrap the proto here.
    1058           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
    1059           0 :       if (!JS_WrapObject(aCx, &proto)) {
    1060           0 :         return false;
    1061             :       }
    1062             :     }
    1063             :   } else {
    1064           0 :     proto = canonicalProto;
    1065             :   }
    1066             : 
    1067           0 :   BindingJSObjectCreator<mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDouble>> creator(aCx);
    1068           0 :   creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
    1069           0 :   if (!aReflector) {
    1070           0 :     return false;
    1071             :   }
    1072             : 
    1073             : 
    1074             : 
    1075           0 :   creator.InitializationSucceeded();
    1076           0 :   return true;
    1077             : }
    1078             : 
    1079             : const NativePropertyHooks sNativePropertyHooks[] = { {
    1080             :   nullptr,
    1081             :   nullptr,
    1082             :   nullptr,
    1083             :   { sNativeProperties.Upcast(), nullptr },
    1084             :   prototypes::id::TestInterfaceIterableDoubleIterator,
    1085             :   constructors::id::_ID_Count,
    1086             :   nullptr,
    1087             :   &DefaultXrayExpandoObjectClass
    1088             : } };
    1089             : 
    1090             : void
    1091           0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    1092             : {
    1093           0 :   JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmIteratorPrototype(aCx));
    1094           0 :   if (!parentProto) {
    1095           0 :     return;
    1096             :   }
    1097             : 
    1098             :   static bool sIdsInited = false;
    1099           0 :   if (!sIdsInited && NS_IsMainThread()) {
    1100           0 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
    1101           0 :       return;
    1102             :     }
    1103           0 :     sIdsInited = true;
    1104             :   }
    1105             : 
    1106           0 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::TestInterfaceIterableDoubleIterator);
    1107           0 :   JS::Heap<JSObject*>* interfaceCache = nullptr;
    1108           0 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    1109             :                               &sPrototypeClass.mBase, protoCache,
    1110             :                               nullptr, nullptr, 0, nullptr,
    1111             :                               interfaceCache,
    1112             :                               sNativeProperties.Upcast(),
    1113             :                               nullptr,
    1114             :                               nullptr, aDefineOnGlobal,
    1115             :                               nullptr,
    1116           0 :                               false);
    1117             : }
    1118             : 
    1119             : JS::Handle<JSObject*>
    1120           0 : GetProtoObjectHandle(JSContext* aCx)
    1121             : {
    1122             :   /* Get the interface prototype object for this class.  This will create the
    1123             :      object as needed. */
    1124           0 :   bool aDefineOnGlobal = true;
    1125             : 
    1126             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    1127           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    1128           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    1129           0 :     return nullptr;
    1130             :   }
    1131             : 
    1132             :   /* Check to see whether the interface objects are already installed */
    1133           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    1134           0 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::TestInterfaceIterableDoubleIterator)) {
    1135           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    1136           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    1137             :   }
    1138             : 
    1139             :   /*
    1140             :    * The object might _still_ be null, but that's OK.
    1141             :    *
    1142             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    1143             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    1144             :    * changed after they have been set.
    1145             :    *
    1146             :    * Calling address() avoids the read read barrier that does gray
    1147             :    * unmarking, but it's not possible for the object to be gray here.
    1148             :    */
    1149             : 
    1150           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::TestInterfaceIterableDoubleIterator);
    1151           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    1152           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    1153             : }
    1154             : 
    1155             : } // namespace TestInterfaceIterableDoubleIteratorBinding
    1156             : 
    1157             : 
    1158             : 
    1159             : namespace TestInterfaceIterableDoubleUnionBinding {
    1160             : 
    1161             : static bool
    1162           0 : entries(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceIterableDoubleUnion* self, const JSJitMethodCallArgs& args)
    1163             : {
    1164             :   typedef mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDoubleUnion> itrType;
    1165             :   RefPtr<itrType> result(new itrType(self,
    1166             :                                        itrType::IterableIteratorType::Entries,
    1167           0 :                                        &TestInterfaceIterableDoubleUnionIteratorBinding::Wrap));
    1168             :   static_assert(!IsPointer<decltype(result)>::value,
    1169             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
    1170           0 :   if (!WrapNewBindingNonWrapperCachedObject(cx, obj, result, args.rval())) {
    1171           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1172           0 :     return false;
    1173             :   }
    1174           0 :   return true;
    1175             : }
    1176             : 
    1177             : static const JSJitInfo::ArgType entries_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
    1178             : static const JSTypedMethodJitInfo entries_methodinfo = {
    1179             :   {
    1180             :     { (JSJitGetterOp)entries },
    1181             :     { prototypes::id::TestInterfaceIterableDoubleUnion },
    1182             :     { PrototypeTraits<prototypes::id::TestInterfaceIterableDoubleUnion>::Depth },
    1183             :     JSJitInfo::Method,
    1184             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1185             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1186             :     false,  /* isInfallible. False in setters. */
    1187             :     false,  /* isMovable.  Not relevant for setters. */
    1188             :     false, /* isEliminatable.  Not relevant for setters. */
    1189             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    1190             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1191             :     true,  /* isTypedMethod.  Only relevant for methods. */
    1192             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1193             :   },
    1194             :   entries_methodinfo_argTypes
    1195             : };
    1196             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1197             : static_assert(0 < 1, "There is no slot for us");
    1198             : 
    1199             : static bool
    1200           0 : keys(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceIterableDoubleUnion* self, const JSJitMethodCallArgs& args)
    1201             : {
    1202             :   typedef mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDoubleUnion> itrType;
    1203             :   RefPtr<itrType> result(new itrType(self,
    1204             :                                        itrType::IterableIteratorType::Keys,
    1205           0 :                                        &TestInterfaceIterableDoubleUnionIteratorBinding::Wrap));
    1206             :   static_assert(!IsPointer<decltype(result)>::value,
    1207             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
    1208           0 :   if (!WrapNewBindingNonWrapperCachedObject(cx, obj, result, args.rval())) {
    1209           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1210           0 :     return false;
    1211             :   }
    1212           0 :   return true;
    1213             : }
    1214             : 
    1215             : static const JSJitInfo::ArgType keys_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
    1216             : static const JSTypedMethodJitInfo keys_methodinfo = {
    1217             :   {
    1218             :     { (JSJitGetterOp)keys },
    1219             :     { prototypes::id::TestInterfaceIterableDoubleUnion },
    1220             :     { PrototypeTraits<prototypes::id::TestInterfaceIterableDoubleUnion>::Depth },
    1221             :     JSJitInfo::Method,
    1222             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1223             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1224             :     false,  /* isInfallible. False in setters. */
    1225             :     false,  /* isMovable.  Not relevant for setters. */
    1226             :     false, /* isEliminatable.  Not relevant for setters. */
    1227             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    1228             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1229             :     true,  /* isTypedMethod.  Only relevant for methods. */
    1230             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1231             :   },
    1232             :   keys_methodinfo_argTypes
    1233             : };
    1234             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1235             : static_assert(0 < 1, "There is no slot for us");
    1236             : 
    1237             : static bool
    1238           0 : values(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceIterableDoubleUnion* self, const JSJitMethodCallArgs& args)
    1239             : {
    1240             :   typedef mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDoubleUnion> itrType;
    1241             :   RefPtr<itrType> result(new itrType(self,
    1242             :                                        itrType::IterableIteratorType::Values,
    1243           0 :                                        &TestInterfaceIterableDoubleUnionIteratorBinding::Wrap));
    1244             :   static_assert(!IsPointer<decltype(result)>::value,
    1245             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
    1246           0 :   if (!WrapNewBindingNonWrapperCachedObject(cx, obj, result, args.rval())) {
    1247           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1248           0 :     return false;
    1249             :   }
    1250           0 :   return true;
    1251             : }
    1252             : 
    1253             : static const JSJitInfo::ArgType values_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
    1254             : static const JSTypedMethodJitInfo values_methodinfo = {
    1255             :   {
    1256             :     { (JSJitGetterOp)values },
    1257             :     { prototypes::id::TestInterfaceIterableDoubleUnion },
    1258             :     { PrototypeTraits<prototypes::id::TestInterfaceIterableDoubleUnion>::Depth },
    1259             :     JSJitInfo::Method,
    1260             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1261             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1262             :     false,  /* isInfallible. False in setters. */
    1263             :     false,  /* isMovable.  Not relevant for setters. */
    1264             :     false, /* isEliminatable.  Not relevant for setters. */
    1265             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    1266             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1267             :     true,  /* isTypedMethod.  Only relevant for methods. */
    1268             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1269             :   },
    1270             :   values_methodinfo_argTypes
    1271             : };
    1272             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1273             : static_assert(0 < 1, "There is no slot for us");
    1274             : 
    1275             : static bool
    1276           0 : forEach(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceIterableDoubleUnion* self, const JSJitMethodCallArgs& args)
    1277             : {
    1278           0 :   JS::Rooted<JSObject*> arg0(cx);
    1279           0 :   if (args.get(0).isObject()) {
    1280           0 :     arg0 = &args.get(0).toObject();
    1281             :   } else {
    1282           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of TestInterfaceIterableDoubleUnion.forEach");
    1283           0 :     return false;
    1284             :   }
    1285           0 :   JS::Rooted<JS::Value> arg1(cx);
    1286           0 :   if (args.hasDefined(1)) {
    1287           0 :     arg1 = args.get(1);
    1288             :   } else {
    1289           0 :     arg1 = JS::UndefinedValue();
    1290             :   }
    1291           0 :   if (!JS::IsCallable(arg0)) {
    1292           0 :     ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "Argument 1 of TestInterfaceIterableDoubleUnion.forEach");
    1293           0 :     return false;
    1294             :   }
    1295           0 :   JS::AutoValueArray<3> callArgs(cx);
    1296           0 :   callArgs[2].setObject(*obj);
    1297           0 :   JS::Rooted<JS::Value> ignoredReturnVal(cx);
    1298           0 :   for (size_t i = 0; i < self->GetIterableLength(); ++i) {
    1299           0 :     if (!ToJSValue(cx, self->GetValueAtIndex(i), callArgs[0])) {
    1300           0 :       return false;
    1301             :     }
    1302           0 :     if (!ToJSValue(cx, self->GetKeyAtIndex(i), callArgs[1])) {
    1303           0 :       return false;
    1304             :     }
    1305           0 :     if (!JS::Call(cx, arg1, arg0, JS::HandleValueArray(callArgs),
    1306             :                   &ignoredReturnVal)) {
    1307           0 :       return false;
    1308             :     }
    1309             :   }
    1310           0 :   args.rval().setUndefined();
    1311           0 :   return true;
    1312             : }
    1313             : 
    1314             : static const JSJitInfo forEach_methodinfo = {
    1315             :   { (JSJitGetterOp)forEach },
    1316             :   { prototypes::id::TestInterfaceIterableDoubleUnion },
    1317             :   { PrototypeTraits<prototypes::id::TestInterfaceIterableDoubleUnion>::Depth },
    1318             :   JSJitInfo::Method,
    1319             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1320             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    1321             :   false,  /* isInfallible. False in setters. */
    1322             :   false,  /* isMovable.  Not relevant for setters. */
    1323             :   false, /* isEliminatable.  Not relevant for setters. */
    1324             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1325             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1326             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1327             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1328             : };
    1329             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1330             : static_assert(0 < 1, "There is no slot for us");
    1331             : 
    1332             : static bool
    1333           0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
    1334             : {
    1335           0 :   mozilla::dom::TestInterfaceIterableDoubleUnion* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceIterableDoubleUnion>(obj);
    1336             :   // We don't want to preserve if we don't have a wrapper, and we
    1337             :   // obviously can't preserve if we're not initialized.
    1338           0 :   if (self && self->GetWrapperPreserveColor()) {
    1339           0 :     PreserveWrapper(self);
    1340             :   }
    1341           0 :   return true;
    1342             : }
    1343             : 
    1344             : static void
    1345           0 : _finalize(js::FreeOp* fop, JSObject* obj)
    1346             : {
    1347           0 :   mozilla::dom::TestInterfaceIterableDoubleUnion* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceIterableDoubleUnion>(obj);
    1348           0 :   if (self) {
    1349           0 :     ClearWrapper(self, self, obj);
    1350           0 :     AddForDeferredFinalization<mozilla::dom::TestInterfaceIterableDoubleUnion>(self);
    1351             :   }
    1352           0 : }
    1353             : 
    1354             : static void
    1355           0 : _objectMoved(JSObject* obj, const JSObject* old)
    1356             : {
    1357           0 :   mozilla::dom::TestInterfaceIterableDoubleUnion* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceIterableDoubleUnion>(obj);
    1358           0 :   if (self) {
    1359           0 :     UpdateWrapper(self, self, obj, old);
    1360             :   }
    1361           0 : }
    1362             : 
    1363             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    1364             : #if defined(__clang__)
    1365             : #pragma clang diagnostic push
    1366             : #pragma clang diagnostic ignored "-Wmissing-braces"
    1367             : #endif
    1368             : static const JSFunctionSpec sMethods_specs[] = {
    1369             :   JS_FNSPEC("entries", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&entries_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    1370             :   JS_FNSPEC("keys", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&keys_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    1371             :   JS_FNSPEC("values", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&values_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    1372             :   JS_FNSPEC("forEach", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&forEach_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    1373             :   JS_FS_END
    1374             : };
    1375             : #if defined(__clang__)
    1376             : #pragma clang diagnostic pop
    1377             : #endif
    1378             : 
    1379             : 
    1380             : // Can't be const because the pref-enabled boolean needs to be writable
    1381             : static Prefable<const JSFunctionSpec> sMethods[] = {
    1382             :   { nullptr, &sMethods_specs[0] },
    1383             :   { nullptr, nullptr }
    1384             : };
    1385             : 
    1386             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    1387             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    1388             : static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    1389             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    1390             : 
    1391             : 
    1392             : static uint16_t sNativeProperties_sortedPropertyIndices[4];
    1393             : static PropertyInfo sNativeProperties_propertyInfos[4];
    1394             : 
    1395             : static const NativePropertiesN<1> sNativeProperties = {
    1396             :   false, 0,
    1397             :   false, 0,
    1398             :   true,  0 /* sMethods */,
    1399             :   false, 0,
    1400             :   false, 0,
    1401             :   false, 0,
    1402             :   false, 0,
    1403             :   0,
    1404             :   4,
    1405             :   sNativeProperties_sortedPropertyIndices,
    1406             :   {
    1407             :     { sMethods, &sNativeProperties_propertyInfos[0] }
    1408             :   }
    1409             : };
    1410             : static_assert(4 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
    1411             :     "We have a property info count that is oversized");
    1412             : 
    1413             : static bool
    1414           0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
    1415             : {
    1416           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    1417           0 :   JS::Rooted<JSObject*> obj(cx, &args.callee());
    1418           0 :   if (!args.isConstructing()) {
    1419             :     // XXXbz wish I could get the name from the callee instead of
    1420             :     // Adding more relocations
    1421           0 :     return ThrowConstructorWithoutNew(cx, "TestInterfaceIterableDoubleUnion");
    1422             :   }
    1423             : 
    1424           0 :   GlobalObject global(cx, obj);
    1425           0 :   if (global.Failed()) {
    1426           0 :     return false;
    1427             :   }
    1428             : 
    1429           0 :   JS::Rooted<JSObject*> desiredProto(cx);
    1430           0 :   if (!GetDesiredProto(cx, args, &desiredProto)) {
    1431           0 :     return false;
    1432             :   }
    1433             : 
    1434           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    1435           0 :   Maybe<JSAutoCompartment> ac;
    1436           0 :   if (objIsXray) {
    1437           0 :     obj = js::CheckedUnwrap(obj);
    1438           0 :     if (!obj) {
    1439           0 :       return false;
    1440             :     }
    1441           0 :     ac.emplace(cx, obj);
    1442           0 :     if (!JS_WrapObject(cx, &desiredProto)) {
    1443           0 :       return false;
    1444             :     }
    1445             :   }
    1446           0 :   binding_detail::FastErrorResult rv;
    1447           0 :   auto result(StrongOrRawPtr<mozilla::dom::TestInterfaceIterableDoubleUnion>(mozilla::dom::TestInterfaceIterableDoubleUnion::Constructor(global, rv)));
    1448           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1449           0 :     return false;
    1450             :   }
    1451           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1452             :   static_assert(!IsPointer<decltype(result)>::value,
    1453             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
    1454           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
    1455           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1456           0 :     return false;
    1457             :   }
    1458           0 :   return true;
    1459             : }
    1460             : 
    1461             : static const js::ClassOps sInterfaceObjectClassOps = {
    1462             :     nullptr,               /* addProperty */
    1463             :     nullptr,               /* delProperty */
    1464             :     nullptr,               /* getProperty */
    1465             :     nullptr,               /* setProperty */
    1466             :     nullptr,               /* enumerate */
    1467             :     nullptr,               /* newEnumerate */
    1468             :     nullptr,               /* resolve */
    1469             :     nullptr,               /* mayResolve */
    1470             :     nullptr,               /* finalize */
    1471             :     _constructor, /* call */
    1472             :     nullptr,               /* hasInstance */
    1473             :     _constructor, /* construct */
    1474             :     nullptr,               /* trace */
    1475             : };
    1476             : 
    1477             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
    1478             :   {
    1479             :     "Function",
    1480             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
    1481             :     &sInterfaceObjectClassOps,
    1482             :     JS_NULL_CLASS_SPEC,
    1483             :     JS_NULL_CLASS_EXT,
    1484             :     &sInterfaceObjectClassObjectOps
    1485             :   },
    1486             :   eInterface,
    1487             :   true,
    1488             :   prototypes::id::TestInterfaceIterableDoubleUnion,
    1489             :   PrototypeTraits<prototypes::id::TestInterfaceIterableDoubleUnion>::Depth,
    1490             :   sNativePropertyHooks,
    1491             :   "function TestInterfaceIterableDoubleUnion() {\n    [native code]\n}",
    1492             :   JS::GetRealmFunctionPrototype
    1493             : };
    1494             : 
    1495             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
    1496             :   {
    1497             :     "TestInterfaceIterableDoubleUnionPrototype",
    1498             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    1499             :     JS_NULL_CLASS_OPS,
    1500             :     JS_NULL_CLASS_SPEC,
    1501             :     JS_NULL_CLASS_EXT,
    1502             :     JS_NULL_OBJECT_OPS
    1503             :   },
    1504             :   eInterfacePrototype,
    1505             :   false,
    1506             :   prototypes::id::TestInterfaceIterableDoubleUnion,
    1507             :   PrototypeTraits<prototypes::id::TestInterfaceIterableDoubleUnion>::Depth,
    1508             :   sNativePropertyHooks,
    1509             :   "[object TestInterfaceIterableDoubleUnionPrototype]",
    1510             :   JS::GetRealmObjectPrototype
    1511             : };
    1512             : 
    1513             : bool
    1514           0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
    1515             : {
    1516             :   static bool sPrefValue;
    1517             :   static bool sPrefCacheSetUp = false;
    1518           0 :   if (!sPrefCacheSetUp) {
    1519           0 :     sPrefCacheSetUp = true;
    1520           0 :     Preferences::AddBoolVarCache(&sPrefValue, "dom.expose_test_interfaces");
    1521             :   }
    1522             : 
    1523           0 :   return sPrefValue;
    1524             : }
    1525             : 
    1526             : JSObject*
    1527           0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
    1528             : {
    1529           0 :   return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
    1530             : }
    1531             : 
    1532             : static const js::ClassOps sClassOps = {
    1533             :   _addProperty, /* addProperty */
    1534             :   nullptr,               /* delProperty */
    1535             :   nullptr,               /* getProperty */
    1536             :   nullptr,               /* setProperty */
    1537             :   nullptr,               /* enumerate */
    1538             :   nullptr, /* newEnumerate */
    1539             :   nullptr, /* resolve */
    1540             :   nullptr, /* mayResolve */
    1541             :   _finalize, /* finalize */
    1542             :   nullptr, /* call */
    1543             :   nullptr,               /* hasInstance */
    1544             :   nullptr,               /* construct */
    1545             :   nullptr, /* trace */
    1546             : };
    1547             : 
    1548             : static const js::ClassExtension sClassExtension = {
    1549             :   nullptr, /* weakmapKeyDelegateOp */
    1550             :   _objectMoved /* objectMovedOp */
    1551             : };
    1552             : 
    1553             : static const DOMJSClass sClass = {
    1554             :   { "TestInterfaceIterableDoubleUnion",
    1555             :     JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
    1556             :     &sClassOps,
    1557             :     JS_NULL_CLASS_SPEC,
    1558             :     &sClassExtension,
    1559             :     JS_NULL_OBJECT_OPS
    1560             :   },
    1561             :   { prototypes::id::TestInterfaceIterableDoubleUnion, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
    1562             :   IsBaseOf<nsISupports, mozilla::dom::TestInterfaceIterableDoubleUnion >::value,
    1563             :   sNativePropertyHooks,
    1564             :   FindAssociatedGlobalForNative<mozilla::dom::TestInterfaceIterableDoubleUnion>::Get,
    1565             :   GetProtoObjectHandle,
    1566             :   GetCCParticipant<mozilla::dom::TestInterfaceIterableDoubleUnion>::Get()
    1567             : };
    1568             : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
    1569             :               "Must have the right minimal number of reserved slots.");
    1570             : static_assert(1 >= 1,
    1571             :               "Must have enough reserved slots.");
    1572             : 
    1573             : const JSClass*
    1574           0 : GetJSClass()
    1575             : {
    1576           0 :   return sClass.ToJSClass();
    1577             : }
    1578             : 
    1579             : bool
    1580           0 : Wrap(JSContext* aCx, mozilla::dom::TestInterfaceIterableDoubleUnion* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
    1581             : {
    1582             :   MOZ_ASSERT(static_cast<mozilla::dom::TestInterfaceIterableDoubleUnion*>(aObject) ==
    1583             :              reinterpret_cast<mozilla::dom::TestInterfaceIterableDoubleUnion*>(aObject),
    1584             :              "Multiple inheritance for mozilla::dom::TestInterfaceIterableDoubleUnion is broken.");
    1585           0 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
    1586           0 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
    1587           0 :   MOZ_ASSERT(!aCache->GetWrapper(),
    1588             :              "You should probably not be using Wrap() directly; use "
    1589             :              "GetOrCreateDOMReflector instead");
    1590             : 
    1591           0 :   MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
    1592             :              "nsISupports must be on our primary inheritance chain");
    1593             : 
    1594           0 :   JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
    1595           0 :   if (!global) {
    1596           0 :     return false;
    1597             :   }
    1598           0 :   MOZ_ASSERT(JS_IsGlobalObject(global));
    1599           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(global));
    1600             : 
    1601             :   // That might have ended up wrapping us already, due to the wonders
    1602             :   // of XBL.  Check for that, and bail out as needed.
    1603           0 :   aReflector.set(aCache->GetWrapper());
    1604           0 :   if (aReflector) {
    1605             : #ifdef DEBUG
    1606           0 :     binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
    1607             : #endif // DEBUG
    1608           0 :     return true;
    1609             :   }
    1610             : 
    1611           0 :   JSAutoCompartment ac(aCx, global);
    1612           0 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
    1613           0 :   if (!canonicalProto) {
    1614           0 :     return false;
    1615             :   }
    1616           0 :   JS::Rooted<JSObject*> proto(aCx);
    1617           0 :   if (aGivenProto) {
    1618           0 :     proto = aGivenProto;
    1619             :     // Unfortunately, while aGivenProto was in the compartment of aCx
    1620             :     // coming in, we changed compartments to that of "parent" so may need
    1621             :     // to wrap the proto here.
    1622           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
    1623           0 :       if (!JS_WrapObject(aCx, &proto)) {
    1624           0 :         return false;
    1625             :       }
    1626             :     }
    1627             :   } else {
    1628           0 :     proto = canonicalProto;
    1629             :   }
    1630             : 
    1631           0 :   BindingJSObjectCreator<mozilla::dom::TestInterfaceIterableDoubleUnion> creator(aCx);
    1632           0 :   creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
    1633           0 :   if (!aReflector) {
    1634           0 :     return false;
    1635             :   }
    1636             : 
    1637           0 :   aCache->SetWrapper(aReflector);
    1638           0 :   creator.InitializationSucceeded();
    1639             : 
    1640           0 :   MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
    1641             :              aCache->GetWrapperPreserveColor() == aReflector);
    1642             :   // If proto != canonicalProto, we have to preserve our wrapper;
    1643             :   // otherwise we won't be able to properly recreate it later, since
    1644             :   // we won't know what proto to use.  Note that we don't check
    1645             :   // aGivenProto here, since it's entirely possible (and even
    1646             :   // somewhat common) to have a non-null aGivenProto which is the
    1647             :   // same as canonicalProto.
    1648           0 :   if (proto != canonicalProto) {
    1649           0 :     PreserveWrapper(aObject);
    1650             :   }
    1651             : 
    1652           0 :   return true;
    1653             : }
    1654             : 
    1655             : const NativePropertyHooks sNativePropertyHooks[] = { {
    1656             :   nullptr,
    1657             :   nullptr,
    1658             :   nullptr,
    1659             :   { sNativeProperties.Upcast(), nullptr },
    1660             :   prototypes::id::TestInterfaceIterableDoubleUnion,
    1661             :   constructors::id::TestInterfaceIterableDoubleUnion,
    1662             :   nullptr,
    1663             :   &DefaultXrayExpandoObjectClass
    1664             : } };
    1665             : 
    1666             : void
    1667           0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    1668             : {
    1669           0 :   JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
    1670           0 :   if (!parentProto) {
    1671           0 :     return;
    1672             :   }
    1673             : 
    1674           0 :   JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
    1675           0 :   if (!constructorProto) {
    1676           0 :     return;
    1677             :   }
    1678             : 
    1679             :   static bool sIdsInited = false;
    1680           0 :   if (!sIdsInited && NS_IsMainThread()) {
    1681           0 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
    1682           0 :       return;
    1683             :     }
    1684           0 :     sIdsInited = true;
    1685             :   }
    1686             : 
    1687           0 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::TestInterfaceIterableDoubleUnion);
    1688           0 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::TestInterfaceIterableDoubleUnion);
    1689           0 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    1690             :                               &sPrototypeClass.mBase, protoCache,
    1691             :                               constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
    1692             :                               interfaceCache,
    1693             :                               sNativeProperties.Upcast(),
    1694             :                               nullptr,
    1695             :                               "TestInterfaceIterableDoubleUnion", aDefineOnGlobal,
    1696             :                               nullptr,
    1697           0 :                               false);
    1698             : 
    1699             :   // Set up aliases on the interface prototype object we just created.
    1700           0 :   JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx);
    1701           0 :   if (!proto) {
    1702           0 :     *protoCache = nullptr;
    1703           0 :     if (interfaceCache) {
    1704           0 :       *interfaceCache = nullptr;
    1705             :     }
    1706           0 :     return;
    1707             :   }
    1708             : 
    1709           0 :   JS::Rooted<JS::Value> aliasedVal(aCx);
    1710             : 
    1711           0 :   if (!JS_GetProperty(aCx, proto, "entries", &aliasedVal)) {
    1712           0 :     *protoCache = nullptr;
    1713           0 :     if (interfaceCache) {
    1714           0 :       *interfaceCache = nullptr;
    1715             :     }
    1716           0 :     return;
    1717             :   }
    1718           0 :   JS::Rooted<jsid> iteratorId(aCx, SYMBOL_TO_JSID(JS::GetWellKnownSymbol(aCx, JS::SymbolCode::iterator)));
    1719           0 :   if (!JS_DefinePropertyById(aCx, proto, iteratorId, aliasedVal, 0)) {
    1720           0 :     *protoCache = nullptr;
    1721           0 :     if (interfaceCache) {
    1722           0 :       *interfaceCache = nullptr;
    1723             :     }
    1724           0 :     return;
    1725             :   }
    1726             : }
    1727             : 
    1728             : JS::Handle<JSObject*>
    1729           0 : GetProtoObjectHandle(JSContext* aCx)
    1730             : {
    1731             :   /* Get the interface prototype object for this class.  This will create the
    1732             :      object as needed. */
    1733           0 :   bool aDefineOnGlobal = true;
    1734             : 
    1735             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    1736           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    1737           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    1738           0 :     return nullptr;
    1739             :   }
    1740             : 
    1741             :   /* Check to see whether the interface objects are already installed */
    1742           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    1743           0 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::TestInterfaceIterableDoubleUnion)) {
    1744           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    1745           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    1746             :   }
    1747             : 
    1748             :   /*
    1749             :    * The object might _still_ be null, but that's OK.
    1750             :    *
    1751             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    1752             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    1753             :    * changed after they have been set.
    1754             :    *
    1755             :    * Calling address() avoids the read read barrier that does gray
    1756             :    * unmarking, but it's not possible for the object to be gray here.
    1757             :    */
    1758             : 
    1759           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::TestInterfaceIterableDoubleUnion);
    1760           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    1761           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    1762             : }
    1763             : 
    1764             : JS::Handle<JSObject*>
    1765           0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
    1766             : {
    1767             :   /* Get the interface object for this class.  This will create the object as
    1768             :      needed. */
    1769             : 
    1770             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    1771           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    1772           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    1773           0 :     return nullptr;
    1774             :   }
    1775             : 
    1776             :   /* Check to see whether the interface objects are already installed */
    1777           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    1778           0 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::TestInterfaceIterableDoubleUnion)) {
    1779           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    1780           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    1781             :   }
    1782             : 
    1783             :   /*
    1784             :    * The object might _still_ be null, but that's OK.
    1785             :    *
    1786             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    1787             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    1788             :    * changed after they have been set.
    1789             :    *
    1790             :    * Calling address() avoids the read read barrier that does gray
    1791             :    * unmarking, but it's not possible for the object to be gray here.
    1792             :    */
    1793             : 
    1794           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::TestInterfaceIterableDoubleUnion);
    1795           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    1796           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    1797             : }
    1798             : 
    1799             : JSObject*
    1800           0 : GetConstructorObject(JSContext* aCx)
    1801             : {
    1802           0 :   return GetConstructorObjectHandle(aCx);
    1803             : }
    1804             : 
    1805             : } // namespace TestInterfaceIterableDoubleUnionBinding
    1806             : 
    1807             : 
    1808             : 
    1809             : namespace TestInterfaceIterableDoubleUnionIteratorBinding {
    1810             : 
    1811             : static bool
    1812           0 : next(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDoubleUnion>* self, const JSJitMethodCallArgs& args)
    1813             : {
    1814           0 :   binding_detail::FastErrorResult rv;
    1815           0 :   JS::Rooted<JSObject*> result(cx);
    1816           0 :   self->Next(cx, &result, rv);
    1817           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1818           0 :     return false;
    1819             :   }
    1820           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1821           0 :   JS::ExposeObjectToActiveJS(result);
    1822           0 :   args.rval().setObject(*result);
    1823           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    1824           0 :     return false;
    1825             :   }
    1826           0 :   return true;
    1827             : }
    1828             : 
    1829             : static const JSJitInfo next_methodinfo = {
    1830             :   { (JSJitGetterOp)next },
    1831             :   { prototypes::id::TestInterfaceIterableDoubleUnionIterator },
    1832             :   { PrototypeTraits<prototypes::id::TestInterfaceIterableDoubleUnionIterator>::Depth },
    1833             :   JSJitInfo::Method,
    1834             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1835             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1836             :   false,  /* isInfallible. False in setters. */
    1837             :   false,  /* isMovable.  Not relevant for setters. */
    1838             :   false, /* isEliminatable.  Not relevant for setters. */
    1839             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1840             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1841             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1842             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1843             : };
    1844             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1845             : static_assert(0 < 1, "There is no slot for us");
    1846             : 
    1847             : static void
    1848           0 : _finalize(js::FreeOp* fop, JSObject* obj)
    1849             : {
    1850           0 :   mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDoubleUnion>* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDoubleUnion>>(obj);
    1851           0 :   if (self) {
    1852           0 :     AddForDeferredFinalization<mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDoubleUnion>>(self);
    1853             :   }
    1854           0 : }
    1855             : 
    1856             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    1857             : #if defined(__clang__)
    1858             : #pragma clang diagnostic push
    1859             : #pragma clang diagnostic ignored "-Wmissing-braces"
    1860             : #endif
    1861             : static const JSFunctionSpec sMethods_specs[] = {
    1862             :   JS_FNSPEC("next", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&next_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    1863             :   JS_FS_END
    1864             : };
    1865             : #if defined(__clang__)
    1866             : #pragma clang diagnostic pop
    1867             : #endif
    1868             : 
    1869             : 
    1870             : // Can't be const because the pref-enabled boolean needs to be writable
    1871             : static Prefable<const JSFunctionSpec> sMethods[] = {
    1872             :   { nullptr, &sMethods_specs[0] },
    1873             :   { nullptr, nullptr }
    1874             : };
    1875             : 
    1876             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    1877             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    1878             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    1879             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    1880             : 
    1881             : 
    1882             : static uint16_t sNativeProperties_sortedPropertyIndices[1];
    1883             : static PropertyInfo sNativeProperties_propertyInfos[1];
    1884             : 
    1885             : static const NativePropertiesN<1> sNativeProperties = {
    1886             :   false, 0,
    1887             :   false, 0,
    1888             :   true,  0 /* sMethods */,
    1889             :   false, 0,
    1890             :   false, 0,
    1891             :   false, 0,
    1892             :   false, 0,
    1893             :   -1,
    1894             :   1,
    1895             :   sNativeProperties_sortedPropertyIndices,
    1896             :   {
    1897             :     { sMethods, &sNativeProperties_propertyInfos[0] }
    1898             :   }
    1899             : };
    1900             : static_assert(1 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
    1901             :     "We have a property info count that is oversized");
    1902             : 
    1903             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
    1904             :   {
    1905             :     "TestInterfaceIterableDoubleUnionIteratorPrototype",
    1906             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    1907             :     JS_NULL_CLASS_OPS,
    1908             :     JS_NULL_CLASS_SPEC,
    1909             :     JS_NULL_CLASS_EXT,
    1910             :     JS_NULL_OBJECT_OPS
    1911             :   },
    1912             :   eInterfacePrototype,
    1913             :   false,
    1914             :   prototypes::id::TestInterfaceIterableDoubleUnionIterator,
    1915             :   PrototypeTraits<prototypes::id::TestInterfaceIterableDoubleUnionIterator>::Depth,
    1916             :   sNativePropertyHooks,
    1917             :   "[object TestInterfaceIterableDoubleUnionIteratorPrototype]",
    1918             :   JS::GetRealmIteratorPrototype
    1919             : };
    1920             : 
    1921             : static const js::ClassOps sClassOps = {
    1922             :   nullptr, /* addProperty */
    1923             :   nullptr,               /* delProperty */
    1924             :   nullptr,               /* getProperty */
    1925             :   nullptr,               /* setProperty */
    1926             :   nullptr,               /* enumerate */
    1927             :   nullptr, /* newEnumerate */
    1928             :   nullptr, /* resolve */
    1929             :   nullptr, /* mayResolve */
    1930             :   _finalize, /* finalize */
    1931             :   nullptr, /* call */
    1932             :   nullptr,               /* hasInstance */
    1933             :   nullptr,               /* construct */
    1934             :   nullptr, /* trace */
    1935             : };
    1936             : 
    1937             : static const js::ClassExtension sClassExtension = {
    1938             :   nullptr, /* weakmapKeyDelegateOp */
    1939             :   nullptr /* objectMovedOp */
    1940             : };
    1941             : 
    1942             : static const DOMJSClass sClass = {
    1943             :   { "TestInterfaceIterableDoubleUnionIterator",
    1944             :     JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
    1945             :     &sClassOps,
    1946             :     JS_NULL_CLASS_SPEC,
    1947             :     &sClassExtension,
    1948             :     JS_NULL_OBJECT_OPS
    1949             :   },
    1950             :   { prototypes::id::TestInterfaceIterableDoubleUnionIterator, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
    1951             :   IsBaseOf<nsISupports, mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDoubleUnion> >::value,
    1952             :   sNativePropertyHooks,
    1953             :   FindAssociatedGlobalForNative<mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDoubleUnion>>::Get,
    1954             :   GetProtoObjectHandle,
    1955             :   GetCCParticipant<mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDoubleUnion>>::Get()
    1956             : };
    1957             : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
    1958             :               "Must have the right minimal number of reserved slots.");
    1959             : static_assert(1 >= 1,
    1960             :               "Must have enough reserved slots.");
    1961             : 
    1962             : const JSClass*
    1963           0 : GetJSClass()
    1964             : {
    1965           0 :   return sClass.ToJSClass();
    1966             : }
    1967             : 
    1968             : bool
    1969           0 : Wrap(JSContext* aCx, mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDoubleUnion>* aObject, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
    1970             : {
    1971             :   MOZ_ASSERT(static_cast<mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDoubleUnion>*>(aObject) ==
    1972             :              reinterpret_cast<mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDoubleUnion>*>(aObject),
    1973             :              "Multiple inheritance for mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDoubleUnion> is broken.");
    1974           0 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
    1975           0 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
    1976             : 
    1977           0 :   JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
    1978           0 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
    1979           0 :   if (!canonicalProto) {
    1980           0 :     return false;
    1981             :   }
    1982           0 :   JS::Rooted<JSObject*> proto(aCx);
    1983           0 :   if (aGivenProto) {
    1984           0 :     proto = aGivenProto;
    1985             :     // Unfortunately, while aGivenProto was in the compartment of aCx
    1986             :     // coming in, we changed compartments to that of "parent" so may need
    1987             :     // to wrap the proto here.
    1988           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
    1989           0 :       if (!JS_WrapObject(aCx, &proto)) {
    1990           0 :         return false;
    1991             :       }
    1992             :     }
    1993             :   } else {
    1994           0 :     proto = canonicalProto;
    1995             :   }
    1996             : 
    1997           0 :   BindingJSObjectCreator<mozilla::dom::IterableIterator<mozilla::dom::TestInterfaceIterableDoubleUnion>> creator(aCx);
    1998           0 :   creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
    1999           0 :   if (!aReflector) {
    2000           0 :     return false;
    2001             :   }
    2002             : 
    2003             : 
    2004             : 
    2005           0 :   creator.InitializationSucceeded();
    2006           0 :   return true;
    2007             : }
    2008             : 
    2009             : const NativePropertyHooks sNativePropertyHooks[] = { {
    2010             :   nullptr,
    2011             :   nullptr,
    2012             :   nullptr,
    2013             :   { sNativeProperties.Upcast(), nullptr },
    2014             :   prototypes::id::TestInterfaceIterableDoubleUnionIterator,
    2015             :   constructors::id::_ID_Count,
    2016             :   nullptr,
    2017             :   &DefaultXrayExpandoObjectClass
    2018             : } };
    2019             : 
    2020             : void
    2021           0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    2022             : {
    2023           0 :   JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmIteratorPrototype(aCx));
    2024           0 :   if (!parentProto) {
    2025           0 :     return;
    2026             :   }
    2027             : 
    2028             :   static bool sIdsInited = false;
    2029           0 :   if (!sIdsInited && NS_IsMainThread()) {
    2030           0 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
    2031           0 :       return;
    2032             :     }
    2033           0 :     sIdsInited = true;
    2034             :   }
    2035             : 
    2036           0 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::TestInterfaceIterableDoubleUnionIterator);
    2037           0 :   JS::Heap<JSObject*>* interfaceCache = nullptr;
    2038           0 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    2039             :                               &sPrototypeClass.mBase, protoCache,
    2040             :                               nullptr, nullptr, 0, nullptr,
    2041             :                               interfaceCache,
    2042             :                               sNativeProperties.Upcast(),
    2043             :                               nullptr,
    2044             :                               nullptr, aDefineOnGlobal,
    2045             :                               nullptr,
    2046           0 :                               false);
    2047             : }
    2048             : 
    2049             : JS::Handle<JSObject*>
    2050           0 : GetProtoObjectHandle(JSContext* aCx)
    2051             : {
    2052             :   /* Get the interface prototype object for this class.  This will create the
    2053             :      object as needed. */
    2054           0 :   bool aDefineOnGlobal = true;
    2055             : 
    2056             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    2057           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    2058           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    2059           0 :     return nullptr;
    2060             :   }
    2061             : 
    2062             :   /* Check to see whether the interface objects are already installed */
    2063           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    2064           0 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::TestInterfaceIterableDoubleUnionIterator)) {
    2065           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    2066           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    2067             :   }
    2068             : 
    2069             :   /*
    2070             :    * The object might _still_ be null, but that's OK.
    2071             :    *
    2072             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    2073             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    2074             :    * changed after they have been set.
    2075             :    *
    2076             :    * Calling address() avoids the read read barrier that does gray
    2077             :    * unmarking, but it's not possible for the object to be gray here.
    2078             :    */
    2079             : 
    2080           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::TestInterfaceIterableDoubleUnionIterator);
    2081           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    2082           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    2083             : }
    2084             : 
    2085             : } // namespace TestInterfaceIterableDoubleUnionIteratorBinding
    2086             : 
    2087             : 
    2088             : 
    2089             : namespace TestInterfaceIterableSingleBinding {
    2090             : 
    2091             : static bool
    2092           0 : get_length(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceIterableSingle* self, JSJitGetterCallArgs args)
    2093             : {
    2094           0 :   uint32_t result(self->Length());
    2095           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2096           0 :   args.rval().setNumber(result);
    2097           0 :   return true;
    2098             : }
    2099             : 
    2100             : static const JSJitInfo length_getterinfo = {
    2101             :   { (JSJitGetterOp)get_length },
    2102             :   { prototypes::id::TestInterfaceIterableSingle },
    2103             :   { PrototypeTraits<prototypes::id::TestInterfaceIterableSingle>::Depth },
    2104             :   JSJitInfo::Getter,
    2105             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2106             :   JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
    2107             :   true,  /* isInfallible. False in setters. */
    2108             :   false,  /* isMovable.  Not relevant for setters. */
    2109             :   false, /* isEliminatable.  Not relevant for setters. */
    2110             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2111             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2112             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2113             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2114             : };
    2115             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2116             : static_assert(0 < 1, "There is no slot for us");
    2117             : 
    2118             : static void
    2119           0 : _objectMoved(JSObject* obj, const JSObject* old)
    2120             : {
    2121           0 :   mozilla::dom::TestInterfaceIterableSingle* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceIterableSingle>(obj);
    2122           0 :   if (self) {
    2123           0 :     UpdateWrapper(self, self, obj, old);
    2124             :   }
    2125           0 : }
    2126             : 
    2127             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    2128             : #if defined(__clang__)
    2129             : #pragma clang diagnostic push
    2130             : #pragma clang diagnostic ignored "-Wmissing-braces"
    2131             : #endif
    2132             : static const JSFunctionSpec sMethods_specs[] = {
    2133             :   JS_SYM_FNSPEC(iterator, nullptr, nullptr, 0, 0, "ArrayValues"),
    2134             :   JS_FNSPEC("keys", nullptr, nullptr, 0, JSPROP_ENUMERATE, "ArrayKeys"),
    2135             :   JS_FNSPEC("values", nullptr, nullptr, 0, JSPROP_ENUMERATE, "ArrayValues"),
    2136             :   JS_FNSPEC("entries", nullptr, nullptr, 0, JSPROP_ENUMERATE, "ArrayEntries"),
    2137             :   JS_FNSPEC("forEach", nullptr, nullptr, 1, JSPROP_ENUMERATE, "ArrayForEach"),
    2138             :   JS_FS_END
    2139             : };
    2140             : #if defined(__clang__)
    2141             : #pragma clang diagnostic pop
    2142             : #endif
    2143             : 
    2144             : 
    2145             : // Can't be const because the pref-enabled boolean needs to be writable
    2146             : static Prefable<const JSFunctionSpec> sMethods[] = {
    2147             :   { nullptr, &sMethods_specs[0] },
    2148             :   { nullptr, nullptr }
    2149             : };
    2150             : 
    2151             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    2152             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    2153             : static_assert(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    2154             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    2155             : 
    2156             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    2157             : #if defined(__clang__)
    2158             : #pragma clang diagnostic push
    2159             : #pragma clang diagnostic ignored "-Wmissing-braces"
    2160             : #endif
    2161             : static const JSPropertySpec sAttributes_specs[] = {
    2162             :   { "length", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &length_getterinfo, nullptr, nullptr },
    2163             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
    2164             : };
    2165             : #if defined(__clang__)
    2166             : #pragma clang diagnostic pop
    2167             : #endif
    2168             : 
    2169             : 
    2170             : // Can't be const because the pref-enabled boolean needs to be writable
    2171             : static Prefable<const JSPropertySpec> sAttributes[] = {
    2172             :   { nullptr, &sAttributes_specs[0] },
    2173             :   { nullptr, nullptr }
    2174             : };
    2175             : 
    2176             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    2177             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    2178             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    2179             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    2180             : 
    2181             : 
    2182             : static uint16_t sNativeProperties_sortedPropertyIndices[6];
    2183             : static PropertyInfo sNativeProperties_propertyInfos[6];
    2184             : 
    2185             : static const NativePropertiesN<2> sNativeProperties = {
    2186             :   false, 0,
    2187             :   false, 0,
    2188             :   true,  0 /* sMethods */,
    2189             :   true,  1 /* sAttributes */,
    2190             :   false, 0,
    2191             :   false, 0,
    2192             :   false, 0,
    2193             :   -1,
    2194             :   6,
    2195             :   sNativeProperties_sortedPropertyIndices,
    2196             :   {
    2197             :     { sMethods, &sNativeProperties_propertyInfos[0] },
    2198             :     { sAttributes, &sNativeProperties_propertyInfos[5] }
    2199             :   }
    2200             : };
    2201             : static_assert(6 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
    2202             :     "We have a property info count that is oversized");
    2203             : 
    2204             : static bool
    2205           0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
    2206             : {
    2207           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    2208           0 :   JS::Rooted<JSObject*> obj(cx, &args.callee());
    2209           0 :   if (!args.isConstructing()) {
    2210             :     // XXXbz wish I could get the name from the callee instead of
    2211             :     // Adding more relocations
    2212           0 :     return ThrowConstructorWithoutNew(cx, "TestInterfaceIterableSingle");
    2213             :   }
    2214             : 
    2215           0 :   GlobalObject global(cx, obj);
    2216           0 :   if (global.Failed()) {
    2217           0 :     return false;
    2218             :   }
    2219             : 
    2220           0 :   JS::Rooted<JSObject*> desiredProto(cx);
    2221           0 :   if (!GetDesiredProto(cx, args, &desiredProto)) {
    2222           0 :     return false;
    2223             :   }
    2224             : 
    2225           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2226           0 :   Maybe<JSAutoCompartment> ac;
    2227           0 :   if (objIsXray) {
    2228           0 :     obj = js::CheckedUnwrap(obj);
    2229           0 :     if (!obj) {
    2230           0 :       return false;
    2231             :     }
    2232           0 :     ac.emplace(cx, obj);
    2233           0 :     if (!JS_WrapObject(cx, &desiredProto)) {
    2234           0 :       return false;
    2235             :     }
    2236             :   }
    2237           0 :   binding_detail::FastErrorResult rv;
    2238           0 :   auto result(StrongOrRawPtr<mozilla::dom::TestInterfaceIterableSingle>(mozilla::dom::TestInterfaceIterableSingle::Constructor(global, rv)));
    2239           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2240           0 :     return false;
    2241             :   }
    2242           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2243             :   static_assert(!IsPointer<decltype(result)>::value,
    2244             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
    2245           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
    2246           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    2247           0 :     return false;
    2248             :   }
    2249           0 :   return true;
    2250             : }
    2251             : 
    2252             : static const js::ClassOps sInterfaceObjectClassOps = {
    2253             :     nullptr,               /* addProperty */
    2254             :     nullptr,               /* delProperty */
    2255             :     nullptr,               /* getProperty */
    2256             :     nullptr,               /* setProperty */
    2257             :     nullptr,               /* enumerate */
    2258             :     nullptr,               /* newEnumerate */
    2259             :     nullptr,               /* resolve */
    2260             :     nullptr,               /* mayResolve */
    2261             :     nullptr,               /* finalize */
    2262             :     _constructor, /* call */
    2263             :     nullptr,               /* hasInstance */
    2264             :     _constructor, /* construct */
    2265             :     nullptr,               /* trace */
    2266             : };
    2267             : 
    2268             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
    2269             :   {
    2270             :     "Function",
    2271             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
    2272             :     &sInterfaceObjectClassOps,
    2273             :     JS_NULL_CLASS_SPEC,
    2274             :     JS_NULL_CLASS_EXT,
    2275             :     &sInterfaceObjectClassObjectOps
    2276             :   },
    2277             :   eInterface,
    2278             :   true,
    2279             :   prototypes::id::TestInterfaceIterableSingle,
    2280             :   PrototypeTraits<prototypes::id::TestInterfaceIterableSingle>::Depth,
    2281             :   sNativePropertyHooks,
    2282             :   "function TestInterfaceIterableSingle() {\n    [native code]\n}",
    2283             :   JS::GetRealmFunctionPrototype
    2284             : };
    2285             : 
    2286             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
    2287             :   {
    2288             :     "TestInterfaceIterableSinglePrototype",
    2289             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    2290             :     JS_NULL_CLASS_OPS,
    2291             :     JS_NULL_CLASS_SPEC,
    2292             :     JS_NULL_CLASS_EXT,
    2293             :     JS_NULL_OBJECT_OPS
    2294             :   },
    2295             :   eInterfacePrototype,
    2296             :   false,
    2297             :   prototypes::id::TestInterfaceIterableSingle,
    2298             :   PrototypeTraits<prototypes::id::TestInterfaceIterableSingle>::Depth,
    2299             :   sNativePropertyHooks,
    2300             :   "[object TestInterfaceIterableSinglePrototype]",
    2301             :   JS::GetRealmObjectPrototype
    2302             : };
    2303             : 
    2304             : bool
    2305           0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
    2306             : {
    2307             :   static bool sPrefValue;
    2308             :   static bool sPrefCacheSetUp = false;
    2309           0 :   if (!sPrefCacheSetUp) {
    2310           0 :     sPrefCacheSetUp = true;
    2311           0 :     Preferences::AddBoolVarCache(&sPrefValue, "dom.expose_test_interfaces");
    2312             :   }
    2313             : 
    2314           0 :   return sPrefValue;
    2315             : }
    2316             : 
    2317             : JSObject*
    2318           0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
    2319             : {
    2320           0 :   return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
    2321             : }
    2322             : 
    2323             : static_assert(IsBaseOf<nsISupports, mozilla::dom::TestInterfaceIterableSingle >::value,
    2324             :                   "We don't support non-nsISupports native classes for "
    2325             :                   "proxy-based bindings yet");
    2326             : 
    2327             : 
    2328             : class DOMProxyHandler : public mozilla::dom::DOMProxyHandler
    2329             : {
    2330             : public:
    2331             :   explicit constexpr DOMProxyHandler()
    2332             :   {
    2333             :   }
    2334             : 
    2335             :   virtual bool
    2336             :   getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
    2337             : 
    2338             :   virtual bool
    2339             :   defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const override;
    2340             : 
    2341             :   using mozilla::dom::DOMProxyHandler::defineProperty;
    2342             : 
    2343             :   virtual bool
    2344             :   ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const override;
    2345             : 
    2346             :   virtual bool
    2347             :   hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const override;
    2348             : 
    2349             :   virtual bool
    2350             :   get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
    2351             : 
    2352             :   virtual const char*
    2353             :   className(JSContext* cx, JS::Handle<JSObject*> proxy) const override;
    2354             : 
    2355             :   virtual bool
    2356             :   finalizeInBackground(const JS::Value& priv) const override;
    2357             : 
    2358             :   virtual void
    2359             :   finalize(JSFreeOp* fop, JSObject* proxy) const override;
    2360             : 
    2361             :   static const DOMProxyHandler*
    2362             :   getInstance();
    2363             : 
    2364             :   virtual bool
    2365             :   delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const override;
    2366             : 
    2367             :   virtual bool
    2368             :   getElements(JSContext* cx, JS::Handle<JSObject*> proxy, uint32_t begin, uint32_t end, js::ElementAdder* adder) const override;
    2369             : };
    2370             : 
    2371             : MOZ_ALWAYS_INLINE bool
    2372           0 : IsProxy(JSObject* obj)
    2373             : {
    2374           0 :   return js::IsProxy(obj) && js::GetProxyHandler(obj) == DOMProxyHandler::getInstance();
    2375             : }
    2376             : 
    2377             : MOZ_ALWAYS_INLINE mozilla::dom::TestInterfaceIterableSingle*
    2378           0 : UnwrapProxy(JSObject* obj)
    2379             : {
    2380           0 :   MOZ_ASSERT(js::IsProxy(obj));
    2381           0 :   if (js::GetProxyHandler(obj) != DOMProxyHandler::getInstance()) {
    2382           0 :     MOZ_ASSERT(xpc::WrapperFactory::IsXrayWrapper(obj));
    2383           0 :     obj = js::UncheckedUnwrap(obj);
    2384             :   }
    2385           0 :   MOZ_ASSERT(IsProxy(obj));
    2386           0 :   return static_cast<mozilla::dom::TestInterfaceIterableSingle*>(js::GetProxyReservedSlot(obj, DOM_OBJECT_SLOT).toPrivate());
    2387             : }
    2388             : 
    2389             : bool
    2390           0 : DOMProxyHandler::getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const
    2391             : {
    2392           0 :   bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
    2393           0 :   uint32_t index = GetArrayIndexFromId(cx, id);
    2394           0 :   if (IsArrayIndex(index)) {
    2395           0 :     mozilla::dom::TestInterfaceIterableSingle* self = UnwrapProxy(proxy);
    2396           0 :     bool found = false;
    2397           0 :     int32_t result(self->IndexedGetter(index, found));
    2398           0 :     MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2399             : 
    2400           0 :     if (found) {
    2401           0 :       desc.value().setInt32(int32_t(result));
    2402           0 :       FillPropertyDescriptor(desc, proxy, true);
    2403           0 :       return true;
    2404             :     }
    2405             :   }
    2406             : 
    2407           0 :   JS::Rooted<JSObject*> expando(cx);
    2408           0 :   if (!isXray && (expando = GetExpandoObject(proxy))) {
    2409           0 :     if (!JS_GetOwnPropertyDescriptorById(cx, expando, id, desc)) {
    2410           0 :       return false;
    2411             :     }
    2412           0 :     if (desc.object()) {
    2413             :       // Pretend the property lives on the wrapper.
    2414           0 :       desc.object().set(proxy);
    2415           0 :       return true;
    2416             :     }
    2417             :   }
    2418             : 
    2419           0 :   desc.object().set(nullptr);
    2420           0 :   return true;
    2421             : }
    2422             : 
    2423             : bool
    2424           0 : DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const
    2425             : {
    2426           0 :   if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {
    2427           0 :     *defined = true;
    2428           0 :     return opresult.failNoIndexedSetter();
    2429             :   }
    2430           0 :   return mozilla::dom::DOMProxyHandler::defineProperty(cx, proxy, id, desc, opresult, defined);
    2431             : }
    2432             : 
    2433             : 
    2434             : bool
    2435           0 : DOMProxyHandler::ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const
    2436             : {
    2437           0 :   bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
    2438             : 
    2439           0 :   uint32_t length = UnwrapProxy(proxy)->Length();
    2440           0 :   MOZ_ASSERT(int32_t(length) >= 0);
    2441           0 :   for (int32_t i = 0; i < int32_t(length); ++i) {
    2442           0 :     if (!props.append(INT_TO_JSID(i))) {
    2443           0 :       return false;
    2444             :     }
    2445             :   }
    2446             : 
    2447           0 :   JS::Rooted<JSObject*> expando(cx);
    2448           0 :   if (!isXray && (expando = DOMProxyHandler::GetExpandoObject(proxy)) &&
    2449           0 :       !js::GetPropertyKeys(cx, expando, flags, &props)) {
    2450           0 :     return false;
    2451             :   }
    2452             : 
    2453           0 :   return true;
    2454             : }
    2455             : 
    2456             : bool
    2457           0 : DOMProxyHandler::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const
    2458             : {
    2459           0 :   MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
    2460             :             "Should not have a XrayWrapper here");
    2461             : 
    2462           0 :   uint32_t index = GetArrayIndexFromId(cx, id);
    2463           0 :   if (IsArrayIndex(index)) {
    2464           0 :     bool found = false;
    2465           0 :     mozilla::dom::TestInterfaceIterableSingle* self = UnwrapProxy(proxy);
    2466           0 :     int32_t result(self->IndexedGetter(index, found));
    2467           0 :     MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2468             :     (void)result;
    2469             : 
    2470           0 :     *bp = found;
    2471           0 :     return true;
    2472             :   }
    2473             : 
    2474             : 
    2475           0 :   JS::Rooted<JSObject*> expando(cx, GetExpandoObject(proxy));
    2476           0 :   if (expando) {
    2477           0 :     bool b = true;
    2478           0 :     bool ok = JS_HasPropertyById(cx, expando, id, &b);
    2479           0 :     *bp = !!b;
    2480           0 :     if (!ok || *bp) {
    2481           0 :       return ok;
    2482             :     }
    2483             :   }
    2484             : 
    2485           0 :   *bp = false;
    2486           0 :   return true;
    2487             : }
    2488             : 
    2489             : bool
    2490           0 : DOMProxyHandler::get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const
    2491             : {
    2492           0 :   MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
    2493             :               "Should not have a XrayWrapper here");
    2494             : 
    2495           0 :   uint32_t index = GetArrayIndexFromId(cx, id);
    2496           0 :   if (IsArrayIndex(index)) {
    2497           0 :     mozilla::dom::TestInterfaceIterableSingle* self = UnwrapProxy(proxy);
    2498           0 :     bool found = false;
    2499           0 :     int32_t result(self->IndexedGetter(index, found));
    2500           0 :     MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2501             : 
    2502           0 :     if (found) {
    2503           0 :       vp.setInt32(int32_t(result));
    2504           0 :       return true;
    2505             :     }
    2506             :     // Even if we don't have this index, we don't forward the
    2507             :     // get on to our expando object.
    2508             :   } else {
    2509             :     { // Scope for expando
    2510           0 :       JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
    2511           0 :       if (expando) {
    2512             :         bool hasProp;
    2513           0 :         if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
    2514           0 :           return false;
    2515             :         }
    2516             : 
    2517           0 :         if (hasProp) {
    2518             :           // Forward the get to the expando object, but our receiver is whatever our
    2519             :           // receiver is.
    2520           0 :           return JS_ForwardGetPropertyTo(cx, expando, id, receiver, vp);
    2521             :         }
    2522             :       }
    2523             :     }
    2524             :   }
    2525             : 
    2526             :   bool foundOnPrototype;
    2527           0 :   if (!GetPropertyOnPrototype(cx, proxy, receiver, id, &foundOnPrototype, vp)) {
    2528           0 :     return false;
    2529             :   }
    2530             : 
    2531           0 :   if (foundOnPrototype) {
    2532           0 :     return true;
    2533             :   }
    2534             : 
    2535           0 :   vp.setUndefined();
    2536           0 :   return true;
    2537             : }
    2538             : 
    2539             : const char*
    2540           0 : DOMProxyHandler::className(JSContext* cx, JS::Handle<JSObject*> proxy) const
    2541             : {
    2542           0 :   return "TestInterfaceIterableSingle";
    2543             : }
    2544             : 
    2545             : bool
    2546           0 : DOMProxyHandler::finalizeInBackground(const JS::Value& priv) const
    2547             : {
    2548           0 :   return false;
    2549             : }
    2550             : 
    2551             : void
    2552           0 : DOMProxyHandler::finalize(JSFreeOp* fop, JSObject* proxy) const
    2553             : {
    2554           0 :   mozilla::dom::TestInterfaceIterableSingle* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceIterableSingle>(proxy);
    2555           0 :   if (self) {
    2556           0 :     ClearWrapper(self, self, proxy);
    2557           0 :     AddForDeferredFinalization<mozilla::dom::TestInterfaceIterableSingle>(self);
    2558             :   }
    2559           0 : }
    2560             : 
    2561             : const DOMProxyHandler*
    2562           0 : DOMProxyHandler::getInstance()
    2563             : {
    2564             :   static const DOMProxyHandler instance;
    2565           0 :   return &instance;
    2566             : }
    2567             : 
    2568             : bool
    2569           0 : DOMProxyHandler::delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const
    2570             : {
    2571           0 :   MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
    2572             :             "Should not have a XrayWrapper here");
    2573             : 
    2574           0 :   uint32_t index = GetArrayIndexFromId(cx, id);
    2575           0 :   if (IsArrayIndex(index)) {
    2576             :     bool deleteSucceeded;
    2577           0 :     bool found = false;
    2578           0 :     mozilla::dom::TestInterfaceIterableSingle* self = UnwrapProxy(proxy);
    2579           0 :     int32_t result(self->IndexedGetter(index, found));
    2580           0 :     MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2581             :     (void)result;
    2582           0 :     deleteSucceeded = !found;
    2583           0 :     return deleteSucceeded ? opresult.succeed() : opresult.failCantDelete();
    2584             :   }
    2585             : 
    2586           0 :   return dom::DOMProxyHandler::delete_(cx, proxy, id, opresult);
    2587             : }
    2588             : 
    2589             : bool
    2590           0 : DOMProxyHandler::getElements(JSContext* cx, JS::Handle<JSObject*> proxy, uint32_t begin, uint32_t end, js::ElementAdder* adder) const
    2591             : {
    2592           0 :   JS::Rooted<JS::Value> temp(cx);
    2593           0 :   MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
    2594             :              "Should not have a XrayWrapper here");
    2595             : 
    2596           0 :   mozilla::dom::TestInterfaceIterableSingle* self = UnwrapProxy(proxy);
    2597           0 :   uint32_t length = self->Length();
    2598             :   // Compute the end of the indices we'll get ourselves
    2599           0 :   uint32_t ourEnd = std::max(begin, std::min(end, length));
    2600             : 
    2601           0 :   for (uint32_t index = begin; index < ourEnd; ++index) {
    2602           0 :     bool found = false;
    2603           0 :     int32_t result(self->IndexedGetter(index, found));
    2604           0 :     MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2605             : 
    2606           0 :     MOZ_ASSERT(found);
    2607           0 :     temp.setInt32(int32_t(result));
    2608           0 :     if (!adder->append(cx, temp)) return false;
    2609           0 :     continue;
    2610             :   }
    2611             : 
    2612           0 :   if (end > ourEnd) {
    2613           0 :     JS::Rooted<JSObject*> proto(cx);
    2614           0 :     if (!js::GetObjectProto(cx, proxy, &proto)) {
    2615           0 :       return false;
    2616             :     }
    2617           0 :     return js::GetElementsWithAdder(cx, proto, proxy, ourEnd, end, adder);
    2618             :   }
    2619             : 
    2620           0 :   return true;
    2621             : }
    2622             : 
    2623             : static const js::ClassExtension sClassExtension = PROXY_MAKE_EXT(
    2624             :     _objectMoved
    2625             : );
    2626             : 
    2627             : static const DOMJSClass sClass = {
    2628             :   PROXY_CLASS_WITH_EXT("TestInterfaceIterableSingle",
    2629             :                        JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1),
    2630             :                        &sClassExtension),
    2631             :   { prototypes::id::TestInterfaceIterableSingle, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
    2632             :   IsBaseOf<nsISupports, mozilla::dom::TestInterfaceIterableSingle >::value,
    2633             :   sNativePropertyHooks,
    2634             :   FindAssociatedGlobalForNative<mozilla::dom::TestInterfaceIterableSingle>::Get,
    2635             :   GetProtoObjectHandle,
    2636             :   GetCCParticipant<mozilla::dom::TestInterfaceIterableSingle>::Get()
    2637             : };
    2638             : 
    2639             : bool
    2640           0 : Wrap(JSContext* aCx, mozilla::dom::TestInterfaceIterableSingle* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
    2641             : {
    2642             :   MOZ_ASSERT(static_cast<mozilla::dom::TestInterfaceIterableSingle*>(aObject) ==
    2643             :              reinterpret_cast<mozilla::dom::TestInterfaceIterableSingle*>(aObject),
    2644             :              "Multiple inheritance for mozilla::dom::TestInterfaceIterableSingle is broken.");
    2645           0 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
    2646           0 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
    2647           0 :   MOZ_ASSERT(!aCache->GetWrapper(),
    2648             :              "You should probably not be using Wrap() directly; use "
    2649             :              "GetOrCreateDOMReflector instead");
    2650             : 
    2651           0 :   MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
    2652             :              "nsISupports must be on our primary inheritance chain");
    2653             : 
    2654           0 :   JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
    2655           0 :   if (!global) {
    2656           0 :     return false;
    2657             :   }
    2658           0 :   MOZ_ASSERT(JS_IsGlobalObject(global));
    2659           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(global));
    2660             : 
    2661             :   // That might have ended up wrapping us already, due to the wonders
    2662             :   // of XBL.  Check for that, and bail out as needed.
    2663           0 :   aReflector.set(aCache->GetWrapper());
    2664           0 :   if (aReflector) {
    2665             : #ifdef DEBUG
    2666           0 :     binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
    2667             : #endif // DEBUG
    2668           0 :     return true;
    2669             :   }
    2670             : 
    2671           0 :   JSAutoCompartment ac(aCx, global);
    2672           0 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
    2673           0 :   if (!canonicalProto) {
    2674           0 :     return false;
    2675             :   }
    2676           0 :   JS::Rooted<JSObject*> proto(aCx);
    2677           0 :   if (aGivenProto) {
    2678           0 :     proto = aGivenProto;
    2679             :     // Unfortunately, while aGivenProto was in the compartment of aCx
    2680             :     // coming in, we changed compartments to that of "parent" so may need
    2681             :     // to wrap the proto here.
    2682           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
    2683           0 :       if (!JS_WrapObject(aCx, &proto)) {
    2684           0 :         return false;
    2685             :       }
    2686             :     }
    2687             :   } else {
    2688           0 :     proto = canonicalProto;
    2689             :   }
    2690             : 
    2691           0 :   BindingJSObjectCreator<mozilla::dom::TestInterfaceIterableSingle> creator(aCx);
    2692           0 :   JS::Rooted<JS::Value> expandoValue(aCx, JS::UndefinedValue());
    2693           0 :   creator.CreateProxyObject(aCx, &sClass.mBase, DOMProxyHandler::getInstance(),
    2694           0 :                             proto, aObject, expandoValue, aReflector);
    2695           0 :   if (!aReflector) {
    2696           0 :     return false;
    2697             :   }
    2698             : 
    2699             : 
    2700           0 :   aCache->SetWrapper(aReflector);
    2701           0 :   creator.InitializationSucceeded();
    2702             : 
    2703           0 :   MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
    2704             :              aCache->GetWrapperPreserveColor() == aReflector);
    2705             :   // If proto != canonicalProto, we have to preserve our wrapper;
    2706             :   // otherwise we won't be able to properly recreate it later, since
    2707             :   // we won't know what proto to use.  Note that we don't check
    2708             :   // aGivenProto here, since it's entirely possible (and even
    2709             :   // somewhat common) to have a non-null aGivenProto which is the
    2710             :   // same as canonicalProto.
    2711           0 :   if (proto != canonicalProto) {
    2712           0 :     PreserveWrapper(aObject);
    2713             :   }
    2714             : 
    2715           0 :   return true;
    2716             : }
    2717             : 
    2718             : static bool
    2719           0 : ResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::MutableHandle<JS::PropertyDescriptor> desc)
    2720             : {
    2721           0 :   return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc);
    2722             : }
    2723             : 
    2724             : static bool
    2725           0 : EnumerateOwnProperties(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::AutoIdVector& props)
    2726             : {
    2727           0 :   return js::GetProxyHandler(obj)->ownPropertyKeys(cx, wrapper, props);
    2728             : }
    2729             : 
    2730             : const NativePropertyHooks sNativePropertyHooks[] = { {
    2731             :   ResolveOwnProperty,
    2732             :   EnumerateOwnProperties,
    2733             :   nullptr,
    2734             :   { sNativeProperties.Upcast(), nullptr },
    2735             :   prototypes::id::TestInterfaceIterableSingle,
    2736             :   constructors::id::TestInterfaceIterableSingle,
    2737             :   nullptr,
    2738             :   &DefaultXrayExpandoObjectClass
    2739             : } };
    2740             : 
    2741             : void
    2742           0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    2743             : {
    2744           0 :   JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
    2745           0 :   if (!parentProto) {
    2746           0 :     return;
    2747             :   }
    2748             : 
    2749           0 :   JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
    2750           0 :   if (!constructorProto) {
    2751           0 :     return;
    2752             :   }
    2753             : 
    2754             :   static bool sIdsInited = false;
    2755           0 :   if (!sIdsInited && NS_IsMainThread()) {
    2756           0 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
    2757           0 :       return;
    2758             :     }
    2759           0 :     sIdsInited = true;
    2760             :   }
    2761             : 
    2762           0 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::TestInterfaceIterableSingle);
    2763           0 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::TestInterfaceIterableSingle);
    2764           0 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    2765             :                               &sPrototypeClass.mBase, protoCache,
    2766             :                               constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
    2767             :                               interfaceCache,
    2768             :                               sNativeProperties.Upcast(),
    2769             :                               nullptr,
    2770             :                               "TestInterfaceIterableSingle", aDefineOnGlobal,
    2771             :                               nullptr,
    2772           0 :                               false);
    2773             : }
    2774             : 
    2775             : JS::Handle<JSObject*>
    2776           0 : GetProtoObjectHandle(JSContext* aCx)
    2777             : {
    2778             :   /* Get the interface prototype object for this class.  This will create the
    2779             :      object as needed. */
    2780           0 :   bool aDefineOnGlobal = true;
    2781             : 
    2782             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    2783           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    2784           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    2785           0 :     return nullptr;
    2786             :   }
    2787             : 
    2788             :   /* Check to see whether the interface objects are already installed */
    2789           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    2790           0 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::TestInterfaceIterableSingle)) {
    2791           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    2792           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    2793             :   }
    2794             : 
    2795             :   /*
    2796             :    * The object might _still_ be null, but that's OK.
    2797             :    *
    2798             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    2799             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    2800             :    * changed after they have been set.
    2801             :    *
    2802             :    * Calling address() avoids the read read barrier that does gray
    2803             :    * unmarking, but it's not possible for the object to be gray here.
    2804             :    */
    2805             : 
    2806           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::TestInterfaceIterableSingle);
    2807           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    2808           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    2809             : }
    2810             : 
    2811             : JS::Handle<JSObject*>
    2812           0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
    2813             : {
    2814             :   /* Get the interface object for this class.  This will create the object as
    2815             :      needed. */
    2816             : 
    2817             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    2818           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    2819           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    2820           0 :     return nullptr;
    2821             :   }
    2822             : 
    2823             :   /* Check to see whether the interface objects are already installed */
    2824           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    2825           0 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::TestInterfaceIterableSingle)) {
    2826           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    2827           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    2828             :   }
    2829             : 
    2830             :   /*
    2831             :    * The object might _still_ be null, but that's OK.
    2832             :    *
    2833             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    2834             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    2835             :    * changed after they have been set.
    2836             :    *
    2837             :    * Calling address() avoids the read read barrier that does gray
    2838             :    * unmarking, but it's not possible for the object to be gray here.
    2839             :    */
    2840             : 
    2841           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::TestInterfaceIterableSingle);
    2842           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    2843           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    2844             : }
    2845             : 
    2846             : JSObject*
    2847           0 : GetConstructorObject(JSContext* aCx)
    2848             : {
    2849           0 :   return GetConstructorObjectHandle(aCx);
    2850             : }
    2851             : 
    2852             : } // namespace TestInterfaceIterableSingleBinding
    2853             : 
    2854             : 
    2855             : 
    2856             : namespace TestInterfaceJSMaplikeBinding {
    2857             : 
    2858             : namespace MaplikeHelpers {
    2859             : void
    2860           0 : Clear(mozilla::dom::TestInterfaceJSMaplike* self, ErrorResult& aRv)
    2861             : {
    2862           0 :   MOZ_ASSERT(self);
    2863           0 :   AutoJSAPI jsapi;
    2864           0 :   jsapi.Init();
    2865           0 :   JSContext* cx = jsapi.cx();
    2866             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    2867             :   // all we want is to wrap into _some_ scope and then unwrap to find
    2868             :   // the reflector, and wrapping has no side-effects.
    2869           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    2870           0 :   JS::Rooted<JS::Value> v(cx);
    2871           0 :   if(!ToJSValue(cx, self, &v)) {
    2872           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    2873           0 :     return;
    2874             :   }
    2875             :   // This is a reflector, but due to trying to name things
    2876             :   // similarly across method generators, it's called obj here.
    2877           0 :   JS::Rooted<JSObject*> obj(cx);
    2878           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    2879           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    2880             : 
    2881           0 :   JS::Rooted<JSObject*> backingObj(cx);
    2882           0 :   bool created = false;
    2883           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    2884           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    2885           0 :     return;
    2886             :   }
    2887           0 :   if (created) {
    2888           0 :     PreserveWrapper<mozilla::dom::TestInterfaceJSMaplike>(self);
    2889             :   }
    2890           0 :   if (!JS::MapClear(cx, backingObj)) {
    2891           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    2892           0 :     return;
    2893             :   }
    2894           0 :   return;
    2895             : }
    2896             : bool
    2897           0 : Delete(mozilla::dom::TestInterfaceJSMaplike* self, const nsAString& aKey, ErrorResult& aRv)
    2898             : {
    2899           0 :   MOZ_ASSERT(self);
    2900           0 :   AutoJSAPI jsapi;
    2901           0 :   jsapi.Init();
    2902           0 :   JSContext* cx = jsapi.cx();
    2903             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    2904             :   // all we want is to wrap into _some_ scope and then unwrap to find
    2905             :   // the reflector, and wrapping has no side-effects.
    2906           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    2907           0 :   JS::Rooted<JS::Value> v(cx);
    2908           0 :   if(!ToJSValue(cx, self, &v)) {
    2909           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    2910           0 :     return false;
    2911             :   }
    2912             :   // This is a reflector, but due to trying to name things
    2913             :   // similarly across method generators, it's called obj here.
    2914           0 :   JS::Rooted<JSObject*> obj(cx);
    2915           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    2916           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    2917             :   bool aRetVal;
    2918           0 :   JS::AutoValueVector argv(cx);
    2919           0 :   if (!argv.resize(1)) {
    2920           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    2921           0 :     return false;
    2922             :   }
    2923             :   do {
    2924           0 :     nsString mutableStr(aKey);
    2925           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    2926           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    2927           0 :       return false;
    2928             :     }
    2929           0 :     break;
    2930             :   } while (0);
    2931             : 
    2932           0 :   JS::Rooted<JSObject*> backingObj(cx);
    2933           0 :   bool created = false;
    2934           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    2935           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    2936           0 :     return false;
    2937             :   }
    2938           0 :   if (created) {
    2939           0 :     PreserveWrapper<mozilla::dom::TestInterfaceJSMaplike>(self);
    2940             :   }
    2941           0 :   if (!JS::MapDelete(cx, backingObj, argv[0], &aRetVal)) {
    2942           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    2943           0 :     return false;
    2944             :   }
    2945           0 :   return aRetVal;
    2946             : }
    2947             : bool
    2948           0 : Has(mozilla::dom::TestInterfaceJSMaplike* self, const nsAString& aKey, ErrorResult& aRv)
    2949             : {
    2950           0 :   MOZ_ASSERT(self);
    2951           0 :   AutoJSAPI jsapi;
    2952           0 :   jsapi.Init();
    2953           0 :   JSContext* cx = jsapi.cx();
    2954             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    2955             :   // all we want is to wrap into _some_ scope and then unwrap to find
    2956             :   // the reflector, and wrapping has no side-effects.
    2957           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    2958           0 :   JS::Rooted<JS::Value> v(cx);
    2959           0 :   if(!ToJSValue(cx, self, &v)) {
    2960           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    2961           0 :     return false;
    2962             :   }
    2963             :   // This is a reflector, but due to trying to name things
    2964             :   // similarly across method generators, it's called obj here.
    2965           0 :   JS::Rooted<JSObject*> obj(cx);
    2966           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    2967           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    2968             :   bool aRetVal;
    2969           0 :   JS::AutoValueVector argv(cx);
    2970           0 :   if (!argv.resize(1)) {
    2971           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    2972           0 :     return false;
    2973             :   }
    2974             :   do {
    2975           0 :     nsString mutableStr(aKey);
    2976           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    2977           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    2978           0 :       return false;
    2979             :     }
    2980           0 :     break;
    2981             :   } while (0);
    2982             : 
    2983           0 :   JS::Rooted<JSObject*> backingObj(cx);
    2984           0 :   bool created = false;
    2985           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    2986           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    2987           0 :     return false;
    2988             :   }
    2989           0 :   if (created) {
    2990           0 :     PreserveWrapper<mozilla::dom::TestInterfaceJSMaplike>(self);
    2991             :   }
    2992           0 :   if (!JS::MapHas(cx, backingObj, argv[0], &aRetVal)) {
    2993           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    2994           0 :     return false;
    2995             :   }
    2996           0 :   return aRetVal;
    2997             : }
    2998             : void
    2999           0 : Set(mozilla::dom::TestInterfaceJSMaplike* self, const nsAString& aKey, int32_t aValue, ErrorResult& aRv)
    3000             : {
    3001           0 :   MOZ_ASSERT(self);
    3002           0 :   AutoJSAPI jsapi;
    3003           0 :   jsapi.Init();
    3004           0 :   JSContext* cx = jsapi.cx();
    3005             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    3006             :   // all we want is to wrap into _some_ scope and then unwrap to find
    3007             :   // the reflector, and wrapping has no side-effects.
    3008           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    3009           0 :   JS::Rooted<JS::Value> v(cx);
    3010           0 :   if(!ToJSValue(cx, self, &v)) {
    3011           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3012           0 :     return;
    3013             :   }
    3014             :   // This is a reflector, but due to trying to name things
    3015             :   // similarly across method generators, it's called obj here.
    3016           0 :   JS::Rooted<JSObject*> obj(cx);
    3017           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    3018           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    3019           0 :   JS::AutoValueVector argv(cx);
    3020           0 :   if (!argv.resize(2)) {
    3021           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    3022           0 :     return;
    3023             :   }
    3024             :   do {
    3025           0 :     argv[1].setInt32(int32_t(aValue));
    3026           0 :     break;
    3027             :   } while (0);
    3028             : 
    3029             :   do {
    3030           0 :     nsString mutableStr(aKey);
    3031           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    3032           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    3033           0 :       return;
    3034             :     }
    3035           0 :     break;
    3036             :   } while (0);
    3037             : 
    3038           0 :   JS::Rooted<JSObject*> backingObj(cx);
    3039           0 :   bool created = false;
    3040           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    3041           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3042           0 :     return;
    3043             :   }
    3044           0 :   if (created) {
    3045           0 :     PreserveWrapper<mozilla::dom::TestInterfaceJSMaplike>(self);
    3046             :   }
    3047           0 :   if (!JS::MapSet(cx, backingObj, argv[0], argv[1])) {
    3048           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    3049           0 :     return;
    3050             :   }
    3051           0 :   return;
    3052             : }
    3053             : } // namespace MaplikeHelpers
    3054             : 
    3055             : static bool
    3056           0 : setInternal(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJSMaplike* self, const JSJitMethodCallArgs& args)
    3057             : {
    3058           0 :   if (MOZ_UNLIKELY(args.length() < 2)) {
    3059           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJSMaplike.setInternal");
    3060             :   }
    3061           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3062           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3063           0 :   if (objIsXray) {
    3064           0 :     unwrappedObj.emplace(cx, obj);
    3065             :   }
    3066           0 :   binding_detail::FakeString arg0;
    3067           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    3068           0 :     return false;
    3069             :   }
    3070             :   int32_t arg1;
    3071           0 :   if (!ValueToPrimitive<int32_t, eDefault>(cx, args[1], &arg1)) {
    3072           0 :     return false;
    3073             :   }
    3074           0 :   if (objIsXray) {
    3075           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3076           0 :     if (!unwrappedObj.ref()) {
    3077           0 :       return false;
    3078             :     }
    3079             :   }
    3080           0 :   binding_detail::FastErrorResult rv;
    3081           0 :   self->SetInternal(NonNullHelper(Constify(arg0)), arg1, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    3082           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3083           0 :     return false;
    3084             :   }
    3085           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3086           0 :   args.rval().setUndefined();
    3087           0 :   return true;
    3088             : }
    3089             : 
    3090             : static const JSJitInfo setInternal_methodinfo = {
    3091             :   { (JSJitGetterOp)setInternal },
    3092             :   { prototypes::id::TestInterfaceJSMaplike },
    3093             :   { PrototypeTraits<prototypes::id::TestInterfaceJSMaplike>::Depth },
    3094             :   JSJitInfo::Method,
    3095             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3096             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    3097             :   false,  /* isInfallible. False in setters. */
    3098             :   false,  /* isMovable.  Not relevant for setters. */
    3099             :   false, /* isEliminatable.  Not relevant for setters. */
    3100             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3101             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3102             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3103             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3104             : };
    3105             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3106             : static_assert(0 < 2, "There is no slot for us");
    3107             : 
    3108             : static bool
    3109           0 : clearInternal(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJSMaplike* self, const JSJitMethodCallArgs& args)
    3110             : {
    3111           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3112           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3113           0 :   if (objIsXray) {
    3114           0 :     unwrappedObj.emplace(cx, obj);
    3115             :   }
    3116           0 :   if (objIsXray) {
    3117           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3118           0 :     if (!unwrappedObj.ref()) {
    3119           0 :       return false;
    3120             :     }
    3121             :   }
    3122           0 :   binding_detail::FastErrorResult rv;
    3123           0 :   self->ClearInternal(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    3124           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3125           0 :     return false;
    3126             :   }
    3127           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3128           0 :   args.rval().setUndefined();
    3129           0 :   return true;
    3130             : }
    3131             : 
    3132             : static const JSJitInfo clearInternal_methodinfo = {
    3133             :   { (JSJitGetterOp)clearInternal },
    3134             :   { prototypes::id::TestInterfaceJSMaplike },
    3135             :   { PrototypeTraits<prototypes::id::TestInterfaceJSMaplike>::Depth },
    3136             :   JSJitInfo::Method,
    3137             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3138             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    3139             :   false,  /* isInfallible. False in setters. */
    3140             :   false,  /* isMovable.  Not relevant for setters. */
    3141             :   false, /* isEliminatable.  Not relevant for setters. */
    3142             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3143             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3144             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3145             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3146             : };
    3147             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3148             : static_assert(0 < 2, "There is no slot for us");
    3149             : 
    3150             : static bool
    3151           0 : deleteInternal(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJSMaplike* self, const JSJitMethodCallArgs& args)
    3152             : {
    3153           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    3154           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJSMaplike.deleteInternal");
    3155             :   }
    3156           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3157           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3158           0 :   if (objIsXray) {
    3159           0 :     unwrappedObj.emplace(cx, obj);
    3160             :   }
    3161           0 :   binding_detail::FakeString arg0;
    3162           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    3163           0 :     return false;
    3164             :   }
    3165           0 :   if (objIsXray) {
    3166           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3167           0 :     if (!unwrappedObj.ref()) {
    3168           0 :       return false;
    3169             :     }
    3170             :   }
    3171           0 :   binding_detail::FastErrorResult rv;
    3172           0 :   bool result(self->DeleteInternal(NonNullHelper(Constify(arg0)), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
    3173           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3174           0 :     return false;
    3175             :   }
    3176           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3177           0 :   args.rval().setBoolean(result);
    3178           0 :   return true;
    3179             : }
    3180             : 
    3181             : static const JSJitInfo deleteInternal_methodinfo = {
    3182             :   { (JSJitGetterOp)deleteInternal },
    3183             :   { prototypes::id::TestInterfaceJSMaplike },
    3184             :   { PrototypeTraits<prototypes::id::TestInterfaceJSMaplike>::Depth },
    3185             :   JSJitInfo::Method,
    3186             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3187             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    3188             :   false,  /* isInfallible. False in setters. */
    3189             :   false,  /* isMovable.  Not relevant for setters. */
    3190             :   false, /* isEliminatable.  Not relevant for setters. */
    3191             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3192             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3193             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3194             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3195             : };
    3196             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3197             : static_assert(0 < 2, "There is no slot for us");
    3198             : 
    3199             : static bool
    3200           0 : get_size(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJSMaplike* self, JSJitGetterCallArgs args)
    3201             : {
    3202           0 :   JS::Rooted<JSObject*> backingObj(cx);
    3203           0 :   bool created = false;
    3204           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    3205           0 :     return false;
    3206             :   }
    3207           0 :   if (created) {
    3208           0 :     PreserveWrapper<mozilla::dom::TestInterfaceJSMaplike>(self);
    3209             :   }
    3210           0 :   uint32_t result = JS::MapSize(cx, backingObj);
    3211           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3212           0 :   args.rval().setNumber(result);
    3213           0 :   return true;
    3214             : }
    3215             : 
    3216             : static const JSJitInfo size_getterinfo = {
    3217             :   { (JSJitGetterOp)get_size },
    3218             :   { prototypes::id::TestInterfaceJSMaplike },
    3219             :   { PrototypeTraits<prototypes::id::TestInterfaceJSMaplike>::Depth },
    3220             :   JSJitInfo::Getter,
    3221             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3222             :   JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
    3223             :   false,  /* isInfallible. False in setters. */
    3224             :   false,  /* isMovable.  Not relevant for setters. */
    3225             :   false, /* isEliminatable.  Not relevant for setters. */
    3226             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3227             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3228             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3229             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3230             : };
    3231             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3232             : static_assert(0 < 2, "There is no slot for us");
    3233             : 
    3234             : static bool
    3235           0 : entries(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJSMaplike* self, const JSJitMethodCallArgs& args)
    3236             : {
    3237           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3238           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3239           0 :   if (objIsXray) {
    3240           0 :     unwrappedObj.emplace(cx, obj);
    3241             :   }
    3242           0 :   if (objIsXray) {
    3243           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3244           0 :     if (!unwrappedObj.ref()) {
    3245           0 :       return false;
    3246             :     }
    3247             :   }
    3248           0 :   JS::Rooted<JSObject*> backingObj(cx);
    3249           0 :   bool created = false;
    3250           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    3251           0 :     return false;
    3252             :   }
    3253           0 :   if (created) {
    3254           0 :     PreserveWrapper<mozilla::dom::TestInterfaceJSMaplike>(self);
    3255             :   }
    3256             :   // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
    3257             :   // after bug 1023984 is fixed.
    3258           0 :   if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    3259           0 :     JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    3260           0 :     return false;
    3261             :   }
    3262           0 :   JS::Rooted<JSObject*> result(cx);
    3263           0 :   JS::Rooted<JS::Value> v(cx);
    3264           0 :   if (!JS::MapEntries(cx, backingObj, &v)) {
    3265           0 :     return false;
    3266             :   }
    3267           0 :   result = &v.toObject();
    3268           0 :   JS::ExposeObjectToActiveJS(result);
    3269           0 :   args.rval().setObject(*result);
    3270           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    3271           0 :     return false;
    3272             :   }
    3273           0 :   return true;
    3274             : }
    3275             : 
    3276             : static const JSJitInfo::ArgType entries_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
    3277             : static const JSTypedMethodJitInfo entries_methodinfo = {
    3278             :   {
    3279             :     { (JSJitGetterOp)entries },
    3280             :     { prototypes::id::TestInterfaceJSMaplike },
    3281             :     { PrototypeTraits<prototypes::id::TestInterfaceJSMaplike>::Depth },
    3282             :     JSJitInfo::Method,
    3283             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3284             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    3285             :     false,  /* isInfallible. False in setters. */
    3286             :     false,  /* isMovable.  Not relevant for setters. */
    3287             :     false, /* isEliminatable.  Not relevant for setters. */
    3288             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    3289             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3290             :     true,  /* isTypedMethod.  Only relevant for methods. */
    3291             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3292             :   },
    3293             :   entries_methodinfo_argTypes
    3294             : };
    3295             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3296             : static_assert(0 < 2, "There is no slot for us");
    3297             : 
    3298             : static bool
    3299           0 : keys(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJSMaplike* self, const JSJitMethodCallArgs& args)
    3300             : {
    3301           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3302           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3303           0 :   if (objIsXray) {
    3304           0 :     unwrappedObj.emplace(cx, obj);
    3305             :   }
    3306           0 :   if (objIsXray) {
    3307           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3308           0 :     if (!unwrappedObj.ref()) {
    3309           0 :       return false;
    3310             :     }
    3311             :   }
    3312           0 :   JS::Rooted<JSObject*> backingObj(cx);
    3313           0 :   bool created = false;
    3314           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    3315           0 :     return false;
    3316             :   }
    3317           0 :   if (created) {
    3318           0 :     PreserveWrapper<mozilla::dom::TestInterfaceJSMaplike>(self);
    3319             :   }
    3320             :   // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
    3321             :   // after bug 1023984 is fixed.
    3322           0 :   if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    3323           0 :     JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    3324           0 :     return false;
    3325             :   }
    3326           0 :   JS::Rooted<JSObject*> result(cx);
    3327           0 :   JS::Rooted<JS::Value> v(cx);
    3328           0 :   if (!JS::MapKeys(cx, backingObj, &v)) {
    3329           0 :     return false;
    3330             :   }
    3331           0 :   result = &v.toObject();
    3332           0 :   JS::ExposeObjectToActiveJS(result);
    3333           0 :   args.rval().setObject(*result);
    3334           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    3335           0 :     return false;
    3336             :   }
    3337           0 :   return true;
    3338             : }
    3339             : 
    3340             : static const JSJitInfo::ArgType keys_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
    3341             : static const JSTypedMethodJitInfo keys_methodinfo = {
    3342             :   {
    3343             :     { (JSJitGetterOp)keys },
    3344             :     { prototypes::id::TestInterfaceJSMaplike },
    3345             :     { PrototypeTraits<prototypes::id::TestInterfaceJSMaplike>::Depth },
    3346             :     JSJitInfo::Method,
    3347             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3348             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    3349             :     false,  /* isInfallible. False in setters. */
    3350             :     false,  /* isMovable.  Not relevant for setters. */
    3351             :     false, /* isEliminatable.  Not relevant for setters. */
    3352             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    3353             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3354             :     true,  /* isTypedMethod.  Only relevant for methods. */
    3355             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3356             :   },
    3357             :   keys_methodinfo_argTypes
    3358             : };
    3359             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3360             : static_assert(0 < 2, "There is no slot for us");
    3361             : 
    3362             : static bool
    3363           0 : values(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJSMaplike* self, const JSJitMethodCallArgs& args)
    3364             : {
    3365           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3366           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3367           0 :   if (objIsXray) {
    3368           0 :     unwrappedObj.emplace(cx, obj);
    3369             :   }
    3370           0 :   if (objIsXray) {
    3371           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3372           0 :     if (!unwrappedObj.ref()) {
    3373           0 :       return false;
    3374             :     }
    3375             :   }
    3376           0 :   JS::Rooted<JSObject*> backingObj(cx);
    3377           0 :   bool created = false;
    3378           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    3379           0 :     return false;
    3380             :   }
    3381           0 :   if (created) {
    3382           0 :     PreserveWrapper<mozilla::dom::TestInterfaceJSMaplike>(self);
    3383             :   }
    3384             :   // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
    3385             :   // after bug 1023984 is fixed.
    3386           0 :   if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    3387           0 :     JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    3388           0 :     return false;
    3389             :   }
    3390           0 :   JS::Rooted<JSObject*> result(cx);
    3391           0 :   JS::Rooted<JS::Value> v(cx);
    3392           0 :   if (!JS::MapValues(cx, backingObj, &v)) {
    3393           0 :     return false;
    3394             :   }
    3395           0 :   result = &v.toObject();
    3396           0 :   JS::ExposeObjectToActiveJS(result);
    3397           0 :   args.rval().setObject(*result);
    3398           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    3399           0 :     return false;
    3400             :   }
    3401           0 :   return true;
    3402             : }
    3403             : 
    3404             : static const JSJitInfo::ArgType values_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
    3405             : static const JSTypedMethodJitInfo values_methodinfo = {
    3406             :   {
    3407             :     { (JSJitGetterOp)values },
    3408             :     { prototypes::id::TestInterfaceJSMaplike },
    3409             :     { PrototypeTraits<prototypes::id::TestInterfaceJSMaplike>::Depth },
    3410             :     JSJitInfo::Method,
    3411             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3412             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    3413             :     false,  /* isInfallible. False in setters. */
    3414             :     false,  /* isMovable.  Not relevant for setters. */
    3415             :     false, /* isEliminatable.  Not relevant for setters. */
    3416             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    3417             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3418             :     true,  /* isTypedMethod.  Only relevant for methods. */
    3419             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3420             :   },
    3421             :   values_methodinfo_argTypes
    3422             : };
    3423             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3424             : static_assert(0 < 2, "There is no slot for us");
    3425             : 
    3426             : static bool
    3427           0 : forEach(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJSMaplike* self, const JSJitMethodCallArgs& args)
    3428             : {
    3429           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3430           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3431           0 :   if (objIsXray) {
    3432           0 :     unwrappedObj.emplace(cx, obj);
    3433             :   }
    3434           0 :   JS::Rooted<JSObject*> arg0(cx);
    3435           0 :   if (args.get(0).isObject()) {
    3436             : #ifdef __clang__
    3437             : #pragma clang diagnostic push
    3438             : #pragma clang diagnostic ignored "-Wunreachable-code"
    3439             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    3440             : #endif // __clang__
    3441           0 :     if ((true) && !CallerSubsumes(args.get(0))) {
    3442           0 :       ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "argument 1 of TestInterfaceJSMaplike.forEach");
    3443           0 :       return false;
    3444             :     }
    3445             : #ifdef __clang__
    3446             : #pragma clang diagnostic pop
    3447             : #endif // __clang__
    3448           0 :     arg0 = &args.get(0).toObject();
    3449             :   } else {
    3450           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of TestInterfaceJSMaplike.forEach");
    3451           0 :     return false;
    3452             :   }
    3453           0 :   JS::Rooted<JS::Value> arg1(cx);
    3454           0 :   if (args.hasDefined(1)) {
    3455             : #ifdef __clang__
    3456             : #pragma clang diagnostic push
    3457             : #pragma clang diagnostic ignored "-Wunreachable-code"
    3458             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    3459             : #endif // __clang__
    3460           0 :     if ((true) && !CallerSubsumes(args.get(1))) {
    3461           0 :       ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "argument 2 of TestInterfaceJSMaplike.forEach");
    3462           0 :       return false;
    3463             :     }
    3464             : #ifdef __clang__
    3465             : #pragma clang diagnostic pop
    3466             : #endif // __clang__
    3467           0 :     arg1 = args.get(1);
    3468             :   } else {
    3469           0 :     arg1 = JS::UndefinedValue();
    3470             :   }
    3471           0 :   if (objIsXray) {
    3472           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3473           0 :     if (!unwrappedObj.ref()) {
    3474           0 :       return false;
    3475             :     }
    3476             :   }
    3477           0 :   JS::Rooted<JSObject*> backingObj(cx);
    3478           0 :   bool created = false;
    3479           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    3480           0 :     return false;
    3481             :   }
    3482           0 :   if (created) {
    3483           0 :     PreserveWrapper<mozilla::dom::TestInterfaceJSMaplike>(self);
    3484             :   }
    3485             :   // Create a wrapper function.
    3486           0 :   JSFunction* func = js::NewFunctionWithReserved(cx, ForEachHandler, 3, 0, nullptr);
    3487           0 :   if (!func) {
    3488           0 :     return false;
    3489             :   }
    3490           0 :   JS::Rooted<JSObject*> funcObj(cx, JS_GetFunctionObject(func));
    3491           0 :   JS::Rooted<JS::Value> funcVal(cx, JS::ObjectValue(*funcObj));
    3492           0 :   js::SetFunctionNativeReserved(funcObj, FOREACH_CALLBACK_SLOT,
    3493           0 :                                 JS::ObjectValue(*arg0));
    3494           0 :   js::SetFunctionNativeReserved(funcObj, FOREACH_MAPLIKEORSETLIKEOBJ_SLOT,
    3495           0 :                                 JS::ObjectValue(*obj));
    3496           0 :   if (!JS::MapForEach(cx, backingObj, funcVal, arg1)) {
    3497           0 :     return false;
    3498             :   }
    3499           0 :   args.rval().setUndefined();
    3500           0 :   return true;
    3501             : }
    3502             : 
    3503             : static const JSJitInfo forEach_methodinfo = {
    3504             :   { (JSJitGetterOp)forEach },
    3505             :   { prototypes::id::TestInterfaceJSMaplike },
    3506             :   { PrototypeTraits<prototypes::id::TestInterfaceJSMaplike>::Depth },
    3507             :   JSJitInfo::Method,
    3508             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3509             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    3510             :   false,  /* isInfallible. False in setters. */
    3511             :   false,  /* isMovable.  Not relevant for setters. */
    3512             :   false, /* isEliminatable.  Not relevant for setters. */
    3513             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3514             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3515             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3516             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3517             : };
    3518             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3519             : static_assert(0 < 2, "There is no slot for us");
    3520             : 
    3521             : static bool
    3522           0 : has(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJSMaplike* self, const JSJitMethodCallArgs& args)
    3523             : {
    3524           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3525           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3526           0 :   if (objIsXray) {
    3527           0 :     unwrappedObj.emplace(cx, obj);
    3528             :   }
    3529           0 :   binding_detail::FakeString arg0;
    3530           0 :   if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
    3531           0 :     return false;
    3532             :   }
    3533           0 :   if (objIsXray) {
    3534           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3535           0 :     if (!unwrappedObj.ref()) {
    3536           0 :       return false;
    3537             :     }
    3538             :   }
    3539           0 :   JS::Rooted<JSObject*> backingObj(cx);
    3540           0 :   bool created = false;
    3541           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    3542           0 :     return false;
    3543             :   }
    3544           0 :   if (created) {
    3545           0 :     PreserveWrapper<mozilla::dom::TestInterfaceJSMaplike>(self);
    3546             :   }
    3547           0 :   JS::Rooted<JS::Value> arg0Val(cx);
    3548           0 :   if (!ToJSValue(cx, arg0, &arg0Val)) {
    3549           0 :     return false;
    3550             :   }
    3551             :   bool result;
    3552           0 :   if (!JS::MapHas(cx, backingObj, arg0Val, &result)) {
    3553           0 :     return false;
    3554             :   }
    3555           0 :   args.rval().setBoolean(result);
    3556           0 :   return true;
    3557             : }
    3558             : 
    3559             : static const JSJitInfo::ArgType has_methodinfo_argTypes[] = { JSJitInfo::String, JSJitInfo::ArgTypeListEnd };
    3560             : static const JSTypedMethodJitInfo has_methodinfo = {
    3561             :   {
    3562             :     { (JSJitGetterOp)has },
    3563             :     { prototypes::id::TestInterfaceJSMaplike },
    3564             :     { PrototypeTraits<prototypes::id::TestInterfaceJSMaplike>::Depth },
    3565             :     JSJitInfo::Method,
    3566             :     JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    3567             :     JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    3568             :     false,  /* isInfallible. False in setters. */
    3569             :     false,  /* isMovable.  Not relevant for setters. */
    3570             :     false, /* isEliminatable.  Not relevant for setters. */
    3571             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    3572             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3573             :     true,  /* isTypedMethod.  Only relevant for methods. */
    3574             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3575             :   },
    3576             :   has_methodinfo_argTypes
    3577             : };
    3578             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3579             : static_assert(0 < 2, "There is no slot for us");
    3580             : 
    3581             : static bool
    3582           0 : __clear(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJSMaplike* self, const JSJitMethodCallArgs& args)
    3583             : {
    3584           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3585           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3586           0 :   if (objIsXray) {
    3587           0 :     unwrappedObj.emplace(cx, obj);
    3588             :   }
    3589           0 :   if (objIsXray) {
    3590           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3591           0 :     if (!unwrappedObj.ref()) {
    3592           0 :       return false;
    3593             :     }
    3594             :   }
    3595           0 :   JS::Rooted<JSObject*> backingObj(cx);
    3596           0 :   bool created = false;
    3597           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    3598           0 :     return false;
    3599             :   }
    3600           0 :   if (created) {
    3601           0 :     PreserveWrapper<mozilla::dom::TestInterfaceJSMaplike>(self);
    3602             :   }
    3603           0 :   if (!JS::MapClear(cx, backingObj)) {
    3604           0 :     return false;
    3605             :   }
    3606           0 :   args.rval().setUndefined();
    3607           0 :   return true;
    3608             : }
    3609             : 
    3610             : static const JSJitInfo __clear_methodinfo = {
    3611             :   { (JSJitGetterOp)__clear },
    3612             :   { prototypes::id::TestInterfaceJSMaplike },
    3613             :   { PrototypeTraits<prototypes::id::TestInterfaceJSMaplike>::Depth },
    3614             :   JSJitInfo::Method,
    3615             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3616             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    3617             :   false,  /* isInfallible. False in setters. */
    3618             :   false,  /* isMovable.  Not relevant for setters. */
    3619             :   false, /* isEliminatable.  Not relevant for setters. */
    3620             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3621             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3622             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3623             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3624             : };
    3625             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3626             : static_assert(0 < 2, "There is no slot for us");
    3627             : 
    3628             : static bool
    3629           0 : __delete(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJSMaplike* self, const JSJitMethodCallArgs& args)
    3630             : {
    3631           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3632           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3633           0 :   if (objIsXray) {
    3634           0 :     unwrappedObj.emplace(cx, obj);
    3635             :   }
    3636           0 :   binding_detail::FakeString arg0;
    3637           0 :   if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
    3638           0 :     return false;
    3639             :   }
    3640           0 :   if (objIsXray) {
    3641           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3642           0 :     if (!unwrappedObj.ref()) {
    3643           0 :       return false;
    3644             :     }
    3645             :   }
    3646           0 :   JS::Rooted<JSObject*> backingObj(cx);
    3647           0 :   bool created = false;
    3648           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    3649           0 :     return false;
    3650             :   }
    3651           0 :   if (created) {
    3652           0 :     PreserveWrapper<mozilla::dom::TestInterfaceJSMaplike>(self);
    3653             :   }
    3654           0 :   JS::Rooted<JS::Value> arg0Val(cx);
    3655           0 :   if (!ToJSValue(cx, arg0, &arg0Val)) {
    3656           0 :     return false;
    3657             :   }
    3658             :   bool result;
    3659           0 :   if (!JS::MapDelete(cx, backingObj, arg0Val, &result)) {
    3660           0 :     return false;
    3661             :   }
    3662           0 :   args.rval().setBoolean(result);
    3663           0 :   return true;
    3664             : }
    3665             : 
    3666             : static const JSJitInfo __delete_methodinfo = {
    3667             :   { (JSJitGetterOp)__delete },
    3668             :   { prototypes::id::TestInterfaceJSMaplike },
    3669             :   { PrototypeTraits<prototypes::id::TestInterfaceJSMaplike>::Depth },
    3670             :   JSJitInfo::Method,
    3671             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3672             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    3673             :   false,  /* isInfallible. False in setters. */
    3674             :   false,  /* isMovable.  Not relevant for setters. */
    3675             :   false, /* isEliminatable.  Not relevant for setters. */
    3676             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3677             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3678             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3679             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3680             : };
    3681             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3682             : static_assert(0 < 2, "There is no slot for us");
    3683             : 
    3684             : static bool
    3685           0 : get(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJSMaplike* self, const JSJitMethodCallArgs& args)
    3686             : {
    3687           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3688           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3689           0 :   if (objIsXray) {
    3690           0 :     unwrappedObj.emplace(cx, obj);
    3691             :   }
    3692           0 :   binding_detail::FakeString arg0;
    3693           0 :   if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
    3694           0 :     return false;
    3695             :   }
    3696           0 :   if (objIsXray) {
    3697           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3698           0 :     if (!unwrappedObj.ref()) {
    3699           0 :       return false;
    3700             :     }
    3701             :   }
    3702           0 :   JS::Rooted<JSObject*> backingObj(cx);
    3703           0 :   bool created = false;
    3704           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    3705           0 :     return false;
    3706             :   }
    3707           0 :   if (created) {
    3708           0 :     PreserveWrapper<mozilla::dom::TestInterfaceJSMaplike>(self);
    3709             :   }
    3710           0 :   JS::Rooted<JS::Value> arg0Val(cx);
    3711           0 :   if (!ToJSValue(cx, arg0, &arg0Val)) {
    3712           0 :     return false;
    3713             :   }
    3714           0 :   JS::Rooted<JS::Value> result(cx);
    3715           0 :   if (!JS::MapGet(cx, backingObj, arg0Val, &result)) {
    3716           0 :     return false;
    3717             :   }
    3718           0 :   JS::ExposeValueToActiveJS(result);
    3719           0 :   args.rval().set(result);
    3720           0 :   if (!MaybeWrapValue(cx, args.rval())) {
    3721           0 :     return false;
    3722             :   }
    3723           0 :   return true;
    3724             : }
    3725             : 
    3726             : static const JSJitInfo::ArgType get_methodinfo_argTypes[] = { JSJitInfo::String, JSJitInfo::ArgTypeListEnd };
    3727             : static const JSTypedMethodJitInfo get_methodinfo = {
    3728             :   {
    3729             :     { (JSJitGetterOp)get },
    3730             :     { prototypes::id::TestInterfaceJSMaplike },
    3731             :     { PrototypeTraits<prototypes::id::TestInterfaceJSMaplike>::Depth },
    3732             :     JSJitInfo::Method,
    3733             :     JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    3734             :     JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    3735             :     false,  /* isInfallible. False in setters. */
    3736             :     false,  /* isMovable.  Not relevant for setters. */
    3737             :     false, /* isEliminatable.  Not relevant for setters. */
    3738             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    3739             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3740             :     true,  /* isTypedMethod.  Only relevant for methods. */
    3741             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3742             :   },
    3743             :   get_methodinfo_argTypes
    3744             : };
    3745             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3746             : static_assert(0 < 2, "There is no slot for us");
    3747             : 
    3748             : static bool
    3749           0 : __set(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJSMaplike* self, const JSJitMethodCallArgs& args)
    3750             : {
    3751           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3752           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3753           0 :   if (objIsXray) {
    3754           0 :     unwrappedObj.emplace(cx, obj);
    3755             :   }
    3756           0 :   binding_detail::FakeString arg0;
    3757           0 :   if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
    3758           0 :     return false;
    3759             :   }
    3760             :   int32_t arg1;
    3761           0 :   if (!ValueToPrimitive<int32_t, eDefault>(cx, args.get(1), &arg1)) {
    3762           0 :     return false;
    3763             :   }
    3764           0 :   if (objIsXray) {
    3765           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3766           0 :     if (!unwrappedObj.ref()) {
    3767           0 :       return false;
    3768             :     }
    3769             :   }
    3770           0 :   JS::Rooted<JSObject*> backingObj(cx);
    3771           0 :   bool created = false;
    3772           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    3773           0 :     return false;
    3774             :   }
    3775           0 :   if (created) {
    3776           0 :     PreserveWrapper<mozilla::dom::TestInterfaceJSMaplike>(self);
    3777             :   }
    3778           0 :   JS::Rooted<JS::Value> arg0Val(cx);
    3779           0 :   if (!ToJSValue(cx, arg0, &arg0Val)) {
    3780           0 :     return false;
    3781             :   }
    3782           0 :   JS::Rooted<JS::Value> arg1Val(cx);
    3783           0 :   if (!ToJSValue(cx, arg1, &arg1Val)) {
    3784           0 :     return false;
    3785             :   }
    3786           0 :   JS::Rooted<JSObject*> result(cx);
    3787           0 :   if (!JS::MapSet(cx, backingObj, arg0Val, arg1Val)) {
    3788           0 :     return false;
    3789             :   }
    3790           0 :   result = obj;
    3791           0 :   JS::ExposeObjectToActiveJS(result);
    3792           0 :   args.rval().setObject(*result);
    3793           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    3794           0 :     return false;
    3795             :   }
    3796           0 :   return true;
    3797             : }
    3798             : 
    3799             : static const JSJitInfo __set_methodinfo = {
    3800             :   { (JSJitGetterOp)__set },
    3801             :   { prototypes::id::TestInterfaceJSMaplike },
    3802             :   { PrototypeTraits<prototypes::id::TestInterfaceJSMaplike>::Depth },
    3803             :   JSJitInfo::Method,
    3804             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3805             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    3806             :   false,  /* isInfallible. False in setters. */
    3807             :   false,  /* isMovable.  Not relevant for setters. */
    3808             :   false, /* isEliminatable.  Not relevant for setters. */
    3809             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3810             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3811             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3812             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3813             : };
    3814             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3815             : static_assert(0 < 2, "There is no slot for us");
    3816             : 
    3817             : static bool
    3818           0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
    3819             : {
    3820           0 :   mozilla::dom::TestInterfaceJSMaplike* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceJSMaplike>(obj);
    3821             :   // We don't want to preserve if we don't have a wrapper, and we
    3822             :   // obviously can't preserve if we're not initialized.
    3823           0 :   if (self && self->GetWrapperPreserveColor()) {
    3824           0 :     PreserveWrapper(self);
    3825             :   }
    3826           0 :   return true;
    3827             : }
    3828             : 
    3829             : static void
    3830           0 : _finalize(js::FreeOp* fop, JSObject* obj)
    3831             : {
    3832           0 :   mozilla::dom::TestInterfaceJSMaplike* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceJSMaplike>(obj);
    3833           0 :   if (self) {
    3834           0 :     ClearWrapper(self, self, obj);
    3835           0 :     AddForDeferredFinalization<mozilla::dom::TestInterfaceJSMaplike>(self);
    3836             :   }
    3837           0 : }
    3838             : 
    3839             : static void
    3840           0 : _objectMoved(JSObject* obj, const JSObject* old)
    3841             : {
    3842           0 :   mozilla::dom::TestInterfaceJSMaplike* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceJSMaplike>(obj);
    3843           0 :   if (self) {
    3844           0 :     UpdateWrapper(self, self, obj, old);
    3845             :   }
    3846           0 : }
    3847             : 
    3848             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    3849             : #if defined(__clang__)
    3850             : #pragma clang diagnostic push
    3851             : #pragma clang diagnostic ignored "-Wmissing-braces"
    3852             : #endif
    3853             : static const JSFunctionSpec sChromeStaticMethods_specs[] = {
    3854             :   JS_FNSPEC("_create", TestInterfaceJSMaplike::_Create, nullptr, 2, 0, nullptr),
    3855             :   JS_FS_END
    3856             : };
    3857             : #if defined(__clang__)
    3858             : #pragma clang diagnostic pop
    3859             : #endif
    3860             : 
    3861             : 
    3862             : // Can't be const because the pref-enabled boolean needs to be writable
    3863             : static Prefable<const JSFunctionSpec> sChromeStaticMethods[] = {
    3864             :   { nullptr, &sChromeStaticMethods_specs[0] },
    3865             :   { nullptr, nullptr }
    3866             : };
    3867             : 
    3868             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    3869             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    3870             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    3871             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    3872             : 
    3873             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    3874             : #if defined(__clang__)
    3875             : #pragma clang diagnostic push
    3876             : #pragma clang diagnostic ignored "-Wmissing-braces"
    3877             : #endif
    3878             : static const JSFunctionSpec sMethods_specs[] = {
    3879             :   JS_FNSPEC("setInternal", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&setInternal_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
    3880             :   JS_FNSPEC("clearInternal", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&clearInternal_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    3881             :   JS_FNSPEC("deleteInternal", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&deleteInternal_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    3882             :   JS_FNSPEC("entries", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&entries_methodinfo), 0, 0, nullptr),
    3883             :   JS_FNSPEC("keys", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&keys_methodinfo), 0, 0, nullptr),
    3884             :   JS_FNSPEC("values", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&values_methodinfo), 0, 0, nullptr),
    3885             :   JS_FNSPEC("forEach", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&forEach_methodinfo), 1, 0, nullptr),
    3886             :   JS_FNSPEC("has", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&has_methodinfo), 1, 0, nullptr),
    3887             :   JS_FNSPEC("get", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&get_methodinfo), 1, 0, nullptr),
    3888             :   JS_FS_END
    3889             : };
    3890             : #if defined(__clang__)
    3891             : #pragma clang diagnostic pop
    3892             : #endif
    3893             : 
    3894             : 
    3895             : // Can't be const because the pref-enabled boolean needs to be writable
    3896             : static Prefable<const JSFunctionSpec> sMethods[] = {
    3897             :   { nullptr, &sMethods_specs[0] },
    3898             :   { nullptr, nullptr }
    3899             : };
    3900             : 
    3901             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    3902             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    3903             : static_assert(9 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    3904             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    3905             : 
    3906             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    3907             : #if defined(__clang__)
    3908             : #pragma clang diagnostic push
    3909             : #pragma clang diagnostic ignored "-Wmissing-braces"
    3910             : #endif
    3911             : static const JSFunctionSpec sChromeMethods_specs[] = {
    3912             :   JS_FNSPEC("__clear", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&__clear_methodinfo), 0, 0, nullptr),
    3913             :   JS_FNSPEC("__delete", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&__delete_methodinfo), 1, 0, nullptr),
    3914             :   JS_FNSPEC("__set", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&__set_methodinfo), 2, 0, nullptr),
    3915             :   JS_FS_END
    3916             : };
    3917             : #if defined(__clang__)
    3918             : #pragma clang diagnostic pop
    3919             : #endif
    3920             : 
    3921             : 
    3922             : // Can't be const because the pref-enabled boolean needs to be writable
    3923             : static Prefable<const JSFunctionSpec> sChromeMethods[] = {
    3924             :   { nullptr, &sChromeMethods_specs[0] },
    3925             :   { nullptr, nullptr }
    3926             : };
    3927             : 
    3928             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    3929             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    3930             : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    3931             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    3932             : 
    3933             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    3934             : #if defined(__clang__)
    3935             : #pragma clang diagnostic push
    3936             : #pragma clang diagnostic ignored "-Wmissing-braces"
    3937             : #endif
    3938             : static const JSPropertySpec sAttributes_specs[] = {
    3939             :   { "size", JSPROP_SHARED, GenericBindingGetter, &size_getterinfo, nullptr, nullptr },
    3940             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
    3941             : };
    3942             : #if defined(__clang__)
    3943             : #pragma clang diagnostic pop
    3944             : #endif
    3945             : 
    3946             : 
    3947             : // Can't be const because the pref-enabled boolean needs to be writable
    3948             : static Prefable<const JSPropertySpec> sAttributes[] = {
    3949             :   { nullptr, &sAttributes_specs[0] },
    3950             :   { nullptr, nullptr }
    3951             : };
    3952             : 
    3953             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    3954             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    3955             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    3956             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    3957             : 
    3958             : 
    3959             : static uint16_t sNativeProperties_sortedPropertyIndices[10];
    3960             : static PropertyInfo sNativeProperties_propertyInfos[10];
    3961             : 
    3962             : static const NativePropertiesN<2> sNativeProperties = {
    3963             :   false, 0,
    3964             :   false, 0,
    3965             :   true,  0 /* sMethods */,
    3966             :   true,  1 /* sAttributes */,
    3967             :   false, 0,
    3968             :   false, 0,
    3969             :   false, 0,
    3970             :   3,
    3971             :   10,
    3972             :   sNativeProperties_sortedPropertyIndices,
    3973             :   {
    3974             :     { sMethods, &sNativeProperties_propertyInfos[0] },
    3975             :     { sAttributes, &sNativeProperties_propertyInfos[9] }
    3976             :   }
    3977             : };
    3978             : static_assert(3 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.iteratorAliasMethodIndex) - 1),
    3979             :     "We have an iterator alias index that is oversized");
    3980             : static_assert(10 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
    3981             :     "We have a property info count that is oversized");
    3982             : 
    3983             : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[4];
    3984             : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[4];
    3985             : 
    3986             : static const NativePropertiesN<2> sChromeOnlyNativeProperties = {
    3987             :   true,  0 /* sChromeStaticMethods */,
    3988             :   false, 0,
    3989             :   true,  1 /* sChromeMethods */,
    3990             :   false, 0,
    3991             :   false, 0,
    3992             :   false, 0,
    3993             :   false, 0,
    3994             :   3,
    3995             :   4,
    3996             :   sChromeOnlyNativeProperties_sortedPropertyIndices,
    3997             :   {
    3998             :     { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] },
    3999             :     { sChromeMethods, &sChromeOnlyNativeProperties_propertyInfos[1] }
    4000             :   }
    4001             : };
    4002             : static_assert(3 < 1ull << (CHAR_BIT * sizeof(sChromeOnlyNativeProperties.iteratorAliasMethodIndex) - 1),
    4003             :     "We have an iterator alias index that is oversized");
    4004             : static_assert(4 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
    4005             :     "We have a property info count that is oversized");
    4006             : 
    4007             : static bool
    4008           0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
    4009             : {
    4010           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    4011           0 :   JS::Rooted<JSObject*> obj(cx, &args.callee());
    4012           0 :   if (!args.isConstructing()) {
    4013             :     // XXXbz wish I could get the name from the callee instead of
    4014             :     // Adding more relocations
    4015           0 :     return ThrowConstructorWithoutNew(cx, "TestInterfaceJSMaplike");
    4016             :   }
    4017             : 
    4018           0 :   GlobalObject global(cx, obj);
    4019           0 :   if (global.Failed()) {
    4020           0 :     return false;
    4021             :   }
    4022             : 
    4023           0 :   JS::Rooted<JSObject*> desiredProto(cx);
    4024           0 :   if (!GetDesiredProto(cx, args, &desiredProto)) {
    4025           0 :     return false;
    4026             :   }
    4027             : 
    4028           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    4029           0 :   Maybe<JSAutoCompartment> ac;
    4030           0 :   if (objIsXray) {
    4031           0 :     obj = js::CheckedUnwrap(obj);
    4032           0 :     if (!obj) {
    4033           0 :       return false;
    4034             :     }
    4035           0 :     ac.emplace(cx, obj);
    4036           0 :     if (!JS_WrapObject(cx, &desiredProto)) {
    4037           0 :       return false;
    4038             :     }
    4039             :   }
    4040           0 :   binding_detail::FastErrorResult rv;
    4041           0 :   auto result(StrongOrRawPtr<mozilla::dom::TestInterfaceJSMaplike>(mozilla::dom::TestInterfaceJSMaplike::Constructor(global, cx, rv)));
    4042           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    4043           0 :     return false;
    4044             :   }
    4045           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    4046             :   static_assert(!IsPointer<decltype(result)>::value,
    4047             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
    4048           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
    4049           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    4050           0 :     return false;
    4051             :   }
    4052           0 :   return true;
    4053             : }
    4054             : 
    4055             : static const js::ClassOps sInterfaceObjectClassOps = {
    4056             :     nullptr,               /* addProperty */
    4057             :     nullptr,               /* delProperty */
    4058             :     nullptr,               /* getProperty */
    4059             :     nullptr,               /* setProperty */
    4060             :     nullptr,               /* enumerate */
    4061             :     nullptr,               /* newEnumerate */
    4062             :     nullptr,               /* resolve */
    4063             :     nullptr,               /* mayResolve */
    4064             :     nullptr,               /* finalize */
    4065             :     _constructor, /* call */
    4066             :     nullptr,               /* hasInstance */
    4067             :     _constructor, /* construct */
    4068             :     nullptr,               /* trace */
    4069             : };
    4070             : 
    4071             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
    4072             :   {
    4073             :     "Function",
    4074             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
    4075             :     &sInterfaceObjectClassOps,
    4076             :     JS_NULL_CLASS_SPEC,
    4077             :     JS_NULL_CLASS_EXT,
    4078             :     &sInterfaceObjectClassObjectOps
    4079             :   },
    4080             :   eInterface,
    4081             :   true,
    4082             :   prototypes::id::TestInterfaceJSMaplike,
    4083             :   PrototypeTraits<prototypes::id::TestInterfaceJSMaplike>::Depth,
    4084             :   sNativePropertyHooks,
    4085             :   "function TestInterfaceJSMaplike() {\n    [native code]\n}",
    4086             :   JS::GetRealmFunctionPrototype
    4087             : };
    4088             : 
    4089             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
    4090             :   {
    4091             :     "TestInterfaceJSMaplikePrototype",
    4092             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    4093             :     JS_NULL_CLASS_OPS,
    4094             :     JS_NULL_CLASS_SPEC,
    4095             :     JS_NULL_CLASS_EXT,
    4096             :     JS_NULL_OBJECT_OPS
    4097             :   },
    4098             :   eInterfacePrototype,
    4099             :   false,
    4100             :   prototypes::id::TestInterfaceJSMaplike,
    4101             :   PrototypeTraits<prototypes::id::TestInterfaceJSMaplike>::Depth,
    4102             :   sNativePropertyHooks,
    4103             :   "[object TestInterfaceJSMaplikePrototype]",
    4104             :   JS::GetRealmObjectPrototype
    4105             : };
    4106             : 
    4107             : bool
    4108           0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
    4109             : {
    4110             :   static bool sPrefValue;
    4111             :   static bool sPrefCacheSetUp = false;
    4112           0 :   if (!sPrefCacheSetUp) {
    4113           0 :     sPrefCacheSetUp = true;
    4114           0 :     Preferences::AddBoolVarCache(&sPrefValue, "dom.expose_test_interfaces");
    4115             :   }
    4116             : 
    4117           0 :   return sPrefValue;
    4118             : }
    4119             : 
    4120             : JSObject*
    4121           0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
    4122             : {
    4123           0 :   return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
    4124             : }
    4125             : 
    4126             : static const js::ClassOps sClassOps = {
    4127             :   _addProperty, /* addProperty */
    4128             :   nullptr,               /* delProperty */
    4129             :   nullptr,               /* getProperty */
    4130             :   nullptr,               /* setProperty */
    4131             :   nullptr,               /* enumerate */
    4132             :   nullptr, /* newEnumerate */
    4133             :   nullptr, /* resolve */
    4134             :   nullptr, /* mayResolve */
    4135             :   _finalize, /* finalize */
    4136             :   nullptr, /* call */
    4137             :   nullptr,               /* hasInstance */
    4138             :   nullptr,               /* construct */
    4139             :   nullptr, /* trace */
    4140             : };
    4141             : 
    4142             : static const js::ClassExtension sClassExtension = {
    4143             :   nullptr, /* weakmapKeyDelegateOp */
    4144             :   _objectMoved /* objectMovedOp */
    4145             : };
    4146             : 
    4147             : static const DOMJSClass sClass = {
    4148             :   { "TestInterfaceJSMaplike",
    4149             :     JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2),
    4150             :     &sClassOps,
    4151             :     JS_NULL_CLASS_SPEC,
    4152             :     &sClassExtension,
    4153             :     JS_NULL_OBJECT_OPS
    4154             :   },
    4155             :   { prototypes::id::TestInterfaceJSMaplike, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
    4156             :   IsBaseOf<nsISupports, mozilla::dom::TestInterfaceJSMaplike >::value,
    4157             :   sNativePropertyHooks,
    4158             :   FindAssociatedGlobalForNative<mozilla::dom::TestInterfaceJSMaplike>::Get,
    4159             :   GetProtoObjectHandle,
    4160             :   GetCCParticipant<mozilla::dom::TestInterfaceJSMaplike>::Get()
    4161             : };
    4162             : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
    4163             :               "Must have the right minimal number of reserved slots.");
    4164             : static_assert(2 >= 2,
    4165             :               "Must have enough reserved slots.");
    4166             : 
    4167             : const JSClass*
    4168           0 : GetJSClass()
    4169             : {
    4170           0 :   return sClass.ToJSClass();
    4171             : }
    4172             : 
    4173             : bool
    4174           0 : Wrap(JSContext* aCx, mozilla::dom::TestInterfaceJSMaplike* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
    4175             : {
    4176             :   MOZ_ASSERT(static_cast<mozilla::dom::TestInterfaceJSMaplike*>(aObject) ==
    4177             :              reinterpret_cast<mozilla::dom::TestInterfaceJSMaplike*>(aObject),
    4178             :              "Multiple inheritance for mozilla::dom::TestInterfaceJSMaplike is broken.");
    4179           0 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
    4180           0 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
    4181           0 :   MOZ_ASSERT(!aCache->GetWrapper(),
    4182             :              "You should probably not be using Wrap() directly; use "
    4183             :              "GetOrCreateDOMReflector instead");
    4184             : 
    4185           0 :   MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
    4186             :              "nsISupports must be on our primary inheritance chain");
    4187             : 
    4188           0 :   JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
    4189           0 :   if (!global) {
    4190           0 :     return false;
    4191             :   }
    4192           0 :   MOZ_ASSERT(JS_IsGlobalObject(global));
    4193           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(global));
    4194             : 
    4195             :   // That might have ended up wrapping us already, due to the wonders
    4196             :   // of XBL.  Check for that, and bail out as needed.
    4197           0 :   aReflector.set(aCache->GetWrapper());
    4198           0 :   if (aReflector) {
    4199             : #ifdef DEBUG
    4200           0 :     binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
    4201             : #endif // DEBUG
    4202           0 :     return true;
    4203             :   }
    4204             : 
    4205           0 :   JSAutoCompartment ac(aCx, global);
    4206           0 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
    4207           0 :   if (!canonicalProto) {
    4208           0 :     return false;
    4209             :   }
    4210           0 :   JS::Rooted<JSObject*> proto(aCx);
    4211           0 :   if (aGivenProto) {
    4212           0 :     proto = aGivenProto;
    4213             :     // Unfortunately, while aGivenProto was in the compartment of aCx
    4214             :     // coming in, we changed compartments to that of "parent" so may need
    4215             :     // to wrap the proto here.
    4216           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
    4217           0 :       if (!JS_WrapObject(aCx, &proto)) {
    4218           0 :         return false;
    4219             :       }
    4220             :     }
    4221             :   } else {
    4222           0 :     proto = canonicalProto;
    4223             :   }
    4224             : 
    4225           0 :   BindingJSObjectCreator<mozilla::dom::TestInterfaceJSMaplike> creator(aCx);
    4226           0 :   creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
    4227           0 :   if (!aReflector) {
    4228           0 :     return false;
    4229             :   }
    4230             : 
    4231           0 :   aCache->SetWrapper(aReflector);
    4232           0 :   creator.InitializationSucceeded();
    4233             : 
    4234           0 :   MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
    4235             :              aCache->GetWrapperPreserveColor() == aReflector);
    4236             :   // If proto != canonicalProto, we have to preserve our wrapper;
    4237             :   // otherwise we won't be able to properly recreate it later, since
    4238             :   // we won't know what proto to use.  Note that we don't check
    4239             :   // aGivenProto here, since it's entirely possible (and even
    4240             :   // somewhat common) to have a non-null aGivenProto which is the
    4241             :   // same as canonicalProto.
    4242           0 :   if (proto != canonicalProto) {
    4243           0 :     PreserveWrapper(aObject);
    4244             :   }
    4245             : 
    4246           0 :   return true;
    4247             : }
    4248             : 
    4249             : // This may allocate too many slots, because we only really need
    4250             : // slots for our non-interface-typed members that we cache.  But
    4251             : // allocating slots only for those would make the slot index
    4252             : // computations much more complicated, so let's do this the simple
    4253             : // way for now.
    4254             : DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 1);
    4255             : 
    4256             : const NativePropertyHooks sNativePropertyHooks[] = { {
    4257             :   nullptr,
    4258             :   nullptr,
    4259             :   nullptr,
    4260             :   { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
    4261             :   prototypes::id::TestInterfaceJSMaplike,
    4262             :   constructors::id::TestInterfaceJSMaplike,
    4263             :   nullptr,
    4264             :   &sXrayExpandoObjectClass
    4265             : } };
    4266             : 
    4267             : void
    4268           0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    4269             : {
    4270           0 :   JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
    4271           0 :   if (!parentProto) {
    4272           0 :     return;
    4273             :   }
    4274             : 
    4275           0 :   JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
    4276           0 :   if (!constructorProto) {
    4277           0 :     return;
    4278             :   }
    4279             : 
    4280             :   static bool sIdsInited = false;
    4281           0 :   if (!sIdsInited && NS_IsMainThread()) {
    4282           0 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
    4283           0 :       return;
    4284             :     }
    4285           0 :     if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
    4286           0 :       return;
    4287             :     }
    4288           0 :     sIdsInited = true;
    4289             :   }
    4290             : 
    4291           0 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::TestInterfaceJSMaplike);
    4292           0 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::TestInterfaceJSMaplike);
    4293           0 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    4294             :                               &sPrototypeClass.mBase, protoCache,
    4295             :                               constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
    4296             :                               interfaceCache,
    4297             :                               sNativeProperties.Upcast(),
    4298           0 :                               nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
    4299             :                               "TestInterfaceJSMaplike", aDefineOnGlobal,
    4300             :                               nullptr,
    4301           0 :                               false);
    4302             : 
    4303             :   // Set up aliases on the interface prototype object we just created.
    4304           0 :   JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx);
    4305           0 :   if (!proto) {
    4306           0 :     *protoCache = nullptr;
    4307           0 :     if (interfaceCache) {
    4308           0 :       *interfaceCache = nullptr;
    4309             :     }
    4310           0 :     return;
    4311             :   }
    4312             : 
    4313           0 :   JS::Rooted<JS::Value> aliasedVal(aCx);
    4314             : 
    4315           0 :   if (!JS_GetProperty(aCx, proto, "entries", &aliasedVal)) {
    4316           0 :     *protoCache = nullptr;
    4317           0 :     if (interfaceCache) {
    4318           0 :       *interfaceCache = nullptr;
    4319             :     }
    4320           0 :     return;
    4321             :   }
    4322           0 :   JS::Rooted<jsid> iteratorId(aCx, SYMBOL_TO_JSID(JS::GetWellKnownSymbol(aCx, JS::SymbolCode::iterator)));
    4323           0 :   if (!JS_DefinePropertyById(aCx, proto, iteratorId, aliasedVal, 0)) {
    4324           0 :     *protoCache = nullptr;
    4325           0 :     if (interfaceCache) {
    4326           0 :       *interfaceCache = nullptr;
    4327             :     }
    4328           0 :     return;
    4329             :   }
    4330             : }
    4331             : 
    4332             : JS::Handle<JSObject*>
    4333           0 : GetProtoObjectHandle(JSContext* aCx)
    4334             : {
    4335             :   /* Get the interface prototype object for this class.  This will create the
    4336             :      object as needed. */
    4337           0 :   bool aDefineOnGlobal = true;
    4338             : 
    4339             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    4340           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    4341           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    4342           0 :     return nullptr;
    4343             :   }
    4344             : 
    4345             :   /* Check to see whether the interface objects are already installed */
    4346           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    4347           0 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::TestInterfaceJSMaplike)) {
    4348           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    4349           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    4350             :   }
    4351             : 
    4352             :   /*
    4353             :    * The object might _still_ be null, but that's OK.
    4354             :    *
    4355             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    4356             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    4357             :    * changed after they have been set.
    4358             :    *
    4359             :    * Calling address() avoids the read read barrier that does gray
    4360             :    * unmarking, but it's not possible for the object to be gray here.
    4361             :    */
    4362             : 
    4363           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::TestInterfaceJSMaplike);
    4364           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    4365           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    4366             : }
    4367             : 
    4368             : JS::Handle<JSObject*>
    4369           0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
    4370             : {
    4371             :   /* Get the interface object for this class.  This will create the object as
    4372             :      needed. */
    4373             : 
    4374             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    4375           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    4376           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    4377           0 :     return nullptr;
    4378             :   }
    4379             : 
    4380             :   /* Check to see whether the interface objects are already installed */
    4381           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    4382           0 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::TestInterfaceJSMaplike)) {
    4383           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    4384           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    4385             :   }
    4386             : 
    4387             :   /*
    4388             :    * The object might _still_ be null, but that's OK.
    4389             :    *
    4390             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    4391             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    4392             :    * changed after they have been set.
    4393             :    *
    4394             :    * Calling address() avoids the read read barrier that does gray
    4395             :    * unmarking, but it's not possible for the object to be gray here.
    4396             :    */
    4397             : 
    4398           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::TestInterfaceJSMaplike);
    4399           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    4400           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    4401             : }
    4402             : 
    4403             : JSObject*
    4404           0 : GetConstructorObject(JSContext* aCx)
    4405             : {
    4406           0 :   return GetConstructorObjectHandle(aCx);
    4407             : }
    4408             : 
    4409             : } // namespace TestInterfaceJSMaplikeBinding
    4410             : 
    4411             : 
    4412             : 
    4413             : namespace TestInterfaceMaplikeBinding {
    4414             : 
    4415             : namespace MaplikeHelpers {
    4416             : void
    4417           0 : Clear(mozilla::dom::TestInterfaceMaplike* self, ErrorResult& aRv)
    4418             : {
    4419           0 :   MOZ_ASSERT(self);
    4420           0 :   AutoJSAPI jsapi;
    4421           0 :   jsapi.Init();
    4422           0 :   JSContext* cx = jsapi.cx();
    4423             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    4424             :   // all we want is to wrap into _some_ scope and then unwrap to find
    4425             :   // the reflector, and wrapping has no side-effects.
    4426           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    4427           0 :   JS::Rooted<JS::Value> v(cx);
    4428           0 :   if(!ToJSValue(cx, self, &v)) {
    4429           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4430           0 :     return;
    4431             :   }
    4432             :   // This is a reflector, but due to trying to name things
    4433             :   // similarly across method generators, it's called obj here.
    4434           0 :   JS::Rooted<JSObject*> obj(cx);
    4435           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    4436           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    4437             : 
    4438           0 :   JS::Rooted<JSObject*> backingObj(cx);
    4439           0 :   bool created = false;
    4440           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    4441           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4442           0 :     return;
    4443             :   }
    4444           0 :   if (created) {
    4445           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplike>(self);
    4446             :   }
    4447           0 :   if (!JS::MapClear(cx, backingObj)) {
    4448           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4449           0 :     return;
    4450             :   }
    4451           0 :   return;
    4452             : }
    4453             : bool
    4454           0 : Delete(mozilla::dom::TestInterfaceMaplike* self, const nsAString& aKey, ErrorResult& aRv)
    4455             : {
    4456           0 :   MOZ_ASSERT(self);
    4457           0 :   AutoJSAPI jsapi;
    4458           0 :   jsapi.Init();
    4459           0 :   JSContext* cx = jsapi.cx();
    4460             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    4461             :   // all we want is to wrap into _some_ scope and then unwrap to find
    4462             :   // the reflector, and wrapping has no side-effects.
    4463           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    4464           0 :   JS::Rooted<JS::Value> v(cx);
    4465           0 :   if(!ToJSValue(cx, self, &v)) {
    4466           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4467           0 :     return false;
    4468             :   }
    4469             :   // This is a reflector, but due to trying to name things
    4470             :   // similarly across method generators, it's called obj here.
    4471           0 :   JS::Rooted<JSObject*> obj(cx);
    4472           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    4473           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    4474             :   bool aRetVal;
    4475           0 :   JS::AutoValueVector argv(cx);
    4476           0 :   if (!argv.resize(1)) {
    4477           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    4478           0 :     return false;
    4479             :   }
    4480             :   do {
    4481           0 :     nsString mutableStr(aKey);
    4482           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    4483           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    4484           0 :       return false;
    4485             :     }
    4486           0 :     break;
    4487             :   } while (0);
    4488             : 
    4489           0 :   JS::Rooted<JSObject*> backingObj(cx);
    4490           0 :   bool created = false;
    4491           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    4492           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4493           0 :     return false;
    4494             :   }
    4495           0 :   if (created) {
    4496           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplike>(self);
    4497             :   }
    4498           0 :   if (!JS::MapDelete(cx, backingObj, argv[0], &aRetVal)) {
    4499           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4500           0 :     return false;
    4501             :   }
    4502           0 :   return aRetVal;
    4503             : }
    4504             : bool
    4505           0 : Has(mozilla::dom::TestInterfaceMaplike* self, const nsAString& aKey, ErrorResult& aRv)
    4506             : {
    4507           0 :   MOZ_ASSERT(self);
    4508           0 :   AutoJSAPI jsapi;
    4509           0 :   jsapi.Init();
    4510           0 :   JSContext* cx = jsapi.cx();
    4511             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    4512             :   // all we want is to wrap into _some_ scope and then unwrap to find
    4513             :   // the reflector, and wrapping has no side-effects.
    4514           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    4515           0 :   JS::Rooted<JS::Value> v(cx);
    4516           0 :   if(!ToJSValue(cx, self, &v)) {
    4517           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4518           0 :     return false;
    4519             :   }
    4520             :   // This is a reflector, but due to trying to name things
    4521             :   // similarly across method generators, it's called obj here.
    4522           0 :   JS::Rooted<JSObject*> obj(cx);
    4523           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    4524           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    4525             :   bool aRetVal;
    4526           0 :   JS::AutoValueVector argv(cx);
    4527           0 :   if (!argv.resize(1)) {
    4528           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    4529           0 :     return false;
    4530             :   }
    4531             :   do {
    4532           0 :     nsString mutableStr(aKey);
    4533           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    4534           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    4535           0 :       return false;
    4536             :     }
    4537           0 :     break;
    4538             :   } while (0);
    4539             : 
    4540           0 :   JS::Rooted<JSObject*> backingObj(cx);
    4541           0 :   bool created = false;
    4542           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    4543           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4544           0 :     return false;
    4545             :   }
    4546           0 :   if (created) {
    4547           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplike>(self);
    4548             :   }
    4549           0 :   if (!JS::MapHas(cx, backingObj, argv[0], &aRetVal)) {
    4550           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4551           0 :     return false;
    4552             :   }
    4553           0 :   return aRetVal;
    4554             : }
    4555             : void
    4556           0 : Set(mozilla::dom::TestInterfaceMaplike* self, const nsAString& aKey, int32_t aValue, ErrorResult& aRv)
    4557             : {
    4558           0 :   MOZ_ASSERT(self);
    4559           0 :   AutoJSAPI jsapi;
    4560           0 :   jsapi.Init();
    4561           0 :   JSContext* cx = jsapi.cx();
    4562             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    4563             :   // all we want is to wrap into _some_ scope and then unwrap to find
    4564             :   // the reflector, and wrapping has no side-effects.
    4565           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    4566           0 :   JS::Rooted<JS::Value> v(cx);
    4567           0 :   if(!ToJSValue(cx, self, &v)) {
    4568           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4569           0 :     return;
    4570             :   }
    4571             :   // This is a reflector, but due to trying to name things
    4572             :   // similarly across method generators, it's called obj here.
    4573           0 :   JS::Rooted<JSObject*> obj(cx);
    4574           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    4575           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    4576           0 :   JS::AutoValueVector argv(cx);
    4577           0 :   if (!argv.resize(2)) {
    4578           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    4579           0 :     return;
    4580             :   }
    4581             :   do {
    4582           0 :     argv[1].setInt32(int32_t(aValue));
    4583           0 :     break;
    4584             :   } while (0);
    4585             : 
    4586             :   do {
    4587           0 :     nsString mutableStr(aKey);
    4588           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    4589           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    4590           0 :       return;
    4591             :     }
    4592           0 :     break;
    4593             :   } while (0);
    4594             : 
    4595           0 :   JS::Rooted<JSObject*> backingObj(cx);
    4596           0 :   bool created = false;
    4597           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    4598           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4599           0 :     return;
    4600             :   }
    4601           0 :   if (created) {
    4602           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplike>(self);
    4603             :   }
    4604           0 :   if (!JS::MapSet(cx, backingObj, argv[0], argv[1])) {
    4605           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    4606           0 :     return;
    4607             :   }
    4608           0 :   return;
    4609             : }
    4610             : } // namespace MaplikeHelpers
    4611             : 
    4612             : static bool
    4613           0 : setInternal(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplike* self, const JSJitMethodCallArgs& args)
    4614             : {
    4615           0 :   if (MOZ_UNLIKELY(args.length() < 2)) {
    4616           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceMaplike.setInternal");
    4617             :   }
    4618           0 :   binding_detail::FakeString arg0;
    4619           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    4620           0 :     return false;
    4621             :   }
    4622             :   int32_t arg1;
    4623           0 :   if (!ValueToPrimitive<int32_t, eDefault>(cx, args[1], &arg1)) {
    4624           0 :     return false;
    4625             :   }
    4626           0 :   self->SetInternal(NonNullHelper(Constify(arg0)), arg1);
    4627           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    4628           0 :   args.rval().setUndefined();
    4629           0 :   return true;
    4630             : }
    4631             : 
    4632             : static const JSJitInfo setInternal_methodinfo = {
    4633             :   { (JSJitGetterOp)setInternal },
    4634             :   { prototypes::id::TestInterfaceMaplike },
    4635             :   { PrototypeTraits<prototypes::id::TestInterfaceMaplike>::Depth },
    4636             :   JSJitInfo::Method,
    4637             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    4638             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    4639             :   false,  /* isInfallible. False in setters. */
    4640             :   false,  /* isMovable.  Not relevant for setters. */
    4641             :   false, /* isEliminatable.  Not relevant for setters. */
    4642             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    4643             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    4644             :   false,  /* isTypedMethod.  Only relevant for methods. */
    4645             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    4646             : };
    4647             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    4648             : static_assert(0 < 2, "There is no slot for us");
    4649             : 
    4650             : static bool
    4651           0 : clearInternal(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplike* self, const JSJitMethodCallArgs& args)
    4652             : {
    4653           0 :   self->ClearInternal();
    4654           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    4655           0 :   args.rval().setUndefined();
    4656           0 :   return true;
    4657             : }
    4658             : 
    4659             : static const JSJitInfo clearInternal_methodinfo = {
    4660             :   { (JSJitGetterOp)clearInternal },
    4661             :   { prototypes::id::TestInterfaceMaplike },
    4662             :   { PrototypeTraits<prototypes::id::TestInterfaceMaplike>::Depth },
    4663             :   JSJitInfo::Method,
    4664             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    4665             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    4666             :   true,  /* isInfallible. False in setters. */
    4667             :   false,  /* isMovable.  Not relevant for setters. */
    4668             :   false, /* isEliminatable.  Not relevant for setters. */
    4669             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    4670             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    4671             :   false,  /* isTypedMethod.  Only relevant for methods. */
    4672             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    4673             : };
    4674             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    4675             : static_assert(0 < 2, "There is no slot for us");
    4676             : 
    4677             : static bool
    4678           0 : deleteInternal(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplike* self, const JSJitMethodCallArgs& args)
    4679             : {
    4680           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    4681           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceMaplike.deleteInternal");
    4682             :   }
    4683           0 :   binding_detail::FakeString arg0;
    4684           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    4685           0 :     return false;
    4686             :   }
    4687           0 :   bool result(self->DeleteInternal(NonNullHelper(Constify(arg0))));
    4688           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    4689           0 :   args.rval().setBoolean(result);
    4690           0 :   return true;
    4691             : }
    4692             : 
    4693             : static const JSJitInfo deleteInternal_methodinfo = {
    4694             :   { (JSJitGetterOp)deleteInternal },
    4695             :   { prototypes::id::TestInterfaceMaplike },
    4696             :   { PrototypeTraits<prototypes::id::TestInterfaceMaplike>::Depth },
    4697             :   JSJitInfo::Method,
    4698             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    4699             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    4700             :   false,  /* isInfallible. False in setters. */
    4701             :   false,  /* isMovable.  Not relevant for setters. */
    4702             :   false, /* isEliminatable.  Not relevant for setters. */
    4703             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    4704             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    4705             :   false,  /* isTypedMethod.  Only relevant for methods. */
    4706             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    4707             : };
    4708             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    4709             : static_assert(0 < 2, "There is no slot for us");
    4710             : 
    4711             : static bool
    4712           0 : hasInternal(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplike* self, const JSJitMethodCallArgs& args)
    4713             : {
    4714           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    4715           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceMaplike.hasInternal");
    4716             :   }
    4717           0 :   binding_detail::FakeString arg0;
    4718           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    4719           0 :     return false;
    4720             :   }
    4721           0 :   bool result(self->HasInternal(NonNullHelper(Constify(arg0))));
    4722           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    4723           0 :   args.rval().setBoolean(result);
    4724           0 :   return true;
    4725             : }
    4726             : 
    4727             : static const JSJitInfo hasInternal_methodinfo = {
    4728             :   { (JSJitGetterOp)hasInternal },
    4729             :   { prototypes::id::TestInterfaceMaplike },
    4730             :   { PrototypeTraits<prototypes::id::TestInterfaceMaplike>::Depth },
    4731             :   JSJitInfo::Method,
    4732             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    4733             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    4734             :   false,  /* isInfallible. False in setters. */
    4735             :   false,  /* isMovable.  Not relevant for setters. */
    4736             :   false, /* isEliminatable.  Not relevant for setters. */
    4737             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    4738             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    4739             :   false,  /* isTypedMethod.  Only relevant for methods. */
    4740             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    4741             : };
    4742             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    4743             : static_assert(0 < 2, "There is no slot for us");
    4744             : 
    4745             : static bool
    4746           0 : get_size(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplike* self, JSJitGetterCallArgs args)
    4747             : {
    4748           0 :   JS::Rooted<JSObject*> backingObj(cx);
    4749           0 :   bool created = false;
    4750           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    4751           0 :     return false;
    4752             :   }
    4753           0 :   if (created) {
    4754           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplike>(self);
    4755             :   }
    4756           0 :   uint32_t result = JS::MapSize(cx, backingObj);
    4757           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    4758           0 :   args.rval().setNumber(result);
    4759           0 :   return true;
    4760             : }
    4761             : 
    4762             : static const JSJitInfo size_getterinfo = {
    4763             :   { (JSJitGetterOp)get_size },
    4764             :   { prototypes::id::TestInterfaceMaplike },
    4765             :   { PrototypeTraits<prototypes::id::TestInterfaceMaplike>::Depth },
    4766             :   JSJitInfo::Getter,
    4767             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    4768             :   JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
    4769             :   true,  /* isInfallible. False in setters. */
    4770             :   false,  /* isMovable.  Not relevant for setters. */
    4771             :   false, /* isEliminatable.  Not relevant for setters. */
    4772             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    4773             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    4774             :   false,  /* isTypedMethod.  Only relevant for methods. */
    4775             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    4776             : };
    4777             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    4778             : static_assert(0 < 2, "There is no slot for us");
    4779             : 
    4780             : static bool
    4781           0 : entries(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplike* self, const JSJitMethodCallArgs& args)
    4782             : {
    4783           0 :   JS::Rooted<JSObject*> backingObj(cx);
    4784           0 :   bool created = false;
    4785           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    4786           0 :     return false;
    4787             :   }
    4788           0 :   if (created) {
    4789           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplike>(self);
    4790             :   }
    4791             :   // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
    4792             :   // after bug 1023984 is fixed.
    4793           0 :   if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    4794           0 :     JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    4795           0 :     return false;
    4796             :   }
    4797           0 :   JS::Rooted<JSObject*> result(cx);
    4798           0 :   JS::Rooted<JS::Value> v(cx);
    4799           0 :   if (!JS::MapEntries(cx, backingObj, &v)) {
    4800           0 :     return false;
    4801             :   }
    4802           0 :   result = &v.toObject();
    4803           0 :   JS::ExposeObjectToActiveJS(result);
    4804           0 :   args.rval().setObject(*result);
    4805           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    4806           0 :     return false;
    4807             :   }
    4808           0 :   return true;
    4809             : }
    4810             : 
    4811             : static const JSJitInfo::ArgType entries_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
    4812             : static const JSTypedMethodJitInfo entries_methodinfo = {
    4813             :   {
    4814             :     { (JSJitGetterOp)entries },
    4815             :     { prototypes::id::TestInterfaceMaplike },
    4816             :     { PrototypeTraits<prototypes::id::TestInterfaceMaplike>::Depth },
    4817             :     JSJitInfo::Method,
    4818             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    4819             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    4820             :     false,  /* isInfallible. False in setters. */
    4821             :     false,  /* isMovable.  Not relevant for setters. */
    4822             :     false, /* isEliminatable.  Not relevant for setters. */
    4823             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    4824             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    4825             :     true,  /* isTypedMethod.  Only relevant for methods. */
    4826             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    4827             :   },
    4828             :   entries_methodinfo_argTypes
    4829             : };
    4830             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    4831             : static_assert(0 < 2, "There is no slot for us");
    4832             : 
    4833             : static bool
    4834           0 : keys(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplike* self, const JSJitMethodCallArgs& args)
    4835             : {
    4836           0 :   JS::Rooted<JSObject*> backingObj(cx);
    4837           0 :   bool created = false;
    4838           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    4839           0 :     return false;
    4840             :   }
    4841           0 :   if (created) {
    4842           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplike>(self);
    4843             :   }
    4844             :   // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
    4845             :   // after bug 1023984 is fixed.
    4846           0 :   if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    4847           0 :     JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    4848           0 :     return false;
    4849             :   }
    4850           0 :   JS::Rooted<JSObject*> result(cx);
    4851           0 :   JS::Rooted<JS::Value> v(cx);
    4852           0 :   if (!JS::MapKeys(cx, backingObj, &v)) {
    4853           0 :     return false;
    4854             :   }
    4855           0 :   result = &v.toObject();
    4856           0 :   JS::ExposeObjectToActiveJS(result);
    4857           0 :   args.rval().setObject(*result);
    4858           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    4859           0 :     return false;
    4860             :   }
    4861           0 :   return true;
    4862             : }
    4863             : 
    4864             : static const JSJitInfo::ArgType keys_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
    4865             : static const JSTypedMethodJitInfo keys_methodinfo = {
    4866             :   {
    4867             :     { (JSJitGetterOp)keys },
    4868             :     { prototypes::id::TestInterfaceMaplike },
    4869             :     { PrototypeTraits<prototypes::id::TestInterfaceMaplike>::Depth },
    4870             :     JSJitInfo::Method,
    4871             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    4872             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    4873             :     false,  /* isInfallible. False in setters. */
    4874             :     false,  /* isMovable.  Not relevant for setters. */
    4875             :     false, /* isEliminatable.  Not relevant for setters. */
    4876             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    4877             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    4878             :     true,  /* isTypedMethod.  Only relevant for methods. */
    4879             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    4880             :   },
    4881             :   keys_methodinfo_argTypes
    4882             : };
    4883             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    4884             : static_assert(0 < 2, "There is no slot for us");
    4885             : 
    4886             : static bool
    4887           0 : values(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplike* self, const JSJitMethodCallArgs& args)
    4888             : {
    4889           0 :   JS::Rooted<JSObject*> backingObj(cx);
    4890           0 :   bool created = false;
    4891           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    4892           0 :     return false;
    4893             :   }
    4894           0 :   if (created) {
    4895           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplike>(self);
    4896             :   }
    4897             :   // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
    4898             :   // after bug 1023984 is fixed.
    4899           0 :   if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    4900           0 :     JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    4901           0 :     return false;
    4902             :   }
    4903           0 :   JS::Rooted<JSObject*> result(cx);
    4904           0 :   JS::Rooted<JS::Value> v(cx);
    4905           0 :   if (!JS::MapValues(cx, backingObj, &v)) {
    4906           0 :     return false;
    4907             :   }
    4908           0 :   result = &v.toObject();
    4909           0 :   JS::ExposeObjectToActiveJS(result);
    4910           0 :   args.rval().setObject(*result);
    4911           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    4912           0 :     return false;
    4913             :   }
    4914           0 :   return true;
    4915             : }
    4916             : 
    4917             : static const JSJitInfo::ArgType values_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
    4918             : static const JSTypedMethodJitInfo values_methodinfo = {
    4919             :   {
    4920             :     { (JSJitGetterOp)values },
    4921             :     { prototypes::id::TestInterfaceMaplike },
    4922             :     { PrototypeTraits<prototypes::id::TestInterfaceMaplike>::Depth },
    4923             :     JSJitInfo::Method,
    4924             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    4925             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    4926             :     false,  /* isInfallible. False in setters. */
    4927             :     false,  /* isMovable.  Not relevant for setters. */
    4928             :     false, /* isEliminatable.  Not relevant for setters. */
    4929             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    4930             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    4931             :     true,  /* isTypedMethod.  Only relevant for methods. */
    4932             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    4933             :   },
    4934             :   values_methodinfo_argTypes
    4935             : };
    4936             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    4937             : static_assert(0 < 2, "There is no slot for us");
    4938             : 
    4939             : static bool
    4940           0 : forEach(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplike* self, const JSJitMethodCallArgs& args)
    4941             : {
    4942           0 :   JS::Rooted<JSObject*> arg0(cx);
    4943           0 :   if (args.get(0).isObject()) {
    4944           0 :     arg0 = &args.get(0).toObject();
    4945             :   } else {
    4946           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of TestInterfaceMaplike.forEach");
    4947           0 :     return false;
    4948             :   }
    4949           0 :   JS::Rooted<JS::Value> arg1(cx);
    4950           0 :   if (args.hasDefined(1)) {
    4951           0 :     arg1 = args.get(1);
    4952             :   } else {
    4953           0 :     arg1 = JS::UndefinedValue();
    4954             :   }
    4955           0 :   JS::Rooted<JSObject*> backingObj(cx);
    4956           0 :   bool created = false;
    4957           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    4958           0 :     return false;
    4959             :   }
    4960           0 :   if (created) {
    4961           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplike>(self);
    4962             :   }
    4963             :   // Create a wrapper function.
    4964           0 :   JSFunction* func = js::NewFunctionWithReserved(cx, ForEachHandler, 3, 0, nullptr);
    4965           0 :   if (!func) {
    4966           0 :     return false;
    4967             :   }
    4968           0 :   JS::Rooted<JSObject*> funcObj(cx, JS_GetFunctionObject(func));
    4969           0 :   JS::Rooted<JS::Value> funcVal(cx, JS::ObjectValue(*funcObj));
    4970           0 :   js::SetFunctionNativeReserved(funcObj, FOREACH_CALLBACK_SLOT,
    4971           0 :                                 JS::ObjectValue(*arg0));
    4972           0 :   js::SetFunctionNativeReserved(funcObj, FOREACH_MAPLIKEORSETLIKEOBJ_SLOT,
    4973           0 :                                 JS::ObjectValue(*obj));
    4974           0 :   if (!JS::MapForEach(cx, backingObj, funcVal, arg1)) {
    4975           0 :     return false;
    4976             :   }
    4977           0 :   args.rval().setUndefined();
    4978           0 :   return true;
    4979             : }
    4980             : 
    4981             : static const JSJitInfo forEach_methodinfo = {
    4982             :   { (JSJitGetterOp)forEach },
    4983             :   { prototypes::id::TestInterfaceMaplike },
    4984             :   { PrototypeTraits<prototypes::id::TestInterfaceMaplike>::Depth },
    4985             :   JSJitInfo::Method,
    4986             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    4987             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    4988             :   false,  /* isInfallible. False in setters. */
    4989             :   false,  /* isMovable.  Not relevant for setters. */
    4990             :   false, /* isEliminatable.  Not relevant for setters. */
    4991             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    4992             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    4993             :   false,  /* isTypedMethod.  Only relevant for methods. */
    4994             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    4995             : };
    4996             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    4997             : static_assert(0 < 2, "There is no slot for us");
    4998             : 
    4999             : static bool
    5000           0 : has(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplike* self, const JSJitMethodCallArgs& args)
    5001             : {
    5002           0 :   binding_detail::FakeString arg0;
    5003           0 :   if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
    5004           0 :     return false;
    5005             :   }
    5006           0 :   JS::Rooted<JSObject*> backingObj(cx);
    5007           0 :   bool created = false;
    5008           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    5009           0 :     return false;
    5010             :   }
    5011           0 :   if (created) {
    5012           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplike>(self);
    5013             :   }
    5014           0 :   JS::Rooted<JS::Value> arg0Val(cx);
    5015           0 :   if (!ToJSValue(cx, arg0, &arg0Val)) {
    5016           0 :     return false;
    5017             :   }
    5018             :   bool result;
    5019           0 :   if (!JS::MapHas(cx, backingObj, arg0Val, &result)) {
    5020           0 :     return false;
    5021             :   }
    5022           0 :   args.rval().setBoolean(result);
    5023           0 :   return true;
    5024             : }
    5025             : 
    5026             : static const JSJitInfo::ArgType has_methodinfo_argTypes[] = { JSJitInfo::String, JSJitInfo::ArgTypeListEnd };
    5027             : static const JSTypedMethodJitInfo has_methodinfo = {
    5028             :   {
    5029             :     { (JSJitGetterOp)has },
    5030             :     { prototypes::id::TestInterfaceMaplike },
    5031             :     { PrototypeTraits<prototypes::id::TestInterfaceMaplike>::Depth },
    5032             :     JSJitInfo::Method,
    5033             :     JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    5034             :     JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    5035             :     false,  /* isInfallible. False in setters. */
    5036             :     false,  /* isMovable.  Not relevant for setters. */
    5037             :     false, /* isEliminatable.  Not relevant for setters. */
    5038             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    5039             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    5040             :     true,  /* isTypedMethod.  Only relevant for methods. */
    5041             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    5042             :   },
    5043             :   has_methodinfo_argTypes
    5044             : };
    5045             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    5046             : static_assert(0 < 2, "There is no slot for us");
    5047             : 
    5048             : static bool
    5049           0 : clear(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplike* self, const JSJitMethodCallArgs& args)
    5050             : {
    5051           0 :   JS::Rooted<JSObject*> backingObj(cx);
    5052           0 :   bool created = false;
    5053           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    5054           0 :     return false;
    5055             :   }
    5056           0 :   if (created) {
    5057           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplike>(self);
    5058             :   }
    5059           0 :   if (!JS::MapClear(cx, backingObj)) {
    5060           0 :     return false;
    5061             :   }
    5062           0 :   args.rval().setUndefined();
    5063           0 :   return true;
    5064             : }
    5065             : 
    5066             : static const JSJitInfo clear_methodinfo = {
    5067             :   { (JSJitGetterOp)clear },
    5068             :   { prototypes::id::TestInterfaceMaplike },
    5069             :   { PrototypeTraits<prototypes::id::TestInterfaceMaplike>::Depth },
    5070             :   JSJitInfo::Method,
    5071             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    5072             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    5073             :   false,  /* isInfallible. False in setters. */
    5074             :   false,  /* isMovable.  Not relevant for setters. */
    5075             :   false, /* isEliminatable.  Not relevant for setters. */
    5076             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    5077             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    5078             :   false,  /* isTypedMethod.  Only relevant for methods. */
    5079             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    5080             : };
    5081             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    5082             : static_assert(0 < 2, "There is no slot for us");
    5083             : 
    5084             : static bool
    5085           0 : _delete_(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplike* self, const JSJitMethodCallArgs& args)
    5086             : {
    5087           0 :   binding_detail::FakeString arg0;
    5088           0 :   if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
    5089           0 :     return false;
    5090             :   }
    5091           0 :   JS::Rooted<JSObject*> backingObj(cx);
    5092           0 :   bool created = false;
    5093           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    5094           0 :     return false;
    5095             :   }
    5096           0 :   if (created) {
    5097           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplike>(self);
    5098             :   }
    5099           0 :   JS::Rooted<JS::Value> arg0Val(cx);
    5100           0 :   if (!ToJSValue(cx, arg0, &arg0Val)) {
    5101           0 :     return false;
    5102             :   }
    5103             :   bool result;
    5104           0 :   if (!JS::MapDelete(cx, backingObj, arg0Val, &result)) {
    5105           0 :     return false;
    5106             :   }
    5107           0 :   args.rval().setBoolean(result);
    5108           0 :   return true;
    5109             : }
    5110             : 
    5111             : static const JSJitInfo delete_methodinfo = {
    5112             :   { (JSJitGetterOp)_delete_ },
    5113             :   { prototypes::id::TestInterfaceMaplike },
    5114             :   { PrototypeTraits<prototypes::id::TestInterfaceMaplike>::Depth },
    5115             :   JSJitInfo::Method,
    5116             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    5117             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    5118             :   false,  /* isInfallible. False in setters. */
    5119             :   false,  /* isMovable.  Not relevant for setters. */
    5120             :   false, /* isEliminatable.  Not relevant for setters. */
    5121             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    5122             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    5123             :   false,  /* isTypedMethod.  Only relevant for methods. */
    5124             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    5125             : };
    5126             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    5127             : static_assert(0 < 2, "There is no slot for us");
    5128             : 
    5129             : static bool
    5130           0 : get(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplike* self, const JSJitMethodCallArgs& args)
    5131             : {
    5132           0 :   binding_detail::FakeString arg0;
    5133           0 :   if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
    5134           0 :     return false;
    5135             :   }
    5136           0 :   JS::Rooted<JSObject*> backingObj(cx);
    5137           0 :   bool created = false;
    5138           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    5139           0 :     return false;
    5140             :   }
    5141           0 :   if (created) {
    5142           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplike>(self);
    5143             :   }
    5144           0 :   JS::Rooted<JS::Value> arg0Val(cx);
    5145           0 :   if (!ToJSValue(cx, arg0, &arg0Val)) {
    5146           0 :     return false;
    5147             :   }
    5148           0 :   JS::Rooted<JS::Value> result(cx);
    5149           0 :   if (!JS::MapGet(cx, backingObj, arg0Val, &result)) {
    5150           0 :     return false;
    5151             :   }
    5152           0 :   JS::ExposeValueToActiveJS(result);
    5153           0 :   args.rval().set(result);
    5154           0 :   if (!MaybeWrapValue(cx, args.rval())) {
    5155           0 :     return false;
    5156             :   }
    5157           0 :   return true;
    5158             : }
    5159             : 
    5160             : static const JSJitInfo::ArgType get_methodinfo_argTypes[] = { JSJitInfo::String, JSJitInfo::ArgTypeListEnd };
    5161             : static const JSTypedMethodJitInfo get_methodinfo = {
    5162             :   {
    5163             :     { (JSJitGetterOp)get },
    5164             :     { prototypes::id::TestInterfaceMaplike },
    5165             :     { PrototypeTraits<prototypes::id::TestInterfaceMaplike>::Depth },
    5166             :     JSJitInfo::Method,
    5167             :     JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    5168             :     JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    5169             :     false,  /* isInfallible. False in setters. */
    5170             :     false,  /* isMovable.  Not relevant for setters. */
    5171             :     false, /* isEliminatable.  Not relevant for setters. */
    5172             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    5173             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    5174             :     true,  /* isTypedMethod.  Only relevant for methods. */
    5175             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    5176             :   },
    5177             :   get_methodinfo_argTypes
    5178             : };
    5179             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    5180             : static_assert(0 < 2, "There is no slot for us");
    5181             : 
    5182             : static bool
    5183           0 : set(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplike* self, const JSJitMethodCallArgs& args)
    5184             : {
    5185           0 :   binding_detail::FakeString arg0;
    5186           0 :   if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
    5187           0 :     return false;
    5188             :   }
    5189             :   int32_t arg1;
    5190           0 :   if (!ValueToPrimitive<int32_t, eDefault>(cx, args.get(1), &arg1)) {
    5191           0 :     return false;
    5192             :   }
    5193           0 :   JS::Rooted<JSObject*> backingObj(cx);
    5194           0 :   bool created = false;
    5195           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    5196           0 :     return false;
    5197             :   }
    5198           0 :   if (created) {
    5199           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplike>(self);
    5200             :   }
    5201           0 :   JS::Rooted<JS::Value> arg0Val(cx);
    5202           0 :   if (!ToJSValue(cx, arg0, &arg0Val)) {
    5203           0 :     return false;
    5204             :   }
    5205           0 :   JS::Rooted<JS::Value> arg1Val(cx);
    5206           0 :   if (!ToJSValue(cx, arg1, &arg1Val)) {
    5207           0 :     return false;
    5208             :   }
    5209           0 :   JS::Rooted<JSObject*> result(cx);
    5210           0 :   if (!JS::MapSet(cx, backingObj, arg0Val, arg1Val)) {
    5211           0 :     return false;
    5212             :   }
    5213           0 :   result = obj;
    5214           0 :   JS::ExposeObjectToActiveJS(result);
    5215           0 :   args.rval().setObject(*result);
    5216           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    5217           0 :     return false;
    5218             :   }
    5219           0 :   return true;
    5220             : }
    5221             : 
    5222             : static const JSJitInfo set_methodinfo = {
    5223             :   { (JSJitGetterOp)set },
    5224             :   { prototypes::id::TestInterfaceMaplike },
    5225             :   { PrototypeTraits<prototypes::id::TestInterfaceMaplike>::Depth },
    5226             :   JSJitInfo::Method,
    5227             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    5228             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    5229             :   false,  /* isInfallible. False in setters. */
    5230             :   false,  /* isMovable.  Not relevant for setters. */
    5231             :   false, /* isEliminatable.  Not relevant for setters. */
    5232             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    5233             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    5234             :   false,  /* isTypedMethod.  Only relevant for methods. */
    5235             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    5236             : };
    5237             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    5238             : static_assert(0 < 2, "There is no slot for us");
    5239             : 
    5240             : static bool
    5241           0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
    5242             : {
    5243           0 :   mozilla::dom::TestInterfaceMaplike* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceMaplike>(obj);
    5244             :   // We don't want to preserve if we don't have a wrapper, and we
    5245             :   // obviously can't preserve if we're not initialized.
    5246           0 :   if (self && self->GetWrapperPreserveColor()) {
    5247           0 :     PreserveWrapper(self);
    5248             :   }
    5249           0 :   return true;
    5250             : }
    5251             : 
    5252             : static void
    5253           0 : _finalize(js::FreeOp* fop, JSObject* obj)
    5254             : {
    5255           0 :   mozilla::dom::TestInterfaceMaplike* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceMaplike>(obj);
    5256           0 :   if (self) {
    5257           0 :     ClearWrapper(self, self, obj);
    5258           0 :     AddForDeferredFinalization<mozilla::dom::TestInterfaceMaplike>(self);
    5259             :   }
    5260           0 : }
    5261             : 
    5262             : static void
    5263           0 : _objectMoved(JSObject* obj, const JSObject* old)
    5264             : {
    5265           0 :   mozilla::dom::TestInterfaceMaplike* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceMaplike>(obj);
    5266           0 :   if (self) {
    5267           0 :     UpdateWrapper(self, self, obj, old);
    5268             :   }
    5269           0 : }
    5270             : 
    5271             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    5272             : #if defined(__clang__)
    5273             : #pragma clang diagnostic push
    5274             : #pragma clang diagnostic ignored "-Wmissing-braces"
    5275             : #endif
    5276             : static const JSFunctionSpec sMethods_specs[] = {
    5277             :   JS_FNSPEC("setInternal", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&setInternal_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
    5278             :   JS_FNSPEC("clearInternal", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&clearInternal_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    5279             :   JS_FNSPEC("deleteInternal", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&deleteInternal_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    5280             :   JS_FNSPEC("hasInternal", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&hasInternal_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    5281             :   JS_FNSPEC("entries", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&entries_methodinfo), 0, 0, nullptr),
    5282             :   JS_FNSPEC("keys", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&keys_methodinfo), 0, 0, nullptr),
    5283             :   JS_FNSPEC("values", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&values_methodinfo), 0, 0, nullptr),
    5284             :   JS_FNSPEC("forEach", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&forEach_methodinfo), 1, 0, nullptr),
    5285             :   JS_FNSPEC("has", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&has_methodinfo), 1, 0, nullptr),
    5286             :   JS_FNSPEC("clear", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&clear_methodinfo), 0, 0, nullptr),
    5287             :   JS_FNSPEC("delete", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&delete_methodinfo), 1, 0, nullptr),
    5288             :   JS_FNSPEC("get", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&get_methodinfo), 1, 0, nullptr),
    5289             :   JS_FNSPEC("set", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&set_methodinfo), 2, 0, nullptr),
    5290             :   JS_FS_END
    5291             : };
    5292             : #if defined(__clang__)
    5293             : #pragma clang diagnostic pop
    5294             : #endif
    5295             : 
    5296             : 
    5297             : // Can't be const because the pref-enabled boolean needs to be writable
    5298             : static Prefable<const JSFunctionSpec> sMethods[] = {
    5299             :   { nullptr, &sMethods_specs[0] },
    5300             :   { nullptr, nullptr }
    5301             : };
    5302             : 
    5303             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    5304             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    5305             : static_assert(13 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    5306             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    5307             : 
    5308             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    5309             : #if defined(__clang__)
    5310             : #pragma clang diagnostic push
    5311             : #pragma clang diagnostic ignored "-Wmissing-braces"
    5312             : #endif
    5313             : static const JSPropertySpec sAttributes_specs[] = {
    5314             :   { "size", JSPROP_SHARED, GenericBindingGetter, &size_getterinfo, nullptr, nullptr },
    5315             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
    5316             : };
    5317             : #if defined(__clang__)
    5318             : #pragma clang diagnostic pop
    5319             : #endif
    5320             : 
    5321             : 
    5322             : // Can't be const because the pref-enabled boolean needs to be writable
    5323             : static Prefable<const JSPropertySpec> sAttributes[] = {
    5324             :   { nullptr, &sAttributes_specs[0] },
    5325             :   { nullptr, nullptr }
    5326             : };
    5327             : 
    5328             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    5329             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    5330             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    5331             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    5332             : 
    5333             : 
    5334             : static uint16_t sNativeProperties_sortedPropertyIndices[14];
    5335             : static PropertyInfo sNativeProperties_propertyInfos[14];
    5336             : 
    5337             : static const NativePropertiesN<2> sNativeProperties = {
    5338             :   false, 0,
    5339             :   false, 0,
    5340             :   true,  0 /* sMethods */,
    5341             :   true,  1 /* sAttributes */,
    5342             :   false, 0,
    5343             :   false, 0,
    5344             :   false, 0,
    5345             :   4,
    5346             :   14,
    5347             :   sNativeProperties_sortedPropertyIndices,
    5348             :   {
    5349             :     { sMethods, &sNativeProperties_propertyInfos[0] },
    5350             :     { sAttributes, &sNativeProperties_propertyInfos[13] }
    5351             :   }
    5352             : };
    5353             : static_assert(4 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.iteratorAliasMethodIndex) - 1),
    5354             :     "We have an iterator alias index that is oversized");
    5355             : static_assert(14 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
    5356             :     "We have a property info count that is oversized");
    5357             : 
    5358             : static bool
    5359           0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
    5360             : {
    5361           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    5362           0 :   JS::Rooted<JSObject*> obj(cx, &args.callee());
    5363           0 :   if (!args.isConstructing()) {
    5364             :     // XXXbz wish I could get the name from the callee instead of
    5365             :     // Adding more relocations
    5366           0 :     return ThrowConstructorWithoutNew(cx, "TestInterfaceMaplike");
    5367             :   }
    5368             : 
    5369           0 :   GlobalObject global(cx, obj);
    5370           0 :   if (global.Failed()) {
    5371           0 :     return false;
    5372             :   }
    5373             : 
    5374           0 :   JS::Rooted<JSObject*> desiredProto(cx);
    5375           0 :   if (!GetDesiredProto(cx, args, &desiredProto)) {
    5376           0 :     return false;
    5377             :   }
    5378             : 
    5379           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    5380           0 :   Maybe<JSAutoCompartment> ac;
    5381           0 :   if (objIsXray) {
    5382           0 :     obj = js::CheckedUnwrap(obj);
    5383           0 :     if (!obj) {
    5384           0 :       return false;
    5385             :     }
    5386           0 :     ac.emplace(cx, obj);
    5387           0 :     if (!JS_WrapObject(cx, &desiredProto)) {
    5388           0 :       return false;
    5389             :     }
    5390             :   }
    5391           0 :   binding_detail::FastErrorResult rv;
    5392           0 :   auto result(StrongOrRawPtr<mozilla::dom::TestInterfaceMaplike>(mozilla::dom::TestInterfaceMaplike::Constructor(global, rv)));
    5393           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    5394           0 :     return false;
    5395             :   }
    5396           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    5397             :   static_assert(!IsPointer<decltype(result)>::value,
    5398             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
    5399           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
    5400           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    5401           0 :     return false;
    5402             :   }
    5403           0 :   return true;
    5404             : }
    5405             : 
    5406             : static const js::ClassOps sInterfaceObjectClassOps = {
    5407             :     nullptr,               /* addProperty */
    5408             :     nullptr,               /* delProperty */
    5409             :     nullptr,               /* getProperty */
    5410             :     nullptr,               /* setProperty */
    5411             :     nullptr,               /* enumerate */
    5412             :     nullptr,               /* newEnumerate */
    5413             :     nullptr,               /* resolve */
    5414             :     nullptr,               /* mayResolve */
    5415             :     nullptr,               /* finalize */
    5416             :     _constructor, /* call */
    5417             :     nullptr,               /* hasInstance */
    5418             :     _constructor, /* construct */
    5419             :     nullptr,               /* trace */
    5420             : };
    5421             : 
    5422             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
    5423             :   {
    5424             :     "Function",
    5425             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
    5426             :     &sInterfaceObjectClassOps,
    5427             :     JS_NULL_CLASS_SPEC,
    5428             :     JS_NULL_CLASS_EXT,
    5429             :     &sInterfaceObjectClassObjectOps
    5430             :   },
    5431             :   eInterface,
    5432             :   true,
    5433             :   prototypes::id::TestInterfaceMaplike,
    5434             :   PrototypeTraits<prototypes::id::TestInterfaceMaplike>::Depth,
    5435             :   sNativePropertyHooks,
    5436             :   "function TestInterfaceMaplike() {\n    [native code]\n}",
    5437             :   JS::GetRealmFunctionPrototype
    5438             : };
    5439             : 
    5440             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
    5441             :   {
    5442             :     "TestInterfaceMaplikePrototype",
    5443             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    5444             :     JS_NULL_CLASS_OPS,
    5445             :     JS_NULL_CLASS_SPEC,
    5446             :     JS_NULL_CLASS_EXT,
    5447             :     JS_NULL_OBJECT_OPS
    5448             :   },
    5449             :   eInterfacePrototype,
    5450             :   false,
    5451             :   prototypes::id::TestInterfaceMaplike,
    5452             :   PrototypeTraits<prototypes::id::TestInterfaceMaplike>::Depth,
    5453             :   sNativePropertyHooks,
    5454             :   "[object TestInterfaceMaplikePrototype]",
    5455             :   JS::GetRealmObjectPrototype
    5456             : };
    5457             : 
    5458             : bool
    5459           0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
    5460             : {
    5461             :   static bool sPrefValue;
    5462             :   static bool sPrefCacheSetUp = false;
    5463           0 :   if (!sPrefCacheSetUp) {
    5464           0 :     sPrefCacheSetUp = true;
    5465           0 :     Preferences::AddBoolVarCache(&sPrefValue, "dom.expose_test_interfaces");
    5466             :   }
    5467             : 
    5468           0 :   return sPrefValue;
    5469             : }
    5470             : 
    5471             : JSObject*
    5472           0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
    5473             : {
    5474           0 :   return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
    5475             : }
    5476             : 
    5477             : static const js::ClassOps sClassOps = {
    5478             :   _addProperty, /* addProperty */
    5479             :   nullptr,               /* delProperty */
    5480             :   nullptr,               /* getProperty */
    5481             :   nullptr,               /* setProperty */
    5482             :   nullptr,               /* enumerate */
    5483             :   nullptr, /* newEnumerate */
    5484             :   nullptr, /* resolve */
    5485             :   nullptr, /* mayResolve */
    5486             :   _finalize, /* finalize */
    5487             :   nullptr, /* call */
    5488             :   nullptr,               /* hasInstance */
    5489             :   nullptr,               /* construct */
    5490             :   nullptr, /* trace */
    5491             : };
    5492             : 
    5493             : static const js::ClassExtension sClassExtension = {
    5494             :   nullptr, /* weakmapKeyDelegateOp */
    5495             :   _objectMoved /* objectMovedOp */
    5496             : };
    5497             : 
    5498             : static const DOMJSClass sClass = {
    5499             :   { "TestInterfaceMaplike",
    5500             :     JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2),
    5501             :     &sClassOps,
    5502             :     JS_NULL_CLASS_SPEC,
    5503             :     &sClassExtension,
    5504             :     JS_NULL_OBJECT_OPS
    5505             :   },
    5506             :   { prototypes::id::TestInterfaceMaplike, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
    5507             :   IsBaseOf<nsISupports, mozilla::dom::TestInterfaceMaplike >::value,
    5508             :   sNativePropertyHooks,
    5509             :   FindAssociatedGlobalForNative<mozilla::dom::TestInterfaceMaplike>::Get,
    5510             :   GetProtoObjectHandle,
    5511             :   GetCCParticipant<mozilla::dom::TestInterfaceMaplike>::Get()
    5512             : };
    5513             : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
    5514             :               "Must have the right minimal number of reserved slots.");
    5515             : static_assert(2 >= 2,
    5516             :               "Must have enough reserved slots.");
    5517             : 
    5518             : const JSClass*
    5519           0 : GetJSClass()
    5520             : {
    5521           0 :   return sClass.ToJSClass();
    5522             : }
    5523             : 
    5524             : bool
    5525           0 : Wrap(JSContext* aCx, mozilla::dom::TestInterfaceMaplike* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
    5526             : {
    5527             :   MOZ_ASSERT(static_cast<mozilla::dom::TestInterfaceMaplike*>(aObject) ==
    5528             :              reinterpret_cast<mozilla::dom::TestInterfaceMaplike*>(aObject),
    5529             :              "Multiple inheritance for mozilla::dom::TestInterfaceMaplike is broken.");
    5530           0 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
    5531           0 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
    5532           0 :   MOZ_ASSERT(!aCache->GetWrapper(),
    5533             :              "You should probably not be using Wrap() directly; use "
    5534             :              "GetOrCreateDOMReflector instead");
    5535             : 
    5536           0 :   MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
    5537             :              "nsISupports must be on our primary inheritance chain");
    5538             : 
    5539           0 :   JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
    5540           0 :   if (!global) {
    5541           0 :     return false;
    5542             :   }
    5543           0 :   MOZ_ASSERT(JS_IsGlobalObject(global));
    5544           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(global));
    5545             : 
    5546             :   // That might have ended up wrapping us already, due to the wonders
    5547             :   // of XBL.  Check for that, and bail out as needed.
    5548           0 :   aReflector.set(aCache->GetWrapper());
    5549           0 :   if (aReflector) {
    5550             : #ifdef DEBUG
    5551           0 :     binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
    5552             : #endif // DEBUG
    5553           0 :     return true;
    5554             :   }
    5555             : 
    5556           0 :   JSAutoCompartment ac(aCx, global);
    5557           0 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
    5558           0 :   if (!canonicalProto) {
    5559           0 :     return false;
    5560             :   }
    5561           0 :   JS::Rooted<JSObject*> proto(aCx);
    5562           0 :   if (aGivenProto) {
    5563           0 :     proto = aGivenProto;
    5564             :     // Unfortunately, while aGivenProto was in the compartment of aCx
    5565             :     // coming in, we changed compartments to that of "parent" so may need
    5566             :     // to wrap the proto here.
    5567           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
    5568           0 :       if (!JS_WrapObject(aCx, &proto)) {
    5569           0 :         return false;
    5570             :       }
    5571             :     }
    5572             :   } else {
    5573           0 :     proto = canonicalProto;
    5574             :   }
    5575             : 
    5576           0 :   BindingJSObjectCreator<mozilla::dom::TestInterfaceMaplike> creator(aCx);
    5577           0 :   creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
    5578           0 :   if (!aReflector) {
    5579           0 :     return false;
    5580             :   }
    5581             : 
    5582           0 :   aCache->SetWrapper(aReflector);
    5583           0 :   creator.InitializationSucceeded();
    5584             : 
    5585           0 :   MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
    5586             :              aCache->GetWrapperPreserveColor() == aReflector);
    5587             :   // If proto != canonicalProto, we have to preserve our wrapper;
    5588             :   // otherwise we won't be able to properly recreate it later, since
    5589             :   // we won't know what proto to use.  Note that we don't check
    5590             :   // aGivenProto here, since it's entirely possible (and even
    5591             :   // somewhat common) to have a non-null aGivenProto which is the
    5592             :   // same as canonicalProto.
    5593           0 :   if (proto != canonicalProto) {
    5594           0 :     PreserveWrapper(aObject);
    5595             :   }
    5596             : 
    5597           0 :   return true;
    5598             : }
    5599             : 
    5600             : // This may allocate too many slots, because we only really need
    5601             : // slots for our non-interface-typed members that we cache.  But
    5602             : // allocating slots only for those would make the slot index
    5603             : // computations much more complicated, so let's do this the simple
    5604             : // way for now.
    5605             : DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 1);
    5606             : 
    5607             : const NativePropertyHooks sNativePropertyHooks[] = { {
    5608             :   nullptr,
    5609             :   nullptr,
    5610             :   nullptr,
    5611             :   { sNativeProperties.Upcast(), nullptr },
    5612             :   prototypes::id::TestInterfaceMaplike,
    5613             :   constructors::id::TestInterfaceMaplike,
    5614             :   nullptr,
    5615             :   &sXrayExpandoObjectClass
    5616             : } };
    5617             : 
    5618             : void
    5619           0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    5620             : {
    5621           0 :   JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
    5622           0 :   if (!parentProto) {
    5623           0 :     return;
    5624             :   }
    5625             : 
    5626           0 :   JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
    5627           0 :   if (!constructorProto) {
    5628           0 :     return;
    5629             :   }
    5630             : 
    5631             :   static bool sIdsInited = false;
    5632           0 :   if (!sIdsInited && NS_IsMainThread()) {
    5633           0 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
    5634           0 :       return;
    5635             :     }
    5636           0 :     sIdsInited = true;
    5637             :   }
    5638             : 
    5639           0 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::TestInterfaceMaplike);
    5640           0 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::TestInterfaceMaplike);
    5641           0 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    5642             :                               &sPrototypeClass.mBase, protoCache,
    5643             :                               constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
    5644             :                               interfaceCache,
    5645             :                               sNativeProperties.Upcast(),
    5646             :                               nullptr,
    5647             :                               "TestInterfaceMaplike", aDefineOnGlobal,
    5648             :                               nullptr,
    5649           0 :                               false);
    5650             : 
    5651             :   // Set up aliases on the interface prototype object we just created.
    5652           0 :   JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx);
    5653           0 :   if (!proto) {
    5654           0 :     *protoCache = nullptr;
    5655           0 :     if (interfaceCache) {
    5656           0 :       *interfaceCache = nullptr;
    5657             :     }
    5658           0 :     return;
    5659             :   }
    5660             : 
    5661           0 :   JS::Rooted<JS::Value> aliasedVal(aCx);
    5662             : 
    5663           0 :   if (!JS_GetProperty(aCx, proto, "entries", &aliasedVal)) {
    5664           0 :     *protoCache = nullptr;
    5665           0 :     if (interfaceCache) {
    5666           0 :       *interfaceCache = nullptr;
    5667             :     }
    5668           0 :     return;
    5669             :   }
    5670           0 :   JS::Rooted<jsid> iteratorId(aCx, SYMBOL_TO_JSID(JS::GetWellKnownSymbol(aCx, JS::SymbolCode::iterator)));
    5671           0 :   if (!JS_DefinePropertyById(aCx, proto, iteratorId, aliasedVal, 0)) {
    5672           0 :     *protoCache = nullptr;
    5673           0 :     if (interfaceCache) {
    5674           0 :       *interfaceCache = nullptr;
    5675             :     }
    5676           0 :     return;
    5677             :   }
    5678             : }
    5679             : 
    5680             : JS::Handle<JSObject*>
    5681           0 : GetProtoObjectHandle(JSContext* aCx)
    5682             : {
    5683             :   /* Get the interface prototype object for this class.  This will create the
    5684             :      object as needed. */
    5685           0 :   bool aDefineOnGlobal = true;
    5686             : 
    5687             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    5688           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    5689           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    5690           0 :     return nullptr;
    5691             :   }
    5692             : 
    5693             :   /* Check to see whether the interface objects are already installed */
    5694           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    5695           0 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::TestInterfaceMaplike)) {
    5696           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    5697           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    5698             :   }
    5699             : 
    5700             :   /*
    5701             :    * The object might _still_ be null, but that's OK.
    5702             :    *
    5703             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    5704             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    5705             :    * changed after they have been set.
    5706             :    *
    5707             :    * Calling address() avoids the read read barrier that does gray
    5708             :    * unmarking, but it's not possible for the object to be gray here.
    5709             :    */
    5710             : 
    5711           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::TestInterfaceMaplike);
    5712           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    5713           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    5714             : }
    5715             : 
    5716             : JS::Handle<JSObject*>
    5717           0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
    5718             : {
    5719             :   /* Get the interface object for this class.  This will create the object as
    5720             :      needed. */
    5721             : 
    5722             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    5723           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    5724           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    5725           0 :     return nullptr;
    5726             :   }
    5727             : 
    5728             :   /* Check to see whether the interface objects are already installed */
    5729           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    5730           0 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::TestInterfaceMaplike)) {
    5731           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    5732           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    5733             :   }
    5734             : 
    5735             :   /*
    5736             :    * The object might _still_ be null, but that's OK.
    5737             :    *
    5738             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    5739             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    5740             :    * changed after they have been set.
    5741             :    *
    5742             :    * Calling address() avoids the read read barrier that does gray
    5743             :    * unmarking, but it's not possible for the object to be gray here.
    5744             :    */
    5745             : 
    5746           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::TestInterfaceMaplike);
    5747           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    5748           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    5749             : }
    5750             : 
    5751             : JSObject*
    5752           0 : GetConstructorObject(JSContext* aCx)
    5753             : {
    5754           0 :   return GetConstructorObjectHandle(aCx);
    5755             : }
    5756             : 
    5757             : } // namespace TestInterfaceMaplikeBinding
    5758             : 
    5759             : 
    5760             : 
    5761             : namespace TestInterfaceMaplikeObjectBinding {
    5762             : 
    5763             : namespace MaplikeHelpers {
    5764             : void
    5765           0 : Clear(mozilla::dom::TestInterfaceMaplikeObject* self, ErrorResult& aRv)
    5766             : {
    5767           0 :   MOZ_ASSERT(self);
    5768           0 :   AutoJSAPI jsapi;
    5769           0 :   jsapi.Init();
    5770           0 :   JSContext* cx = jsapi.cx();
    5771             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    5772             :   // all we want is to wrap into _some_ scope and then unwrap to find
    5773             :   // the reflector, and wrapping has no side-effects.
    5774           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    5775           0 :   JS::Rooted<JS::Value> v(cx);
    5776           0 :   if(!ToJSValue(cx, self, &v)) {
    5777           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5778           0 :     return;
    5779             :   }
    5780             :   // This is a reflector, but due to trying to name things
    5781             :   // similarly across method generators, it's called obj here.
    5782           0 :   JS::Rooted<JSObject*> obj(cx);
    5783           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    5784           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    5785             : 
    5786           0 :   JS::Rooted<JSObject*> backingObj(cx);
    5787           0 :   bool created = false;
    5788           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    5789           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5790           0 :     return;
    5791             :   }
    5792           0 :   if (created) {
    5793           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplikeObject>(self);
    5794             :   }
    5795           0 :   if (!JS::MapClear(cx, backingObj)) {
    5796           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5797           0 :     return;
    5798             :   }
    5799           0 :   return;
    5800             : }
    5801             : bool
    5802           0 : Delete(mozilla::dom::TestInterfaceMaplikeObject* self, const nsAString& aKey, ErrorResult& aRv)
    5803             : {
    5804           0 :   MOZ_ASSERT(self);
    5805           0 :   AutoJSAPI jsapi;
    5806           0 :   jsapi.Init();
    5807           0 :   JSContext* cx = jsapi.cx();
    5808             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    5809             :   // all we want is to wrap into _some_ scope and then unwrap to find
    5810             :   // the reflector, and wrapping has no side-effects.
    5811           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    5812           0 :   JS::Rooted<JS::Value> v(cx);
    5813           0 :   if(!ToJSValue(cx, self, &v)) {
    5814           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5815           0 :     return false;
    5816             :   }
    5817             :   // This is a reflector, but due to trying to name things
    5818             :   // similarly across method generators, it's called obj here.
    5819           0 :   JS::Rooted<JSObject*> obj(cx);
    5820           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    5821           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    5822             :   bool aRetVal;
    5823           0 :   JS::AutoValueVector argv(cx);
    5824           0 :   if (!argv.resize(1)) {
    5825           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    5826           0 :     return false;
    5827             :   }
    5828             :   do {
    5829           0 :     nsString mutableStr(aKey);
    5830           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    5831           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5832           0 :       return false;
    5833             :     }
    5834           0 :     break;
    5835             :   } while (0);
    5836             : 
    5837           0 :   JS::Rooted<JSObject*> backingObj(cx);
    5838           0 :   bool created = false;
    5839           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    5840           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5841           0 :     return false;
    5842             :   }
    5843           0 :   if (created) {
    5844           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplikeObject>(self);
    5845             :   }
    5846           0 :   if (!JS::MapDelete(cx, backingObj, argv[0], &aRetVal)) {
    5847           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5848           0 :     return false;
    5849             :   }
    5850           0 :   return aRetVal;
    5851             : }
    5852             : bool
    5853           0 : Has(mozilla::dom::TestInterfaceMaplikeObject* self, const nsAString& aKey, ErrorResult& aRv)
    5854             : {
    5855           0 :   MOZ_ASSERT(self);
    5856           0 :   AutoJSAPI jsapi;
    5857           0 :   jsapi.Init();
    5858           0 :   JSContext* cx = jsapi.cx();
    5859             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    5860             :   // all we want is to wrap into _some_ scope and then unwrap to find
    5861             :   // the reflector, and wrapping has no side-effects.
    5862           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    5863           0 :   JS::Rooted<JS::Value> v(cx);
    5864           0 :   if(!ToJSValue(cx, self, &v)) {
    5865           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5866           0 :     return false;
    5867             :   }
    5868             :   // This is a reflector, but due to trying to name things
    5869             :   // similarly across method generators, it's called obj here.
    5870           0 :   JS::Rooted<JSObject*> obj(cx);
    5871           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    5872           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    5873             :   bool aRetVal;
    5874           0 :   JS::AutoValueVector argv(cx);
    5875           0 :   if (!argv.resize(1)) {
    5876           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    5877           0 :     return false;
    5878             :   }
    5879             :   do {
    5880           0 :     nsString mutableStr(aKey);
    5881           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    5882           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5883           0 :       return false;
    5884             :     }
    5885           0 :     break;
    5886             :   } while (0);
    5887             : 
    5888           0 :   JS::Rooted<JSObject*> backingObj(cx);
    5889           0 :   bool created = false;
    5890           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    5891           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5892           0 :     return false;
    5893             :   }
    5894           0 :   if (created) {
    5895           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplikeObject>(self);
    5896             :   }
    5897           0 :   if (!JS::MapHas(cx, backingObj, argv[0], &aRetVal)) {
    5898           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5899           0 :     return false;
    5900             :   }
    5901           0 :   return aRetVal;
    5902             : }
    5903             : void
    5904           0 : Set(mozilla::dom::TestInterfaceMaplikeObject* self, const nsAString& aKey, TestInterfaceMaplike& aValue, ErrorResult& aRv)
    5905             : {
    5906           0 :   MOZ_ASSERT(self);
    5907           0 :   AutoJSAPI jsapi;
    5908           0 :   jsapi.Init();
    5909           0 :   JSContext* cx = jsapi.cx();
    5910             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    5911             :   // all we want is to wrap into _some_ scope and then unwrap to find
    5912             :   // the reflector, and wrapping has no side-effects.
    5913           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    5914           0 :   JS::Rooted<JS::Value> v(cx);
    5915           0 :   if(!ToJSValue(cx, self, &v)) {
    5916           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5917           0 :     return;
    5918             :   }
    5919             :   // This is a reflector, but due to trying to name things
    5920             :   // similarly across method generators, it's called obj here.
    5921           0 :   JS::Rooted<JSObject*> obj(cx);
    5922           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    5923           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    5924           0 :   JS::AutoValueVector argv(cx);
    5925           0 :   if (!argv.resize(2)) {
    5926           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    5927           0 :     return;
    5928             :   }
    5929             :   do {
    5930           0 :     if (!GetOrCreateDOMReflector(cx, aValue, argv[1])) {
    5931           0 :       MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    5932           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5933           0 :       return;
    5934             :     }
    5935           0 :     break;
    5936             :   } while (0);
    5937             : 
    5938             :   do {
    5939           0 :     nsString mutableStr(aKey);
    5940           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    5941           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5942           0 :       return;
    5943             :     }
    5944           0 :     break;
    5945             :   } while (0);
    5946             : 
    5947           0 :   JS::Rooted<JSObject*> backingObj(cx);
    5948           0 :   bool created = false;
    5949           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    5950           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5951           0 :     return;
    5952             :   }
    5953           0 :   if (created) {
    5954           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplikeObject>(self);
    5955             :   }
    5956           0 :   if (!JS::MapSet(cx, backingObj, argv[0], argv[1])) {
    5957           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5958           0 :     return;
    5959             :   }
    5960           0 :   return;
    5961             : }
    5962             : } // namespace MaplikeHelpers
    5963             : 
    5964             : static bool
    5965           0 : setInternal(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplikeObject* self, const JSJitMethodCallArgs& args)
    5966             : {
    5967           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    5968           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceMaplikeObject.setInternal");
    5969             :   }
    5970           0 :   binding_detail::FakeString arg0;
    5971           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    5972           0 :     return false;
    5973             :   }
    5974           0 :   self->SetInternal(NonNullHelper(Constify(arg0)));
    5975           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    5976           0 :   args.rval().setUndefined();
    5977           0 :   return true;
    5978             : }
    5979             : 
    5980             : static const JSJitInfo setInternal_methodinfo = {
    5981             :   { (JSJitGetterOp)setInternal },
    5982             :   { prototypes::id::TestInterfaceMaplikeObject },
    5983             :   { PrototypeTraits<prototypes::id::TestInterfaceMaplikeObject>::Depth },
    5984             :   JSJitInfo::Method,
    5985             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    5986             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    5987             :   false,  /* isInfallible. False in setters. */
    5988             :   false,  /* isMovable.  Not relevant for setters. */
    5989             :   false, /* isEliminatable.  Not relevant for setters. */
    5990             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    5991             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    5992             :   false,  /* isTypedMethod.  Only relevant for methods. */
    5993             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    5994             : };
    5995             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    5996             : static_assert(0 < 2, "There is no slot for us");
    5997             : 
    5998             : static bool
    5999           0 : clearInternal(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplikeObject* self, const JSJitMethodCallArgs& args)
    6000             : {
    6001           0 :   self->ClearInternal();
    6002           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    6003           0 :   args.rval().setUndefined();
    6004           0 :   return true;
    6005             : }
    6006             : 
    6007             : static const JSJitInfo clearInternal_methodinfo = {
    6008             :   { (JSJitGetterOp)clearInternal },
    6009             :   { prototypes::id::TestInterfaceMaplikeObject },
    6010             :   { PrototypeTraits<prototypes::id::TestInterfaceMaplikeObject>::Depth },
    6011             :   JSJitInfo::Method,
    6012             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    6013             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    6014             :   true,  /* isInfallible. False in setters. */
    6015             :   false,  /* isMovable.  Not relevant for setters. */
    6016             :   false, /* isEliminatable.  Not relevant for setters. */
    6017             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    6018             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    6019             :   false,  /* isTypedMethod.  Only relevant for methods. */
    6020             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    6021             : };
    6022             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    6023             : static_assert(0 < 2, "There is no slot for us");
    6024             : 
    6025             : static bool
    6026           0 : deleteInternal(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplikeObject* self, const JSJitMethodCallArgs& args)
    6027             : {
    6028           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    6029           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceMaplikeObject.deleteInternal");
    6030             :   }
    6031           0 :   binding_detail::FakeString arg0;
    6032           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    6033           0 :     return false;
    6034             :   }
    6035           0 :   bool result(self->DeleteInternal(NonNullHelper(Constify(arg0))));
    6036           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    6037           0 :   args.rval().setBoolean(result);
    6038           0 :   return true;
    6039             : }
    6040             : 
    6041             : static const JSJitInfo deleteInternal_methodinfo = {
    6042             :   { (JSJitGetterOp)deleteInternal },
    6043             :   { prototypes::id::TestInterfaceMaplikeObject },
    6044             :   { PrototypeTraits<prototypes::id::TestInterfaceMaplikeObject>::Depth },
    6045             :   JSJitInfo::Method,
    6046             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    6047             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    6048             :   false,  /* isInfallible. False in setters. */
    6049             :   false,  /* isMovable.  Not relevant for setters. */
    6050             :   false, /* isEliminatable.  Not relevant for setters. */
    6051             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    6052             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    6053             :   false,  /* isTypedMethod.  Only relevant for methods. */
    6054             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    6055             : };
    6056             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    6057             : static_assert(0 < 2, "There is no slot for us");
    6058             : 
    6059             : static bool
    6060           0 : hasInternal(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplikeObject* self, const JSJitMethodCallArgs& args)
    6061             : {
    6062           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    6063           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceMaplikeObject.hasInternal");
    6064             :   }
    6065           0 :   binding_detail::FakeString arg0;
    6066           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    6067           0 :     return false;
    6068             :   }
    6069           0 :   bool result(self->HasInternal(NonNullHelper(Constify(arg0))));
    6070           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    6071           0 :   args.rval().setBoolean(result);
    6072           0 :   return true;
    6073             : }
    6074             : 
    6075             : static const JSJitInfo hasInternal_methodinfo = {
    6076             :   { (JSJitGetterOp)hasInternal },
    6077             :   { prototypes::id::TestInterfaceMaplikeObject },
    6078             :   { PrototypeTraits<prototypes::id::TestInterfaceMaplikeObject>::Depth },
    6079             :   JSJitInfo::Method,
    6080             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    6081             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    6082             :   false,  /* isInfallible. False in setters. */
    6083             :   false,  /* isMovable.  Not relevant for setters. */
    6084             :   false, /* isEliminatable.  Not relevant for setters. */
    6085             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    6086             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    6087             :   false,  /* isTypedMethod.  Only relevant for methods. */
    6088             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    6089             : };
    6090             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    6091             : static_assert(0 < 2, "There is no slot for us");
    6092             : 
    6093             : static bool
    6094           0 : get_size(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplikeObject* self, JSJitGetterCallArgs args)
    6095             : {
    6096           0 :   JS::Rooted<JSObject*> backingObj(cx);
    6097           0 :   bool created = false;
    6098           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    6099           0 :     return false;
    6100             :   }
    6101           0 :   if (created) {
    6102           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplikeObject>(self);
    6103             :   }
    6104           0 :   uint32_t result = JS::MapSize(cx, backingObj);
    6105           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    6106           0 :   args.rval().setNumber(result);
    6107           0 :   return true;
    6108             : }
    6109             : 
    6110             : static const JSJitInfo size_getterinfo = {
    6111             :   { (JSJitGetterOp)get_size },
    6112             :   { prototypes::id::TestInterfaceMaplikeObject },
    6113             :   { PrototypeTraits<prototypes::id::TestInterfaceMaplikeObject>::Depth },
    6114             :   JSJitInfo::Getter,
    6115             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    6116             :   JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
    6117             :   true,  /* isInfallible. False in setters. */
    6118             :   false,  /* isMovable.  Not relevant for setters. */
    6119             :   false, /* isEliminatable.  Not relevant for setters. */
    6120             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    6121             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    6122             :   false,  /* isTypedMethod.  Only relevant for methods. */
    6123             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    6124             : };
    6125             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    6126             : static_assert(0 < 2, "There is no slot for us");
    6127             : 
    6128             : static bool
    6129           0 : entries(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplikeObject* self, const JSJitMethodCallArgs& args)
    6130             : {
    6131           0 :   JS::Rooted<JSObject*> backingObj(cx);
    6132           0 :   bool created = false;
    6133           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    6134           0 :     return false;
    6135             :   }
    6136           0 :   if (created) {
    6137           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplikeObject>(self);
    6138             :   }
    6139             :   // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
    6140             :   // after bug 1023984 is fixed.
    6141           0 :   if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    6142           0 :     JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    6143           0 :     return false;
    6144             :   }
    6145           0 :   JS::Rooted<JSObject*> result(cx);
    6146           0 :   JS::Rooted<JS::Value> v(cx);
    6147           0 :   if (!JS::MapEntries(cx, backingObj, &v)) {
    6148           0 :     return false;
    6149             :   }
    6150           0 :   result = &v.toObject();
    6151           0 :   JS::ExposeObjectToActiveJS(result);
    6152           0 :   args.rval().setObject(*result);
    6153           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    6154           0 :     return false;
    6155             :   }
    6156           0 :   return true;
    6157             : }
    6158             : 
    6159             : static const JSJitInfo::ArgType entries_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
    6160             : static const JSTypedMethodJitInfo entries_methodinfo = {
    6161             :   {
    6162             :     { (JSJitGetterOp)entries },
    6163             :     { prototypes::id::TestInterfaceMaplikeObject },
    6164             :     { PrototypeTraits<prototypes::id::TestInterfaceMaplikeObject>::Depth },
    6165             :     JSJitInfo::Method,
    6166             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    6167             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    6168             :     false,  /* isInfallible. False in setters. */
    6169             :     false,  /* isMovable.  Not relevant for setters. */
    6170             :     false, /* isEliminatable.  Not relevant for setters. */
    6171             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    6172             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    6173             :     true,  /* isTypedMethod.  Only relevant for methods. */
    6174             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    6175             :   },
    6176             :   entries_methodinfo_argTypes
    6177             : };
    6178             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    6179             : static_assert(0 < 2, "There is no slot for us");
    6180             : 
    6181             : static bool
    6182           0 : keys(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplikeObject* self, const JSJitMethodCallArgs& args)
    6183             : {
    6184           0 :   JS::Rooted<JSObject*> backingObj(cx);
    6185           0 :   bool created = false;
    6186           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    6187           0 :     return false;
    6188             :   }
    6189           0 :   if (created) {
    6190           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplikeObject>(self);
    6191             :   }
    6192             :   // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
    6193             :   // after bug 1023984 is fixed.
    6194           0 :   if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    6195           0 :     JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    6196           0 :     return false;
    6197             :   }
    6198           0 :   JS::Rooted<JSObject*> result(cx);
    6199           0 :   JS::Rooted<JS::Value> v(cx);
    6200           0 :   if (!JS::MapKeys(cx, backingObj, &v)) {
    6201           0 :     return false;
    6202             :   }
    6203           0 :   result = &v.toObject();
    6204           0 :   JS::ExposeObjectToActiveJS(result);
    6205           0 :   args.rval().setObject(*result);
    6206           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    6207           0 :     return false;
    6208             :   }
    6209           0 :   return true;
    6210             : }
    6211             : 
    6212             : static const JSJitInfo::ArgType keys_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
    6213             : static const JSTypedMethodJitInfo keys_methodinfo = {
    6214             :   {
    6215             :     { (JSJitGetterOp)keys },
    6216             :     { prototypes::id::TestInterfaceMaplikeObject },
    6217             :     { PrototypeTraits<prototypes::id::TestInterfaceMaplikeObject>::Depth },
    6218             :     JSJitInfo::Method,
    6219             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    6220             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    6221             :     false,  /* isInfallible. False in setters. */
    6222             :     false,  /* isMovable.  Not relevant for setters. */
    6223             :     false, /* isEliminatable.  Not relevant for setters. */
    6224             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    6225             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    6226             :     true,  /* isTypedMethod.  Only relevant for methods. */
    6227             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    6228             :   },
    6229             :   keys_methodinfo_argTypes
    6230             : };
    6231             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    6232             : static_assert(0 < 2, "There is no slot for us");
    6233             : 
    6234             : static bool
    6235           0 : values(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplikeObject* self, const JSJitMethodCallArgs& args)
    6236             : {
    6237           0 :   JS::Rooted<JSObject*> backingObj(cx);
    6238           0 :   bool created = false;
    6239           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    6240           0 :     return false;
    6241             :   }
    6242           0 :   if (created) {
    6243           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplikeObject>(self);
    6244             :   }
    6245             :   // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
    6246             :   // after bug 1023984 is fixed.
    6247           0 :   if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    6248           0 :     JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    6249           0 :     return false;
    6250             :   }
    6251           0 :   JS::Rooted<JSObject*> result(cx);
    6252           0 :   JS::Rooted<JS::Value> v(cx);
    6253           0 :   if (!JS::MapValues(cx, backingObj, &v)) {
    6254           0 :     return false;
    6255             :   }
    6256           0 :   result = &v.toObject();
    6257           0 :   JS::ExposeObjectToActiveJS(result);
    6258           0 :   args.rval().setObject(*result);
    6259           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    6260           0 :     return false;
    6261             :   }
    6262           0 :   return true;
    6263             : }
    6264             : 
    6265             : static const JSJitInfo::ArgType values_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
    6266             : static const JSTypedMethodJitInfo values_methodinfo = {
    6267             :   {
    6268             :     { (JSJitGetterOp)values },
    6269             :     { prototypes::id::TestInterfaceMaplikeObject },
    6270             :     { PrototypeTraits<prototypes::id::TestInterfaceMaplikeObject>::Depth },
    6271             :     JSJitInfo::Method,
    6272             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    6273             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    6274             :     false,  /* isInfallible. False in setters. */
    6275             :     false,  /* isMovable.  Not relevant for setters. */
    6276             :     false, /* isEliminatable.  Not relevant for setters. */
    6277             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    6278             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    6279             :     true,  /* isTypedMethod.  Only relevant for methods. */
    6280             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    6281             :   },
    6282             :   values_methodinfo_argTypes
    6283             : };
    6284             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    6285             : static_assert(0 < 2, "There is no slot for us");
    6286             : 
    6287             : static bool
    6288           0 : forEach(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplikeObject* self, const JSJitMethodCallArgs& args)
    6289             : {
    6290           0 :   JS::Rooted<JSObject*> arg0(cx);
    6291           0 :   if (args.get(0).isObject()) {
    6292           0 :     arg0 = &args.get(0).toObject();
    6293             :   } else {
    6294           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of TestInterfaceMaplikeObject.forEach");
    6295           0 :     return false;
    6296             :   }
    6297           0 :   JS::Rooted<JS::Value> arg1(cx);
    6298           0 :   if (args.hasDefined(1)) {
    6299           0 :     arg1 = args.get(1);
    6300             :   } else {
    6301           0 :     arg1 = JS::UndefinedValue();
    6302             :   }
    6303           0 :   JS::Rooted<JSObject*> backingObj(cx);
    6304           0 :   bool created = false;
    6305           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    6306           0 :     return false;
    6307             :   }
    6308           0 :   if (created) {
    6309           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplikeObject>(self);
    6310             :   }
    6311             :   // Create a wrapper function.
    6312           0 :   JSFunction* func = js::NewFunctionWithReserved(cx, ForEachHandler, 3, 0, nullptr);
    6313           0 :   if (!func) {
    6314           0 :     return false;
    6315             :   }
    6316           0 :   JS::Rooted<JSObject*> funcObj(cx, JS_GetFunctionObject(func));
    6317           0 :   JS::Rooted<JS::Value> funcVal(cx, JS::ObjectValue(*funcObj));
    6318           0 :   js::SetFunctionNativeReserved(funcObj, FOREACH_CALLBACK_SLOT,
    6319           0 :                                 JS::ObjectValue(*arg0));
    6320           0 :   js::SetFunctionNativeReserved(funcObj, FOREACH_MAPLIKEORSETLIKEOBJ_SLOT,
    6321           0 :                                 JS::ObjectValue(*obj));
    6322           0 :   if (!JS::MapForEach(cx, backingObj, funcVal, arg1)) {
    6323           0 :     return false;
    6324             :   }
    6325           0 :   args.rval().setUndefined();
    6326           0 :   return true;
    6327             : }
    6328             : 
    6329             : static const JSJitInfo forEach_methodinfo = {
    6330             :   { (JSJitGetterOp)forEach },
    6331             :   { prototypes::id::TestInterfaceMaplikeObject },
    6332             :   { PrototypeTraits<prototypes::id::TestInterfaceMaplikeObject>::Depth },
    6333             :   JSJitInfo::Method,
    6334             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    6335             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    6336             :   false,  /* isInfallible. False in setters. */
    6337             :   false,  /* isMovable.  Not relevant for setters. */
    6338             :   false, /* isEliminatable.  Not relevant for setters. */
    6339             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    6340             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    6341             :   false,  /* isTypedMethod.  Only relevant for methods. */
    6342             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    6343             : };
    6344             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    6345             : static_assert(0 < 2, "There is no slot for us");
    6346             : 
    6347             : static bool
    6348           0 : has(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplikeObject* self, const JSJitMethodCallArgs& args)
    6349             : {
    6350           0 :   binding_detail::FakeString arg0;
    6351           0 :   if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
    6352           0 :     return false;
    6353             :   }
    6354           0 :   JS::Rooted<JSObject*> backingObj(cx);
    6355           0 :   bool created = false;
    6356           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    6357           0 :     return false;
    6358             :   }
    6359           0 :   if (created) {
    6360           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplikeObject>(self);
    6361             :   }
    6362           0 :   JS::Rooted<JS::Value> arg0Val(cx);
    6363           0 :   if (!ToJSValue(cx, arg0, &arg0Val)) {
    6364           0 :     return false;
    6365             :   }
    6366             :   bool result;
    6367           0 :   if (!JS::MapHas(cx, backingObj, arg0Val, &result)) {
    6368           0 :     return false;
    6369             :   }
    6370           0 :   args.rval().setBoolean(result);
    6371           0 :   return true;
    6372             : }
    6373             : 
    6374             : static const JSJitInfo::ArgType has_methodinfo_argTypes[] = { JSJitInfo::String, JSJitInfo::ArgTypeListEnd };
    6375             : static const JSTypedMethodJitInfo has_methodinfo = {
    6376             :   {
    6377             :     { (JSJitGetterOp)has },
    6378             :     { prototypes::id::TestInterfaceMaplikeObject },
    6379             :     { PrototypeTraits<prototypes::id::TestInterfaceMaplikeObject>::Depth },
    6380             :     JSJitInfo::Method,
    6381             :     JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    6382             :     JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    6383             :     false,  /* isInfallible. False in setters. */
    6384             :     false,  /* isMovable.  Not relevant for setters. */
    6385             :     false, /* isEliminatable.  Not relevant for setters. */
    6386             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    6387             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    6388             :     true,  /* isTypedMethod.  Only relevant for methods. */
    6389             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    6390             :   },
    6391             :   has_methodinfo_argTypes
    6392             : };
    6393             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    6394             : static_assert(0 < 2, "There is no slot for us");
    6395             : 
    6396             : static bool
    6397           0 : get(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceMaplikeObject* self, const JSJitMethodCallArgs& args)
    6398             : {
    6399           0 :   binding_detail::FakeString arg0;
    6400           0 :   if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
    6401           0 :     return false;
    6402             :   }
    6403           0 :   JS::Rooted<JSObject*> backingObj(cx);
    6404           0 :   bool created = false;
    6405           0 :   if (!GetMaplikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    6406           0 :     return false;
    6407             :   }
    6408           0 :   if (created) {
    6409           0 :     PreserveWrapper<mozilla::dom::TestInterfaceMaplikeObject>(self);
    6410             :   }
    6411           0 :   JS::Rooted<JS::Value> arg0Val(cx);
    6412           0 :   if (!ToJSValue(cx, arg0, &arg0Val)) {
    6413           0 :     return false;
    6414             :   }
    6415           0 :   JS::Rooted<JS::Value> result(cx);
    6416           0 :   if (!JS::MapGet(cx, backingObj, arg0Val, &result)) {
    6417           0 :     return false;
    6418             :   }
    6419           0 :   JS::ExposeValueToActiveJS(result);
    6420           0 :   args.rval().set(result);
    6421           0 :   if (!MaybeWrapValue(cx, args.rval())) {
    6422           0 :     return false;
    6423             :   }
    6424           0 :   return true;
    6425             : }
    6426             : 
    6427             : static const JSJitInfo::ArgType get_methodinfo_argTypes[] = { JSJitInfo::String, JSJitInfo::ArgTypeListEnd };
    6428             : static const JSTypedMethodJitInfo get_methodinfo = {
    6429             :   {
    6430             :     { (JSJitGetterOp)get },
    6431             :     { prototypes::id::TestInterfaceMaplikeObject },
    6432             :     { PrototypeTraits<prototypes::id::TestInterfaceMaplikeObject>::Depth },
    6433             :     JSJitInfo::Method,
    6434             :     JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    6435             :     JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    6436             :     false,  /* isInfallible. False in setters. */
    6437             :     false,  /* isMovable.  Not relevant for setters. */
    6438             :     false, /* isEliminatable.  Not relevant for setters. */
    6439             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    6440             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    6441             :     true,  /* isTypedMethod.  Only relevant for methods. */
    6442             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    6443             :   },
    6444             :   get_methodinfo_argTypes
    6445             : };
    6446             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    6447             : static_assert(0 < 2, "There is no slot for us");
    6448             : 
    6449             : static bool
    6450           0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
    6451             : {
    6452           0 :   mozilla::dom::TestInterfaceMaplikeObject* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceMaplikeObject>(obj);
    6453             :   // We don't want to preserve if we don't have a wrapper, and we
    6454             :   // obviously can't preserve if we're not initialized.
    6455           0 :   if (self && self->GetWrapperPreserveColor()) {
    6456           0 :     PreserveWrapper(self);
    6457             :   }
    6458           0 :   return true;
    6459             : }
    6460             : 
    6461             : static void
    6462           0 : _finalize(js::FreeOp* fop, JSObject* obj)
    6463             : {
    6464           0 :   mozilla::dom::TestInterfaceMaplikeObject* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceMaplikeObject>(obj);
    6465           0 :   if (self) {
    6466           0 :     ClearWrapper(self, self, obj);
    6467           0 :     AddForDeferredFinalization<mozilla::dom::TestInterfaceMaplikeObject>(self);
    6468             :   }
    6469           0 : }
    6470             : 
    6471             : static void
    6472           0 : _objectMoved(JSObject* obj, const JSObject* old)
    6473             : {
    6474           0 :   mozilla::dom::TestInterfaceMaplikeObject* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceMaplikeObject>(obj);
    6475           0 :   if (self) {
    6476           0 :     UpdateWrapper(self, self, obj, old);
    6477             :   }
    6478           0 : }
    6479             : 
    6480             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    6481             : #if defined(__clang__)
    6482             : #pragma clang diagnostic push
    6483             : #pragma clang diagnostic ignored "-Wmissing-braces"
    6484             : #endif
    6485             : static const JSFunctionSpec sMethods_specs[] = {
    6486             :   JS_FNSPEC("setInternal", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&setInternal_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    6487             :   JS_FNSPEC("clearInternal", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&clearInternal_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    6488             :   JS_FNSPEC("deleteInternal", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&deleteInternal_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    6489             :   JS_FNSPEC("hasInternal", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&hasInternal_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    6490             :   JS_FNSPEC("entries", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&entries_methodinfo), 0, 0, nullptr),
    6491             :   JS_FNSPEC("keys", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&keys_methodinfo), 0, 0, nullptr),
    6492             :   JS_FNSPEC("values", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&values_methodinfo), 0, 0, nullptr),
    6493             :   JS_FNSPEC("forEach", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&forEach_methodinfo), 1, 0, nullptr),
    6494             :   JS_FNSPEC("has", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&has_methodinfo), 1, 0, nullptr),
    6495             :   JS_FNSPEC("get", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&get_methodinfo), 1, 0, nullptr),
    6496             :   JS_FS_END
    6497             : };
    6498             : #if defined(__clang__)
    6499             : #pragma clang diagnostic pop
    6500             : #endif
    6501             : 
    6502             : 
    6503             : // Can't be const because the pref-enabled boolean needs to be writable
    6504             : static Prefable<const JSFunctionSpec> sMethods[] = {
    6505             :   { nullptr, &sMethods_specs[0] },
    6506             :   { nullptr, nullptr }
    6507             : };
    6508             : 
    6509             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    6510             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    6511             : static_assert(10 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    6512             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    6513             : 
    6514             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    6515             : #if defined(__clang__)
    6516             : #pragma clang diagnostic push
    6517             : #pragma clang diagnostic ignored "-Wmissing-braces"
    6518             : #endif
    6519             : static const JSPropertySpec sAttributes_specs[] = {
    6520             :   { "size", JSPROP_SHARED, GenericBindingGetter, &size_getterinfo, nullptr, nullptr },
    6521             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
    6522             : };
    6523             : #if defined(__clang__)
    6524             : #pragma clang diagnostic pop
    6525             : #endif
    6526             : 
    6527             : 
    6528             : // Can't be const because the pref-enabled boolean needs to be writable
    6529             : static Prefable<const JSPropertySpec> sAttributes[] = {
    6530             :   { nullptr, &sAttributes_specs[0] },
    6531             :   { nullptr, nullptr }
    6532             : };
    6533             : 
    6534             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    6535             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    6536             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    6537             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    6538             : 
    6539             : 
    6540             : static uint16_t sNativeProperties_sortedPropertyIndices[11];
    6541             : static PropertyInfo sNativeProperties_propertyInfos[11];
    6542             : 
    6543             : static const NativePropertiesN<2> sNativeProperties = {
    6544             :   false, 0,
    6545             :   false, 0,
    6546             :   true,  0 /* sMethods */,
    6547             :   true,  1 /* sAttributes */,
    6548             :   false, 0,
    6549             :   false, 0,
    6550             :   false, 0,
    6551             :   4,
    6552             :   11,
    6553             :   sNativeProperties_sortedPropertyIndices,
    6554             :   {
    6555             :     { sMethods, &sNativeProperties_propertyInfos[0] },
    6556             :     { sAttributes, &sNativeProperties_propertyInfos[10] }
    6557             :   }
    6558             : };
    6559             : static_assert(4 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.iteratorAliasMethodIndex) - 1),
    6560             :     "We have an iterator alias index that is oversized");
    6561             : static_assert(11 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
    6562             :     "We have a property info count that is oversized");
    6563             : 
    6564             : static bool
    6565           0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
    6566             : {
    6567           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    6568           0 :   JS::Rooted<JSObject*> obj(cx, &args.callee());
    6569           0 :   if (!args.isConstructing()) {
    6570             :     // XXXbz wish I could get the name from the callee instead of
    6571             :     // Adding more relocations
    6572           0 :     return ThrowConstructorWithoutNew(cx, "TestInterfaceMaplikeObject");
    6573             :   }
    6574             : 
    6575           0 :   GlobalObject global(cx, obj);
    6576           0 :   if (global.Failed()) {
    6577           0 :     return false;
    6578             :   }
    6579             : 
    6580           0 :   JS::Rooted<JSObject*> desiredProto(cx);
    6581           0 :   if (!GetDesiredProto(cx, args, &desiredProto)) {
    6582           0 :     return false;
    6583             :   }
    6584             : 
    6585           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    6586           0 :   Maybe<JSAutoCompartment> ac;
    6587           0 :   if (objIsXray) {
    6588           0 :     obj = js::CheckedUnwrap(obj);
    6589           0 :     if (!obj) {
    6590           0 :       return false;
    6591             :     }
    6592           0 :     ac.emplace(cx, obj);
    6593           0 :     if (!JS_WrapObject(cx, &desiredProto)) {
    6594           0 :       return false;
    6595             :     }
    6596             :   }
    6597           0 :   binding_detail::FastErrorResult rv;
    6598           0 :   auto result(StrongOrRawPtr<mozilla::dom::TestInterfaceMaplikeObject>(mozilla::dom::TestInterfaceMaplikeObject::Constructor(global, rv)));
    6599           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    6600           0 :     return false;
    6601             :   }
    6602           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    6603             :   static_assert(!IsPointer<decltype(result)>::value,
    6604             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
    6605           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
    6606           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    6607           0 :     return false;
    6608             :   }
    6609           0 :   return true;
    6610             : }
    6611             : 
    6612             : static const js::ClassOps sInterfaceObjectClassOps = {
    6613             :     nullptr,               /* addProperty */
    6614             :     nullptr,               /* delProperty */
    6615             :     nullptr,               /* getProperty */
    6616             :     nullptr,               /* setProperty */
    6617             :     nullptr,               /* enumerate */
    6618             :     nullptr,               /* newEnumerate */
    6619             :     nullptr,               /* resolve */
    6620             :     nullptr,               /* mayResolve */
    6621             :     nullptr,               /* finalize */
    6622             :     _constructor, /* call */
    6623             :     nullptr,               /* hasInstance */
    6624             :     _constructor, /* construct */
    6625             :     nullptr,               /* trace */
    6626             : };
    6627             : 
    6628             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
    6629             :   {
    6630             :     "Function",
    6631             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
    6632             :     &sInterfaceObjectClassOps,
    6633             :     JS_NULL_CLASS_SPEC,
    6634             :     JS_NULL_CLASS_EXT,
    6635             :     &sInterfaceObjectClassObjectOps
    6636             :   },
    6637             :   eInterface,
    6638             :   true,
    6639             :   prototypes::id::TestInterfaceMaplikeObject,
    6640             :   PrototypeTraits<prototypes::id::TestInterfaceMaplikeObject>::Depth,
    6641             :   sNativePropertyHooks,
    6642             :   "function TestInterfaceMaplikeObject() {\n    [native code]\n}",
    6643             :   JS::GetRealmFunctionPrototype
    6644             : };
    6645             : 
    6646             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
    6647             :   {
    6648             :     "TestInterfaceMaplikeObjectPrototype",
    6649             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    6650             :     JS_NULL_CLASS_OPS,
    6651             :     JS_NULL_CLASS_SPEC,
    6652             :     JS_NULL_CLASS_EXT,
    6653             :     JS_NULL_OBJECT_OPS
    6654             :   },
    6655             :   eInterfacePrototype,
    6656             :   false,
    6657             :   prototypes::id::TestInterfaceMaplikeObject,
    6658             :   PrototypeTraits<prototypes::id::TestInterfaceMaplikeObject>::Depth,
    6659             :   sNativePropertyHooks,
    6660             :   "[object TestInterfaceMaplikeObjectPrototype]",
    6661             :   JS::GetRealmObjectPrototype
    6662             : };
    6663             : 
    6664             : bool
    6665           0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
    6666             : {
    6667             :   static bool sPrefValue;
    6668             :   static bool sPrefCacheSetUp = false;
    6669           0 :   if (!sPrefCacheSetUp) {
    6670           0 :     sPrefCacheSetUp = true;
    6671           0 :     Preferences::AddBoolVarCache(&sPrefValue, "dom.expose_test_interfaces");
    6672             :   }
    6673             : 
    6674           0 :   return sPrefValue;
    6675             : }
    6676             : 
    6677             : JSObject*
    6678           0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
    6679             : {
    6680           0 :   return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
    6681             : }
    6682             : 
    6683             : static const js::ClassOps sClassOps = {
    6684             :   _addProperty, /* addProperty */
    6685             :   nullptr,               /* delProperty */
    6686             :   nullptr,               /* getProperty */
    6687             :   nullptr,               /* setProperty */
    6688             :   nullptr,               /* enumerate */
    6689             :   nullptr, /* newEnumerate */
    6690             :   nullptr, /* resolve */
    6691             :   nullptr, /* mayResolve */
    6692             :   _finalize, /* finalize */
    6693             :   nullptr, /* call */
    6694             :   nullptr,               /* hasInstance */
    6695             :   nullptr,               /* construct */
    6696             :   nullptr, /* trace */
    6697             : };
    6698             : 
    6699             : static const js::ClassExtension sClassExtension = {
    6700             :   nullptr, /* weakmapKeyDelegateOp */
    6701             :   _objectMoved /* objectMovedOp */
    6702             : };
    6703             : 
    6704             : static const DOMJSClass sClass = {
    6705             :   { "TestInterfaceMaplikeObject",
    6706             :     JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2),
    6707             :     &sClassOps,
    6708             :     JS_NULL_CLASS_SPEC,
    6709             :     &sClassExtension,
    6710             :     JS_NULL_OBJECT_OPS
    6711             :   },
    6712             :   { prototypes::id::TestInterfaceMaplikeObject, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
    6713             :   IsBaseOf<nsISupports, mozilla::dom::TestInterfaceMaplikeObject >::value,
    6714             :   sNativePropertyHooks,
    6715             :   FindAssociatedGlobalForNative<mozilla::dom::TestInterfaceMaplikeObject>::Get,
    6716             :   GetProtoObjectHandle,
    6717             :   GetCCParticipant<mozilla::dom::TestInterfaceMaplikeObject>::Get()
    6718             : };
    6719             : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
    6720             :               "Must have the right minimal number of reserved slots.");
    6721             : static_assert(2 >= 2,
    6722             :               "Must have enough reserved slots.");
    6723             : 
    6724             : const JSClass*
    6725           0 : GetJSClass()
    6726             : {
    6727           0 :   return sClass.ToJSClass();
    6728             : }
    6729             : 
    6730             : bool
    6731           0 : Wrap(JSContext* aCx, mozilla::dom::TestInterfaceMaplikeObject* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
    6732             : {
    6733             :   MOZ_ASSERT(static_cast<mozilla::dom::TestInterfaceMaplikeObject*>(aObject) ==
    6734             :              reinterpret_cast<mozilla::dom::TestInterfaceMaplikeObject*>(aObject),
    6735             :              "Multiple inheritance for mozilla::dom::TestInterfaceMaplikeObject is broken.");
    6736           0 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
    6737           0 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
    6738           0 :   MOZ_ASSERT(!aCache->GetWrapper(),
    6739             :              "You should probably not be using Wrap() directly; use "
    6740             :              "GetOrCreateDOMReflector instead");
    6741             : 
    6742           0 :   MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
    6743             :              "nsISupports must be on our primary inheritance chain");
    6744             : 
    6745           0 :   JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
    6746           0 :   if (!global) {
    6747           0 :     return false;
    6748             :   }
    6749           0 :   MOZ_ASSERT(JS_IsGlobalObject(global));
    6750           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(global));
    6751             : 
    6752             :   // That might have ended up wrapping us already, due to the wonders
    6753             :   // of XBL.  Check for that, and bail out as needed.
    6754           0 :   aReflector.set(aCache->GetWrapper());
    6755           0 :   if (aReflector) {
    6756             : #ifdef DEBUG
    6757           0 :     binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
    6758             : #endif // DEBUG
    6759           0 :     return true;
    6760             :   }
    6761             : 
    6762           0 :   JSAutoCompartment ac(aCx, global);
    6763           0 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
    6764           0 :   if (!canonicalProto) {
    6765           0 :     return false;
    6766             :   }
    6767           0 :   JS::Rooted<JSObject*> proto(aCx);
    6768           0 :   if (aGivenProto) {
    6769           0 :     proto = aGivenProto;
    6770             :     // Unfortunately, while aGivenProto was in the compartment of aCx
    6771             :     // coming in, we changed compartments to that of "parent" so may need
    6772             :     // to wrap the proto here.
    6773           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
    6774           0 :       if (!JS_WrapObject(aCx, &proto)) {
    6775           0 :         return false;
    6776             :       }
    6777             :     }
    6778             :   } else {
    6779           0 :     proto = canonicalProto;
    6780             :   }
    6781             : 
    6782           0 :   BindingJSObjectCreator<mozilla::dom::TestInterfaceMaplikeObject> creator(aCx);
    6783           0 :   creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
    6784           0 :   if (!aReflector) {
    6785           0 :     return false;
    6786             :   }
    6787             : 
    6788           0 :   aCache->SetWrapper(aReflector);
    6789           0 :   creator.InitializationSucceeded();
    6790             : 
    6791           0 :   MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
    6792             :              aCache->GetWrapperPreserveColor() == aReflector);
    6793             :   // If proto != canonicalProto, we have to preserve our wrapper;
    6794             :   // otherwise we won't be able to properly recreate it later, since
    6795             :   // we won't know what proto to use.  Note that we don't check
    6796             :   // aGivenProto here, since it's entirely possible (and even
    6797             :   // somewhat common) to have a non-null aGivenProto which is the
    6798             :   // same as canonicalProto.
    6799           0 :   if (proto != canonicalProto) {
    6800           0 :     PreserveWrapper(aObject);
    6801             :   }
    6802             : 
    6803           0 :   return true;
    6804             : }
    6805             : 
    6806             : // This may allocate too many slots, because we only really need
    6807             : // slots for our non-interface-typed members that we cache.  But
    6808             : // allocating slots only for those would make the slot index
    6809             : // computations much more complicated, so let's do this the simple
    6810             : // way for now.
    6811             : DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 1);
    6812             : 
    6813             : const NativePropertyHooks sNativePropertyHooks[] = { {
    6814             :   nullptr,
    6815             :   nullptr,
    6816             :   nullptr,
    6817             :   { sNativeProperties.Upcast(), nullptr },
    6818             :   prototypes::id::TestInterfaceMaplikeObject,
    6819             :   constructors::id::TestInterfaceMaplikeObject,
    6820             :   nullptr,
    6821             :   &sXrayExpandoObjectClass
    6822             : } };
    6823             : 
    6824             : void
    6825           0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    6826             : {
    6827           0 :   JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
    6828           0 :   if (!parentProto) {
    6829           0 :     return;
    6830             :   }
    6831             : 
    6832           0 :   JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
    6833           0 :   if (!constructorProto) {
    6834           0 :     return;
    6835             :   }
    6836             : 
    6837             :   static bool sIdsInited = false;
    6838           0 :   if (!sIdsInited && NS_IsMainThread()) {
    6839           0 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
    6840           0 :       return;
    6841             :     }
    6842           0 :     sIdsInited = true;
    6843             :   }
    6844             : 
    6845           0 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::TestInterfaceMaplikeObject);
    6846           0 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::TestInterfaceMaplikeObject);
    6847           0 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    6848             :                               &sPrototypeClass.mBase, protoCache,
    6849             :                               constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
    6850             :                               interfaceCache,
    6851             :                               sNativeProperties.Upcast(),
    6852             :                               nullptr,
    6853             :                               "TestInterfaceMaplikeObject", aDefineOnGlobal,
    6854             :                               nullptr,
    6855           0 :                               false);
    6856             : 
    6857             :   // Set up aliases on the interface prototype object we just created.
    6858           0 :   JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx);
    6859           0 :   if (!proto) {
    6860           0 :     *protoCache = nullptr;
    6861           0 :     if (interfaceCache) {
    6862           0 :       *interfaceCache = nullptr;
    6863             :     }
    6864           0 :     return;
    6865             :   }
    6866             : 
    6867           0 :   JS::Rooted<JS::Value> aliasedVal(aCx);
    6868             : 
    6869           0 :   if (!JS_GetProperty(aCx, proto, "entries", &aliasedVal)) {
    6870           0 :     *protoCache = nullptr;
    6871           0 :     if (interfaceCache) {
    6872           0 :       *interfaceCache = nullptr;
    6873             :     }
    6874           0 :     return;
    6875             :   }
    6876           0 :   JS::Rooted<jsid> iteratorId(aCx, SYMBOL_TO_JSID(JS::GetWellKnownSymbol(aCx, JS::SymbolCode::iterator)));
    6877           0 :   if (!JS_DefinePropertyById(aCx, proto, iteratorId, aliasedVal, 0)) {
    6878           0 :     *protoCache = nullptr;
    6879           0 :     if (interfaceCache) {
    6880           0 :       *interfaceCache = nullptr;
    6881             :     }
    6882           0 :     return;
    6883             :   }
    6884             : }
    6885             : 
    6886             : JS::Handle<JSObject*>
    6887           0 : GetProtoObjectHandle(JSContext* aCx)
    6888             : {
    6889             :   /* Get the interface prototype object for this class.  This will create the
    6890             :      object as needed. */
    6891           0 :   bool aDefineOnGlobal = true;
    6892             : 
    6893             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    6894           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    6895           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    6896           0 :     return nullptr;
    6897             :   }
    6898             : 
    6899             :   /* Check to see whether the interface objects are already installed */
    6900           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    6901           0 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::TestInterfaceMaplikeObject)) {
    6902           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    6903           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    6904             :   }
    6905             : 
    6906             :   /*
    6907             :    * The object might _still_ be null, but that's OK.
    6908             :    *
    6909             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    6910             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    6911             :    * changed after they have been set.
    6912             :    *
    6913             :    * Calling address() avoids the read read barrier that does gray
    6914             :    * unmarking, but it's not possible for the object to be gray here.
    6915             :    */
    6916             : 
    6917           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::TestInterfaceMaplikeObject);
    6918           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    6919           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    6920             : }
    6921             : 
    6922             : JS::Handle<JSObject*>
    6923           0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
    6924             : {
    6925             :   /* Get the interface object for this class.  This will create the object as
    6926             :      needed. */
    6927             : 
    6928             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    6929           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    6930           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    6931           0 :     return nullptr;
    6932             :   }
    6933             : 
    6934             :   /* Check to see whether the interface objects are already installed */
    6935           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    6936           0 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::TestInterfaceMaplikeObject)) {
    6937           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    6938           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    6939             :   }
    6940             : 
    6941             :   /*
    6942             :    * The object might _still_ be null, but that's OK.
    6943             :    *
    6944             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    6945             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    6946             :    * changed after they have been set.
    6947             :    *
    6948             :    * Calling address() avoids the read read barrier that does gray
    6949             :    * unmarking, but it's not possible for the object to be gray here.
    6950             :    */
    6951             : 
    6952           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::TestInterfaceMaplikeObject);
    6953           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    6954           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    6955             : }
    6956             : 
    6957             : JSObject*
    6958           0 : GetConstructorObject(JSContext* aCx)
    6959             : {
    6960           0 :   return GetConstructorObjectHandle(aCx);
    6961             : }
    6962             : 
    6963             : } // namespace TestInterfaceMaplikeObjectBinding
    6964             : 
    6965             : 
    6966             : 
    6967             : namespace TestInterfaceSetlikeBinding {
    6968             : 
    6969             : namespace SetlikeHelpers {
    6970             : void
    6971           0 : Clear(mozilla::dom::TestInterfaceSetlike* self, ErrorResult& aRv)
    6972             : {
    6973           0 :   MOZ_ASSERT(self);
    6974           0 :   AutoJSAPI jsapi;
    6975           0 :   jsapi.Init();
    6976           0 :   JSContext* cx = jsapi.cx();
    6977             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    6978             :   // all we want is to wrap into _some_ scope and then unwrap to find
    6979             :   // the reflector, and wrapping has no side-effects.
    6980           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    6981           0 :   JS::Rooted<JS::Value> v(cx);
    6982           0 :   if(!ToJSValue(cx, self, &v)) {
    6983           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6984           0 :     return;
    6985             :   }
    6986             :   // This is a reflector, but due to trying to name things
    6987             :   // similarly across method generators, it's called obj here.
    6988           0 :   JS::Rooted<JSObject*> obj(cx);
    6989           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    6990           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    6991             : 
    6992           0 :   JS::Rooted<JSObject*> backingObj(cx);
    6993           0 :   bool created = false;
    6994           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    6995           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6996           0 :     return;
    6997             :   }
    6998           0 :   if (created) {
    6999           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlike>(self);
    7000             :   }
    7001           0 :   if (!JS::SetClear(cx, backingObj)) {
    7002           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7003           0 :     return;
    7004             :   }
    7005           0 :   return;
    7006             : }
    7007             : bool
    7008           0 : Delete(mozilla::dom::TestInterfaceSetlike* self, const nsAString& aKey, ErrorResult& aRv)
    7009             : {
    7010           0 :   MOZ_ASSERT(self);
    7011           0 :   AutoJSAPI jsapi;
    7012           0 :   jsapi.Init();
    7013           0 :   JSContext* cx = jsapi.cx();
    7014             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    7015             :   // all we want is to wrap into _some_ scope and then unwrap to find
    7016             :   // the reflector, and wrapping has no side-effects.
    7017           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    7018           0 :   JS::Rooted<JS::Value> v(cx);
    7019           0 :   if(!ToJSValue(cx, self, &v)) {
    7020           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7021           0 :     return false;
    7022             :   }
    7023             :   // This is a reflector, but due to trying to name things
    7024             :   // similarly across method generators, it's called obj here.
    7025           0 :   JS::Rooted<JSObject*> obj(cx);
    7026           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    7027           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    7028             :   bool aRetVal;
    7029           0 :   JS::AutoValueVector argv(cx);
    7030           0 :   if (!argv.resize(1)) {
    7031           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    7032           0 :     return false;
    7033             :   }
    7034             :   do {
    7035           0 :     nsString mutableStr(aKey);
    7036           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    7037           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    7038           0 :       return false;
    7039             :     }
    7040           0 :     break;
    7041             :   } while (0);
    7042             : 
    7043           0 :   JS::Rooted<JSObject*> backingObj(cx);
    7044           0 :   bool created = false;
    7045           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    7046           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7047           0 :     return false;
    7048             :   }
    7049           0 :   if (created) {
    7050           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlike>(self);
    7051             :   }
    7052           0 :   if (!JS::SetDelete(cx, backingObj, argv[0], &aRetVal)) {
    7053           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7054           0 :     return false;
    7055             :   }
    7056           0 :   return aRetVal;
    7057             : }
    7058             : bool
    7059           0 : Has(mozilla::dom::TestInterfaceSetlike* self, const nsAString& aKey, ErrorResult& aRv)
    7060             : {
    7061           0 :   MOZ_ASSERT(self);
    7062           0 :   AutoJSAPI jsapi;
    7063           0 :   jsapi.Init();
    7064           0 :   JSContext* cx = jsapi.cx();
    7065             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    7066             :   // all we want is to wrap into _some_ scope and then unwrap to find
    7067             :   // the reflector, and wrapping has no side-effects.
    7068           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    7069           0 :   JS::Rooted<JS::Value> v(cx);
    7070           0 :   if(!ToJSValue(cx, self, &v)) {
    7071           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7072           0 :     return false;
    7073             :   }
    7074             :   // This is a reflector, but due to trying to name things
    7075             :   // similarly across method generators, it's called obj here.
    7076           0 :   JS::Rooted<JSObject*> obj(cx);
    7077           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    7078           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    7079             :   bool aRetVal;
    7080           0 :   JS::AutoValueVector argv(cx);
    7081           0 :   if (!argv.resize(1)) {
    7082           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    7083           0 :     return false;
    7084             :   }
    7085             :   do {
    7086           0 :     nsString mutableStr(aKey);
    7087           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    7088           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    7089           0 :       return false;
    7090             :     }
    7091           0 :     break;
    7092             :   } while (0);
    7093             : 
    7094           0 :   JS::Rooted<JSObject*> backingObj(cx);
    7095           0 :   bool created = false;
    7096           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    7097           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7098           0 :     return false;
    7099             :   }
    7100           0 :   if (created) {
    7101           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlike>(self);
    7102             :   }
    7103           0 :   if (!JS::SetHas(cx, backingObj, argv[0], &aRetVal)) {
    7104           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7105           0 :     return false;
    7106             :   }
    7107           0 :   return aRetVal;
    7108             : }
    7109             : void
    7110           0 : Add(mozilla::dom::TestInterfaceSetlike* self, const nsAString& aKey, ErrorResult& aRv)
    7111             : {
    7112           0 :   MOZ_ASSERT(self);
    7113           0 :   AutoJSAPI jsapi;
    7114           0 :   jsapi.Init();
    7115           0 :   JSContext* cx = jsapi.cx();
    7116             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    7117             :   // all we want is to wrap into _some_ scope and then unwrap to find
    7118             :   // the reflector, and wrapping has no side-effects.
    7119           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    7120           0 :   JS::Rooted<JS::Value> v(cx);
    7121           0 :   if(!ToJSValue(cx, self, &v)) {
    7122           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7123           0 :     return;
    7124             :   }
    7125             :   // This is a reflector, but due to trying to name things
    7126             :   // similarly across method generators, it's called obj here.
    7127           0 :   JS::Rooted<JSObject*> obj(cx);
    7128           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    7129           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    7130           0 :   JS::AutoValueVector argv(cx);
    7131           0 :   if (!argv.resize(1)) {
    7132           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    7133           0 :     return;
    7134             :   }
    7135             :   do {
    7136           0 :     nsString mutableStr(aKey);
    7137           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    7138           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    7139           0 :       return;
    7140             :     }
    7141           0 :     break;
    7142             :   } while (0);
    7143             : 
    7144           0 :   JS::Rooted<JSObject*> backingObj(cx);
    7145           0 :   bool created = false;
    7146           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    7147           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7148           0 :     return;
    7149             :   }
    7150           0 :   if (created) {
    7151           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlike>(self);
    7152             :   }
    7153           0 :   if (!JS::SetAdd(cx, backingObj, argv[0])) {
    7154           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7155           0 :     return;
    7156             :   }
    7157           0 :   return;
    7158             : }
    7159             : } // namespace SetlikeHelpers
    7160             : 
    7161             : static bool
    7162           0 : get_size(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceSetlike* self, JSJitGetterCallArgs args)
    7163             : {
    7164           0 :   JS::Rooted<JSObject*> backingObj(cx);
    7165           0 :   bool created = false;
    7166           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    7167           0 :     return false;
    7168             :   }
    7169           0 :   if (created) {
    7170           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlike>(self);
    7171             :   }
    7172           0 :   uint32_t result = JS::SetSize(cx, backingObj);
    7173           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    7174           0 :   args.rval().setNumber(result);
    7175           0 :   return true;
    7176             : }
    7177             : 
    7178             : static const JSJitInfo size_getterinfo = {
    7179             :   { (JSJitGetterOp)get_size },
    7180             :   { prototypes::id::TestInterfaceSetlike },
    7181             :   { PrototypeTraits<prototypes::id::TestInterfaceSetlike>::Depth },
    7182             :   JSJitInfo::Getter,
    7183             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    7184             :   JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
    7185             :   true,  /* isInfallible. False in setters. */
    7186             :   false,  /* isMovable.  Not relevant for setters. */
    7187             :   false, /* isEliminatable.  Not relevant for setters. */
    7188             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    7189             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    7190             :   false,  /* isTypedMethod.  Only relevant for methods. */
    7191             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    7192             : };
    7193             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    7194             : static_assert(0 < 2, "There is no slot for us");
    7195             : 
    7196             : static bool
    7197           0 : entries(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceSetlike* self, const JSJitMethodCallArgs& args)
    7198             : {
    7199           0 :   JS::Rooted<JSObject*> backingObj(cx);
    7200           0 :   bool created = false;
    7201           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    7202           0 :     return false;
    7203             :   }
    7204           0 :   if (created) {
    7205           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlike>(self);
    7206             :   }
    7207             :   // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
    7208             :   // after bug 1023984 is fixed.
    7209           0 :   if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    7210           0 :     JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    7211           0 :     return false;
    7212             :   }
    7213           0 :   JS::Rooted<JSObject*> result(cx);
    7214           0 :   JS::Rooted<JS::Value> v(cx);
    7215           0 :   if (!JS::SetEntries(cx, backingObj, &v)) {
    7216           0 :     return false;
    7217             :   }
    7218           0 :   result = &v.toObject();
    7219           0 :   JS::ExposeObjectToActiveJS(result);
    7220           0 :   args.rval().setObject(*result);
    7221           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    7222           0 :     return false;
    7223             :   }
    7224           0 :   return true;
    7225             : }
    7226             : 
    7227             : static const JSJitInfo::ArgType entries_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
    7228             : static const JSTypedMethodJitInfo entries_methodinfo = {
    7229             :   {
    7230             :     { (JSJitGetterOp)entries },
    7231             :     { prototypes::id::TestInterfaceSetlike },
    7232             :     { PrototypeTraits<prototypes::id::TestInterfaceSetlike>::Depth },
    7233             :     JSJitInfo::Method,
    7234             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    7235             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    7236             :     false,  /* isInfallible. False in setters. */
    7237             :     false,  /* isMovable.  Not relevant for setters. */
    7238             :     false, /* isEliminatable.  Not relevant for setters. */
    7239             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    7240             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    7241             :     true,  /* isTypedMethod.  Only relevant for methods. */
    7242             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    7243             :   },
    7244             :   entries_methodinfo_argTypes
    7245             : };
    7246             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    7247             : static_assert(0 < 2, "There is no slot for us");
    7248             : 
    7249             : static bool
    7250           0 : keys(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceSetlike* self, const JSJitMethodCallArgs& args)
    7251             : {
    7252           0 :   JS::Rooted<JSObject*> backingObj(cx);
    7253           0 :   bool created = false;
    7254           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    7255           0 :     return false;
    7256             :   }
    7257           0 :   if (created) {
    7258           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlike>(self);
    7259             :   }
    7260             :   // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
    7261             :   // after bug 1023984 is fixed.
    7262           0 :   if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    7263           0 :     JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    7264           0 :     return false;
    7265             :   }
    7266           0 :   JS::Rooted<JSObject*> result(cx);
    7267           0 :   JS::Rooted<JS::Value> v(cx);
    7268           0 :   if (!JS::SetKeys(cx, backingObj, &v)) {
    7269           0 :     return false;
    7270             :   }
    7271           0 :   result = &v.toObject();
    7272           0 :   JS::ExposeObjectToActiveJS(result);
    7273           0 :   args.rval().setObject(*result);
    7274           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    7275           0 :     return false;
    7276             :   }
    7277           0 :   return true;
    7278             : }
    7279             : 
    7280             : static const JSJitInfo::ArgType keys_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
    7281             : static const JSTypedMethodJitInfo keys_methodinfo = {
    7282             :   {
    7283             :     { (JSJitGetterOp)keys },
    7284             :     { prototypes::id::TestInterfaceSetlike },
    7285             :     { PrototypeTraits<prototypes::id::TestInterfaceSetlike>::Depth },
    7286             :     JSJitInfo::Method,
    7287             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    7288             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    7289             :     false,  /* isInfallible. False in setters. */
    7290             :     false,  /* isMovable.  Not relevant for setters. */
    7291             :     false, /* isEliminatable.  Not relevant for setters. */
    7292             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    7293             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    7294             :     true,  /* isTypedMethod.  Only relevant for methods. */
    7295             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    7296             :   },
    7297             :   keys_methodinfo_argTypes
    7298             : };
    7299             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    7300             : static_assert(0 < 2, "There is no slot for us");
    7301             : 
    7302             : static bool
    7303           0 : values(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceSetlike* self, const JSJitMethodCallArgs& args)
    7304             : {
    7305           0 :   JS::Rooted<JSObject*> backingObj(cx);
    7306           0 :   bool created = false;
    7307           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    7308           0 :     return false;
    7309             :   }
    7310           0 :   if (created) {
    7311           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlike>(self);
    7312             :   }
    7313             :   // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
    7314             :   // after bug 1023984 is fixed.
    7315           0 :   if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    7316           0 :     JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    7317           0 :     return false;
    7318             :   }
    7319           0 :   JS::Rooted<JSObject*> result(cx);
    7320           0 :   JS::Rooted<JS::Value> v(cx);
    7321           0 :   if (!JS::SetValues(cx, backingObj, &v)) {
    7322           0 :     return false;
    7323             :   }
    7324           0 :   result = &v.toObject();
    7325           0 :   JS::ExposeObjectToActiveJS(result);
    7326           0 :   args.rval().setObject(*result);
    7327           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    7328           0 :     return false;
    7329             :   }
    7330           0 :   return true;
    7331             : }
    7332             : 
    7333             : static const JSJitInfo::ArgType values_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
    7334             : static const JSTypedMethodJitInfo values_methodinfo = {
    7335             :   {
    7336             :     { (JSJitGetterOp)values },
    7337             :     { prototypes::id::TestInterfaceSetlike },
    7338             :     { PrototypeTraits<prototypes::id::TestInterfaceSetlike>::Depth },
    7339             :     JSJitInfo::Method,
    7340             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    7341             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    7342             :     false,  /* isInfallible. False in setters. */
    7343             :     false,  /* isMovable.  Not relevant for setters. */
    7344             :     false, /* isEliminatable.  Not relevant for setters. */
    7345             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    7346             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    7347             :     true,  /* isTypedMethod.  Only relevant for methods. */
    7348             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    7349             :   },
    7350             :   values_methodinfo_argTypes
    7351             : };
    7352             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    7353             : static_assert(0 < 2, "There is no slot for us");
    7354             : 
    7355             : static bool
    7356           0 : forEach(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceSetlike* self, const JSJitMethodCallArgs& args)
    7357             : {
    7358           0 :   JS::Rooted<JSObject*> arg0(cx);
    7359           0 :   if (args.get(0).isObject()) {
    7360           0 :     arg0 = &args.get(0).toObject();
    7361             :   } else {
    7362           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of TestInterfaceSetlike.forEach");
    7363           0 :     return false;
    7364             :   }
    7365           0 :   JS::Rooted<JS::Value> arg1(cx);
    7366           0 :   if (args.hasDefined(1)) {
    7367           0 :     arg1 = args.get(1);
    7368             :   } else {
    7369           0 :     arg1 = JS::UndefinedValue();
    7370             :   }
    7371           0 :   JS::Rooted<JSObject*> backingObj(cx);
    7372           0 :   bool created = false;
    7373           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    7374           0 :     return false;
    7375             :   }
    7376           0 :   if (created) {
    7377           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlike>(self);
    7378             :   }
    7379             :   // Create a wrapper function.
    7380           0 :   JSFunction* func = js::NewFunctionWithReserved(cx, ForEachHandler, 3, 0, nullptr);
    7381           0 :   if (!func) {
    7382           0 :     return false;
    7383             :   }
    7384           0 :   JS::Rooted<JSObject*> funcObj(cx, JS_GetFunctionObject(func));
    7385           0 :   JS::Rooted<JS::Value> funcVal(cx, JS::ObjectValue(*funcObj));
    7386           0 :   js::SetFunctionNativeReserved(funcObj, FOREACH_CALLBACK_SLOT,
    7387           0 :                                 JS::ObjectValue(*arg0));
    7388           0 :   js::SetFunctionNativeReserved(funcObj, FOREACH_MAPLIKEORSETLIKEOBJ_SLOT,
    7389           0 :                                 JS::ObjectValue(*obj));
    7390           0 :   if (!JS::SetForEach(cx, backingObj, funcVal, arg1)) {
    7391           0 :     return false;
    7392             :   }
    7393           0 :   args.rval().setUndefined();
    7394           0 :   return true;
    7395             : }
    7396             : 
    7397             : static const JSJitInfo forEach_methodinfo = {
    7398             :   { (JSJitGetterOp)forEach },
    7399             :   { prototypes::id::TestInterfaceSetlike },
    7400             :   { PrototypeTraits<prototypes::id::TestInterfaceSetlike>::Depth },
    7401             :   JSJitInfo::Method,
    7402             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    7403             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    7404             :   false,  /* isInfallible. False in setters. */
    7405             :   false,  /* isMovable.  Not relevant for setters. */
    7406             :   false, /* isEliminatable.  Not relevant for setters. */
    7407             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    7408             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    7409             :   false,  /* isTypedMethod.  Only relevant for methods. */
    7410             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    7411             : };
    7412             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    7413             : static_assert(0 < 2, "There is no slot for us");
    7414             : 
    7415             : static bool
    7416           0 : has(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceSetlike* self, const JSJitMethodCallArgs& args)
    7417             : {
    7418           0 :   binding_detail::FakeString arg0;
    7419           0 :   if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
    7420           0 :     return false;
    7421             :   }
    7422           0 :   JS::Rooted<JSObject*> backingObj(cx);
    7423           0 :   bool created = false;
    7424           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    7425           0 :     return false;
    7426             :   }
    7427           0 :   if (created) {
    7428           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlike>(self);
    7429             :   }
    7430           0 :   JS::Rooted<JS::Value> arg0Val(cx);
    7431           0 :   if (!ToJSValue(cx, arg0, &arg0Val)) {
    7432           0 :     return false;
    7433             :   }
    7434             :   bool result;
    7435           0 :   if (!JS::SetHas(cx, backingObj, arg0Val, &result)) {
    7436           0 :     return false;
    7437             :   }
    7438           0 :   args.rval().setBoolean(result);
    7439           0 :   return true;
    7440             : }
    7441             : 
    7442             : static const JSJitInfo::ArgType has_methodinfo_argTypes[] = { JSJitInfo::String, JSJitInfo::ArgTypeListEnd };
    7443             : static const JSTypedMethodJitInfo has_methodinfo = {
    7444             :   {
    7445             :     { (JSJitGetterOp)has },
    7446             :     { prototypes::id::TestInterfaceSetlike },
    7447             :     { PrototypeTraits<prototypes::id::TestInterfaceSetlike>::Depth },
    7448             :     JSJitInfo::Method,
    7449             :     JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    7450             :     JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    7451             :     false,  /* isInfallible. False in setters. */
    7452             :     false,  /* isMovable.  Not relevant for setters. */
    7453             :     false, /* isEliminatable.  Not relevant for setters. */
    7454             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    7455             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    7456             :     true,  /* isTypedMethod.  Only relevant for methods. */
    7457             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    7458             :   },
    7459             :   has_methodinfo_argTypes
    7460             : };
    7461             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    7462             : static_assert(0 < 2, "There is no slot for us");
    7463             : 
    7464             : static bool
    7465           0 : clear(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceSetlike* self, const JSJitMethodCallArgs& args)
    7466             : {
    7467           0 :   JS::Rooted<JSObject*> backingObj(cx);
    7468           0 :   bool created = false;
    7469           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    7470           0 :     return false;
    7471             :   }
    7472           0 :   if (created) {
    7473           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlike>(self);
    7474             :   }
    7475           0 :   if (!JS::SetClear(cx, backingObj)) {
    7476           0 :     return false;
    7477             :   }
    7478           0 :   args.rval().setUndefined();
    7479           0 :   return true;
    7480             : }
    7481             : 
    7482             : static const JSJitInfo clear_methodinfo = {
    7483             :   { (JSJitGetterOp)clear },
    7484             :   { prototypes::id::TestInterfaceSetlike },
    7485             :   { PrototypeTraits<prototypes::id::TestInterfaceSetlike>::Depth },
    7486             :   JSJitInfo::Method,
    7487             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    7488             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    7489             :   false,  /* isInfallible. False in setters. */
    7490             :   false,  /* isMovable.  Not relevant for setters. */
    7491             :   false, /* isEliminatable.  Not relevant for setters. */
    7492             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    7493             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    7494             :   false,  /* isTypedMethod.  Only relevant for methods. */
    7495             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    7496             : };
    7497             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    7498             : static_assert(0 < 2, "There is no slot for us");
    7499             : 
    7500             : static bool
    7501           0 : _delete_(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceSetlike* self, const JSJitMethodCallArgs& args)
    7502             : {
    7503           0 :   binding_detail::FakeString arg0;
    7504           0 :   if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
    7505           0 :     return false;
    7506             :   }
    7507           0 :   JS::Rooted<JSObject*> backingObj(cx);
    7508           0 :   bool created = false;
    7509           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    7510           0 :     return false;
    7511             :   }
    7512           0 :   if (created) {
    7513           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlike>(self);
    7514             :   }
    7515           0 :   JS::Rooted<JS::Value> arg0Val(cx);
    7516           0 :   if (!ToJSValue(cx, arg0, &arg0Val)) {
    7517           0 :     return false;
    7518             :   }
    7519             :   bool result;
    7520           0 :   if (!JS::SetDelete(cx, backingObj, arg0Val, &result)) {
    7521           0 :     return false;
    7522             :   }
    7523           0 :   args.rval().setBoolean(result);
    7524           0 :   return true;
    7525             : }
    7526             : 
    7527             : static const JSJitInfo delete_methodinfo = {
    7528             :   { (JSJitGetterOp)_delete_ },
    7529             :   { prototypes::id::TestInterfaceSetlike },
    7530             :   { PrototypeTraits<prototypes::id::TestInterfaceSetlike>::Depth },
    7531             :   JSJitInfo::Method,
    7532             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    7533             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    7534             :   false,  /* isInfallible. False in setters. */
    7535             :   false,  /* isMovable.  Not relevant for setters. */
    7536             :   false, /* isEliminatable.  Not relevant for setters. */
    7537             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    7538             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    7539             :   false,  /* isTypedMethod.  Only relevant for methods. */
    7540             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    7541             : };
    7542             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    7543             : static_assert(0 < 2, "There is no slot for us");
    7544             : 
    7545             : static bool
    7546           0 : add(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceSetlike* self, const JSJitMethodCallArgs& args)
    7547             : {
    7548           0 :   binding_detail::FakeString arg0;
    7549           0 :   if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
    7550           0 :     return false;
    7551             :   }
    7552           0 :   JS::Rooted<JSObject*> backingObj(cx);
    7553           0 :   bool created = false;
    7554           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    7555           0 :     return false;
    7556             :   }
    7557           0 :   if (created) {
    7558           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlike>(self);
    7559             :   }
    7560           0 :   JS::Rooted<JS::Value> arg0Val(cx);
    7561           0 :   if (!ToJSValue(cx, arg0, &arg0Val)) {
    7562           0 :     return false;
    7563             :   }
    7564           0 :   JS::Rooted<JSObject*> result(cx);
    7565           0 :   if (!JS::SetAdd(cx, backingObj, arg0Val)) {
    7566           0 :     return false;
    7567             :   }
    7568           0 :   result = obj;
    7569           0 :   JS::ExposeObjectToActiveJS(result);
    7570           0 :   args.rval().setObject(*result);
    7571           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    7572           0 :     return false;
    7573             :   }
    7574           0 :   return true;
    7575             : }
    7576             : 
    7577             : static const JSJitInfo add_methodinfo = {
    7578             :   { (JSJitGetterOp)add },
    7579             :   { prototypes::id::TestInterfaceSetlike },
    7580             :   { PrototypeTraits<prototypes::id::TestInterfaceSetlike>::Depth },
    7581             :   JSJitInfo::Method,
    7582             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    7583             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    7584             :   false,  /* isInfallible. False in setters. */
    7585             :   false,  /* isMovable.  Not relevant for setters. */
    7586             :   false, /* isEliminatable.  Not relevant for setters. */
    7587             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    7588             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    7589             :   false,  /* isTypedMethod.  Only relevant for methods. */
    7590             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    7591             : };
    7592             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    7593             : static_assert(0 < 2, "There is no slot for us");
    7594             : 
    7595             : static bool
    7596           0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
    7597             : {
    7598           0 :   mozilla::dom::TestInterfaceSetlike* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceSetlike>(obj);
    7599             :   // We don't want to preserve if we don't have a wrapper, and we
    7600             :   // obviously can't preserve if we're not initialized.
    7601           0 :   if (self && self->GetWrapperPreserveColor()) {
    7602           0 :     PreserveWrapper(self);
    7603             :   }
    7604           0 :   return true;
    7605             : }
    7606             : 
    7607             : static void
    7608           0 : _finalize(js::FreeOp* fop, JSObject* obj)
    7609             : {
    7610           0 :   mozilla::dom::TestInterfaceSetlike* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceSetlike>(obj);
    7611           0 :   if (self) {
    7612           0 :     ClearWrapper(self, self, obj);
    7613           0 :     AddForDeferredFinalization<mozilla::dom::TestInterfaceSetlike>(self);
    7614             :   }
    7615           0 : }
    7616             : 
    7617             : static void
    7618           0 : _objectMoved(JSObject* obj, const JSObject* old)
    7619             : {
    7620           0 :   mozilla::dom::TestInterfaceSetlike* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceSetlike>(obj);
    7621           0 :   if (self) {
    7622           0 :     UpdateWrapper(self, self, obj, old);
    7623             :   }
    7624           0 : }
    7625             : 
    7626             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    7627             : #if defined(__clang__)
    7628             : #pragma clang diagnostic push
    7629             : #pragma clang diagnostic ignored "-Wmissing-braces"
    7630             : #endif
    7631             : static const JSFunctionSpec sMethods_specs[] = {
    7632             :   JS_FNSPEC("entries", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&entries_methodinfo), 0, 0, nullptr),
    7633             :   JS_FNSPEC("keys", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&keys_methodinfo), 0, 0, nullptr),
    7634             :   JS_FNSPEC("values", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&values_methodinfo), 0, 0, nullptr),
    7635             :   JS_FNSPEC("forEach", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&forEach_methodinfo), 1, 0, nullptr),
    7636             :   JS_FNSPEC("has", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&has_methodinfo), 1, 0, nullptr),
    7637             :   JS_FNSPEC("clear", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&clear_methodinfo), 0, 0, nullptr),
    7638             :   JS_FNSPEC("delete", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&delete_methodinfo), 1, 0, nullptr),
    7639             :   JS_FNSPEC("add", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&add_methodinfo), 1, 0, nullptr),
    7640             :   JS_FS_END
    7641             : };
    7642             : #if defined(__clang__)
    7643             : #pragma clang diagnostic pop
    7644             : #endif
    7645             : 
    7646             : 
    7647             : // Can't be const because the pref-enabled boolean needs to be writable
    7648             : static Prefable<const JSFunctionSpec> sMethods[] = {
    7649             :   { nullptr, &sMethods_specs[0] },
    7650             :   { nullptr, nullptr }
    7651             : };
    7652             : 
    7653             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    7654             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    7655             : static_assert(8 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    7656             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    7657             : 
    7658             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    7659             : #if defined(__clang__)
    7660             : #pragma clang diagnostic push
    7661             : #pragma clang diagnostic ignored "-Wmissing-braces"
    7662             : #endif
    7663             : static const JSPropertySpec sAttributes_specs[] = {
    7664             :   { "size", JSPROP_SHARED, GenericBindingGetter, &size_getterinfo, nullptr, nullptr },
    7665             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
    7666             : };
    7667             : #if defined(__clang__)
    7668             : #pragma clang diagnostic pop
    7669             : #endif
    7670             : 
    7671             : 
    7672             : // Can't be const because the pref-enabled boolean needs to be writable
    7673             : static Prefable<const JSPropertySpec> sAttributes[] = {
    7674             :   { nullptr, &sAttributes_specs[0] },
    7675             :   { nullptr, nullptr }
    7676             : };
    7677             : 
    7678             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    7679             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    7680             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    7681             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    7682             : 
    7683             : 
    7684             : static uint16_t sNativeProperties_sortedPropertyIndices[9];
    7685             : static PropertyInfo sNativeProperties_propertyInfos[9];
    7686             : 
    7687             : static const NativePropertiesN<2> sNativeProperties = {
    7688             :   false, 0,
    7689             :   false, 0,
    7690             :   true,  0 /* sMethods */,
    7691             :   true,  1 /* sAttributes */,
    7692             :   false, 0,
    7693             :   false, 0,
    7694             :   false, 0,
    7695             :   2,
    7696             :   9,
    7697             :   sNativeProperties_sortedPropertyIndices,
    7698             :   {
    7699             :     { sMethods, &sNativeProperties_propertyInfos[0] },
    7700             :     { sAttributes, &sNativeProperties_propertyInfos[8] }
    7701             :   }
    7702             : };
    7703             : static_assert(2 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.iteratorAliasMethodIndex) - 1),
    7704             :     "We have an iterator alias index that is oversized");
    7705             : static_assert(9 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
    7706             :     "We have a property info count that is oversized");
    7707             : 
    7708             : static bool
    7709           0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
    7710             : {
    7711           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    7712           0 :   JS::Rooted<JSObject*> obj(cx, &args.callee());
    7713           0 :   if (!args.isConstructing()) {
    7714             :     // XXXbz wish I could get the name from the callee instead of
    7715             :     // Adding more relocations
    7716           0 :     return ThrowConstructorWithoutNew(cx, "TestInterfaceSetlike");
    7717             :   }
    7718             : 
    7719           0 :   GlobalObject global(cx, obj);
    7720           0 :   if (global.Failed()) {
    7721           0 :     return false;
    7722             :   }
    7723             : 
    7724           0 :   JS::Rooted<JSObject*> desiredProto(cx);
    7725           0 :   if (!GetDesiredProto(cx, args, &desiredProto)) {
    7726           0 :     return false;
    7727             :   }
    7728             : 
    7729           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    7730           0 :   Maybe<JSAutoCompartment> ac;
    7731           0 :   if (objIsXray) {
    7732           0 :     obj = js::CheckedUnwrap(obj);
    7733           0 :     if (!obj) {
    7734           0 :       return false;
    7735             :     }
    7736           0 :     ac.emplace(cx, obj);
    7737           0 :     if (!JS_WrapObject(cx, &desiredProto)) {
    7738           0 :       return false;
    7739             :     }
    7740             :   }
    7741           0 :   binding_detail::FastErrorResult rv;
    7742           0 :   auto result(StrongOrRawPtr<mozilla::dom::TestInterfaceSetlike>(mozilla::dom::TestInterfaceSetlike::Constructor(global, rv)));
    7743           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    7744           0 :     return false;
    7745             :   }
    7746           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    7747             :   static_assert(!IsPointer<decltype(result)>::value,
    7748             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
    7749           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
    7750           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    7751           0 :     return false;
    7752             :   }
    7753           0 :   return true;
    7754             : }
    7755             : 
    7756             : static const js::ClassOps sInterfaceObjectClassOps = {
    7757             :     nullptr,               /* addProperty */
    7758             :     nullptr,               /* delProperty */
    7759             :     nullptr,               /* getProperty */
    7760             :     nullptr,               /* setProperty */
    7761             :     nullptr,               /* enumerate */
    7762             :     nullptr,               /* newEnumerate */
    7763             :     nullptr,               /* resolve */
    7764             :     nullptr,               /* mayResolve */
    7765             :     nullptr,               /* finalize */
    7766             :     _constructor, /* call */
    7767             :     nullptr,               /* hasInstance */
    7768             :     _constructor, /* construct */
    7769             :     nullptr,               /* trace */
    7770             : };
    7771             : 
    7772             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
    7773             :   {
    7774             :     "Function",
    7775             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
    7776             :     &sInterfaceObjectClassOps,
    7777             :     JS_NULL_CLASS_SPEC,
    7778             :     JS_NULL_CLASS_EXT,
    7779             :     &sInterfaceObjectClassObjectOps
    7780             :   },
    7781             :   eInterface,
    7782             :   true,
    7783             :   prototypes::id::TestInterfaceSetlike,
    7784             :   PrototypeTraits<prototypes::id::TestInterfaceSetlike>::Depth,
    7785             :   sNativePropertyHooks,
    7786             :   "function TestInterfaceSetlike() {\n    [native code]\n}",
    7787             :   JS::GetRealmFunctionPrototype
    7788             : };
    7789             : 
    7790             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
    7791             :   {
    7792             :     "TestInterfaceSetlikePrototype",
    7793             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    7794             :     JS_NULL_CLASS_OPS,
    7795             :     JS_NULL_CLASS_SPEC,
    7796             :     JS_NULL_CLASS_EXT,
    7797             :     JS_NULL_OBJECT_OPS
    7798             :   },
    7799             :   eInterfacePrototype,
    7800             :   false,
    7801             :   prototypes::id::TestInterfaceSetlike,
    7802             :   PrototypeTraits<prototypes::id::TestInterfaceSetlike>::Depth,
    7803             :   sNativePropertyHooks,
    7804             :   "[object TestInterfaceSetlikePrototype]",
    7805             :   JS::GetRealmObjectPrototype
    7806             : };
    7807             : 
    7808             : bool
    7809           0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
    7810             : {
    7811             :   static bool sPrefValue;
    7812             :   static bool sPrefCacheSetUp = false;
    7813           0 :   if (!sPrefCacheSetUp) {
    7814           0 :     sPrefCacheSetUp = true;
    7815           0 :     Preferences::AddBoolVarCache(&sPrefValue, "dom.expose_test_interfaces");
    7816             :   }
    7817             : 
    7818           0 :   return sPrefValue;
    7819             : }
    7820             : 
    7821             : JSObject*
    7822           0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
    7823             : {
    7824           0 :   return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
    7825             : }
    7826             : 
    7827             : static const js::ClassOps sClassOps = {
    7828             :   _addProperty, /* addProperty */
    7829             :   nullptr,               /* delProperty */
    7830             :   nullptr,               /* getProperty */
    7831             :   nullptr,               /* setProperty */
    7832             :   nullptr,               /* enumerate */
    7833             :   nullptr, /* newEnumerate */
    7834             :   nullptr, /* resolve */
    7835             :   nullptr, /* mayResolve */
    7836             :   _finalize, /* finalize */
    7837             :   nullptr, /* call */
    7838             :   nullptr,               /* hasInstance */
    7839             :   nullptr,               /* construct */
    7840             :   nullptr, /* trace */
    7841             : };
    7842             : 
    7843             : static const js::ClassExtension sClassExtension = {
    7844             :   nullptr, /* weakmapKeyDelegateOp */
    7845             :   _objectMoved /* objectMovedOp */
    7846             : };
    7847             : 
    7848             : static const DOMJSClass sClass = {
    7849             :   { "TestInterfaceSetlike",
    7850             :     JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2),
    7851             :     &sClassOps,
    7852             :     JS_NULL_CLASS_SPEC,
    7853             :     &sClassExtension,
    7854             :     JS_NULL_OBJECT_OPS
    7855             :   },
    7856             :   { prototypes::id::TestInterfaceSetlike, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
    7857             :   IsBaseOf<nsISupports, mozilla::dom::TestInterfaceSetlike >::value,
    7858             :   sNativePropertyHooks,
    7859             :   FindAssociatedGlobalForNative<mozilla::dom::TestInterfaceSetlike>::Get,
    7860             :   GetProtoObjectHandle,
    7861             :   GetCCParticipant<mozilla::dom::TestInterfaceSetlike>::Get()
    7862             : };
    7863             : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
    7864             :               "Must have the right minimal number of reserved slots.");
    7865             : static_assert(2 >= 2,
    7866             :               "Must have enough reserved slots.");
    7867             : 
    7868             : const JSClass*
    7869           0 : GetJSClass()
    7870             : {
    7871           0 :   return sClass.ToJSClass();
    7872             : }
    7873             : 
    7874             : bool
    7875           0 : Wrap(JSContext* aCx, mozilla::dom::TestInterfaceSetlike* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
    7876             : {
    7877             :   MOZ_ASSERT(static_cast<mozilla::dom::TestInterfaceSetlike*>(aObject) ==
    7878             :              reinterpret_cast<mozilla::dom::TestInterfaceSetlike*>(aObject),
    7879             :              "Multiple inheritance for mozilla::dom::TestInterfaceSetlike is broken.");
    7880           0 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
    7881           0 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
    7882           0 :   MOZ_ASSERT(!aCache->GetWrapper(),
    7883             :              "You should probably not be using Wrap() directly; use "
    7884             :              "GetOrCreateDOMReflector instead");
    7885             : 
    7886           0 :   MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
    7887             :              "nsISupports must be on our primary inheritance chain");
    7888             : 
    7889           0 :   JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
    7890           0 :   if (!global) {
    7891           0 :     return false;
    7892             :   }
    7893           0 :   MOZ_ASSERT(JS_IsGlobalObject(global));
    7894           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(global));
    7895             : 
    7896             :   // That might have ended up wrapping us already, due to the wonders
    7897             :   // of XBL.  Check for that, and bail out as needed.
    7898           0 :   aReflector.set(aCache->GetWrapper());
    7899           0 :   if (aReflector) {
    7900             : #ifdef DEBUG
    7901           0 :     binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
    7902             : #endif // DEBUG
    7903           0 :     return true;
    7904             :   }
    7905             : 
    7906           0 :   JSAutoCompartment ac(aCx, global);
    7907           0 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
    7908           0 :   if (!canonicalProto) {
    7909           0 :     return false;
    7910             :   }
    7911           0 :   JS::Rooted<JSObject*> proto(aCx);
    7912           0 :   if (aGivenProto) {
    7913           0 :     proto = aGivenProto;
    7914             :     // Unfortunately, while aGivenProto was in the compartment of aCx
    7915             :     // coming in, we changed compartments to that of "parent" so may need
    7916             :     // to wrap the proto here.
    7917           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
    7918           0 :       if (!JS_WrapObject(aCx, &proto)) {
    7919           0 :         return false;
    7920             :       }
    7921             :     }
    7922             :   } else {
    7923           0 :     proto = canonicalProto;
    7924             :   }
    7925             : 
    7926           0 :   BindingJSObjectCreator<mozilla::dom::TestInterfaceSetlike> creator(aCx);
    7927           0 :   creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
    7928           0 :   if (!aReflector) {
    7929           0 :     return false;
    7930             :   }
    7931             : 
    7932           0 :   aCache->SetWrapper(aReflector);
    7933           0 :   creator.InitializationSucceeded();
    7934             : 
    7935           0 :   MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
    7936             :              aCache->GetWrapperPreserveColor() == aReflector);
    7937             :   // If proto != canonicalProto, we have to preserve our wrapper;
    7938             :   // otherwise we won't be able to properly recreate it later, since
    7939             :   // we won't know what proto to use.  Note that we don't check
    7940             :   // aGivenProto here, since it's entirely possible (and even
    7941             :   // somewhat common) to have a non-null aGivenProto which is the
    7942             :   // same as canonicalProto.
    7943           0 :   if (proto != canonicalProto) {
    7944           0 :     PreserveWrapper(aObject);
    7945             :   }
    7946             : 
    7947           0 :   return true;
    7948             : }
    7949             : 
    7950             : // This may allocate too many slots, because we only really need
    7951             : // slots for our non-interface-typed members that we cache.  But
    7952             : // allocating slots only for those would make the slot index
    7953             : // computations much more complicated, so let's do this the simple
    7954             : // way for now.
    7955             : DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 1);
    7956             : 
    7957             : const NativePropertyHooks sNativePropertyHooks[] = { {
    7958             :   nullptr,
    7959             :   nullptr,
    7960             :   nullptr,
    7961             :   { sNativeProperties.Upcast(), nullptr },
    7962             :   prototypes::id::TestInterfaceSetlike,
    7963             :   constructors::id::TestInterfaceSetlike,
    7964             :   nullptr,
    7965             :   &sXrayExpandoObjectClass
    7966             : } };
    7967             : 
    7968             : void
    7969           0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    7970             : {
    7971           0 :   JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
    7972           0 :   if (!parentProto) {
    7973           0 :     return;
    7974             :   }
    7975             : 
    7976           0 :   JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
    7977           0 :   if (!constructorProto) {
    7978           0 :     return;
    7979             :   }
    7980             : 
    7981             :   static bool sIdsInited = false;
    7982           0 :   if (!sIdsInited && NS_IsMainThread()) {
    7983           0 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
    7984           0 :       return;
    7985             :     }
    7986           0 :     sIdsInited = true;
    7987             :   }
    7988             : 
    7989           0 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::TestInterfaceSetlike);
    7990           0 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::TestInterfaceSetlike);
    7991           0 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    7992             :                               &sPrototypeClass.mBase, protoCache,
    7993             :                               constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
    7994             :                               interfaceCache,
    7995             :                               sNativeProperties.Upcast(),
    7996             :                               nullptr,
    7997             :                               "TestInterfaceSetlike", aDefineOnGlobal,
    7998             :                               nullptr,
    7999           0 :                               false);
    8000             : 
    8001             :   // Set up aliases on the interface prototype object we just created.
    8002           0 :   JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx);
    8003           0 :   if (!proto) {
    8004           0 :     *protoCache = nullptr;
    8005           0 :     if (interfaceCache) {
    8006           0 :       *interfaceCache = nullptr;
    8007             :     }
    8008           0 :     return;
    8009             :   }
    8010             : 
    8011           0 :   JS::Rooted<JS::Value> aliasedVal(aCx);
    8012             : 
    8013           0 :   if (!JS_GetProperty(aCx, proto, "values", &aliasedVal)) {
    8014           0 :     *protoCache = nullptr;
    8015           0 :     if (interfaceCache) {
    8016           0 :       *interfaceCache = nullptr;
    8017             :     }
    8018           0 :     return;
    8019             :   }
    8020           0 :   JS::Rooted<jsid> iteratorId(aCx, SYMBOL_TO_JSID(JS::GetWellKnownSymbol(aCx, JS::SymbolCode::iterator)));
    8021           0 :   if (!JS_DefinePropertyById(aCx, proto, iteratorId, aliasedVal, 0)) {
    8022           0 :     *protoCache = nullptr;
    8023           0 :     if (interfaceCache) {
    8024           0 :       *interfaceCache = nullptr;
    8025             :     }
    8026           0 :     return;
    8027             :   }
    8028             : }
    8029             : 
    8030             : JS::Handle<JSObject*>
    8031           0 : GetProtoObjectHandle(JSContext* aCx)
    8032             : {
    8033             :   /* Get the interface prototype object for this class.  This will create the
    8034             :      object as needed. */
    8035           0 :   bool aDefineOnGlobal = true;
    8036             : 
    8037             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    8038           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    8039           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    8040           0 :     return nullptr;
    8041             :   }
    8042             : 
    8043             :   /* Check to see whether the interface objects are already installed */
    8044           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    8045           0 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::TestInterfaceSetlike)) {
    8046           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    8047           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    8048             :   }
    8049             : 
    8050             :   /*
    8051             :    * The object might _still_ be null, but that's OK.
    8052             :    *
    8053             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    8054             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    8055             :    * changed after they have been set.
    8056             :    *
    8057             :    * Calling address() avoids the read read barrier that does gray
    8058             :    * unmarking, but it's not possible for the object to be gray here.
    8059             :    */
    8060             : 
    8061           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::TestInterfaceSetlike);
    8062           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    8063           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    8064             : }
    8065             : 
    8066             : JS::Handle<JSObject*>
    8067           0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
    8068             : {
    8069             :   /* Get the interface object for this class.  This will create the object as
    8070             :      needed. */
    8071             : 
    8072             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    8073           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    8074           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    8075           0 :     return nullptr;
    8076             :   }
    8077             : 
    8078             :   /* Check to see whether the interface objects are already installed */
    8079           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    8080           0 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::TestInterfaceSetlike)) {
    8081           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    8082           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    8083             :   }
    8084             : 
    8085             :   /*
    8086             :    * The object might _still_ be null, but that's OK.
    8087             :    *
    8088             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    8089             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    8090             :    * changed after they have been set.
    8091             :    *
    8092             :    * Calling address() avoids the read read barrier that does gray
    8093             :    * unmarking, but it's not possible for the object to be gray here.
    8094             :    */
    8095             : 
    8096           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::TestInterfaceSetlike);
    8097           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    8098           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    8099             : }
    8100             : 
    8101             : JSObject*
    8102           0 : GetConstructorObject(JSContext* aCx)
    8103             : {
    8104           0 :   return GetConstructorObjectHandle(aCx);
    8105             : }
    8106             : 
    8107             : } // namespace TestInterfaceSetlikeBinding
    8108             : 
    8109             : 
    8110             : 
    8111             : namespace TestInterfaceSetlikeNodeBinding {
    8112             : 
    8113             : namespace SetlikeHelpers {
    8114             : void
    8115           0 : Clear(mozilla::dom::TestInterfaceSetlikeNode* self, ErrorResult& aRv)
    8116             : {
    8117           0 :   MOZ_ASSERT(self);
    8118           0 :   AutoJSAPI jsapi;
    8119           0 :   jsapi.Init();
    8120           0 :   JSContext* cx = jsapi.cx();
    8121             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    8122             :   // all we want is to wrap into _some_ scope and then unwrap to find
    8123             :   // the reflector, and wrapping has no side-effects.
    8124           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    8125           0 :   JS::Rooted<JS::Value> v(cx);
    8126           0 :   if(!ToJSValue(cx, self, &v)) {
    8127           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    8128           0 :     return;
    8129             :   }
    8130             :   // This is a reflector, but due to trying to name things
    8131             :   // similarly across method generators, it's called obj here.
    8132           0 :   JS::Rooted<JSObject*> obj(cx);
    8133           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    8134           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    8135             : 
    8136           0 :   JS::Rooted<JSObject*> backingObj(cx);
    8137           0 :   bool created = false;
    8138           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    8139           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    8140           0 :     return;
    8141             :   }
    8142           0 :   if (created) {
    8143           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlikeNode>(self);
    8144             :   }
    8145           0 :   if (!JS::SetClear(cx, backingObj)) {
    8146           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    8147           0 :     return;
    8148             :   }
    8149           0 :   return;
    8150             : }
    8151             : bool
    8152           0 : Delete(mozilla::dom::TestInterfaceSetlikeNode* self, nsINode& aKey, ErrorResult& aRv)
    8153             : {
    8154           0 :   MOZ_ASSERT(self);
    8155           0 :   AutoJSAPI jsapi;
    8156           0 :   jsapi.Init();
    8157           0 :   JSContext* cx = jsapi.cx();
    8158             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    8159             :   // all we want is to wrap into _some_ scope and then unwrap to find
    8160             :   // the reflector, and wrapping has no side-effects.
    8161           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    8162           0 :   JS::Rooted<JS::Value> v(cx);
    8163           0 :   if(!ToJSValue(cx, self, &v)) {
    8164           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    8165           0 :     return false;
    8166             :   }
    8167             :   // This is a reflector, but due to trying to name things
    8168             :   // similarly across method generators, it's called obj here.
    8169           0 :   JS::Rooted<JSObject*> obj(cx);
    8170           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    8171           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    8172             :   bool aRetVal;
    8173           0 :   JS::AutoValueVector argv(cx);
    8174           0 :   if (!argv.resize(1)) {
    8175           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    8176           0 :     return false;
    8177             :   }
    8178             :   do {
    8179           0 :     if (!GetOrCreateDOMReflector(cx, aKey, argv[0])) {
    8180           0 :       MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    8181           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    8182           0 :       return false;
    8183             :     }
    8184           0 :     break;
    8185             :   } while (0);
    8186             : 
    8187           0 :   JS::Rooted<JSObject*> backingObj(cx);
    8188           0 :   bool created = false;
    8189           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    8190           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    8191           0 :     return false;
    8192             :   }
    8193           0 :   if (created) {
    8194           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlikeNode>(self);
    8195             :   }
    8196           0 :   if (!JS::SetDelete(cx, backingObj, argv[0], &aRetVal)) {
    8197           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    8198           0 :     return false;
    8199             :   }
    8200           0 :   return aRetVal;
    8201             : }
    8202             : bool
    8203           0 : Has(mozilla::dom::TestInterfaceSetlikeNode* self, nsINode& aKey, ErrorResult& aRv)
    8204             : {
    8205           0 :   MOZ_ASSERT(self);
    8206           0 :   AutoJSAPI jsapi;
    8207           0 :   jsapi.Init();
    8208           0 :   JSContext* cx = jsapi.cx();
    8209             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    8210             :   // all we want is to wrap into _some_ scope and then unwrap to find
    8211             :   // the reflector, and wrapping has no side-effects.
    8212           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    8213           0 :   JS::Rooted<JS::Value> v(cx);
    8214           0 :   if(!ToJSValue(cx, self, &v)) {
    8215           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    8216           0 :     return false;
    8217             :   }
    8218             :   // This is a reflector, but due to trying to name things
    8219             :   // similarly across method generators, it's called obj here.
    8220           0 :   JS::Rooted<JSObject*> obj(cx);
    8221           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    8222           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    8223             :   bool aRetVal;
    8224           0 :   JS::AutoValueVector argv(cx);
    8225           0 :   if (!argv.resize(1)) {
    8226           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    8227           0 :     return false;
    8228             :   }
    8229             :   do {
    8230           0 :     if (!GetOrCreateDOMReflector(cx, aKey, argv[0])) {
    8231           0 :       MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    8232           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    8233           0 :       return false;
    8234             :     }
    8235           0 :     break;
    8236             :   } while (0);
    8237             : 
    8238           0 :   JS::Rooted<JSObject*> backingObj(cx);
    8239           0 :   bool created = false;
    8240           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    8241           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    8242           0 :     return false;
    8243             :   }
    8244           0 :   if (created) {
    8245           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlikeNode>(self);
    8246             :   }
    8247           0 :   if (!JS::SetHas(cx, backingObj, argv[0], &aRetVal)) {
    8248           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    8249           0 :     return false;
    8250             :   }
    8251           0 :   return aRetVal;
    8252             : }
    8253             : void
    8254           0 : Add(mozilla::dom::TestInterfaceSetlikeNode* self, nsINode& aKey, ErrorResult& aRv)
    8255             : {
    8256           0 :   MOZ_ASSERT(self);
    8257           0 :   AutoJSAPI jsapi;
    8258           0 :   jsapi.Init();
    8259           0 :   JSContext* cx = jsapi.cx();
    8260             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
    8261             :   // all we want is to wrap into _some_ scope and then unwrap to find
    8262             :   // the reflector, and wrapping has no side-effects.
    8263           0 :   JSAutoCompartment tempCompartment(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
    8264           0 :   JS::Rooted<JS::Value> v(cx);
    8265           0 :   if(!ToJSValue(cx, self, &v)) {
    8266           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    8267           0 :     return;
    8268             :   }
    8269             :   // This is a reflector, but due to trying to name things
    8270             :   // similarly across method generators, it's called obj here.
    8271           0 :   JS::Rooted<JSObject*> obj(cx);
    8272           0 :   obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
    8273           0 :   JSAutoCompartment reflectorCompartment(cx, obj);
    8274           0 :   JS::AutoValueVector argv(cx);
    8275           0 :   if (!argv.resize(1)) {
    8276           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    8277           0 :     return;
    8278             :   }
    8279             :   do {
    8280           0 :     if (!GetOrCreateDOMReflector(cx, aKey, argv[0])) {
    8281           0 :       MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    8282           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    8283           0 :       return;
    8284             :     }
    8285           0 :     break;
    8286             :   } while (0);
    8287             : 
    8288           0 :   JS::Rooted<JSObject*> backingObj(cx);
    8289           0 :   bool created = false;
    8290           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    8291           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    8292           0 :     return;
    8293             :   }
    8294           0 :   if (created) {
    8295           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlikeNode>(self);
    8296             :   }
    8297           0 :   if (!JS::SetAdd(cx, backingObj, argv[0])) {
    8298           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    8299           0 :     return;
    8300             :   }
    8301           0 :   return;
    8302             : }
    8303             : } // namespace SetlikeHelpers
    8304             : 
    8305             : static bool
    8306           0 : get_size(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceSetlikeNode* self, JSJitGetterCallArgs args)
    8307             : {
    8308           0 :   JS::Rooted<JSObject*> backingObj(cx);
    8309           0 :   bool created = false;
    8310           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    8311           0 :     return false;
    8312             :   }
    8313           0 :   if (created) {
    8314           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlikeNode>(self);
    8315             :   }
    8316           0 :   uint32_t result = JS::SetSize(cx, backingObj);
    8317           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    8318           0 :   args.rval().setNumber(result);
    8319           0 :   return true;
    8320             : }
    8321             : 
    8322             : static const JSJitInfo size_getterinfo = {
    8323             :   { (JSJitGetterOp)get_size },
    8324             :   { prototypes::id::TestInterfaceSetlikeNode },
    8325             :   { PrototypeTraits<prototypes::id::TestInterfaceSetlikeNode>::Depth },
    8326             :   JSJitInfo::Getter,
    8327             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    8328             :   JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
    8329             :   true,  /* isInfallible. False in setters. */
    8330             :   false,  /* isMovable.  Not relevant for setters. */
    8331             :   false, /* isEliminatable.  Not relevant for setters. */
    8332             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    8333             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    8334             :   false,  /* isTypedMethod.  Only relevant for methods. */
    8335             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    8336             : };
    8337             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    8338             : static_assert(0 < 2, "There is no slot for us");
    8339             : 
    8340             : static bool
    8341           0 : entries(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceSetlikeNode* self, const JSJitMethodCallArgs& args)
    8342             : {
    8343           0 :   JS::Rooted<JSObject*> backingObj(cx);
    8344           0 :   bool created = false;
    8345           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    8346           0 :     return false;
    8347             :   }
    8348           0 :   if (created) {
    8349           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlikeNode>(self);
    8350             :   }
    8351             :   // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
    8352             :   // after bug 1023984 is fixed.
    8353           0 :   if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    8354           0 :     JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    8355           0 :     return false;
    8356             :   }
    8357           0 :   JS::Rooted<JSObject*> result(cx);
    8358           0 :   JS::Rooted<JS::Value> v(cx);
    8359           0 :   if (!JS::SetEntries(cx, backingObj, &v)) {
    8360           0 :     return false;
    8361             :   }
    8362           0 :   result = &v.toObject();
    8363           0 :   JS::ExposeObjectToActiveJS(result);
    8364           0 :   args.rval().setObject(*result);
    8365           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    8366           0 :     return false;
    8367             :   }
    8368           0 :   return true;
    8369             : }
    8370             : 
    8371             : static const JSJitInfo::ArgType entries_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
    8372             : static const JSTypedMethodJitInfo entries_methodinfo = {
    8373             :   {
    8374             :     { (JSJitGetterOp)entries },
    8375             :     { prototypes::id::TestInterfaceSetlikeNode },
    8376             :     { PrototypeTraits<prototypes::id::TestInterfaceSetlikeNode>::Depth },
    8377             :     JSJitInfo::Method,
    8378             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    8379             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    8380             :     false,  /* isInfallible. False in setters. */
    8381             :     false,  /* isMovable.  Not relevant for setters. */
    8382             :     false, /* isEliminatable.  Not relevant for setters. */
    8383             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    8384             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    8385             :     true,  /* isTypedMethod.  Only relevant for methods. */
    8386             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    8387             :   },
    8388             :   entries_methodinfo_argTypes
    8389             : };
    8390             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    8391             : static_assert(0 < 2, "There is no slot for us");
    8392             : 
    8393             : static bool
    8394           0 : keys(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceSetlikeNode* self, const JSJitMethodCallArgs& args)
    8395             : {
    8396           0 :   JS::Rooted<JSObject*> backingObj(cx);
    8397           0 :   bool created = false;
    8398           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    8399           0 :     return false;
    8400             :   }
    8401           0 :   if (created) {
    8402           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlikeNode>(self);
    8403             :   }
    8404             :   // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
    8405             :   // after bug 1023984 is fixed.
    8406           0 :   if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    8407           0 :     JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    8408           0 :     return false;
    8409             :   }
    8410           0 :   JS::Rooted<JSObject*> result(cx);
    8411           0 :   JS::Rooted<JS::Value> v(cx);
    8412           0 :   if (!JS::SetKeys(cx, backingObj, &v)) {
    8413           0 :     return false;
    8414             :   }
    8415           0 :   result = &v.toObject();
    8416           0 :   JS::ExposeObjectToActiveJS(result);
    8417           0 :   args.rval().setObject(*result);
    8418           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    8419           0 :     return false;
    8420             :   }
    8421           0 :   return true;
    8422             : }
    8423             : 
    8424             : static const JSJitInfo::ArgType keys_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
    8425             : static const JSTypedMethodJitInfo keys_methodinfo = {
    8426             :   {
    8427             :     { (JSJitGetterOp)keys },
    8428             :     { prototypes::id::TestInterfaceSetlikeNode },
    8429             :     { PrototypeTraits<prototypes::id::TestInterfaceSetlikeNode>::Depth },
    8430             :     JSJitInfo::Method,
    8431             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    8432             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    8433             :     false,  /* isInfallible. False in setters. */
    8434             :     false,  /* isMovable.  Not relevant for setters. */
    8435             :     false, /* isEliminatable.  Not relevant for setters. */
    8436             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    8437             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    8438             :     true,  /* isTypedMethod.  Only relevant for methods. */
    8439             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    8440             :   },
    8441             :   keys_methodinfo_argTypes
    8442             : };
    8443             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    8444             : static_assert(0 < 2, "There is no slot for us");
    8445             : 
    8446             : static bool
    8447           0 : values(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceSetlikeNode* self, const JSJitMethodCallArgs& args)
    8448             : {
    8449           0 :   JS::Rooted<JSObject*> backingObj(cx);
    8450           0 :   bool created = false;
    8451           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    8452           0 :     return false;
    8453             :   }
    8454           0 :   if (created) {
    8455           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlikeNode>(self);
    8456             :   }
    8457             :   // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
    8458             :   // after bug 1023984 is fixed.
    8459           0 :   if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    8460           0 :     JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    8461           0 :     return false;
    8462             :   }
    8463           0 :   JS::Rooted<JSObject*> result(cx);
    8464           0 :   JS::Rooted<JS::Value> v(cx);
    8465           0 :   if (!JS::SetValues(cx, backingObj, &v)) {
    8466           0 :     return false;
    8467             :   }
    8468           0 :   result = &v.toObject();
    8469           0 :   JS::ExposeObjectToActiveJS(result);
    8470           0 :   args.rval().setObject(*result);
    8471           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    8472           0 :     return false;
    8473             :   }
    8474           0 :   return true;
    8475             : }
    8476             : 
    8477             : static const JSJitInfo::ArgType values_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
    8478             : static const JSTypedMethodJitInfo values_methodinfo = {
    8479             :   {
    8480             :     { (JSJitGetterOp)values },
    8481             :     { prototypes::id::TestInterfaceSetlikeNode },
    8482             :     { PrototypeTraits<prototypes::id::TestInterfaceSetlikeNode>::Depth },
    8483             :     JSJitInfo::Method,
    8484             :     JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    8485             :     JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    8486             :     false,  /* isInfallible. False in setters. */
    8487             :     false,  /* isMovable.  Not relevant for setters. */
    8488             :     false, /* isEliminatable.  Not relevant for setters. */
    8489             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    8490             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    8491             :     true,  /* isTypedMethod.  Only relevant for methods. */
    8492             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    8493             :   },
    8494             :   values_methodinfo_argTypes
    8495             : };
    8496             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    8497             : static_assert(0 < 2, "There is no slot for us");
    8498             : 
    8499             : static bool
    8500           0 : forEach(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceSetlikeNode* self, const JSJitMethodCallArgs& args)
    8501             : {
    8502           0 :   JS::Rooted<JSObject*> arg0(cx);
    8503           0 :   if (args.get(0).isObject()) {
    8504           0 :     arg0 = &args.get(0).toObject();
    8505             :   } else {
    8506           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of TestInterfaceSetlikeNode.forEach");
    8507           0 :     return false;
    8508             :   }
    8509           0 :   JS::Rooted<JS::Value> arg1(cx);
    8510           0 :   if (args.hasDefined(1)) {
    8511           0 :     arg1 = args.get(1);
    8512             :   } else {
    8513           0 :     arg1 = JS::UndefinedValue();
    8514             :   }
    8515           0 :   JS::Rooted<JSObject*> backingObj(cx);
    8516           0 :   bool created = false;
    8517           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    8518           0 :     return false;
    8519             :   }
    8520           0 :   if (created) {
    8521           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlikeNode>(self);
    8522             :   }
    8523             :   // Create a wrapper function.
    8524           0 :   JSFunction* func = js::NewFunctionWithReserved(cx, ForEachHandler, 3, 0, nullptr);
    8525           0 :   if (!func) {
    8526           0 :     return false;
    8527             :   }
    8528           0 :   JS::Rooted<JSObject*> funcObj(cx, JS_GetFunctionObject(func));
    8529           0 :   JS::Rooted<JS::Value> funcVal(cx, JS::ObjectValue(*funcObj));
    8530           0 :   js::SetFunctionNativeReserved(funcObj, FOREACH_CALLBACK_SLOT,
    8531           0 :                                 JS::ObjectValue(*arg0));
    8532           0 :   js::SetFunctionNativeReserved(funcObj, FOREACH_MAPLIKEORSETLIKEOBJ_SLOT,
    8533           0 :                                 JS::ObjectValue(*obj));
    8534           0 :   if (!JS::SetForEach(cx, backingObj, funcVal, arg1)) {
    8535           0 :     return false;
    8536             :   }
    8537           0 :   args.rval().setUndefined();
    8538           0 :   return true;
    8539             : }
    8540             : 
    8541             : static const JSJitInfo forEach_methodinfo = {
    8542             :   { (JSJitGetterOp)forEach },
    8543             :   { prototypes::id::TestInterfaceSetlikeNode },
    8544             :   { PrototypeTraits<prototypes::id::TestInterfaceSetlikeNode>::Depth },
    8545             :   JSJitInfo::Method,
    8546             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    8547             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    8548             :   false,  /* isInfallible. False in setters. */
    8549             :   false,  /* isMovable.  Not relevant for setters. */
    8550             :   false, /* isEliminatable.  Not relevant for setters. */
    8551             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    8552             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    8553             :   false,  /* isTypedMethod.  Only relevant for methods. */
    8554             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    8555             : };
    8556             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    8557             : static_assert(0 < 2, "There is no slot for us");
    8558             : 
    8559             : static bool
    8560           0 : has(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceSetlikeNode* self, const JSJitMethodCallArgs& args)
    8561             : {
    8562           0 :   NonNull<nsINode> arg0;
    8563           0 :   if (args.get(0).isObject()) {
    8564             :     {
    8565           0 :       nsresult rv = UnwrapObject<prototypes::id::Node, nsINode>(args[0], arg0);
    8566           0 :       if (NS_FAILED(rv)) {
    8567           0 :         ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of TestInterfaceSetlikeNode.has", "Node");
    8568           0 :         return false;
    8569             :       }
    8570             :     }
    8571             :   } else {
    8572           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of TestInterfaceSetlikeNode.has");
    8573           0 :     return false;
    8574             :   }
    8575           0 :   JS::Rooted<JSObject*> backingObj(cx);
    8576           0 :   bool created = false;
    8577           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    8578           0 :     return false;
    8579             :   }
    8580           0 :   if (created) {
    8581           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlikeNode>(self);
    8582             :   }
    8583           0 :   JS::Rooted<JS::Value> arg0Val(cx);
    8584           0 :   if (!ToJSValue(cx, arg0, &arg0Val)) {
    8585           0 :     return false;
    8586             :   }
    8587             :   bool result;
    8588           0 :   if (!JS::SetHas(cx, backingObj, arg0Val, &result)) {
    8589           0 :     return false;
    8590             :   }
    8591           0 :   args.rval().setBoolean(result);
    8592           0 :   return true;
    8593             : }
    8594             : 
    8595             : static const JSJitInfo::ArgType has_methodinfo_argTypes[] = { JSJitInfo::Object, JSJitInfo::ArgTypeListEnd };
    8596             : static const JSTypedMethodJitInfo has_methodinfo = {
    8597             :   {
    8598             :     { (JSJitGetterOp)has },
    8599             :     { prototypes::id::TestInterfaceSetlikeNode },
    8600             :     { PrototypeTraits<prototypes::id::TestInterfaceSetlikeNode>::Depth },
    8601             :     JSJitInfo::Method,
    8602             :     JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    8603             :     JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    8604             :     false,  /* isInfallible. False in setters. */
    8605             :     false,  /* isMovable.  Not relevant for setters. */
    8606             :     false, /* isEliminatable.  Not relevant for setters. */
    8607             :     false, /* isAlwaysInSlot.  Only relevant for getters. */
    8608             :     false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    8609             :     true,  /* isTypedMethod.  Only relevant for methods. */
    8610             :     0   /* Reserved slot index, if we're stored in a slot, else 0. */
    8611             :   },
    8612             :   has_methodinfo_argTypes
    8613             : };
    8614             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    8615             : static_assert(0 < 2, "There is no slot for us");
    8616             : 
    8617             : static bool
    8618           0 : clear(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceSetlikeNode* self, const JSJitMethodCallArgs& args)
    8619             : {
    8620           0 :   JS::Rooted<JSObject*> backingObj(cx);
    8621           0 :   bool created = false;
    8622           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    8623           0 :     return false;
    8624             :   }
    8625           0 :   if (created) {
    8626           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlikeNode>(self);
    8627             :   }
    8628           0 :   if (!JS::SetClear(cx, backingObj)) {
    8629           0 :     return false;
    8630             :   }
    8631           0 :   args.rval().setUndefined();
    8632           0 :   return true;
    8633             : }
    8634             : 
    8635             : static const JSJitInfo clear_methodinfo = {
    8636             :   { (JSJitGetterOp)clear },
    8637             :   { prototypes::id::TestInterfaceSetlikeNode },
    8638             :   { PrototypeTraits<prototypes::id::TestInterfaceSetlikeNode>::Depth },
    8639             :   JSJitInfo::Method,
    8640             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    8641             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    8642             :   false,  /* isInfallible. False in setters. */
    8643             :   false,  /* isMovable.  Not relevant for setters. */
    8644             :   false, /* isEliminatable.  Not relevant for setters. */
    8645             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    8646             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    8647             :   false,  /* isTypedMethod.  Only relevant for methods. */
    8648             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    8649             : };
    8650             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    8651             : static_assert(0 < 2, "There is no slot for us");
    8652             : 
    8653             : static bool
    8654           0 : _delete_(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceSetlikeNode* self, const JSJitMethodCallArgs& args)
    8655             : {
    8656           0 :   NonNull<nsINode> arg0;
    8657           0 :   if (args.get(0).isObject()) {
    8658             :     {
    8659           0 :       nsresult rv = UnwrapObject<prototypes::id::Node, nsINode>(args[0], arg0);
    8660           0 :       if (NS_FAILED(rv)) {
    8661           0 :         ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of TestInterfaceSetlikeNode.delete", "Node");
    8662           0 :         return false;
    8663             :       }
    8664             :     }
    8665             :   } else {
    8666           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of TestInterfaceSetlikeNode.delete");
    8667           0 :     return false;
    8668             :   }
    8669           0 :   JS::Rooted<JSObject*> backingObj(cx);
    8670           0 :   bool created = false;
    8671           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    8672           0 :     return false;
    8673             :   }
    8674           0 :   if (created) {
    8675           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlikeNode>(self);
    8676             :   }
    8677           0 :   JS::Rooted<JS::Value> arg0Val(cx);
    8678           0 :   if (!ToJSValue(cx, arg0, &arg0Val)) {
    8679           0 :     return false;
    8680             :   }
    8681             :   bool result;
    8682           0 :   if (!JS::SetDelete(cx, backingObj, arg0Val, &result)) {
    8683           0 :     return false;
    8684             :   }
    8685           0 :   args.rval().setBoolean(result);
    8686           0 :   return true;
    8687             : }
    8688             : 
    8689             : static const JSJitInfo delete_methodinfo = {
    8690             :   { (JSJitGetterOp)_delete_ },
    8691             :   { prototypes::id::TestInterfaceSetlikeNode },
    8692             :   { PrototypeTraits<prototypes::id::TestInterfaceSetlikeNode>::Depth },
    8693             :   JSJitInfo::Method,
    8694             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    8695             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    8696             :   false,  /* isInfallible. False in setters. */
    8697             :   false,  /* isMovable.  Not relevant for setters. */
    8698             :   false, /* isEliminatable.  Not relevant for setters. */
    8699             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    8700             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    8701             :   false,  /* isTypedMethod.  Only relevant for methods. */
    8702             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    8703             : };
    8704             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    8705             : static_assert(0 < 2, "There is no slot for us");
    8706             : 
    8707             : static bool
    8708           0 : add(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceSetlikeNode* self, const JSJitMethodCallArgs& args)
    8709             : {
    8710           0 :   NonNull<nsINode> arg0;
    8711           0 :   if (args.get(0).isObject()) {
    8712             :     {
    8713           0 :       nsresult rv = UnwrapObject<prototypes::id::Node, nsINode>(args[0], arg0);
    8714           0 :       if (NS_FAILED(rv)) {
    8715           0 :         ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of TestInterfaceSetlikeNode.add", "Node");
    8716           0 :         return false;
    8717             :       }
    8718             :     }
    8719             :   } else {
    8720           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of TestInterfaceSetlikeNode.add");
    8721           0 :     return false;
    8722             :   }
    8723           0 :   JS::Rooted<JSObject*> backingObj(cx);
    8724           0 :   bool created = false;
    8725           0 :   if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    8726           0 :     return false;
    8727             :   }
    8728           0 :   if (created) {
    8729           0 :     PreserveWrapper<mozilla::dom::TestInterfaceSetlikeNode>(self);
    8730             :   }
    8731           0 :   JS::Rooted<JS::Value> arg0Val(cx);
    8732           0 :   if (!ToJSValue(cx, arg0, &arg0Val)) {
    8733           0 :     return false;
    8734             :   }
    8735           0 :   JS::Rooted<JSObject*> result(cx);
    8736           0 :   if (!JS::SetAdd(cx, backingObj, arg0Val)) {
    8737           0 :     return false;
    8738             :   }
    8739           0 :   result = obj;
    8740           0 :   JS::ExposeObjectToActiveJS(result);
    8741           0 :   args.rval().setObject(*result);
    8742           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    8743           0 :     return false;
    8744             :   }
    8745           0 :   return true;
    8746             : }
    8747             : 
    8748             : static const JSJitInfo add_methodinfo = {
    8749             :   { (JSJitGetterOp)add },
    8750             :   { prototypes::id::TestInterfaceSetlikeNode },
    8751             :   { PrototypeTraits<prototypes::id::TestInterfaceSetlikeNode>::Depth },
    8752             :   JSJitInfo::Method,
    8753             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    8754             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    8755             :   false,  /* isInfallible. False in setters. */
    8756             :   false,  /* isMovable.  Not relevant for setters. */
    8757             :   false, /* isEliminatable.  Not relevant for setters. */
    8758             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    8759             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    8760             :   false,  /* isTypedMethod.  Only relevant for methods. */
    8761             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    8762             : };
    8763             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    8764             : static_assert(0 < 2, "There is no slot for us");
    8765             : 
    8766             : static bool
    8767           0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
    8768             : {
    8769           0 :   mozilla::dom::TestInterfaceSetlikeNode* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceSetlikeNode>(obj);
    8770             :   // We don't want to preserve if we don't have a wrapper, and we
    8771             :   // obviously can't preserve if we're not initialized.
    8772           0 :   if (self && self->GetWrapperPreserveColor()) {
    8773           0 :     PreserveWrapper(self);
    8774             :   }
    8775           0 :   return true;
    8776             : }
    8777             : 
    8778             : static void
    8779           0 : _finalize(js::FreeOp* fop, JSObject* obj)
    8780             : {
    8781           0 :   mozilla::dom::TestInterfaceSetlikeNode* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceSetlikeNode>(obj);
    8782           0 :   if (self) {
    8783           0 :     ClearWrapper(self, self, obj);
    8784           0 :     AddForDeferredFinalization<mozilla::dom::TestInterfaceSetlikeNode>(self);
    8785             :   }
    8786           0 : }
    8787             : 
    8788             : static void
    8789           0 : _objectMoved(JSObject* obj, const JSObject* old)
    8790             : {
    8791           0 :   mozilla::dom::TestInterfaceSetlikeNode* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceSetlikeNode>(obj);
    8792           0 :   if (self) {
    8793           0 :     UpdateWrapper(self, self, obj, old);
    8794             :   }
    8795           0 : }
    8796             : 
    8797             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    8798             : #if defined(__clang__)
    8799             : #pragma clang diagnostic push
    8800             : #pragma clang diagnostic ignored "-Wmissing-braces"
    8801             : #endif
    8802             : static const JSFunctionSpec sMethods_specs[] = {
    8803             :   JS_FNSPEC("entries", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&entries_methodinfo), 0, 0, nullptr),
    8804             :   JS_FNSPEC("keys", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&keys_methodinfo), 0, 0, nullptr),
    8805             :   JS_FNSPEC("values", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&values_methodinfo), 0, 0, nullptr),
    8806             :   JS_FNSPEC("forEach", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&forEach_methodinfo), 1, 0, nullptr),
    8807             :   JS_FNSPEC("has", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&has_methodinfo), 1, 0, nullptr),
    8808             :   JS_FNSPEC("clear", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&clear_methodinfo), 0, 0, nullptr),
    8809             :   JS_FNSPEC("delete", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&delete_methodinfo), 1, 0, nullptr),
    8810             :   JS_FNSPEC("add", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&add_methodinfo), 1, 0, nullptr),
    8811             :   JS_FS_END
    8812             : };
    8813             : #if defined(__clang__)
    8814             : #pragma clang diagnostic pop
    8815             : #endif
    8816             : 
    8817             : 
    8818             : // Can't be const because the pref-enabled boolean needs to be writable
    8819             : static Prefable<const JSFunctionSpec> sMethods[] = {
    8820             :   { nullptr, &sMethods_specs[0] },
    8821             :   { nullptr, nullptr }
    8822             : };
    8823             : 
    8824             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    8825             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    8826             : static_assert(8 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    8827             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    8828             : 
    8829             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    8830             : #if defined(__clang__)
    8831             : #pragma clang diagnostic push
    8832             : #pragma clang diagnostic ignored "-Wmissing-braces"
    8833             : #endif
    8834             : static const JSPropertySpec sAttributes_specs[] = {
    8835             :   { "size", JSPROP_SHARED, GenericBindingGetter, &size_getterinfo, nullptr, nullptr },
    8836             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
    8837             : };
    8838             : #if defined(__clang__)
    8839             : #pragma clang diagnostic pop
    8840             : #endif
    8841             : 
    8842             : 
    8843             : // Can't be const because the pref-enabled boolean needs to be writable
    8844             : static Prefable<const JSPropertySpec> sAttributes[] = {
    8845             :   { nullptr, &sAttributes_specs[0] },
    8846             :   { nullptr, nullptr }
    8847             : };
    8848             : 
    8849             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    8850             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    8851             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    8852             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    8853             : 
    8854             : 
    8855             : static uint16_t sNativeProperties_sortedPropertyIndices[9];
    8856             : static PropertyInfo sNativeProperties_propertyInfos[9];
    8857             : 
    8858             : static const NativePropertiesN<2> sNativeProperties = {
    8859             :   false, 0,
    8860             :   false, 0,
    8861             :   true,  0 /* sMethods */,
    8862             :   true,  1 /* sAttributes */,
    8863             :   false, 0,
    8864             :   false, 0,
    8865             :   false, 0,
    8866             :   2,
    8867             :   9,
    8868             :   sNativeProperties_sortedPropertyIndices,
    8869             :   {
    8870             :     { sMethods, &sNativeProperties_propertyInfos[0] },
    8871             :     { sAttributes, &sNativeProperties_propertyInfos[8] }
    8872             :   }
    8873             : };
    8874             : static_assert(2 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.iteratorAliasMethodIndex) - 1),
    8875             :     "We have an iterator alias index that is oversized");
    8876             : static_assert(9 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
    8877             :     "We have a property info count that is oversized");
    8878             : 
    8879             : static bool
    8880           0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
    8881             : {
    8882           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    8883           0 :   JS::Rooted<JSObject*> obj(cx, &args.callee());
    8884           0 :   if (!args.isConstructing()) {
    8885             :     // XXXbz wish I could get the name from the callee instead of
    8886             :     // Adding more relocations
    8887           0 :     return ThrowConstructorWithoutNew(cx, "TestInterfaceSetlikeNode");
    8888             :   }
    8889             : 
    8890           0 :   GlobalObject global(cx, obj);
    8891           0 :   if (global.Failed()) {
    8892           0 :     return false;
    8893             :   }
    8894             : 
    8895           0 :   JS::Rooted<JSObject*> desiredProto(cx);
    8896           0 :   if (!GetDesiredProto(cx, args, &desiredProto)) {
    8897           0 :     return false;
    8898             :   }
    8899             : 
    8900           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    8901           0 :   Maybe<JSAutoCompartment> ac;
    8902           0 :   if (objIsXray) {
    8903           0 :     obj = js::CheckedUnwrap(obj);
    8904           0 :     if (!obj) {
    8905           0 :       return false;
    8906             :     }
    8907           0 :     ac.emplace(cx, obj);
    8908           0 :     if (!JS_WrapObject(cx, &desiredProto)) {
    8909           0 :       return false;
    8910             :     }
    8911             :   }
    8912           0 :   binding_detail::FastErrorResult rv;
    8913           0 :   auto result(StrongOrRawPtr<mozilla::dom::TestInterfaceSetlikeNode>(mozilla::dom::TestInterfaceSetlikeNode::Constructor(global, rv)));
    8914           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    8915           0 :     return false;
    8916             :   }
    8917           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    8918             :   static_assert(!IsPointer<decltype(result)>::value,
    8919             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
    8920           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
    8921           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    8922           0 :     return false;
    8923             :   }
    8924           0 :   return true;
    8925             : }
    8926             : 
    8927             : static const js::ClassOps sInterfaceObjectClassOps = {
    8928             :     nullptr,               /* addProperty */
    8929             :     nullptr,               /* delProperty */
    8930             :     nullptr,               /* getProperty */
    8931             :     nullptr,               /* setProperty */
    8932             :     nullptr,               /* enumerate */
    8933             :     nullptr,               /* newEnumerate */
    8934             :     nullptr,               /* resolve */
    8935             :     nullptr,               /* mayResolve */
    8936             :     nullptr,               /* finalize */
    8937             :     _constructor, /* call */
    8938             :     nullptr,               /* hasInstance */
    8939             :     _constructor, /* construct */
    8940             :     nullptr,               /* trace */
    8941             : };
    8942             : 
    8943             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
    8944             :   {
    8945             :     "Function",
    8946             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
    8947             :     &sInterfaceObjectClassOps,
    8948             :     JS_NULL_CLASS_SPEC,
    8949             :     JS_NULL_CLASS_EXT,
    8950             :     &sInterfaceObjectClassObjectOps
    8951             :   },
    8952             :   eInterface,
    8953             :   true,
    8954             :   prototypes::id::TestInterfaceSetlikeNode,
    8955             :   PrototypeTraits<prototypes::id::TestInterfaceSetlikeNode>::Depth,
    8956             :   sNativePropertyHooks,
    8957             :   "function TestInterfaceSetlikeNode() {\n    [native code]\n}",
    8958             :   JS::GetRealmFunctionPrototype
    8959             : };
    8960             : 
    8961             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
    8962             :   {
    8963             :     "TestInterfaceSetlikeNodePrototype",
    8964             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    8965             :     JS_NULL_CLASS_OPS,
    8966             :     JS_NULL_CLASS_SPEC,
    8967             :     JS_NULL_CLASS_EXT,
    8968             :     JS_NULL_OBJECT_OPS
    8969             :   },
    8970             :   eInterfacePrototype,
    8971             :   false,
    8972             :   prototypes::id::TestInterfaceSetlikeNode,
    8973             :   PrototypeTraits<prototypes::id::TestInterfaceSetlikeNode>::Depth,
    8974             :   sNativePropertyHooks,
    8975             :   "[object TestInterfaceSetlikeNodePrototype]",
    8976             :   JS::GetRealmObjectPrototype
    8977             : };
    8978             : 
    8979             : bool
    8980           0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
    8981             : {
    8982             :   static bool sPrefValue;
    8983             :   static bool sPrefCacheSetUp = false;
    8984           0 :   if (!sPrefCacheSetUp) {
    8985           0 :     sPrefCacheSetUp = true;
    8986           0 :     Preferences::AddBoolVarCache(&sPrefValue, "dom.expose_test_interfaces");
    8987             :   }
    8988             : 
    8989           0 :   return sPrefValue;
    8990             : }
    8991             : 
    8992             : JSObject*
    8993           0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
    8994             : {
    8995           0 :   return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
    8996             : }
    8997             : 
    8998             : static const js::ClassOps sClassOps = {
    8999             :   _addProperty, /* addProperty */
    9000             :   nullptr,               /* delProperty */
    9001             :   nullptr,               /* getProperty */
    9002             :   nullptr,               /* setProperty */
    9003             :   nullptr,               /* enumerate */
    9004             :   nullptr, /* newEnumerate */
    9005             :   nullptr, /* resolve */
    9006             :   nullptr, /* mayResolve */
    9007             :   _finalize, /* finalize */
    9008             :   nullptr, /* call */
    9009             :   nullptr,               /* hasInstance */
    9010             :   nullptr,               /* construct */
    9011             :   nullptr, /* trace */
    9012             : };
    9013             : 
    9014             : static const js::ClassExtension sClassExtension = {
    9015             :   nullptr, /* weakmapKeyDelegateOp */
    9016             :   _objectMoved /* objectMovedOp */
    9017             : };
    9018             : 
    9019             : static const DOMJSClass sClass = {
    9020             :   { "TestInterfaceSetlikeNode",
    9021             :     JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2),
    9022             :     &sClassOps,
    9023             :     JS_NULL_CLASS_SPEC,
    9024             :     &sClassExtension,
    9025             :     JS_NULL_OBJECT_OPS
    9026             :   },
    9027             :   { prototypes::id::TestInterfaceSetlikeNode, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
    9028             :   IsBaseOf<nsISupports, mozilla::dom::TestInterfaceSetlikeNode >::value,
    9029             :   sNativePropertyHooks,
    9030             :   FindAssociatedGlobalForNative<mozilla::dom::TestInterfaceSetlikeNode>::Get,
    9031             :   GetProtoObjectHandle,
    9032             :   GetCCParticipant<mozilla::dom::TestInterfaceSetlikeNode>::Get()
    9033             : };
    9034             : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
    9035             :               "Must have the right minimal number of reserved slots.");
    9036             : static_assert(2 >= 2,
    9037             :               "Must have enough reserved slots.");
    9038             : 
    9039             : const JSClass*
    9040           0 : GetJSClass()
    9041             : {
    9042           0 :   return sClass.ToJSClass();
    9043             : }
    9044             : 
    9045             : bool
    9046           0 : Wrap(JSContext* aCx, mozilla::dom::TestInterfaceSetlikeNode* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
    9047             : {
    9048             :   MOZ_ASSERT(static_cast<mozilla::dom::TestInterfaceSetlikeNode*>(aObject) ==
    9049             :              reinterpret_cast<mozilla::dom::TestInterfaceSetlikeNode*>(aObject),
    9050             :              "Multiple inheritance for mozilla::dom::TestInterfaceSetlikeNode is broken.");
    9051           0 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
    9052           0 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
    9053           0 :   MOZ_ASSERT(!aCache->GetWrapper(),
    9054             :              "You should probably not be using Wrap() directly; use "
    9055             :              "GetOrCreateDOMReflector instead");
    9056             : 
    9057           0 :   MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
    9058             :              "nsISupports must be on our primary inheritance chain");
    9059             : 
    9060           0 :   JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
    9061           0 :   if (!global) {
    9062           0 :     return false;
    9063             :   }
    9064           0 :   MOZ_ASSERT(JS_IsGlobalObject(global));
    9065           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(global));
    9066             : 
    9067             :   // That might have ended up wrapping us already, due to the wonders
    9068             :   // of XBL.  Check for that, and bail out as needed.
    9069           0 :   aReflector.set(aCache->GetWrapper());
    9070           0 :   if (aReflector) {
    9071             : #ifdef DEBUG
    9072           0 :     binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
    9073             : #endif // DEBUG
    9074           0 :     return true;
    9075             :   }
    9076             : 
    9077           0 :   JSAutoCompartment ac(aCx, global);
    9078           0 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
    9079           0 :   if (!canonicalProto) {
    9080           0 :     return false;
    9081             :   }
    9082           0 :   JS::Rooted<JSObject*> proto(aCx);
    9083           0 :   if (aGivenProto) {
    9084           0 :     proto = aGivenProto;
    9085             :     // Unfortunately, while aGivenProto was in the compartment of aCx
    9086             :     // coming in, we changed compartments to that of "parent" so may need
    9087             :     // to wrap the proto here.
    9088           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
    9089           0 :       if (!JS_WrapObject(aCx, &proto)) {
    9090           0 :         return false;
    9091             :       }
    9092             :     }
    9093             :   } else {
    9094           0 :     proto = canonicalProto;
    9095             :   }
    9096             : 
    9097           0 :   BindingJSObjectCreator<mozilla::dom::TestInterfaceSetlikeNode> creator(aCx);
    9098           0 :   creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
    9099           0 :   if (!aReflector) {
    9100           0 :     return false;
    9101             :   }
    9102             : 
    9103           0 :   aCache->SetWrapper(aReflector);
    9104           0 :   creator.InitializationSucceeded();
    9105             : 
    9106           0 :   MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
    9107             :              aCache->GetWrapperPreserveColor() == aReflector);
    9108             :   // If proto != canonicalProto, we have to preserve our wrapper;
    9109             :   // otherwise we won't be able to properly recreate it later, since
    9110             :   // we won't know what proto to use.  Note that we don't check
    9111             :   // aGivenProto here, since it's entirely possible (and even
    9112             :   // somewhat common) to have a non-null aGivenProto which is the
    9113             :   // same as canonicalProto.
    9114           0 :   if (proto != canonicalProto) {
    9115           0 :     PreserveWrapper(aObject);
    9116             :   }
    9117             : 
    9118           0 :   return true;
    9119             : }
    9120             : 
    9121             : // This may allocate too many slots, because we only really need
    9122             : // slots for our non-interface-typed members that we cache.  But
    9123             : // allocating slots only for those would make the slot index
    9124             : // computations much more complicated, so let's do this the simple
    9125             : // way for now.
    9126             : DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 1);
    9127             : 
    9128             : const NativePropertyHooks sNativePropertyHooks[] = { {
    9129             :   nullptr,
    9130             :   nullptr,
    9131             :   nullptr,
    9132             :   { sNativeProperties.Upcast(), nullptr },
    9133             :   prototypes::id::TestInterfaceSetlikeNode,
    9134             :   constructors::id::TestInterfaceSetlikeNode,
    9135             :   nullptr,
    9136             :   &sXrayExpandoObjectClass
    9137             : } };
    9138             : 
    9139             : void
    9140           0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    9141             : {
    9142           0 :   JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
    9143           0 :   if (!parentProto) {
    9144           0 :     return;
    9145             :   }
    9146             : 
    9147           0 :   JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
    9148           0 :   if (!constructorProto) {
    9149           0 :     return;
    9150             :   }
    9151             : 
    9152             :   static bool sIdsInited = false;
    9153           0 :   if (!sIdsInited && NS_IsMainThread()) {
    9154           0 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
    9155           0 :       return;
    9156             :     }
    9157           0 :     sIdsInited = true;
    9158             :   }
    9159             : 
    9160           0 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::TestInterfaceSetlikeNode);
    9161           0 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::TestInterfaceSetlikeNode);
    9162           0 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    9163             :                               &sPrototypeClass.mBase, protoCache,
    9164             :                               constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
    9165             :                               interfaceCache,
    9166             :                               sNativeProperties.Upcast(),
    9167             :                               nullptr,
    9168             :                               "TestInterfaceSetlikeNode", aDefineOnGlobal,
    9169             :                               nullptr,
    9170           0 :                               false);
    9171             : 
    9172             :   // Set up aliases on the interface prototype object we just created.
    9173           0 :   JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx);
    9174           0 :   if (!proto) {
    9175           0 :     *protoCache = nullptr;
    9176           0 :     if (interfaceCache) {
    9177           0 :       *interfaceCache = nullptr;
    9178             :     }
    9179           0 :     return;
    9180             :   }
    9181             : 
    9182           0 :   JS::Rooted<JS::Value> aliasedVal(aCx);
    9183             : 
    9184           0 :   if (!JS_GetProperty(aCx, proto, "values", &aliasedVal)) {
    9185           0 :     *protoCache = nullptr;
    9186           0 :     if (interfaceCache) {
    9187           0 :       *interfaceCache = nullptr;
    9188             :     }
    9189           0 :     return;
    9190             :   }
    9191           0 :   JS::Rooted<jsid> iteratorId(aCx, SYMBOL_TO_JSID(JS::GetWellKnownSymbol(aCx, JS::SymbolCode::iterator)));
    9192           0 :   if (!JS_DefinePropertyById(aCx, proto, iteratorId, aliasedVal, 0)) {
    9193           0 :     *protoCache = nullptr;
    9194           0 :     if (interfaceCache) {
    9195           0 :       *interfaceCache = nullptr;
    9196             :     }
    9197           0 :     return;
    9198             :   }
    9199             : }
    9200             : 
    9201             : JS::Handle<JSObject*>
    9202           0 : GetProtoObjectHandle(JSContext* aCx)
    9203             : {
    9204             :   /* Get the interface prototype object for this class.  This will create the
    9205             :      object as needed. */
    9206           0 :   bool aDefineOnGlobal = true;
    9207             : 
    9208             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    9209           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    9210           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    9211           0 :     return nullptr;
    9212             :   }
    9213             : 
    9214             :   /* Check to see whether the interface objects are already installed */
    9215           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    9216           0 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::TestInterfaceSetlikeNode)) {
    9217           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    9218           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    9219             :   }
    9220             : 
    9221             :   /*
    9222             :    * The object might _still_ be null, but that's OK.
    9223             :    *
    9224             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    9225             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    9226             :    * changed after they have been set.
    9227             :    *
    9228             :    * Calling address() avoids the read read barrier that does gray
    9229             :    * unmarking, but it's not possible for the object to be gray here.
    9230             :    */
    9231             : 
    9232           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::TestInterfaceSetlikeNode);
    9233           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    9234           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    9235             : }
    9236             : 
    9237             : JS::Handle<JSObject*>
    9238           0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
    9239             : {
    9240             :   /* Get the interface object for this class.  This will create the object as
    9241             :      needed. */
    9242             : 
    9243             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    9244           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    9245           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    9246           0 :     return nullptr;
    9247             :   }
    9248             : 
    9249             :   /* Check to see whether the interface objects are already installed */
    9250           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    9251           0 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::TestInterfaceSetlikeNode)) {
    9252           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    9253           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    9254             :   }
    9255             : 
    9256             :   /*
    9257             :    * The object might _still_ be null, but that's OK.
    9258             :    *
    9259             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    9260             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    9261             :    * changed after they have been set.
    9262             :    *
    9263             :    * Calling address() avoids the read read barrier that does gray
    9264             :    * unmarking, but it's not possible for the object to be gray here.
    9265             :    */
    9266             : 
    9267           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::TestInterfaceSetlikeNode);
    9268           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    9269           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    9270             : }
    9271             : 
    9272             : JSObject*
    9273           0 : GetConstructorObject(JSContext* aCx)
    9274             : {
    9275           0 :   return GetConstructorObjectHandle(aCx);
    9276             : }
    9277             : 
    9278             : } // namespace TestInterfaceSetlikeNodeBinding
    9279             : 
    9280             : 
    9281             : 
    9282             : void
    9283           0 : TestInterfaceJSMaplikeJSImpl::SetInternal(const nsAString& aKey, int32_t aValue, ErrorResult& aRv, JSCompartment* aCompartment)
    9284             : {
    9285           0 :   CallSetup s(this, aRv, "TestInterfaceJSMaplike.setInternal", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    9286           0 :   JSContext* cx = s.GetContext();
    9287           0 :   if (!cx) {
    9288           0 :     MOZ_ASSERT(aRv.Failed());
    9289           0 :     return;
    9290             :   }
    9291           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    9292           0 :   JS::AutoValueVector argv(cx);
    9293           0 :   if (!argv.resize(2)) {
    9294           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    9295           0 :     return;
    9296             :   }
    9297           0 :   unsigned argc = 2;
    9298             : 
    9299             :   do {
    9300           0 :     argv[1].setInt32(int32_t(aValue));
    9301           0 :     break;
    9302             :   } while (0);
    9303             : 
    9304             :   do {
    9305           0 :     nsString mutableStr(aKey);
    9306           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    9307           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    9308           0 :       return;
    9309             :     }
    9310           0 :     break;
    9311             :   } while (0);
    9312             : 
    9313           0 :   JS::Rooted<JS::Value> callable(cx);
    9314           0 :   TestInterfaceJSMaplikeAtoms* atomsCache = GetAtomCache<TestInterfaceJSMaplikeAtoms>(cx);
    9315           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    9316           0 :       !GetCallableProperty(cx, atomsCache->setInternal_id, &callable)) {
    9317           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9318           0 :     return;
    9319             :   }
    9320           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    9321           0 :   if (!JS::Call(cx, thisValue, callable,
    9322           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    9323           0 :     aRv.NoteJSContextException(cx);
    9324           0 :     return;
    9325             :   }
    9326             : }
    9327             : 
    9328             : void
    9329           0 : TestInterfaceJSMaplikeJSImpl::ClearInternal(ErrorResult& aRv, JSCompartment* aCompartment)
    9330             : {
    9331           0 :   CallSetup s(this, aRv, "TestInterfaceJSMaplike.clearInternal", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    9332           0 :   JSContext* cx = s.GetContext();
    9333           0 :   if (!cx) {
    9334           0 :     MOZ_ASSERT(aRv.Failed());
    9335           0 :     return;
    9336             :   }
    9337           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    9338             : 
    9339           0 :   JS::Rooted<JS::Value> callable(cx);
    9340           0 :   TestInterfaceJSMaplikeAtoms* atomsCache = GetAtomCache<TestInterfaceJSMaplikeAtoms>(cx);
    9341           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    9342           0 :       !GetCallableProperty(cx, atomsCache->clearInternal_id, &callable)) {
    9343           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9344           0 :     return;
    9345             :   }
    9346           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    9347           0 :   if (!JS::Call(cx, thisValue, callable,
    9348           0 :                 JS::HandleValueArray::empty(), &rval)) {
    9349           0 :     aRv.NoteJSContextException(cx);
    9350           0 :     return;
    9351             :   }
    9352             : }
    9353             : 
    9354             : bool
    9355           0 : TestInterfaceJSMaplikeJSImpl::DeleteInternal(const nsAString& aKey, ErrorResult& aRv, JSCompartment* aCompartment)
    9356             : {
    9357           0 :   CallSetup s(this, aRv, "TestInterfaceJSMaplike.deleteInternal", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    9358           0 :   JSContext* cx = s.GetContext();
    9359           0 :   if (!cx) {
    9360           0 :     MOZ_ASSERT(aRv.Failed());
    9361           0 :     return bool(0);
    9362             :   }
    9363           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    9364           0 :   JS::AutoValueVector argv(cx);
    9365           0 :   if (!argv.resize(1)) {
    9366           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    9367           0 :     return bool(0);
    9368             :   }
    9369           0 :   unsigned argc = 1;
    9370             : 
    9371             :   do {
    9372           0 :     nsString mutableStr(aKey);
    9373           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    9374           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    9375           0 :       return bool(0);
    9376             :     }
    9377           0 :     break;
    9378             :   } while (0);
    9379             : 
    9380           0 :   JS::Rooted<JS::Value> callable(cx);
    9381           0 :   TestInterfaceJSMaplikeAtoms* atomsCache = GetAtomCache<TestInterfaceJSMaplikeAtoms>(cx);
    9382           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    9383           0 :       !GetCallableProperty(cx, atomsCache->deleteInternal_id, &callable)) {
    9384           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9385           0 :     return bool(0);
    9386             :   }
    9387           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    9388           0 :   if (!JS::Call(cx, thisValue, callable,
    9389           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    9390           0 :     aRv.NoteJSContextException(cx);
    9391           0 :     return bool(0);
    9392             :   }
    9393             :   bool rvalDecl;
    9394           0 :   if (!ValueToPrimitive<bool, eDefault>(cx, rval, &rvalDecl)) {
    9395           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9396           0 :     return bool(0);
    9397             :   }
    9398           0 :   return rvalDecl;
    9399             : }
    9400             : 
    9401             : void
    9402           0 : TestInterfaceJSMaplikeJSImpl::Entries(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    9403             : {
    9404           0 :   CallSetup s(this, aRv, "TestInterfaceJSMaplike.entries", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    9405           0 :   JSContext* cx = s.GetContext();
    9406           0 :   if (!cx) {
    9407           0 :     MOZ_ASSERT(aRv.Failed());
    9408           0 :     return;
    9409             :   }
    9410           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    9411             : 
    9412           0 :   JS::Rooted<JS::Value> callable(cx);
    9413           0 :   TestInterfaceJSMaplikeAtoms* atomsCache = GetAtomCache<TestInterfaceJSMaplikeAtoms>(cx);
    9414           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    9415           0 :       !GetCallableProperty(cx, atomsCache->entries_id, &callable)) {
    9416           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9417           0 :     return;
    9418             :   }
    9419           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    9420           0 :   if (!JS::Call(cx, thisValue, callable,
    9421           0 :                 JS::HandleValueArray::empty(), &rval)) {
    9422           0 :     aRv.NoteJSContextException(cx);
    9423           0 :     return;
    9424             :   }
    9425           0 :   JS::Rooted<JSObject*> rvalDecl(cx);
    9426           0 :   if (rval.isObject()) {
    9427             : #ifdef __clang__
    9428             : #pragma clang diagnostic push
    9429             : #pragma clang diagnostic ignored "-Wunreachable-code"
    9430             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    9431             : #endif // __clang__
    9432           0 :     if ((false) && !CallerSubsumes(rval)) {
    9433           0 :       ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "return value of TestInterfaceJSMaplike.entries");
    9434           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    9435           0 :       return;
    9436             :     }
    9437             : #ifdef __clang__
    9438             : #pragma clang diagnostic pop
    9439             : #endif // __clang__
    9440           0 :     rvalDecl = &rval.toObject();
    9441             :   } else {
    9442           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of TestInterfaceJSMaplike.entries");
    9443           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9444           0 :     return;
    9445             :   }
    9446           0 :   aRetVal.set(rvalDecl);
    9447             : }
    9448             : 
    9449             : void
    9450           0 : TestInterfaceJSMaplikeJSImpl::Keys(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    9451             : {
    9452           0 :   CallSetup s(this, aRv, "TestInterfaceJSMaplike.keys", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    9453           0 :   JSContext* cx = s.GetContext();
    9454           0 :   if (!cx) {
    9455           0 :     MOZ_ASSERT(aRv.Failed());
    9456           0 :     return;
    9457             :   }
    9458           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    9459             : 
    9460           0 :   JS::Rooted<JS::Value> callable(cx);
    9461           0 :   TestInterfaceJSMaplikeAtoms* atomsCache = GetAtomCache<TestInterfaceJSMaplikeAtoms>(cx);
    9462           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    9463           0 :       !GetCallableProperty(cx, atomsCache->keys_id, &callable)) {
    9464           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9465           0 :     return;
    9466             :   }
    9467           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    9468           0 :   if (!JS::Call(cx, thisValue, callable,
    9469           0 :                 JS::HandleValueArray::empty(), &rval)) {
    9470           0 :     aRv.NoteJSContextException(cx);
    9471           0 :     return;
    9472             :   }
    9473           0 :   JS::Rooted<JSObject*> rvalDecl(cx);
    9474           0 :   if (rval.isObject()) {
    9475             : #ifdef __clang__
    9476             : #pragma clang diagnostic push
    9477             : #pragma clang diagnostic ignored "-Wunreachable-code"
    9478             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    9479             : #endif // __clang__
    9480           0 :     if ((false) && !CallerSubsumes(rval)) {
    9481           0 :       ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "return value of TestInterfaceJSMaplike.keys");
    9482           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    9483           0 :       return;
    9484             :     }
    9485             : #ifdef __clang__
    9486             : #pragma clang diagnostic pop
    9487             : #endif // __clang__
    9488           0 :     rvalDecl = &rval.toObject();
    9489             :   } else {
    9490           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of TestInterfaceJSMaplike.keys");
    9491           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9492           0 :     return;
    9493             :   }
    9494           0 :   aRetVal.set(rvalDecl);
    9495             : }
    9496             : 
    9497             : void
    9498           0 : TestInterfaceJSMaplikeJSImpl::Values(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    9499             : {
    9500           0 :   CallSetup s(this, aRv, "TestInterfaceJSMaplike.values", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    9501           0 :   JSContext* cx = s.GetContext();
    9502           0 :   if (!cx) {
    9503           0 :     MOZ_ASSERT(aRv.Failed());
    9504           0 :     return;
    9505             :   }
    9506           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    9507             : 
    9508           0 :   JS::Rooted<JS::Value> callable(cx);
    9509           0 :   TestInterfaceJSMaplikeAtoms* atomsCache = GetAtomCache<TestInterfaceJSMaplikeAtoms>(cx);
    9510           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    9511           0 :       !GetCallableProperty(cx, atomsCache->values_id, &callable)) {
    9512           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9513           0 :     return;
    9514             :   }
    9515           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    9516           0 :   if (!JS::Call(cx, thisValue, callable,
    9517           0 :                 JS::HandleValueArray::empty(), &rval)) {
    9518           0 :     aRv.NoteJSContextException(cx);
    9519           0 :     return;
    9520             :   }
    9521           0 :   JS::Rooted<JSObject*> rvalDecl(cx);
    9522           0 :   if (rval.isObject()) {
    9523             : #ifdef __clang__
    9524             : #pragma clang diagnostic push
    9525             : #pragma clang diagnostic ignored "-Wunreachable-code"
    9526             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    9527             : #endif // __clang__
    9528           0 :     if ((false) && !CallerSubsumes(rval)) {
    9529           0 :       ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "return value of TestInterfaceJSMaplike.values");
    9530           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    9531           0 :       return;
    9532             :     }
    9533             : #ifdef __clang__
    9534             : #pragma clang diagnostic pop
    9535             : #endif // __clang__
    9536           0 :     rvalDecl = &rval.toObject();
    9537             :   } else {
    9538           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of TestInterfaceJSMaplike.values");
    9539           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9540           0 :     return;
    9541             :   }
    9542           0 :   aRetVal.set(rvalDecl);
    9543             : }
    9544             : 
    9545             : void
    9546           0 : TestInterfaceJSMaplikeJSImpl::ForEach(JS::Handle<JSObject*> callback, JS::Handle<JS::Value> thisArg, ErrorResult& aRv, JSCompartment* aCompartment)
    9547             : {
    9548           0 :   CallSetup s(this, aRv, "TestInterfaceJSMaplike.forEach", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    9549           0 :   JSContext* cx = s.GetContext();
    9550           0 :   if (!cx) {
    9551           0 :     MOZ_ASSERT(aRv.Failed());
    9552           0 :     return;
    9553             :   }
    9554           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    9555           0 :   JS::AutoValueVector argv(cx);
    9556           0 :   if (!argv.resize(2)) {
    9557           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    9558           0 :     return;
    9559             :   }
    9560           0 :   unsigned argc = 2;
    9561             : 
    9562             :   do {
    9563           0 :     JS::ExposeValueToActiveJS(thisArg);
    9564           0 :     argv[1].set(thisArg);
    9565           0 :     if (!MaybeWrapValue(cx, argv[1])) {
    9566           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    9567           0 :       return;
    9568             :     }
    9569           0 :     break;
    9570             :   } while (0);
    9571             : 
    9572             :   do {
    9573           0 :     JS::ExposeObjectToActiveJS(callback);
    9574           0 :     argv[0].setObject(*callback);
    9575           0 :     if (!MaybeWrapObjectValue(cx, argv[0])) {
    9576           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    9577           0 :       return;
    9578             :     }
    9579           0 :     break;
    9580             :   } while (0);
    9581             : 
    9582           0 :   JS::Rooted<JS::Value> callable(cx);
    9583           0 :   TestInterfaceJSMaplikeAtoms* atomsCache = GetAtomCache<TestInterfaceJSMaplikeAtoms>(cx);
    9584           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    9585           0 :       !GetCallableProperty(cx, atomsCache->forEach_id, &callable)) {
    9586           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9587           0 :     return;
    9588             :   }
    9589           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    9590           0 :   if (!JS::Call(cx, thisValue, callable,
    9591           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    9592           0 :     aRv.NoteJSContextException(cx);
    9593           0 :     return;
    9594             :   }
    9595             : }
    9596             : 
    9597             : bool
    9598           0 : TestInterfaceJSMaplikeJSImpl::Has(const nsAString& key, ErrorResult& aRv, JSCompartment* aCompartment)
    9599             : {
    9600           0 :   CallSetup s(this, aRv, "TestInterfaceJSMaplike.has", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    9601           0 :   JSContext* cx = s.GetContext();
    9602           0 :   if (!cx) {
    9603           0 :     MOZ_ASSERT(aRv.Failed());
    9604           0 :     return bool(0);
    9605             :   }
    9606           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    9607           0 :   JS::AutoValueVector argv(cx);
    9608           0 :   if (!argv.resize(1)) {
    9609           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    9610           0 :     return bool(0);
    9611             :   }
    9612           0 :   unsigned argc = 1;
    9613             : 
    9614             :   do {
    9615           0 :     nsString mutableStr(key);
    9616           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    9617           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    9618           0 :       return bool(0);
    9619             :     }
    9620           0 :     break;
    9621             :   } while (0);
    9622             : 
    9623           0 :   JS::Rooted<JS::Value> callable(cx);
    9624           0 :   TestInterfaceJSMaplikeAtoms* atomsCache = GetAtomCache<TestInterfaceJSMaplikeAtoms>(cx);
    9625           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    9626           0 :       !GetCallableProperty(cx, atomsCache->has_id, &callable)) {
    9627           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9628           0 :     return bool(0);
    9629             :   }
    9630           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    9631           0 :   if (!JS::Call(cx, thisValue, callable,
    9632           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    9633           0 :     aRv.NoteJSContextException(cx);
    9634           0 :     return bool(0);
    9635             :   }
    9636             :   bool rvalDecl;
    9637           0 :   if (!ValueToPrimitive<bool, eDefault>(cx, rval, &rvalDecl)) {
    9638           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9639           0 :     return bool(0);
    9640             :   }
    9641           0 :   return rvalDecl;
    9642             : }
    9643             : 
    9644             : void
    9645           0 : TestInterfaceJSMaplikeJSImpl::__clear(ErrorResult& aRv, JSCompartment* aCompartment)
    9646             : {
    9647           0 :   CallSetup s(this, aRv, "TestInterfaceJSMaplike.__clear", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    9648           0 :   JSContext* cx = s.GetContext();
    9649           0 :   if (!cx) {
    9650           0 :     MOZ_ASSERT(aRv.Failed());
    9651           0 :     return;
    9652             :   }
    9653           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    9654             : 
    9655           0 :   JS::Rooted<JS::Value> callable(cx);
    9656           0 :   TestInterfaceJSMaplikeAtoms* atomsCache = GetAtomCache<TestInterfaceJSMaplikeAtoms>(cx);
    9657           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    9658           0 :       !GetCallableProperty(cx, atomsCache->__clear_id, &callable)) {
    9659           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9660           0 :     return;
    9661             :   }
    9662           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    9663           0 :   if (!JS::Call(cx, thisValue, callable,
    9664           0 :                 JS::HandleValueArray::empty(), &rval)) {
    9665           0 :     aRv.NoteJSContextException(cx);
    9666           0 :     return;
    9667             :   }
    9668             : }
    9669             : 
    9670             : bool
    9671           0 : TestInterfaceJSMaplikeJSImpl::__delete(const nsAString& key, ErrorResult& aRv, JSCompartment* aCompartment)
    9672             : {
    9673           0 :   CallSetup s(this, aRv, "TestInterfaceJSMaplike.__delete", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    9674           0 :   JSContext* cx = s.GetContext();
    9675           0 :   if (!cx) {
    9676           0 :     MOZ_ASSERT(aRv.Failed());
    9677           0 :     return bool(0);
    9678             :   }
    9679           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    9680           0 :   JS::AutoValueVector argv(cx);
    9681           0 :   if (!argv.resize(1)) {
    9682           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    9683           0 :     return bool(0);
    9684             :   }
    9685           0 :   unsigned argc = 1;
    9686             : 
    9687             :   do {
    9688           0 :     nsString mutableStr(key);
    9689           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    9690           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    9691           0 :       return bool(0);
    9692             :     }
    9693           0 :     break;
    9694             :   } while (0);
    9695             : 
    9696           0 :   JS::Rooted<JS::Value> callable(cx);
    9697           0 :   TestInterfaceJSMaplikeAtoms* atomsCache = GetAtomCache<TestInterfaceJSMaplikeAtoms>(cx);
    9698           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    9699           0 :       !GetCallableProperty(cx, atomsCache->__delete_id, &callable)) {
    9700           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9701           0 :     return bool(0);
    9702             :   }
    9703           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    9704           0 :   if (!JS::Call(cx, thisValue, callable,
    9705           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    9706           0 :     aRv.NoteJSContextException(cx);
    9707           0 :     return bool(0);
    9708             :   }
    9709             :   bool rvalDecl;
    9710           0 :   if (!ValueToPrimitive<bool, eDefault>(cx, rval, &rvalDecl)) {
    9711           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9712           0 :     return bool(0);
    9713             :   }
    9714           0 :   return rvalDecl;
    9715             : }
    9716             : 
    9717             : void
    9718           0 : TestInterfaceJSMaplikeJSImpl::Get(const nsAString& key, JS::MutableHandle<JS::Value> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    9719             : {
    9720           0 :   CallSetup s(this, aRv, "TestInterfaceJSMaplike.get", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    9721           0 :   JSContext* cx = s.GetContext();
    9722           0 :   if (!cx) {
    9723           0 :     MOZ_ASSERT(aRv.Failed());
    9724           0 :     return;
    9725             :   }
    9726           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    9727           0 :   JS::AutoValueVector argv(cx);
    9728           0 :   if (!argv.resize(1)) {
    9729           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    9730           0 :     return;
    9731             :   }
    9732           0 :   unsigned argc = 1;
    9733             : 
    9734             :   do {
    9735           0 :     nsString mutableStr(key);
    9736           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    9737           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    9738           0 :       return;
    9739             :     }
    9740           0 :     break;
    9741             :   } while (0);
    9742             : 
    9743           0 :   JS::Rooted<JS::Value> callable(cx);
    9744           0 :   TestInterfaceJSMaplikeAtoms* atomsCache = GetAtomCache<TestInterfaceJSMaplikeAtoms>(cx);
    9745           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    9746           0 :       !GetCallableProperty(cx, atomsCache->get_id, &callable)) {
    9747           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9748           0 :     return;
    9749             :   }
    9750           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    9751           0 :   if (!JS::Call(cx, thisValue, callable,
    9752           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    9753           0 :     aRv.NoteJSContextException(cx);
    9754           0 :     return;
    9755             :   }
    9756           0 :   JS::Rooted<JS::Value> rvalDecl(cx);
    9757             : #ifdef __clang__
    9758             : #pragma clang diagnostic push
    9759             : #pragma clang diagnostic ignored "-Wunreachable-code"
    9760             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    9761             : #endif // __clang__
    9762           0 :   if ((false) && !CallerSubsumes(rval)) {
    9763           0 :     ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "return value of TestInterfaceJSMaplike.get");
    9764           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9765           0 :     return;
    9766             :   }
    9767             : #ifdef __clang__
    9768             : #pragma clang diagnostic pop
    9769             : #endif // __clang__
    9770           0 :   rvalDecl = rval;
    9771           0 :   aRetVal.set(rvalDecl);
    9772             : }
    9773             : 
    9774             : void
    9775           0 : TestInterfaceJSMaplikeJSImpl::__set(const nsAString& key, int32_t value, JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    9776             : {
    9777           0 :   CallSetup s(this, aRv, "TestInterfaceJSMaplike.__set", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    9778           0 :   JSContext* cx = s.GetContext();
    9779           0 :   if (!cx) {
    9780           0 :     MOZ_ASSERT(aRv.Failed());
    9781           0 :     return;
    9782             :   }
    9783           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    9784           0 :   JS::AutoValueVector argv(cx);
    9785           0 :   if (!argv.resize(2)) {
    9786           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    9787           0 :     return;
    9788             :   }
    9789           0 :   unsigned argc = 2;
    9790             : 
    9791             :   do {
    9792           0 :     argv[1].setInt32(int32_t(value));
    9793           0 :     break;
    9794             :   } while (0);
    9795             : 
    9796             :   do {
    9797           0 :     nsString mutableStr(key);
    9798           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    9799           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    9800           0 :       return;
    9801             :     }
    9802           0 :     break;
    9803             :   } while (0);
    9804             : 
    9805           0 :   JS::Rooted<JS::Value> callable(cx);
    9806           0 :   TestInterfaceJSMaplikeAtoms* atomsCache = GetAtomCache<TestInterfaceJSMaplikeAtoms>(cx);
    9807           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    9808           0 :       !GetCallableProperty(cx, atomsCache->__set_id, &callable)) {
    9809           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9810           0 :     return;
    9811             :   }
    9812           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    9813           0 :   if (!JS::Call(cx, thisValue, callable,
    9814           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    9815           0 :     aRv.NoteJSContextException(cx);
    9816           0 :     return;
    9817             :   }
    9818           0 :   JS::Rooted<JSObject*> rvalDecl(cx);
    9819           0 :   if (rval.isObject()) {
    9820             : #ifdef __clang__
    9821             : #pragma clang diagnostic push
    9822             : #pragma clang diagnostic ignored "-Wunreachable-code"
    9823             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    9824             : #endif // __clang__
    9825           0 :     if ((false) && !CallerSubsumes(rval)) {
    9826           0 :       ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "return value of TestInterfaceJSMaplike.__set");
    9827           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    9828           0 :       return;
    9829             :     }
    9830             : #ifdef __clang__
    9831             : #pragma clang diagnostic pop
    9832             : #endif // __clang__
    9833           0 :     rvalDecl = &rval.toObject();
    9834             :   } else {
    9835           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of TestInterfaceJSMaplike.__set");
    9836           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9837           0 :     return;
    9838             :   }
    9839           0 :   aRetVal.set(rvalDecl);
    9840             : }
    9841             : 
    9842             : void
    9843           0 : TestInterfaceJSMaplikeJSImpl::__Init(ErrorResult& aRv, JSCompartment* aCompartment)
    9844             : {
    9845           0 :   CallSetup s(this, aRv, "__init", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    9846           0 :   JSContext* cx = s.GetContext();
    9847           0 :   if (!cx) {
    9848           0 :     MOZ_ASSERT(aRv.Failed());
    9849           0 :     return;
    9850             :   }
    9851           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    9852             : 
    9853           0 :   JS::Rooted<JS::Value> callable(cx);
    9854           0 :   TestInterfaceJSMaplikeAtoms* atomsCache = GetAtomCache<TestInterfaceJSMaplikeAtoms>(cx);
    9855           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    9856           0 :       !GetCallableProperty(cx, atomsCache->__init_id, &callable)) {
    9857           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9858           0 :     return;
    9859             :   }
    9860           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    9861           0 :   if (!JS::Call(cx, thisValue, callable,
    9862           0 :                 JS::HandleValueArray::empty(), &rval)) {
    9863           0 :     aRv.NoteJSContextException(cx);
    9864           0 :     return;
    9865             :   }
    9866             : }
    9867             : 
    9868             : bool
    9869           0 : TestInterfaceJSMaplikeJSImpl::InitIds(JSContext* cx, TestInterfaceJSMaplikeAtoms* atomsCache)
    9870             : {
    9871           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
    9872             : 
    9873             :   // Initialize these in reverse order so that any failure leaves the first one
    9874             :   // uninitialized.
    9875           0 :   if (!atomsCache->__init_id.init(cx, "__init") ||
    9876           0 :       !atomsCache->__set_id.init(cx, "__set") ||
    9877           0 :       !atomsCache->get_id.init(cx, "get") ||
    9878           0 :       !atomsCache->__delete_id.init(cx, "__delete") ||
    9879           0 :       !atomsCache->__clear_id.init(cx, "__clear") ||
    9880           0 :       !atomsCache->has_id.init(cx, "has") ||
    9881           0 :       !atomsCache->forEach_id.init(cx, "forEach") ||
    9882           0 :       !atomsCache->values_id.init(cx, "values") ||
    9883           0 :       !atomsCache->keys_id.init(cx, "keys") ||
    9884           0 :       !atomsCache->entries_id.init(cx, "entries") ||
    9885           0 :       !atomsCache->size_id.init(cx, "size") ||
    9886           0 :       !atomsCache->deleteInternal_id.init(cx, "deleteInternal") ||
    9887           0 :       !atomsCache->clearInternal_id.init(cx, "clearInternal") ||
    9888           0 :       !atomsCache->setInternal_id.init(cx, "setInternal")) {
    9889           0 :     return false;
    9890             :   }
    9891           0 :   return true;
    9892             : }
    9893             : 
    9894             : 
    9895             : uint32_t
    9896           0 : TestInterfaceJSMaplikeJSImpl::GetSize(ErrorResult& aRv, JSCompartment* aCompartment)
    9897             : {
    9898           0 :   CallSetup s(this, aRv, "TestInterfaceJSMaplike.size", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    9899           0 :   JSContext* cx = s.GetContext();
    9900           0 :   if (!cx) {
    9901           0 :     MOZ_ASSERT(aRv.Failed());
    9902           0 :     return uint32_t(0);
    9903             :   }
    9904           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    9905             : 
    9906           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    9907           0 :   TestInterfaceJSMaplikeAtoms* atomsCache = GetAtomCache<TestInterfaceJSMaplikeAtoms>(cx);
    9908           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    9909           0 :       !JS_GetPropertyById(cx, callback, atomsCache->size_id, &rval)) {
    9910           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9911           0 :     return uint32_t(0);
    9912             :   }
    9913             :   uint32_t rvalDecl;
    9914           0 :   if (!ValueToPrimitive<uint32_t, eDefault>(cx, rval, &rvalDecl)) {
    9915           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    9916           0 :     return uint32_t(0);
    9917             :   }
    9918           0 :   return rvalDecl;
    9919             : }
    9920             : 
    9921             : 
    9922             : NS_IMPL_CYCLE_COLLECTION_CLASS(TestInterfaceJSMaplike)
    9923           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(TestInterfaceJSMaplike)
    9924           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mImpl)
    9925           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
    9926           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
    9927           0 :   tmp->ClearWeakReferences();
    9928           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
    9929           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(TestInterfaceJSMaplike)
    9930           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImpl)
    9931           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
    9932           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
    9933           0 : NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(TestInterfaceJSMaplike)
    9934           0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(TestInterfaceJSMaplike)
    9935           0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(TestInterfaceJSMaplike)
    9936           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TestInterfaceJSMaplike)
    9937           0 :   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
    9938           0 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
    9939           0 :   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
    9940           0 : NS_INTERFACE_MAP_END
    9941             : 
    9942           0 : TestInterfaceJSMaplike::TestInterfaceJSMaplike(JS::Handle<JSObject*> aJSImplObject, nsIGlobalObject* aParent)
    9943           0 :   : mImpl(new TestInterfaceJSMaplikeJSImpl(nullptr, aJSImplObject, /* aIncumbentGlobal = */ nullptr)),
    9944           0 :     mParent(aParent)
    9945             : {
    9946           0 : }
    9947             : 
    9948             : 
    9949           0 : TestInterfaceJSMaplike::~TestInterfaceJSMaplike()
    9950             : {
    9951           0 : }
    9952             : 
    9953             : nsISupports*
    9954           0 : TestInterfaceJSMaplike::GetParentObject() const
    9955             : {
    9956           0 :   return mParent;
    9957             : }
    9958             : 
    9959             : JSObject*
    9960           0 : TestInterfaceJSMaplike::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
    9961             : {
    9962           0 :   JS::Rooted<JSObject*> obj(aCx, TestInterfaceJSMaplikeBinding::Wrap(aCx, this, aGivenProto));
    9963           0 :   if (!obj) {
    9964           0 :     return nullptr;
    9965             :   }
    9966             : 
    9967             :   // Now define it on our chrome object
    9968           0 :   JSAutoCompartment ac(aCx, mImpl->CallbackOrNull());
    9969           0 :   if (!JS_WrapObject(aCx, &obj)) {
    9970           0 :     return nullptr;
    9971             :   }
    9972           0 :   if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
    9973           0 :     return nullptr;
    9974             :   }
    9975           0 :   return obj;
    9976             : }
    9977             : 
    9978             : already_AddRefed<TestInterfaceJSMaplike>
    9979           0 : TestInterfaceJSMaplike::Constructor(const GlobalObject& global, JSContext* cx, ErrorResult& aRv)
    9980             : {
    9981           0 :   JS::Rooted<JSObject*> jsImplObj(cx);
    9982             :   nsCOMPtr<nsIGlobalObject> globalHolder =
    9983           0 :     ConstructJSImplementation("@mozilla.org/dom/test-interface-js-maplike;1", global, &jsImplObj, aRv);
    9984           0 :   if (aRv.Failed()) {
    9985           0 :     return nullptr;
    9986             :   }
    9987             :   // Build the C++ implementation.
    9988           0 :   RefPtr<TestInterfaceJSMaplike> impl = new TestInterfaceJSMaplike(jsImplObj, globalHolder);
    9989           0 :   return impl.forget();
    9990             : }
    9991             : 
    9992             : void
    9993           0 : TestInterfaceJSMaplike::SetInternal(const nsAString& aKey, int32_t aValue, ErrorResult& aRv, JSCompartment* aCompartment)
    9994             : {
    9995           0 :   return mImpl->SetInternal(aKey, aValue, aRv, aCompartment);
    9996             : }
    9997             : 
    9998             : void
    9999           0 : TestInterfaceJSMaplike::ClearInternal(ErrorResult& aRv, JSCompartment* aCompartment)
   10000             : {
   10001           0 :   return mImpl->ClearInternal(aRv, aCompartment);
   10002             : }
   10003             : 
   10004             : bool
   10005           0 : TestInterfaceJSMaplike::DeleteInternal(const nsAString& aKey, ErrorResult& aRv, JSCompartment* aCompartment)
   10006             : {
   10007           0 :   return mImpl->DeleteInternal(aKey, aRv, aCompartment);
   10008             : }
   10009             : 
   10010             : uint32_t
   10011           0 : TestInterfaceJSMaplike::GetSize(ErrorResult& aRv, JSCompartment* aCompartment) const
   10012             : {
   10013           0 :   return mImpl->GetSize(aRv, aCompartment);
   10014             : }
   10015             : 
   10016             : void
   10017           0 : TestInterfaceJSMaplike::Entries(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
   10018             : {
   10019           0 :   return mImpl->Entries(aRetVal, aRv, aCompartment);
   10020             : }
   10021             : 
   10022             : void
   10023           0 : TestInterfaceJSMaplike::Keys(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
   10024             : {
   10025           0 :   return mImpl->Keys(aRetVal, aRv, aCompartment);
   10026             : }
   10027             : 
   10028             : void
   10029           0 : TestInterfaceJSMaplike::Values(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
   10030             : {
   10031           0 :   return mImpl->Values(aRetVal, aRv, aCompartment);
   10032             : }
   10033             : 
   10034             : void
   10035           0 : TestInterfaceJSMaplike::ForEach(JS::Handle<JSObject*> callback, JS::Handle<JS::Value> thisArg, ErrorResult& aRv, JSCompartment* aCompartment)
   10036             : {
   10037           0 :   return mImpl->ForEach(callback, thisArg, aRv, aCompartment);
   10038             : }
   10039             : 
   10040             : bool
   10041           0 : TestInterfaceJSMaplike::Has(const nsAString& key, ErrorResult& aRv, JSCompartment* aCompartment)
   10042             : {
   10043           0 :   return mImpl->Has(key, aRv, aCompartment);
   10044             : }
   10045             : 
   10046             : void
   10047           0 : TestInterfaceJSMaplike::__clear(ErrorResult& aRv, JSCompartment* aCompartment)
   10048             : {
   10049           0 :   return mImpl->__clear(aRv, aCompartment);
   10050             : }
   10051             : 
   10052             : bool
   10053           0 : TestInterfaceJSMaplike::__delete(const nsAString& key, ErrorResult& aRv, JSCompartment* aCompartment)
   10054             : {
   10055           0 :   return mImpl->__delete(key, aRv, aCompartment);
   10056             : }
   10057             : 
   10058             : void
   10059           0 : TestInterfaceJSMaplike::Get(const nsAString& key, JS::MutableHandle<JS::Value> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
   10060             : {
   10061           0 :   return mImpl->Get(key, aRetVal, aRv, aCompartment);
   10062             : }
   10063             : 
   10064             : void
   10065           0 : TestInterfaceJSMaplike::__set(const nsAString& key, int32_t value, JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
   10066             : {
   10067           0 :   return mImpl->__set(key, value, aRetVal, aRv, aCompartment);
   10068             : }
   10069             : 
   10070             : bool
   10071           0 : TestInterfaceJSMaplike::_Create(JSContext* cx, unsigned argc, JS::Value* vp)
   10072             : {
   10073           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
   10074           0 :   if (args.length() < 2) {
   10075           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJSMaplike._create");
   10076             :   }
   10077           0 :   if (!args[0].isObject()) {
   10078           0 :     return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of TestInterfaceJSMaplike._create");
   10079             :   }
   10080           0 :   if (!args[1].isObject()) {
   10081           0 :     return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of TestInterfaceJSMaplike._create");
   10082             :   }
   10083             : 
   10084             :   // GlobalObject will go through wrappers as needed for us, and
   10085             :   // is simpler than the right UnwrapArg incantation.
   10086           0 :   GlobalObject global(cx, &args[0].toObject());
   10087           0 :   if (global.Failed()) {
   10088           0 :     return false;
   10089             :   }
   10090           0 :   nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports());
   10091           0 :   MOZ_ASSERT(globalHolder);
   10092           0 :   JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
   10093           0 :   RefPtr<TestInterfaceJSMaplike> impl = new TestInterfaceJSMaplike(arg, globalHolder);
   10094           0 :   MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
   10095           0 :   return GetOrCreateDOMReflector(cx, impl, args.rval());
   10096             : }
   10097             : 
   10098             : 
   10099             : } // namespace dom
   10100             : } // namespace mozilla

Generated by: LCOV version 1.13