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

          Line data    Source code
       1             : /* THIS FILE IS AUTOGENERATED FROM TestInterfaceJS.webidl BY Codegen.py - DO NOT EDIT */
       2             : 
       3             : #include "AtomList.h"
       4             : #include "EventHandlerBinding.h"
       5             : #include "EventTargetBinding.h"
       6             : #include "FunctionBinding.h"
       7             : #include "PromiseBinding.h"
       8             : #include "TestInterfaceJSBinding.h"
       9             : #include "TestInterfaceJSDictionariesBinding.h"
      10             : #include "WrapperFactory.h"
      11             : #include "XrayWrapper.h"
      12             : #include "mozilla/OwningNonNull.h"
      13             : #include "mozilla/Preferences.h"
      14             : #include "mozilla/dom/BindingUtils.h"
      15             : #include "mozilla/dom/DOMJSClass.h"
      16             : #include "mozilla/dom/Location.h"
      17             : #include "mozilla/dom/NonRefcountedDOMObject.h"
      18             : #include "mozilla/dom/Nullable.h"
      19             : #include "mozilla/dom/PrimitiveConversions.h"
      20             : #include "mozilla/dom/Promise.h"
      21             : #include "mozilla/dom/ScriptSettings.h"
      22             : #include "mozilla/dom/ToJSValue.h"
      23             : #include "mozilla/dom/UnionConversions.h"
      24             : #include "mozilla/dom/UnionTypes.h"
      25             : #include "mozilla/dom/XrayExpandoClass.h"
      26             : #include "nsContentUtils.h"
      27             : #include "nsIGlobalObject.h"
      28             : 
      29             : namespace mozilla {
      30             : namespace dom {
      31             : 
      32             : void
      33           0 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningLocationOrTestInterfaceJS& aUnion, const char* aName, uint32_t aFlags)
      34             : {
      35           0 :   if (aUnion.IsLocation()) {
      36           0 :     ImplCycleCollectionTraverse(aCallback, aUnion.GetAsLocation(), "mLocation", aFlags);
      37           0 :   } else if (aUnion.IsTestInterfaceJS()) {
      38           0 :     ImplCycleCollectionTraverse(aCallback, aUnion.GetAsTestInterfaceJS(), "mTestInterfaceJS", aFlags);
      39             :   }
      40           0 : }
      41             : 
      42             : 
      43             : void
      44           0 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningStringOrTestInterfaceJSOrNull& aUnion, const char* aName, uint32_t aFlags)
      45             : {
      46           0 :   if (aUnion.IsTestInterfaceJS()) {
      47           0 :     ImplCycleCollectionTraverse(aCallback, aUnion.GetAsTestInterfaceJS(), "mTestInterfaceJS", aFlags);
      48             :   }
      49           0 : }
      50             : 
      51             : 
      52             : void
      53           0 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningTestInterfaceJSOrLong& aUnion, const char* aName, uint32_t aFlags)
      54             : {
      55           0 :   if (aUnion.IsTestInterfaceJS()) {
      56           0 :     ImplCycleCollectionTraverse(aCallback, aUnion.GetAsTestInterfaceJS(), "mTestInterfaceJS", aFlags);
      57             :   }
      58           0 : }
      59             : 
      60             : 
      61             : void
      62           0 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningTestInterfaceJSOrNullOrString& aUnion, const char* aName, uint32_t aFlags)
      63             : {
      64           0 :   if (aUnion.IsTestInterfaceJS()) {
      65           0 :     ImplCycleCollectionTraverse(aCallback, aUnion.GetAsTestInterfaceJS(), "mTestInterfaceJS", aFlags);
      66             :   }
      67           0 : }
      68             : 
      69             : 
      70             : void
      71           0 : ImplCycleCollectionUnlink(OwningLocationOrTestInterfaceJS& aUnion)
      72             : {
      73           0 :   aUnion.Uninit();
      74           0 : }
      75             : 
      76             : 
      77             : void
      78           0 : ImplCycleCollectionUnlink(OwningStringOrTestInterfaceJSOrNull& aUnion)
      79             : {
      80           0 :   aUnion.Uninit();
      81           0 : }
      82             : 
      83             : 
      84             : void
      85           0 : ImplCycleCollectionUnlink(OwningTestInterfaceJSOrLong& aUnion)
      86             : {
      87           0 :   aUnion.Uninit();
      88           0 : }
      89             : 
      90             : 
      91             : void
      92           0 : ImplCycleCollectionUnlink(OwningTestInterfaceJSOrNullOrString& aUnion)
      93             : {
      94           0 :   aUnion.Uninit();
      95           0 : }
      96             : 
      97             : 
      98             : bool
      99           0 : LocationOrTestInterfaceJS::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
     100             : {
     101           0 :   switch (mType) {
     102             :     case eUninitialized: {
     103           0 :       return false;
     104             :       break;
     105             :     }
     106             :     case eLocation: {
     107           0 :       if (!GetOrCreateDOMReflector(cx, mValue.mLocation.Value(), rval)) {
     108           0 :         MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     109           0 :         return false;
     110             :       }
     111           0 :       return true;
     112             :       break;
     113             :     }
     114             :     case eTestInterfaceJS: {
     115           0 :       if (!GetOrCreateDOMReflector(cx, mValue.mTestInterfaceJS.Value(), rval)) {
     116           0 :         MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     117           0 :         return false;
     118             :       }
     119           0 :       return true;
     120             :       break;
     121             :     }
     122             :     default: {
     123           0 :       return false;
     124             :       break;
     125             :     }
     126             :   }
     127             : 
     128             :   return false;
     129             : }
     130             : 
     131             : 
     132             : OwningNonNull<mozilla::dom::Location>&
     133           0 : OwningLocationOrTestInterfaceJS::RawSetAsLocation()
     134             : {
     135           0 :   if (mType == eLocation) {
     136           0 :     return mValue.mLocation.Value();
     137             :   }
     138           0 :   MOZ_ASSERT(mType == eUninitialized);
     139           0 :   mType = eLocation;
     140           0 :   return mValue.mLocation.SetValue();
     141             : }
     142             : 
     143             : OwningNonNull<mozilla::dom::Location>&
     144           0 : OwningLocationOrTestInterfaceJS::SetAsLocation()
     145             : {
     146           0 :   if (mType == eLocation) {
     147           0 :     return mValue.mLocation.Value();
     148             :   }
     149           0 :   Uninit();
     150           0 :   mType = eLocation;
     151           0 :   return mValue.mLocation.SetValue();
     152             : }
     153             : 
     154             : bool
     155           0 : OwningLocationOrTestInterfaceJS::TrySetToLocation(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
     156             : {
     157           0 :   tryNext = false;
     158             :   { // scope for memberSlot
     159           0 :     OwningNonNull<mozilla::dom::Location>& memberSlot = RawSetAsLocation();
     160             :     static_assert(IsRefcounted<mozilla::dom::Location>::value, "We can only store refcounted classes.");{
     161           0 :       nsresult rv = UnwrapObject<prototypes::id::Location, mozilla::dom::Location>(value, memberSlot);
     162           0 :       if (NS_FAILED(rv)) {
     163           0 :         DestroyLocation();
     164           0 :         tryNext = true;
     165           0 :         return true;
     166             :       }
     167             :     }
     168             :   }
     169           0 :   return true;
     170             : }
     171             : 
     172             : void
     173           0 : OwningLocationOrTestInterfaceJS::DestroyLocation()
     174             : {
     175           0 :   MOZ_ASSERT(IsLocation(), "Wrong type!");
     176           0 :   mValue.mLocation.Destroy();
     177           0 :   mType = eUninitialized;
     178           0 : }
     179             : 
     180             : 
     181             : 
     182             : 
     183             : OwningNonNull<mozilla::dom::TestInterfaceJS>&
     184           0 : OwningLocationOrTestInterfaceJS::RawSetAsTestInterfaceJS()
     185             : {
     186           0 :   if (mType == eTestInterfaceJS) {
     187           0 :     return mValue.mTestInterfaceJS.Value();
     188             :   }
     189           0 :   MOZ_ASSERT(mType == eUninitialized);
     190           0 :   mType = eTestInterfaceJS;
     191           0 :   return mValue.mTestInterfaceJS.SetValue();
     192             : }
     193             : 
     194             : OwningNonNull<mozilla::dom::TestInterfaceJS>&
     195           0 : OwningLocationOrTestInterfaceJS::SetAsTestInterfaceJS()
     196             : {
     197           0 :   if (mType == eTestInterfaceJS) {
     198           0 :     return mValue.mTestInterfaceJS.Value();
     199             :   }
     200           0 :   Uninit();
     201           0 :   mType = eTestInterfaceJS;
     202           0 :   return mValue.mTestInterfaceJS.SetValue();
     203             : }
     204             : 
     205             : bool
     206           0 : OwningLocationOrTestInterfaceJS::TrySetToTestInterfaceJS(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
     207             : {
     208           0 :   tryNext = false;
     209             :   { // scope for memberSlot
     210           0 :     OwningNonNull<mozilla::dom::TestInterfaceJS>& memberSlot = RawSetAsTestInterfaceJS();
     211             :     static_assert(IsRefcounted<mozilla::dom::TestInterfaceJS>::value, "We can only store refcounted classes.");{
     212           0 :       nsresult rv = UnwrapObject<prototypes::id::TestInterfaceJS, mozilla::dom::TestInterfaceJS>(value, memberSlot);
     213           0 :       if (NS_FAILED(rv)) {
     214           0 :         DestroyTestInterfaceJS();
     215           0 :         tryNext = true;
     216           0 :         return true;
     217             :       }
     218             :     }
     219             :   }
     220           0 :   return true;
     221             : }
     222             : 
     223             : void
     224           0 : OwningLocationOrTestInterfaceJS::DestroyTestInterfaceJS()
     225             : {
     226           0 :   MOZ_ASSERT(IsTestInterfaceJS(), "Wrong type!");
     227           0 :   mValue.mTestInterfaceJS.Destroy();
     228           0 :   mType = eUninitialized;
     229           0 : }
     230             : 
     231             : 
     232             : 
     233             : 
     234             : void
     235           0 : OwningLocationOrTestInterfaceJS::Uninit()
     236             : {
     237           0 :   switch (mType) {
     238             :     case eUninitialized: {
     239           0 :       break;
     240             :     }
     241             :     case eLocation: {
     242           0 :       DestroyLocation();
     243           0 :       break;
     244             :     }
     245             :     case eTestInterfaceJS: {
     246           0 :       DestroyTestInterfaceJS();
     247           0 :       break;
     248             :     }
     249             :   }
     250           0 : }
     251             : 
     252             : bool
     253           0 : OwningLocationOrTestInterfaceJS::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
     254             : {
     255           0 :   switch (mType) {
     256             :     case eUninitialized: {
     257           0 :       return false;
     258             :       break;
     259             :     }
     260             :     case eLocation: {
     261           0 :       if (!GetOrCreateDOMReflector(cx, mValue.mLocation.Value(), rval)) {
     262           0 :         MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     263           0 :         return false;
     264             :       }
     265           0 :       return true;
     266             :       break;
     267             :     }
     268             :     case eTestInterfaceJS: {
     269           0 :       if (!GetOrCreateDOMReflector(cx, mValue.mTestInterfaceJS.Value(), rval)) {
     270           0 :         MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     271           0 :         return false;
     272             :       }
     273           0 :       return true;
     274             :       break;
     275             :     }
     276             :     default: {
     277           0 :       return false;
     278             :       break;
     279             :     }
     280             :   }
     281             : 
     282             :   return false;
     283             : }
     284             : 
     285             : void
     286           0 : OwningLocationOrTestInterfaceJS::TraceUnion(JSTracer* trc)
     287             : {
     288           0 : }
     289             : 
     290             : OwningLocationOrTestInterfaceJS&
     291           0 : OwningLocationOrTestInterfaceJS::operator=(const OwningLocationOrTestInterfaceJS& aOther)
     292             : {
     293           0 :   switch (aOther.mType) {
     294             :     case eUninitialized: {
     295           0 :       MOZ_ASSERT(mType == eUninitialized,
     296             :                  "We need to destroy ourselves?");
     297           0 :       break;
     298             :     }
     299             :     case eLocation: {
     300           0 :       SetAsLocation() = aOther.GetAsLocation();
     301           0 :       break;
     302             :     }
     303             :     case eTestInterfaceJS: {
     304           0 :       SetAsTestInterfaceJS() = aOther.GetAsTestInterfaceJS();
     305           0 :       break;
     306             :     }
     307             :   }
     308           0 :   return *this;
     309             : }
     310             : 
     311             : 
     312             : bool
     313           0 : StringOrTestInterfaceJSOrNull::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
     314             : {
     315           0 :   switch (mType) {
     316             :     case eUninitialized: {
     317           0 :       return false;
     318             :       break;
     319             :     }
     320             :     case eNull: {
     321           0 :       rval.setNull();
     322           0 :       return true;
     323             :       break;
     324             :     }
     325             :     case eString: {
     326           0 :       if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
     327           0 :         return false;
     328             :       }
     329           0 :       return true;
     330             :       break;
     331             :     }
     332             :     case eTestInterfaceJS: {
     333           0 :       if (!GetOrCreateDOMReflector(cx, mValue.mTestInterfaceJS.Value(), rval)) {
     334           0 :         MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     335           0 :         return false;
     336             :       }
     337           0 :       return true;
     338             :       break;
     339             :     }
     340             :     default: {
     341           0 :       return false;
     342             :       break;
     343             :     }
     344             :   }
     345             : 
     346             :   return false;
     347             : }
     348             : 
     349             : 
     350             : nsString&
     351           0 : OwningStringOrTestInterfaceJSOrNull::RawSetAsString()
     352             : {
     353           0 :   if (mType == eString) {
     354           0 :     return mValue.mString.Value();
     355             :   }
     356           0 :   MOZ_ASSERT(mType == eUninitialized);
     357           0 :   mType = eString;
     358           0 :   return mValue.mString.SetValue();
     359             : }
     360             : 
     361             : nsString&
     362           0 : OwningStringOrTestInterfaceJSOrNull::SetAsString()
     363             : {
     364           0 :   if (mType == eString) {
     365           0 :     return mValue.mString.Value();
     366             :   }
     367           0 :   Uninit();
     368           0 :   mType = eString;
     369           0 :   return mValue.mString.SetValue();
     370             : }
     371             : 
     372             : bool
     373           0 : OwningStringOrTestInterfaceJSOrNull::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
     374             : {
     375           0 :   tryNext = false;
     376             :   { // scope for memberSlot
     377           0 :     nsString& memberSlot = RawSetAsString();
     378           0 :     if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
     379           0 :       return false;
     380             :     }
     381             :   }
     382           0 :   return true;
     383             : }
     384             : 
     385             : 
     386             : void
     387           0 : OwningStringOrTestInterfaceJSOrNull::DestroyString()
     388             : {
     389           0 :   MOZ_ASSERT(IsString(), "Wrong type!");
     390           0 :   mValue.mString.Destroy();
     391           0 :   mType = eUninitialized;
     392           0 : }
     393             : 
     394             : 
     395             : 
     396             : 
     397             : OwningNonNull<mozilla::dom::TestInterfaceJS>&
     398           0 : OwningStringOrTestInterfaceJSOrNull::RawSetAsTestInterfaceJS()
     399             : {
     400           0 :   if (mType == eTestInterfaceJS) {
     401           0 :     return mValue.mTestInterfaceJS.Value();
     402             :   }
     403           0 :   MOZ_ASSERT(mType == eUninitialized);
     404           0 :   mType = eTestInterfaceJS;
     405           0 :   return mValue.mTestInterfaceJS.SetValue();
     406             : }
     407             : 
     408             : OwningNonNull<mozilla::dom::TestInterfaceJS>&
     409           0 : OwningStringOrTestInterfaceJSOrNull::SetAsTestInterfaceJS()
     410             : {
     411           0 :   if (mType == eTestInterfaceJS) {
     412           0 :     return mValue.mTestInterfaceJS.Value();
     413             :   }
     414           0 :   Uninit();
     415           0 :   mType = eTestInterfaceJS;
     416           0 :   return mValue.mTestInterfaceJS.SetValue();
     417             : }
     418             : 
     419             : bool
     420           0 : OwningStringOrTestInterfaceJSOrNull::TrySetToTestInterfaceJS(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
     421             : {
     422           0 :   tryNext = false;
     423             :   { // scope for memberSlot
     424           0 :     OwningNonNull<mozilla::dom::TestInterfaceJS>& memberSlot = RawSetAsTestInterfaceJS();
     425             :     static_assert(IsRefcounted<mozilla::dom::TestInterfaceJS>::value, "We can only store refcounted classes.");{
     426           0 :       nsresult rv = UnwrapObject<prototypes::id::TestInterfaceJS, mozilla::dom::TestInterfaceJS>(value, memberSlot);
     427           0 :       if (NS_FAILED(rv)) {
     428           0 :         DestroyTestInterfaceJS();
     429           0 :         tryNext = true;
     430           0 :         return true;
     431             :       }
     432             :     }
     433             :   }
     434           0 :   return true;
     435             : }
     436             : 
     437             : void
     438           0 : OwningStringOrTestInterfaceJSOrNull::DestroyTestInterfaceJS()
     439             : {
     440           0 :   MOZ_ASSERT(IsTestInterfaceJS(), "Wrong type!");
     441           0 :   mValue.mTestInterfaceJS.Destroy();
     442           0 :   mType = eUninitialized;
     443           0 : }
     444             : 
     445             : 
     446             : 
     447             : 
     448             : void
     449           0 : OwningStringOrTestInterfaceJSOrNull::Uninit()
     450             : {
     451           0 :   switch (mType) {
     452             :     case eUninitialized: {
     453           0 :       break;
     454             :     }
     455             :     case eNull: {
     456           0 :       break;
     457             :     }
     458             :     case eString: {
     459           0 :       DestroyString();
     460           0 :       break;
     461             :     }
     462             :     case eTestInterfaceJS: {
     463           0 :       DestroyTestInterfaceJS();
     464           0 :       break;
     465             :     }
     466             :   }
     467           0 : }
     468             : 
     469             : bool
     470           0 : OwningStringOrTestInterfaceJSOrNull::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
     471             : {
     472           0 :   switch (mType) {
     473             :     case eUninitialized: {
     474           0 :       return false;
     475             :       break;
     476             :     }
     477             :     case eNull: {
     478           0 :       rval.setNull();
     479           0 :       return true;
     480             :       break;
     481             :     }
     482             :     case eString: {
     483           0 :       if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
     484           0 :         return false;
     485             :       }
     486           0 :       return true;
     487             :       break;
     488             :     }
     489             :     case eTestInterfaceJS: {
     490           0 :       if (!GetOrCreateDOMReflector(cx, mValue.mTestInterfaceJS.Value(), rval)) {
     491           0 :         MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     492           0 :         return false;
     493             :       }
     494           0 :       return true;
     495             :       break;
     496             :     }
     497             :     default: {
     498           0 :       return false;
     499             :       break;
     500             :     }
     501             :   }
     502             : 
     503             :   return false;
     504             : }
     505             : 
     506             : void
     507           0 : OwningStringOrTestInterfaceJSOrNull::TraceUnion(JSTracer* trc)
     508             : {
     509           0 : }
     510             : 
     511             : OwningStringOrTestInterfaceJSOrNull&
     512           0 : OwningStringOrTestInterfaceJSOrNull::operator=(const OwningStringOrTestInterfaceJSOrNull& aOther)
     513             : {
     514           0 :   switch (aOther.mType) {
     515             :     case eUninitialized: {
     516           0 :       MOZ_ASSERT(mType == eUninitialized,
     517             :                  "We need to destroy ourselves?");
     518           0 :       break;
     519             :     }
     520             :     case eNull: {
     521           0 :       MOZ_ASSERT(mType == eUninitialized);
     522           0 :       mType = eNull;
     523           0 :       break;
     524             :     }
     525             :     case eString: {
     526           0 :       SetAsString() = aOther.GetAsString();
     527           0 :       break;
     528             :     }
     529             :     case eTestInterfaceJS: {
     530           0 :       SetAsTestInterfaceJS() = aOther.GetAsTestInterfaceJS();
     531           0 :       break;
     532             :     }
     533             :   }
     534           0 :   return *this;
     535             : }
     536             : 
     537             : 
     538             : bool
     539           0 : StringSequenceOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
     540             : {
     541           0 :   switch (mType) {
     542             :     case eUninitialized: {
     543           0 :       return false;
     544             :       break;
     545             :     }
     546             :     case eStringSequence: {
     547             : 
     548           0 :       uint32_t length = mValue.mStringSequence.Value().Length();
     549           0 :       JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
     550           0 :       if (!returnArray) {
     551           0 :         return false;
     552             :       }
     553             :       // Scope for 'tmp'
     554             :       {
     555           0 :         JS::Rooted<JS::Value> tmp(cx);
     556           0 :         for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
     557             :           // Control block to let us common up the JS_DefineElement calls when there
     558             :           // are different ways to succeed at wrapping the object.
     559             :           do {
     560           0 :             if (!xpc::NonVoidStringToJsval(cx, mValue.mStringSequence.Value()[sequenceIdx0], &tmp)) {
     561           0 :               return false;
     562             :             }
     563           0 :             break;
     564             :           } while (0);
     565           0 :           if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
     566             :                                 JSPROP_ENUMERATE)) {
     567           0 :             return false;
     568             :           }
     569             :         }
     570             :       }
     571           0 :       rval.setObject(*returnArray);
     572           0 :       return true;
     573             :       break;
     574             :     }
     575             :     case eString: {
     576           0 :       if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
     577           0 :         return false;
     578             :       }
     579           0 :       return true;
     580             :       break;
     581             :     }
     582             :     default: {
     583           0 :       return false;
     584             :       break;
     585             :     }
     586             :   }
     587             : 
     588             :   return false;
     589             : }
     590             : 
     591             : 
     592             : Sequence<nsString>&
     593           0 : OwningStringSequenceOrString::RawSetAsStringSequence()
     594             : {
     595           0 :   if (mType == eStringSequence) {
     596           0 :     return mValue.mStringSequence.Value();
     597             :   }
     598           0 :   MOZ_ASSERT(mType == eUninitialized);
     599           0 :   mType = eStringSequence;
     600           0 :   return mValue.mStringSequence.SetValue();
     601             : }
     602             : 
     603             : Sequence<nsString>&
     604           0 : OwningStringSequenceOrString::SetAsStringSequence()
     605             : {
     606           0 :   if (mType == eStringSequence) {
     607           0 :     return mValue.mStringSequence.Value();
     608             :   }
     609           0 :   Uninit();
     610           0 :   mType = eStringSequence;
     611           0 :   return mValue.mStringSequence.SetValue();
     612             : }
     613             : 
     614             : bool
     615           0 : OwningStringSequenceOrString::TrySetToStringSequence(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
     616             : {
     617           0 :   tryNext = false;
     618             :   { // scope for memberSlot
     619           0 :     Sequence<nsString>& memberSlot = RawSetAsStringSequence();
     620           0 :     JS::ForOfIterator iter(cx);
     621           0 :     if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
     622           0 :       return false;
     623             :     }
     624           0 :     if (!iter.valueIsIterable()) {
     625           0 :       DestroyStringSequence();
     626           0 :       tryNext = true;
     627           0 :       return true;
     628             :     }
     629           0 :     Sequence<nsString> &arr = memberSlot;
     630           0 :     JS::Rooted<JS::Value> temp(cx);
     631             :     while (true) {
     632             :       bool done;
     633           0 :       if (!iter.next(&temp, &done)) {
     634           0 :         return false;
     635             :       }
     636           0 :       if (done) {
     637           0 :         break;
     638             :       }
     639           0 :       nsString* slotPtr = arr.AppendElement(mozilla::fallible);
     640           0 :       if (!slotPtr) {
     641           0 :         JS_ReportOutOfMemory(cx);
     642           0 :         return false;
     643             :       }
     644           0 :       nsString& slot = *slotPtr;
     645           0 :       if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
     646           0 :         return false;
     647             :       }
     648           0 :     }
     649             :   }
     650           0 :   return true;
     651             : }
     652             : 
     653             : void
     654           0 : OwningStringSequenceOrString::DestroyStringSequence()
     655             : {
     656           0 :   MOZ_ASSERT(IsStringSequence(), "Wrong type!");
     657           0 :   mValue.mStringSequence.Destroy();
     658           0 :   mType = eUninitialized;
     659           0 : }
     660             : 
     661             : 
     662             : 
     663             : 
     664             : nsString&
     665           0 : OwningStringSequenceOrString::RawSetAsString()
     666             : {
     667           0 :   if (mType == eString) {
     668           0 :     return mValue.mString.Value();
     669             :   }
     670           0 :   MOZ_ASSERT(mType == eUninitialized);
     671           0 :   mType = eString;
     672           0 :   return mValue.mString.SetValue();
     673             : }
     674             : 
     675             : nsString&
     676           0 : OwningStringSequenceOrString::SetAsString()
     677             : {
     678           0 :   if (mType == eString) {
     679           0 :     return mValue.mString.Value();
     680             :   }
     681           0 :   Uninit();
     682           0 :   mType = eString;
     683           0 :   return mValue.mString.SetValue();
     684             : }
     685             : 
     686             : bool
     687           0 : OwningStringSequenceOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
     688             : {
     689           0 :   tryNext = false;
     690             :   { // scope for memberSlot
     691           0 :     nsString& memberSlot = RawSetAsString();
     692           0 :     if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
     693           0 :       return false;
     694             :     }
     695             :   }
     696           0 :   return true;
     697             : }
     698             : 
     699             : 
     700             : void
     701           0 : OwningStringSequenceOrString::DestroyString()
     702             : {
     703           0 :   MOZ_ASSERT(IsString(), "Wrong type!");
     704           0 :   mValue.mString.Destroy();
     705           0 :   mType = eUninitialized;
     706           0 : }
     707             : 
     708             : 
     709             : 
     710             : 
     711             : void
     712           0 : OwningStringSequenceOrString::Uninit()
     713             : {
     714           0 :   switch (mType) {
     715             :     case eUninitialized: {
     716           0 :       break;
     717             :     }
     718             :     case eStringSequence: {
     719           0 :       DestroyStringSequence();
     720           0 :       break;
     721             :     }
     722             :     case eString: {
     723           0 :       DestroyString();
     724           0 :       break;
     725             :     }
     726             :   }
     727           0 : }
     728             : 
     729             : bool
     730           0 : OwningStringSequenceOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
     731             : {
     732           0 :   switch (mType) {
     733             :     case eUninitialized: {
     734           0 :       return false;
     735             :       break;
     736             :     }
     737             :     case eStringSequence: {
     738             : 
     739           0 :       uint32_t length = mValue.mStringSequence.Value().Length();
     740           0 :       JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
     741           0 :       if (!returnArray) {
     742           0 :         return false;
     743             :       }
     744             :       // Scope for 'tmp'
     745             :       {
     746           0 :         JS::Rooted<JS::Value> tmp(cx);
     747           0 :         for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
     748             :           // Control block to let us common up the JS_DefineElement calls when there
     749             :           // are different ways to succeed at wrapping the object.
     750             :           do {
     751           0 :             if (!xpc::NonVoidStringToJsval(cx, mValue.mStringSequence.Value()[sequenceIdx0], &tmp)) {
     752           0 :               return false;
     753             :             }
     754           0 :             break;
     755             :           } while (0);
     756           0 :           if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
     757             :                                 JSPROP_ENUMERATE)) {
     758           0 :             return false;
     759             :           }
     760             :         }
     761             :       }
     762           0 :       rval.setObject(*returnArray);
     763           0 :       return true;
     764             :       break;
     765             :     }
     766             :     case eString: {
     767           0 :       if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
     768           0 :         return false;
     769             :       }
     770           0 :       return true;
     771             :       break;
     772             :     }
     773             :     default: {
     774           0 :       return false;
     775             :       break;
     776             :     }
     777             :   }
     778             : 
     779             :   return false;
     780             : }
     781             : 
     782             : void
     783           0 : OwningStringSequenceOrString::TraceUnion(JSTracer* trc)
     784             : {
     785           0 : }
     786             : 
     787             : OwningStringSequenceOrString&
     788           0 : OwningStringSequenceOrString::operator=(const OwningStringSequenceOrString& aOther)
     789             : {
     790           0 :   switch (aOther.mType) {
     791             :     case eUninitialized: {
     792           0 :       MOZ_ASSERT(mType == eUninitialized,
     793             :                  "We need to destroy ourselves?");
     794           0 :       break;
     795             :     }
     796             :     case eStringSequence: {
     797           0 :       SetAsStringSequence() = aOther.GetAsStringSequence();
     798           0 :       break;
     799             :     }
     800             :     case eString: {
     801           0 :       SetAsString() = aOther.GetAsString();
     802           0 :       break;
     803             :     }
     804             :   }
     805           0 :   return *this;
     806             : }
     807             : 
     808             : 
     809             : bool
     810           0 : TestInterfaceJSOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
     811             : {
     812           0 :   switch (mType) {
     813             :     case eUninitialized: {
     814           0 :       return false;
     815             :       break;
     816             :     }
     817             :     case eTestInterfaceJS: {
     818           0 :       if (!GetOrCreateDOMReflector(cx, mValue.mTestInterfaceJS.Value(), rval)) {
     819           0 :         MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     820           0 :         return false;
     821             :       }
     822           0 :       return true;
     823             :       break;
     824             :     }
     825             :     case eLong: {
     826           0 :       rval.setInt32(int32_t(mValue.mLong.Value()));
     827           0 :       return true;
     828             :       break;
     829             :     }
     830             :     default: {
     831           0 :       return false;
     832             :       break;
     833             :     }
     834             :   }
     835             : 
     836             :   return false;
     837             : }
     838             : 
     839             : 
     840             : OwningNonNull<mozilla::dom::TestInterfaceJS>&
     841           0 : OwningTestInterfaceJSOrLong::RawSetAsTestInterfaceJS()
     842             : {
     843           0 :   if (mType == eTestInterfaceJS) {
     844           0 :     return mValue.mTestInterfaceJS.Value();
     845             :   }
     846           0 :   MOZ_ASSERT(mType == eUninitialized);
     847           0 :   mType = eTestInterfaceJS;
     848           0 :   return mValue.mTestInterfaceJS.SetValue();
     849             : }
     850             : 
     851             : OwningNonNull<mozilla::dom::TestInterfaceJS>&
     852           0 : OwningTestInterfaceJSOrLong::SetAsTestInterfaceJS()
     853             : {
     854           0 :   if (mType == eTestInterfaceJS) {
     855           0 :     return mValue.mTestInterfaceJS.Value();
     856             :   }
     857           0 :   Uninit();
     858           0 :   mType = eTestInterfaceJS;
     859           0 :   return mValue.mTestInterfaceJS.SetValue();
     860             : }
     861             : 
     862             : bool
     863           0 : OwningTestInterfaceJSOrLong::TrySetToTestInterfaceJS(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
     864             : {
     865           0 :   tryNext = false;
     866             :   { // scope for memberSlot
     867           0 :     OwningNonNull<mozilla::dom::TestInterfaceJS>& memberSlot = RawSetAsTestInterfaceJS();
     868             :     static_assert(IsRefcounted<mozilla::dom::TestInterfaceJS>::value, "We can only store refcounted classes.");{
     869           0 :       nsresult rv = UnwrapObject<prototypes::id::TestInterfaceJS, mozilla::dom::TestInterfaceJS>(value, memberSlot);
     870           0 :       if (NS_FAILED(rv)) {
     871           0 :         DestroyTestInterfaceJS();
     872           0 :         tryNext = true;
     873           0 :         return true;
     874             :       }
     875             :     }
     876             :   }
     877           0 :   return true;
     878             : }
     879             : 
     880             : void
     881           0 : OwningTestInterfaceJSOrLong::DestroyTestInterfaceJS()
     882             : {
     883           0 :   MOZ_ASSERT(IsTestInterfaceJS(), "Wrong type!");
     884           0 :   mValue.mTestInterfaceJS.Destroy();
     885           0 :   mType = eUninitialized;
     886           0 : }
     887             : 
     888             : 
     889             : 
     890             : 
     891             : int32_t&
     892           0 : OwningTestInterfaceJSOrLong::RawSetAsLong()
     893             : {
     894           0 :   if (mType == eLong) {
     895           0 :     return mValue.mLong.Value();
     896             :   }
     897           0 :   MOZ_ASSERT(mType == eUninitialized);
     898           0 :   mType = eLong;
     899           0 :   return mValue.mLong.SetValue();
     900             : }
     901             : 
     902             : int32_t&
     903           0 : OwningTestInterfaceJSOrLong::SetAsLong()
     904             : {
     905           0 :   if (mType == eLong) {
     906           0 :     return mValue.mLong.Value();
     907             :   }
     908           0 :   Uninit();
     909           0 :   mType = eLong;
     910           0 :   return mValue.mLong.SetValue();
     911             : }
     912             : 
     913             : bool
     914           0 : OwningTestInterfaceJSOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
     915             : {
     916           0 :   tryNext = false;
     917             :   { // scope for memberSlot
     918           0 :     int32_t& memberSlot = RawSetAsLong();
     919           0 :     if (!ValueToPrimitive<int32_t, eDefault>(cx, value, &memberSlot)) {
     920           0 :       return false;
     921             :     }
     922             :   }
     923           0 :   return true;
     924             : }
     925             : 
     926             : void
     927           0 : OwningTestInterfaceJSOrLong::DestroyLong()
     928             : {
     929           0 :   MOZ_ASSERT(IsLong(), "Wrong type!");
     930           0 :   mValue.mLong.Destroy();
     931           0 :   mType = eUninitialized;
     932           0 : }
     933             : 
     934             : 
     935             : 
     936             : 
     937             : void
     938           0 : OwningTestInterfaceJSOrLong::Uninit()
     939             : {
     940           0 :   switch (mType) {
     941             :     case eUninitialized: {
     942           0 :       break;
     943             :     }
     944             :     case eTestInterfaceJS: {
     945           0 :       DestroyTestInterfaceJS();
     946           0 :       break;
     947             :     }
     948             :     case eLong: {
     949           0 :       DestroyLong();
     950           0 :       break;
     951             :     }
     952             :   }
     953           0 : }
     954             : 
     955             : bool
     956           0 : OwningTestInterfaceJSOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
     957             : {
     958           0 :   switch (mType) {
     959             :     case eUninitialized: {
     960           0 :       return false;
     961             :       break;
     962             :     }
     963             :     case eTestInterfaceJS: {
     964           0 :       if (!GetOrCreateDOMReflector(cx, mValue.mTestInterfaceJS.Value(), rval)) {
     965           0 :         MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     966           0 :         return false;
     967             :       }
     968           0 :       return true;
     969             :       break;
     970             :     }
     971             :     case eLong: {
     972           0 :       rval.setInt32(int32_t(mValue.mLong.Value()));
     973           0 :       return true;
     974             :       break;
     975             :     }
     976             :     default: {
     977           0 :       return false;
     978             :       break;
     979             :     }
     980             :   }
     981             : 
     982             :   return false;
     983             : }
     984             : 
     985             : void
     986           0 : OwningTestInterfaceJSOrLong::TraceUnion(JSTracer* trc)
     987             : {
     988           0 : }
     989             : 
     990             : OwningTestInterfaceJSOrLong&
     991           0 : OwningTestInterfaceJSOrLong::operator=(const OwningTestInterfaceJSOrLong& aOther)
     992             : {
     993           0 :   switch (aOther.mType) {
     994             :     case eUninitialized: {
     995           0 :       MOZ_ASSERT(mType == eUninitialized,
     996             :                  "We need to destroy ourselves?");
     997           0 :       break;
     998             :     }
     999             :     case eTestInterfaceJS: {
    1000           0 :       SetAsTestInterfaceJS() = aOther.GetAsTestInterfaceJS();
    1001           0 :       break;
    1002             :     }
    1003             :     case eLong: {
    1004           0 :       SetAsLong() = aOther.GetAsLong();
    1005           0 :       break;
    1006             :     }
    1007             :   }
    1008           0 :   return *this;
    1009             : }
    1010             : 
    1011             : 
    1012             : bool
    1013           0 : TestInterfaceJSOrNullOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
    1014             : {
    1015           0 :   switch (mType) {
    1016             :     case eUninitialized: {
    1017           0 :       return false;
    1018             :       break;
    1019             :     }
    1020             :     case eNull: {
    1021           0 :       rval.setNull();
    1022           0 :       return true;
    1023             :       break;
    1024             :     }
    1025             :     case eTestInterfaceJS: {
    1026           0 :       if (!GetOrCreateDOMReflector(cx, mValue.mTestInterfaceJS.Value(), rval)) {
    1027           0 :         MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1028           0 :         return false;
    1029             :       }
    1030           0 :       return true;
    1031             :       break;
    1032             :     }
    1033             :     case eString: {
    1034           0 :       if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
    1035           0 :         return false;
    1036             :       }
    1037           0 :       return true;
    1038             :       break;
    1039             :     }
    1040             :     default: {
    1041           0 :       return false;
    1042             :       break;
    1043             :     }
    1044             :   }
    1045             : 
    1046             :   return false;
    1047             : }
    1048             : 
    1049             : 
    1050             : OwningNonNull<mozilla::dom::TestInterfaceJS>&
    1051           0 : OwningTestInterfaceJSOrNullOrString::RawSetAsTestInterfaceJS()
    1052             : {
    1053           0 :   if (mType == eTestInterfaceJS) {
    1054           0 :     return mValue.mTestInterfaceJS.Value();
    1055             :   }
    1056           0 :   MOZ_ASSERT(mType == eUninitialized);
    1057           0 :   mType = eTestInterfaceJS;
    1058           0 :   return mValue.mTestInterfaceJS.SetValue();
    1059             : }
    1060             : 
    1061             : OwningNonNull<mozilla::dom::TestInterfaceJS>&
    1062           0 : OwningTestInterfaceJSOrNullOrString::SetAsTestInterfaceJS()
    1063             : {
    1064           0 :   if (mType == eTestInterfaceJS) {
    1065           0 :     return mValue.mTestInterfaceJS.Value();
    1066             :   }
    1067           0 :   Uninit();
    1068           0 :   mType = eTestInterfaceJS;
    1069           0 :   return mValue.mTestInterfaceJS.SetValue();
    1070             : }
    1071             : 
    1072             : bool
    1073           0 : OwningTestInterfaceJSOrNullOrString::TrySetToTestInterfaceJS(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
    1074             : {
    1075           0 :   tryNext = false;
    1076             :   { // scope for memberSlot
    1077           0 :     OwningNonNull<mozilla::dom::TestInterfaceJS>& memberSlot = RawSetAsTestInterfaceJS();
    1078             :     static_assert(IsRefcounted<mozilla::dom::TestInterfaceJS>::value, "We can only store refcounted classes.");{
    1079           0 :       nsresult rv = UnwrapObject<prototypes::id::TestInterfaceJS, mozilla::dom::TestInterfaceJS>(value, memberSlot);
    1080           0 :       if (NS_FAILED(rv)) {
    1081           0 :         DestroyTestInterfaceJS();
    1082           0 :         tryNext = true;
    1083           0 :         return true;
    1084             :       }
    1085             :     }
    1086             :   }
    1087           0 :   return true;
    1088             : }
    1089             : 
    1090             : void
    1091           0 : OwningTestInterfaceJSOrNullOrString::DestroyTestInterfaceJS()
    1092             : {
    1093           0 :   MOZ_ASSERT(IsTestInterfaceJS(), "Wrong type!");
    1094           0 :   mValue.mTestInterfaceJS.Destroy();
    1095           0 :   mType = eUninitialized;
    1096           0 : }
    1097             : 
    1098             : 
    1099             : 
    1100             : 
    1101             : nsString&
    1102           0 : OwningTestInterfaceJSOrNullOrString::RawSetAsString()
    1103             : {
    1104           0 :   if (mType == eString) {
    1105           0 :     return mValue.mString.Value();
    1106             :   }
    1107           0 :   MOZ_ASSERT(mType == eUninitialized);
    1108           0 :   mType = eString;
    1109           0 :   return mValue.mString.SetValue();
    1110             : }
    1111             : 
    1112             : nsString&
    1113           0 : OwningTestInterfaceJSOrNullOrString::SetAsString()
    1114             : {
    1115           0 :   if (mType == eString) {
    1116           0 :     return mValue.mString.Value();
    1117             :   }
    1118           0 :   Uninit();
    1119           0 :   mType = eString;
    1120           0 :   return mValue.mString.SetValue();
    1121             : }
    1122             : 
    1123             : bool
    1124           0 : OwningTestInterfaceJSOrNullOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
    1125             : {
    1126           0 :   tryNext = false;
    1127             :   { // scope for memberSlot
    1128           0 :     nsString& memberSlot = RawSetAsString();
    1129           0 :     if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
    1130           0 :       return false;
    1131             :     }
    1132             :   }
    1133           0 :   return true;
    1134             : }
    1135             : 
    1136             : 
    1137             : void
    1138           0 : OwningTestInterfaceJSOrNullOrString::DestroyString()
    1139             : {
    1140           0 :   MOZ_ASSERT(IsString(), "Wrong type!");
    1141           0 :   mValue.mString.Destroy();
    1142           0 :   mType = eUninitialized;
    1143           0 : }
    1144             : 
    1145             : 
    1146             : 
    1147             : 
    1148             : void
    1149           0 : OwningTestInterfaceJSOrNullOrString::Uninit()
    1150             : {
    1151           0 :   switch (mType) {
    1152             :     case eUninitialized: {
    1153           0 :       break;
    1154             :     }
    1155             :     case eNull: {
    1156           0 :       break;
    1157             :     }
    1158             :     case eTestInterfaceJS: {
    1159           0 :       DestroyTestInterfaceJS();
    1160           0 :       break;
    1161             :     }
    1162             :     case eString: {
    1163           0 :       DestroyString();
    1164           0 :       break;
    1165             :     }
    1166             :   }
    1167           0 : }
    1168             : 
    1169             : bool
    1170           0 : OwningTestInterfaceJSOrNullOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
    1171             : {
    1172           0 :   switch (mType) {
    1173             :     case eUninitialized: {
    1174           0 :       return false;
    1175             :       break;
    1176             :     }
    1177             :     case eNull: {
    1178           0 :       rval.setNull();
    1179           0 :       return true;
    1180             :       break;
    1181             :     }
    1182             :     case eTestInterfaceJS: {
    1183           0 :       if (!GetOrCreateDOMReflector(cx, mValue.mTestInterfaceJS.Value(), rval)) {
    1184           0 :         MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1185           0 :         return false;
    1186             :       }
    1187           0 :       return true;
    1188             :       break;
    1189             :     }
    1190             :     case eString: {
    1191           0 :       if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
    1192           0 :         return false;
    1193             :       }
    1194           0 :       return true;
    1195             :       break;
    1196             :     }
    1197             :     default: {
    1198           0 :       return false;
    1199             :       break;
    1200             :     }
    1201             :   }
    1202             : 
    1203             :   return false;
    1204             : }
    1205             : 
    1206             : void
    1207           0 : OwningTestInterfaceJSOrNullOrString::TraceUnion(JSTracer* trc)
    1208             : {
    1209           0 : }
    1210             : 
    1211             : OwningTestInterfaceJSOrNullOrString&
    1212           0 : OwningTestInterfaceJSOrNullOrString::operator=(const OwningTestInterfaceJSOrNullOrString& aOther)
    1213             : {
    1214           0 :   switch (aOther.mType) {
    1215             :     case eUninitialized: {
    1216           0 :       MOZ_ASSERT(mType == eUninitialized,
    1217             :                  "We need to destroy ourselves?");
    1218           0 :       break;
    1219             :     }
    1220             :     case eNull: {
    1221           0 :       MOZ_ASSERT(mType == eUninitialized);
    1222           0 :       mType = eNull;
    1223           0 :       break;
    1224             :     }
    1225             :     case eTestInterfaceJS: {
    1226           0 :       SetAsTestInterfaceJS() = aOther.GetAsTestInterfaceJS();
    1227           0 :       break;
    1228             :     }
    1229             :     case eString: {
    1230           0 :       SetAsString() = aOther.GetAsString();
    1231           0 :       break;
    1232             :     }
    1233             :   }
    1234           0 :   return *this;
    1235             : }
    1236             : 
    1237             : 
    1238             : 
    1239           0 : TestInterfaceJSUnionableDictionary::TestInterfaceJSUnionableDictionary()
    1240           0 :   : mAnyMember(JS::UndefinedValue())
    1241             : {
    1242             :   // Safe to pass a null context if we pass a null value
    1243           0 :   Init(nullptr, JS::NullHandleValue);
    1244           0 : }
    1245             : 
    1246             : 
    1247             : bool
    1248           0 : TestInterfaceJSUnionableDictionary::InitIds(JSContext* cx, TestInterfaceJSUnionableDictionaryAtoms* atomsCache)
    1249             : {
    1250           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
    1251             : 
    1252             :   // Initialize these in reverse order so that any failure leaves the first one
    1253             :   // uninitialized.
    1254           0 :   if (!atomsCache->objectMember_id.init(cx, "objectMember") ||
    1255           0 :       !atomsCache->anyMember_id.init(cx, "anyMember")) {
    1256           0 :     return false;
    1257             :   }
    1258           0 :   return true;
    1259             : }
    1260             : 
    1261             : bool
    1262           0 : TestInterfaceJSUnionableDictionary::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
    1263             : {
    1264             :   // Passing a null JSContext is OK only if we're initing from null,
    1265             :   // Since in that case we will not have to do any property gets
    1266             :   // Also evaluate isNullOrUndefined in order to avoid false-positive
    1267             :   // checkers by static analysis tools
    1268           0 :   MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
    1269           0 :   TestInterfaceJSUnionableDictionaryAtoms* atomsCache = nullptr;
    1270           0 :   if (cx) {
    1271           0 :     atomsCache = GetAtomCache<TestInterfaceJSUnionableDictionaryAtoms>(cx);
    1272           0 :     if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
    1273           0 :       return false;
    1274             :     }
    1275             :   }
    1276             : 
    1277           0 :   if (!IsConvertibleToDictionary(val)) {
    1278           0 :     return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
    1279             :   }
    1280             : 
    1281           0 :   bool isNull = val.isNullOrUndefined();
    1282             :   // We only need these if !isNull, in which case we have |cx|.
    1283           0 :   Maybe<JS::Rooted<JSObject *> > object;
    1284           0 :   Maybe<JS::Rooted<JS::Value> > temp;
    1285           0 :   if (!isNull) {
    1286           0 :     MOZ_ASSERT(cx);
    1287           0 :     object.emplace(cx, &val.toObject());
    1288           0 :     temp.emplace(cx);
    1289             :   }
    1290           0 :   if (!isNull) {
    1291           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->anyMember_id, temp.ptr())) {
    1292           0 :       return false;
    1293             :     }
    1294             :   }
    1295           0 :   if (!isNull && !temp->isUndefined()) {
    1296             : #ifdef __clang__
    1297             : #pragma clang diagnostic push
    1298             : #pragma clang diagnostic ignored "-Wunreachable-code"
    1299             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    1300             : #endif // __clang__
    1301           0 :     if ((passedToJSImpl) && !CallerSubsumes(temp.ref())) {
    1302           0 :       ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "'anyMember' member of TestInterfaceJSUnionableDictionary");
    1303           0 :       return false;
    1304             :     }
    1305             : #ifdef __clang__
    1306             : #pragma clang diagnostic pop
    1307             : #endif // __clang__
    1308           0 :     mAnyMember = temp.ref();
    1309             :   } else {
    1310           0 :     mAnyMember = JS::UndefinedValue();
    1311             :   }
    1312           0 :   mIsAnyMemberPresent = true;
    1313             : 
    1314           0 :   if (!isNull) {
    1315           0 :     if (!JS_GetPropertyById(cx, *object, atomsCache->objectMember_id, temp.ptr())) {
    1316           0 :       return false;
    1317             :     }
    1318             :   }
    1319           0 :   if (!isNull && !temp->isUndefined()) {
    1320           0 :     mObjectMember.Construct();
    1321           0 :     if (temp.ref().isObject()) {
    1322             : #ifdef __clang__
    1323             : #pragma clang diagnostic push
    1324             : #pragma clang diagnostic ignored "-Wunreachable-code"
    1325             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    1326             : #endif // __clang__
    1327           0 :       if ((passedToJSImpl) && !CallerSubsumes(temp.ref())) {
    1328           0 :         ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "'objectMember' member of TestInterfaceJSUnionableDictionary");
    1329           0 :         return false;
    1330             :       }
    1331             : #ifdef __clang__
    1332             : #pragma clang diagnostic pop
    1333             : #endif // __clang__
    1334           0 :       (mObjectMember.Value()) = &temp.ref().toObject();
    1335             :     } else {
    1336           0 :       ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'objectMember' member of TestInterfaceJSUnionableDictionary");
    1337           0 :       return false;
    1338             :     }
    1339           0 :     mIsAnyMemberPresent = true;
    1340             :   }
    1341           0 :   return true;
    1342             : }
    1343             : 
    1344             : bool
    1345           0 : TestInterfaceJSUnionableDictionary::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
    1346             : {
    1347           0 :   TestInterfaceJSUnionableDictionaryAtoms* atomsCache = GetAtomCache<TestInterfaceJSUnionableDictionaryAtoms>(cx);
    1348           0 :   if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
    1349           0 :     return false;
    1350             :   }
    1351             : 
    1352           0 :   JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
    1353           0 :   if (!obj) {
    1354           0 :     return false;
    1355             :   }
    1356           0 :   rval.set(JS::ObjectValue(*obj));
    1357             : 
    1358             :   do {
    1359             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    1360           0 :     JS::Rooted<JS::Value> temp(cx);
    1361           0 :     JS::Value const & currentValue = mAnyMember;
    1362           0 :     JS::ExposeValueToActiveJS(currentValue);
    1363           0 :     temp.set(currentValue);
    1364           0 :     if (!MaybeWrapValue(cx, &temp)) {
    1365           0 :       return false;
    1366             :     }
    1367           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->anyMember_id, temp, JSPROP_ENUMERATE)) {
    1368           0 :       return false;
    1369             :     }
    1370           0 :     break;
    1371             :   } while(0);
    1372             : 
    1373           0 :   if (mObjectMember.WasPassed()) {
    1374             :     do {
    1375             :       // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    1376           0 :       JS::Rooted<JS::Value> temp(cx);
    1377           0 :       JSObject* const & currentValue = mObjectMember.InternalValue();
    1378           0 :       JS::ExposeObjectToActiveJS(currentValue);
    1379           0 :       temp.setObject(*currentValue);
    1380           0 :       if (!MaybeWrapObjectValue(cx, &temp)) {
    1381           0 :         return false;
    1382             :       }
    1383           0 :       if (!JS_DefinePropertyById(cx, obj, atomsCache->objectMember_id, temp, JSPROP_ENUMERATE)) {
    1384           0 :         return false;
    1385             :       }
    1386           0 :       break;
    1387             :     } while(0);
    1388             :   }
    1389             : 
    1390           0 :   return true;
    1391             : }
    1392             : 
    1393             : void
    1394           0 : TestInterfaceJSUnionableDictionary::TraceDictionary(JSTracer* trc)
    1395             : {
    1396           0 :   JS::UnsafeTraceRoot(trc, &mAnyMember, "TestInterfaceJSUnionableDictionary.mAnyMember");
    1397             : 
    1398           0 :   if (mObjectMember.WasPassed()) {
    1399           0 :     JS::UnsafeTraceRoot(trc, &mObjectMember.Value(), "TestInterfaceJSUnionableDictionary.mObjectMember");
    1400             :   }
    1401           0 : }
    1402             : 
    1403             : namespace binding_detail {
    1404             : } // namespace binding_detail
    1405             : 
    1406             : 
    1407             : bool
    1408           0 : TestInterfaceJSUnionableDictionaryOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
    1409             : {
    1410           0 :   switch (mType) {
    1411             :     case eUninitialized: {
    1412           0 :       return false;
    1413             :       break;
    1414             :     }
    1415             :     case eTestInterfaceJSUnionableDictionary: {
    1416           0 :       if (!mValue.mTestInterfaceJSUnionableDictionary.Value().ToObjectInternal(cx, rval)) {
    1417           0 :         return false;
    1418             :       }
    1419           0 :       return true;
    1420             :       break;
    1421             :     }
    1422             :     case eLong: {
    1423           0 :       rval.setInt32(int32_t(mValue.mLong.Value()));
    1424           0 :       return true;
    1425             :       break;
    1426             :     }
    1427             :     default: {
    1428           0 :       return false;
    1429             :       break;
    1430             :     }
    1431             :   }
    1432             : 
    1433             :   return false;
    1434             : }
    1435             : 
    1436             : 
    1437             : TestInterfaceJSUnionableDictionary&
    1438           0 : OwningTestInterfaceJSUnionableDictionaryOrLong::RawSetAsTestInterfaceJSUnionableDictionary()
    1439             : {
    1440           0 :   if (mType == eTestInterfaceJSUnionableDictionary) {
    1441           0 :     return mValue.mTestInterfaceJSUnionableDictionary.Value();
    1442             :   }
    1443           0 :   MOZ_ASSERT(mType == eUninitialized);
    1444           0 :   mType = eTestInterfaceJSUnionableDictionary;
    1445           0 :   return mValue.mTestInterfaceJSUnionableDictionary.SetValue();
    1446             : }
    1447             : 
    1448             : TestInterfaceJSUnionableDictionary&
    1449           0 : OwningTestInterfaceJSUnionableDictionaryOrLong::SetAsTestInterfaceJSUnionableDictionary()
    1450             : {
    1451           0 :   if (mType == eTestInterfaceJSUnionableDictionary) {
    1452           0 :     return mValue.mTestInterfaceJSUnionableDictionary.Value();
    1453             :   }
    1454           0 :   Uninit();
    1455           0 :   mType = eTestInterfaceJSUnionableDictionary;
    1456           0 :   return mValue.mTestInterfaceJSUnionableDictionary.SetValue();
    1457             : }
    1458             : 
    1459             : bool
    1460           0 : OwningTestInterfaceJSUnionableDictionaryOrLong::TrySetToTestInterfaceJSUnionableDictionary(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
    1461             : {
    1462           0 :   tryNext = false;
    1463             :   { // scope for memberSlot
    1464           0 :     TestInterfaceJSUnionableDictionary& memberSlot = RawSetAsTestInterfaceJSUnionableDictionary();
    1465           0 :     if (!IsConvertibleToDictionary(value)) {
    1466           0 :       DestroyTestInterfaceJSUnionableDictionary();
    1467           0 :       tryNext = true;
    1468           0 :       return true;
    1469             :     }
    1470           0 :     if (!memberSlot.Init(cx, value,  "Member of TestInterfaceJSUnionableDictionaryOrLong", passedToJSImpl)) {
    1471           0 :       return false;
    1472             :     }
    1473             :   }
    1474           0 :   return true;
    1475             : }
    1476             : 
    1477             : void
    1478           0 : OwningTestInterfaceJSUnionableDictionaryOrLong::DestroyTestInterfaceJSUnionableDictionary()
    1479             : {
    1480           0 :   MOZ_ASSERT(IsTestInterfaceJSUnionableDictionary(), "Wrong type!");
    1481           0 :   mValue.mTestInterfaceJSUnionableDictionary.Destroy();
    1482           0 :   mType = eUninitialized;
    1483           0 : }
    1484             : 
    1485             : 
    1486             : 
    1487             : 
    1488             : int32_t&
    1489           0 : OwningTestInterfaceJSUnionableDictionaryOrLong::RawSetAsLong()
    1490             : {
    1491           0 :   if (mType == eLong) {
    1492           0 :     return mValue.mLong.Value();
    1493             :   }
    1494           0 :   MOZ_ASSERT(mType == eUninitialized);
    1495           0 :   mType = eLong;
    1496           0 :   return mValue.mLong.SetValue();
    1497             : }
    1498             : 
    1499             : int32_t&
    1500           0 : OwningTestInterfaceJSUnionableDictionaryOrLong::SetAsLong()
    1501             : {
    1502           0 :   if (mType == eLong) {
    1503           0 :     return mValue.mLong.Value();
    1504             :   }
    1505           0 :   Uninit();
    1506           0 :   mType = eLong;
    1507           0 :   return mValue.mLong.SetValue();
    1508             : }
    1509             : 
    1510             : bool
    1511           0 : OwningTestInterfaceJSUnionableDictionaryOrLong::TrySetToLong(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
    1512             : {
    1513           0 :   tryNext = false;
    1514             :   { // scope for memberSlot
    1515           0 :     int32_t& memberSlot = RawSetAsLong();
    1516           0 :     if (!ValueToPrimitive<int32_t, eDefault>(cx, value, &memberSlot)) {
    1517           0 :       return false;
    1518             :     }
    1519             :   }
    1520           0 :   return true;
    1521             : }
    1522             : 
    1523             : void
    1524           0 : OwningTestInterfaceJSUnionableDictionaryOrLong::DestroyLong()
    1525             : {
    1526           0 :   MOZ_ASSERT(IsLong(), "Wrong type!");
    1527           0 :   mValue.mLong.Destroy();
    1528           0 :   mType = eUninitialized;
    1529           0 : }
    1530             : 
    1531             : 
    1532             : 
    1533             : 
    1534             : void
    1535           0 : OwningTestInterfaceJSUnionableDictionaryOrLong::Uninit()
    1536             : {
    1537           0 :   switch (mType) {
    1538             :     case eUninitialized: {
    1539           0 :       break;
    1540             :     }
    1541             :     case eTestInterfaceJSUnionableDictionary: {
    1542           0 :       DestroyTestInterfaceJSUnionableDictionary();
    1543           0 :       break;
    1544             :     }
    1545             :     case eLong: {
    1546           0 :       DestroyLong();
    1547           0 :       break;
    1548             :     }
    1549             :   }
    1550           0 : }
    1551             : 
    1552             : bool
    1553           0 : OwningTestInterfaceJSUnionableDictionaryOrLong::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
    1554             : {
    1555           0 :   switch (mType) {
    1556             :     case eUninitialized: {
    1557           0 :       return false;
    1558             :       break;
    1559             :     }
    1560             :     case eTestInterfaceJSUnionableDictionary: {
    1561           0 :       if (!mValue.mTestInterfaceJSUnionableDictionary.Value().ToObjectInternal(cx, rval)) {
    1562           0 :         return false;
    1563             :       }
    1564           0 :       return true;
    1565             :       break;
    1566             :     }
    1567             :     case eLong: {
    1568           0 :       rval.setInt32(int32_t(mValue.mLong.Value()));
    1569           0 :       return true;
    1570             :       break;
    1571             :     }
    1572             :     default: {
    1573           0 :       return false;
    1574             :       break;
    1575             :     }
    1576             :   }
    1577             : 
    1578             :   return false;
    1579             : }
    1580             : 
    1581             : void
    1582           0 : OwningTestInterfaceJSUnionableDictionaryOrLong::TraceUnion(JSTracer* trc)
    1583             : {
    1584           0 :   switch (mType) {
    1585             :     case eTestInterfaceJSUnionableDictionary: {
    1586           0 :       mValue.mTestInterfaceJSUnionableDictionary.Value().TraceDictionary(trc);
    1587           0 :       break;
    1588             :     }
    1589             :     default: {
    1590           0 :       break;
    1591             :     }
    1592             :   }
    1593           0 : }
    1594             : 
    1595             : 
    1596             : namespace TestInterfaceJSBinding {
    1597             : 
    1598             : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventTargetBinding::NativeType>::value,
    1599             :               "Can't inherit from an interface with a different ownership model.");
    1600             : 
    1601             : static bool
    1602           0 : get_anyArg(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, JSJitGetterCallArgs args)
    1603             : {
    1604           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    1605           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    1606           0 :   if (objIsXray) {
    1607           0 :     unwrappedObj.emplace(cx, obj);
    1608             :   }
    1609           0 :   if (objIsXray) {
    1610           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    1611           0 :     if (!unwrappedObj.ref()) {
    1612           0 :       return false;
    1613             :     }
    1614             :   }
    1615           0 :   binding_detail::FastErrorResult rv;
    1616           0 :   JS::Rooted<JS::Value> result(cx);
    1617           0 :   self->GetAnyArg(&result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    1618           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1619           0 :     return false;
    1620             :   }
    1621           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1622           0 :   JS::ExposeValueToActiveJS(result);
    1623           0 :   args.rval().set(result);
    1624           0 :   if (!MaybeWrapValue(cx, args.rval())) {
    1625           0 :     return false;
    1626             :   }
    1627           0 :   return true;
    1628             : }
    1629             : 
    1630             : static const JSJitInfo anyArg_getterinfo = {
    1631             :   { (JSJitGetterOp)get_anyArg },
    1632             :   { prototypes::id::TestInterfaceJS },
    1633             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    1634             :   JSJitInfo::Getter,
    1635             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1636             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    1637             :   false,  /* isInfallible. False in setters. */
    1638             :   false,  /* isMovable.  Not relevant for setters. */
    1639             :   false, /* isEliminatable.  Not relevant for setters. */
    1640             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1641             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1642             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1643             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1644             : };
    1645             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1646             : static_assert(0 < 4, "There is no slot for us");
    1647             : 
    1648             : static bool
    1649           0 : get_objectArg(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, JSJitGetterCallArgs args)
    1650             : {
    1651           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    1652           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    1653           0 :   if (objIsXray) {
    1654           0 :     unwrappedObj.emplace(cx, obj);
    1655             :   }
    1656           0 :   if (objIsXray) {
    1657           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    1658           0 :     if (!unwrappedObj.ref()) {
    1659           0 :       return false;
    1660             :     }
    1661             :   }
    1662           0 :   binding_detail::FastErrorResult rv;
    1663           0 :   JS::Rooted<JSObject*> result(cx);
    1664           0 :   self->GetObjectArg(&result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    1665           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1666           0 :     return false;
    1667             :   }
    1668           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1669           0 :   JS::ExposeObjectToActiveJS(result);
    1670           0 :   args.rval().setObject(*result);
    1671           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    1672           0 :     return false;
    1673             :   }
    1674           0 :   return true;
    1675             : }
    1676             : 
    1677             : static const JSJitInfo objectArg_getterinfo = {
    1678             :   { (JSJitGetterOp)get_objectArg },
    1679             :   { prototypes::id::TestInterfaceJS },
    1680             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    1681             :   JSJitInfo::Getter,
    1682             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1683             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1684             :   false,  /* isInfallible. False in setters. */
    1685             :   false,  /* isMovable.  Not relevant for setters. */
    1686             :   false, /* isEliminatable.  Not relevant for setters. */
    1687             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1688             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1689             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1690             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1691             : };
    1692             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1693             : static_assert(0 < 4, "There is no slot for us");
    1694             : 
    1695             : static bool
    1696           0 : get_dictionaryArg(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, JSJitGetterCallArgs args)
    1697             : {
    1698             :   // Have to either root across the getter call or reget after.
    1699             :   bool isXray;
    1700           0 :   JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
    1701           0 :   if (!slotStorage) {
    1702           0 :     return false;
    1703             :   }
    1704           0 :   const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 0) : (DOM_INSTANCE_RESERVED_SLOTS + 0);
    1705           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    1706             :   {
    1707             :     // Scope for cachedVal
    1708           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    1709           0 :     if (!cachedVal.isUndefined()) {
    1710           0 :       args.rval().set(cachedVal);
    1711             :       // The cached value is in the compartment of slotStorage,
    1712             :       // so wrap into the caller compartment as needed.
    1713           0 :       return MaybeWrapNonDOMObjectValue(cx, args.rval());
    1714             :     }
    1715             :   }
    1716             : 
    1717           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    1718           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    1719           0 :   if (objIsXray) {
    1720           0 :     unwrappedObj.emplace(cx, obj);
    1721             :   }
    1722           0 :   if (objIsXray) {
    1723           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    1724           0 :     if (!unwrappedObj.ref()) {
    1725           0 :       return false;
    1726             :     }
    1727             :   }
    1728           0 :   binding_detail::FastErrorResult rv;
    1729           0 :   RootedDictionary<TestInterfaceJSDictionary> result(cx);
    1730           0 :   self->GetDictionaryArg(result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    1731           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1732           0 :     return false;
    1733             :   }
    1734           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1735             :   {
    1736           0 :     JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
    1737           0 :     JSAutoCompartment ac(cx, conversionScope);
    1738             :     do { // block we break out of when done wrapping
    1739           0 :       if (!result.ToObjectInternal(cx, args.rval())) {
    1740           0 :         return false;
    1741             :       }
    1742           0 :       break;
    1743             :     } while (0);
    1744             :   }
    1745             :   { // And now store things in the compartment of our slotStorage.
    1746           0 :     JSAutoCompartment ac(cx, slotStorage);
    1747             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    1748           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    1749           0 :     if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
    1750           0 :       return false;
    1751             :     }
    1752           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    1753           0 :     if (!isXray) {
    1754             :       // In the Xray case we don't need to do this, because getting the
    1755             :       // expando object already preserved our wrapper.
    1756           0 :       PreserveWrapper(self);
    1757             :     }
    1758             :   }
    1759             :   // And now make sure args.rval() is in the caller compartment
    1760           0 :   return MaybeWrapNonDOMObjectValue(cx, args.rval());
    1761             : }
    1762             : 
    1763             : static const JSJitInfo dictionaryArg_getterinfo = {
    1764             :   { (JSJitGetterOp)get_dictionaryArg },
    1765             :   { prototypes::id::TestInterfaceJS },
    1766             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    1767             :   JSJitInfo::Getter,
    1768             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    1769             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1770             :   false,  /* isInfallible. False in setters. */
    1771             :   false,  /* isMovable.  Not relevant for setters. */
    1772             :   false, /* isEliminatable.  Not relevant for setters. */
    1773             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1774             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1775             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1776             :   (DOM_INSTANCE_RESERVED_SLOTS + 0)   /* Reserved slot index, if we're stored in a slot, else 0. */
    1777             : };
    1778             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit");
    1779             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 4, "There is no slot for us");
    1780             : 
    1781             : static bool
    1782           0 : get_anyAttr(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, JSJitGetterCallArgs args)
    1783             : {
    1784           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    1785           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    1786           0 :   if (objIsXray) {
    1787           0 :     unwrappedObj.emplace(cx, obj);
    1788             :   }
    1789           0 :   if (objIsXray) {
    1790           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    1791           0 :     if (!unwrappedObj.ref()) {
    1792           0 :       return false;
    1793             :     }
    1794             :   }
    1795           0 :   binding_detail::FastErrorResult rv;
    1796           0 :   JS::Rooted<JS::Value> result(cx);
    1797           0 :   self->GetAnyAttr(&result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    1798           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1799           0 :     return false;
    1800             :   }
    1801           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1802           0 :   JS::ExposeValueToActiveJS(result);
    1803           0 :   args.rval().set(result);
    1804           0 :   if (!MaybeWrapValue(cx, args.rval())) {
    1805           0 :     return false;
    1806             :   }
    1807           0 :   return true;
    1808             : }
    1809             : 
    1810             : static bool
    1811           0 : set_anyAttr(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, JSJitSetterCallArgs args)
    1812             : {
    1813           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    1814           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    1815           0 :   if (objIsXray) {
    1816           0 :     unwrappedObj.emplace(cx, obj);
    1817             :   }
    1818           0 :   JS::Rooted<JS::Value> arg0(cx);
    1819             : #ifdef __clang__
    1820             : #pragma clang diagnostic push
    1821             : #pragma clang diagnostic ignored "-Wunreachable-code"
    1822             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    1823             : #endif // __clang__
    1824           0 :   if ((true) && !CallerSubsumes(args[0])) {
    1825           0 :     ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "value being assigned to TestInterfaceJS.anyAttr");
    1826           0 :     return false;
    1827             :   }
    1828             : #ifdef __clang__
    1829             : #pragma clang diagnostic pop
    1830             : #endif // __clang__
    1831           0 :   arg0 = args[0];
    1832           0 :   if (objIsXray) {
    1833           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    1834           0 :     if (!unwrappedObj.ref()) {
    1835           0 :       return false;
    1836             :     }
    1837             :   }
    1838           0 :   binding_detail::FastErrorResult rv;
    1839           0 :   self->SetAnyAttr(arg0, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    1840           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1841           0 :     return false;
    1842             :   }
    1843           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1844             : 
    1845           0 :   return true;
    1846             : }
    1847             : 
    1848             : static const JSJitInfo anyAttr_getterinfo = {
    1849             :   { (JSJitGetterOp)get_anyAttr },
    1850             :   { prototypes::id::TestInterfaceJS },
    1851             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    1852             :   JSJitInfo::Getter,
    1853             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1854             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    1855             :   false,  /* isInfallible. False in setters. */
    1856             :   false,  /* isMovable.  Not relevant for setters. */
    1857             :   false, /* isEliminatable.  Not relevant for setters. */
    1858             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1859             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1860             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1861             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1862             : };
    1863             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1864             : static_assert(0 < 4, "There is no slot for us");
    1865             : static const JSJitInfo anyAttr_setterinfo = {
    1866             :   { (JSJitGetterOp)set_anyAttr },
    1867             :   { prototypes::id::TestInterfaceJS },
    1868             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    1869             :   JSJitInfo::Setter,
    1870             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1871             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    1872             :   false,  /* isInfallible. False in setters. */
    1873             :   false,  /* isMovable.  Not relevant for setters. */
    1874             :   false, /* isEliminatable.  Not relevant for setters. */
    1875             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1876             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1877             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1878             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1879             : };
    1880             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1881             : static_assert(0 < 4, "There is no slot for us");
    1882             : 
    1883             : static bool
    1884           0 : get_objectAttr(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, JSJitGetterCallArgs args)
    1885             : {
    1886           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    1887           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    1888           0 :   if (objIsXray) {
    1889           0 :     unwrappedObj.emplace(cx, obj);
    1890             :   }
    1891           0 :   if (objIsXray) {
    1892           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    1893           0 :     if (!unwrappedObj.ref()) {
    1894           0 :       return false;
    1895             :     }
    1896             :   }
    1897           0 :   binding_detail::FastErrorResult rv;
    1898           0 :   JS::Rooted<JSObject*> result(cx);
    1899           0 :   self->GetObjectAttr(&result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    1900           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1901           0 :     return false;
    1902             :   }
    1903           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1904           0 :   JS::ExposeObjectToActiveJS(result);
    1905           0 :   args.rval().setObject(*result);
    1906           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    1907           0 :     return false;
    1908             :   }
    1909           0 :   return true;
    1910             : }
    1911             : 
    1912             : static bool
    1913           0 : set_objectAttr(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, JSJitSetterCallArgs args)
    1914             : {
    1915           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    1916           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    1917           0 :   if (objIsXray) {
    1918           0 :     unwrappedObj.emplace(cx, obj);
    1919             :   }
    1920           0 :   JS::Rooted<JSObject*> arg0(cx);
    1921           0 :   if (args[0].isObject()) {
    1922             : #ifdef __clang__
    1923             : #pragma clang diagnostic push
    1924             : #pragma clang diagnostic ignored "-Wunreachable-code"
    1925             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    1926             : #endif // __clang__
    1927           0 :     if ((true) && !CallerSubsumes(args[0])) {
    1928           0 :       ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "value being assigned to TestInterfaceJS.objectAttr");
    1929           0 :       return false;
    1930             :     }
    1931             : #ifdef __clang__
    1932             : #pragma clang diagnostic pop
    1933             : #endif // __clang__
    1934           0 :     arg0 = &args[0].toObject();
    1935             :   } else {
    1936           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Value being assigned to TestInterfaceJS.objectAttr");
    1937           0 :     return false;
    1938             :   }
    1939           0 :   if (objIsXray) {
    1940           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    1941           0 :     if (!unwrappedObj.ref()) {
    1942           0 :       return false;
    1943             :     }
    1944             :   }
    1945           0 :   binding_detail::FastErrorResult rv;
    1946           0 :   self->SetObjectAttr(arg0, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    1947           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1948           0 :     return false;
    1949             :   }
    1950           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1951             : 
    1952           0 :   return true;
    1953             : }
    1954             : 
    1955             : static const JSJitInfo objectAttr_getterinfo = {
    1956             :   { (JSJitGetterOp)get_objectAttr },
    1957             :   { prototypes::id::TestInterfaceJS },
    1958             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    1959             :   JSJitInfo::Getter,
    1960             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1961             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1962             :   false,  /* isInfallible. False in setters. */
    1963             :   false,  /* isMovable.  Not relevant for setters. */
    1964             :   false, /* isEliminatable.  Not relevant for setters. */
    1965             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1966             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1967             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1968             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1969             : };
    1970             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1971             : static_assert(0 < 4, "There is no slot for us");
    1972             : static const JSJitInfo objectAttr_setterinfo = {
    1973             :   { (JSJitGetterOp)set_objectAttr },
    1974             :   { prototypes::id::TestInterfaceJS },
    1975             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    1976             :   JSJitInfo::Setter,
    1977             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1978             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    1979             :   false,  /* isInfallible. False in setters. */
    1980             :   false,  /* isMovable.  Not relevant for setters. */
    1981             :   false, /* isEliminatable.  Not relevant for setters. */
    1982             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1983             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1984             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1985             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1986             : };
    1987             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1988             : static_assert(0 < 4, "There is no slot for us");
    1989             : 
    1990             : static bool
    1991           0 : get_dictionaryAttr(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, JSJitGetterCallArgs args)
    1992             : {
    1993             :   // Have to either root across the getter call or reget after.
    1994             :   bool isXray;
    1995           0 :   JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
    1996           0 :   if (!slotStorage) {
    1997           0 :     return false;
    1998             :   }
    1999           0 :   const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 1) : (DOM_INSTANCE_RESERVED_SLOTS + 1);
    2000           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    2001             :   {
    2002             :     // Scope for cachedVal
    2003           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    2004           0 :     if (!cachedVal.isUndefined()) {
    2005           0 :       args.rval().set(cachedVal);
    2006             :       // The cached value is in the compartment of slotStorage,
    2007             :       // so wrap into the caller compartment as needed.
    2008           0 :       return MaybeWrapNonDOMObjectValue(cx, args.rval());
    2009             :     }
    2010             :   }
    2011             : 
    2012           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2013           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2014           0 :   if (objIsXray) {
    2015           0 :     unwrappedObj.emplace(cx, obj);
    2016             :   }
    2017           0 :   if (objIsXray) {
    2018           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2019           0 :     if (!unwrappedObj.ref()) {
    2020           0 :       return false;
    2021             :     }
    2022             :   }
    2023           0 :   binding_detail::FastErrorResult rv;
    2024           0 :   RootedDictionary<TestInterfaceJSDictionary> result(cx);
    2025           0 :   self->GetDictionaryAttr(result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    2026           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2027           0 :     return false;
    2028             :   }
    2029           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2030             :   {
    2031           0 :     JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
    2032           0 :     JSAutoCompartment ac(cx, conversionScope);
    2033             :     do { // block we break out of when done wrapping
    2034           0 :       if (!result.ToObjectInternal(cx, args.rval())) {
    2035           0 :         return false;
    2036             :       }
    2037           0 :       break;
    2038             :     } while (0);
    2039             :   }
    2040             :   { // And now store things in the compartment of our slotStorage.
    2041           0 :     JSAutoCompartment ac(cx, slotStorage);
    2042             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    2043           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    2044           0 :     if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
    2045           0 :       return false;
    2046             :     }
    2047           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    2048           0 :     if (!isXray) {
    2049             :       // In the Xray case we don't need to do this, because getting the
    2050             :       // expando object already preserved our wrapper.
    2051           0 :       PreserveWrapper(self);
    2052             :     }
    2053             :   }
    2054             :   // And now make sure args.rval() is in the caller compartment
    2055           0 :   return MaybeWrapNonDOMObjectValue(cx, args.rval());
    2056             : }
    2057             : 
    2058             : static bool
    2059           0 : set_dictionaryAttr(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, JSJitSetterCallArgs args)
    2060             : {
    2061           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2062           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2063           0 :   if (objIsXray) {
    2064           0 :     unwrappedObj.emplace(cx, obj);
    2065             :   }
    2066           0 :   RootedDictionary<binding_detail::FastTestInterfaceJSDictionary> arg0(cx);
    2067           0 :   if (!arg0.Init(cx, args[0],  "Value being assigned to TestInterfaceJS.dictionaryAttr", true)) {
    2068           0 :     return false;
    2069             :   }
    2070           0 :   if (objIsXray) {
    2071           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2072           0 :     if (!unwrappedObj.ref()) {
    2073           0 :       return false;
    2074             :     }
    2075             :   }
    2076           0 :   binding_detail::FastErrorResult rv;
    2077           0 :   self->SetDictionaryAttr(Constify(arg0), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    2078           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2079           0 :     return false;
    2080             :   }
    2081           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2082             : 
    2083           0 :   ClearCachedDictionaryAttrValue(self);
    2084           0 :   return true;
    2085             : }
    2086             : 
    2087             : static const JSJitInfo dictionaryAttr_getterinfo = {
    2088             :   { (JSJitGetterOp)get_dictionaryAttr },
    2089             :   { prototypes::id::TestInterfaceJS },
    2090             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    2091             :   JSJitInfo::Getter,
    2092             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    2093             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    2094             :   false,  /* isInfallible. False in setters. */
    2095             :   false,  /* isMovable.  Not relevant for setters. */
    2096             :   false, /* isEliminatable.  Not relevant for setters. */
    2097             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2098             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2099             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2100             :   (DOM_INSTANCE_RESERVED_SLOTS + 1)   /* Reserved slot index, if we're stored in a slot, else 0. */
    2101             : };
    2102             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 1) <= JSJitInfo::maxSlotIndex, "We won't fit");
    2103             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 1) < 4, "There is no slot for us");
    2104             : static const JSJitInfo dictionaryAttr_setterinfo = {
    2105             :   { (JSJitGetterOp)set_dictionaryAttr },
    2106             :   { prototypes::id::TestInterfaceJS },
    2107             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    2108             :   JSJitInfo::Setter,
    2109             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2110             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    2111             :   false,  /* isInfallible. False in setters. */
    2112             :   false,  /* isMovable.  Not relevant for setters. */
    2113             :   false, /* isEliminatable.  Not relevant for setters. */
    2114             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2115             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2116             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2117             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2118             : };
    2119             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2120             : static_assert(0 < 4, "There is no slot for us");
    2121             : 
    2122             : static bool
    2123           0 : pingPongAny(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    2124             : {
    2125           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    2126           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJS.pingPongAny");
    2127             :   }
    2128           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2129           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2130           0 :   if (objIsXray) {
    2131           0 :     unwrappedObj.emplace(cx, obj);
    2132             :   }
    2133           0 :   JS::Rooted<JS::Value> arg0(cx);
    2134             : #ifdef __clang__
    2135             : #pragma clang diagnostic push
    2136             : #pragma clang diagnostic ignored "-Wunreachable-code"
    2137             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    2138             : #endif // __clang__
    2139           0 :   if ((true) && !CallerSubsumes(args[0])) {
    2140           0 :     ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "argument 1 of TestInterfaceJS.pingPongAny");
    2141           0 :     return false;
    2142             :   }
    2143             : #ifdef __clang__
    2144             : #pragma clang diagnostic pop
    2145             : #endif // __clang__
    2146           0 :   arg0 = args[0];
    2147           0 :   if (objIsXray) {
    2148           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2149           0 :     if (!unwrappedObj.ref()) {
    2150           0 :       return false;
    2151             :     }
    2152             :   }
    2153           0 :   binding_detail::FastErrorResult rv;
    2154           0 :   JS::Rooted<JS::Value> result(cx);
    2155           0 :   self->PingPongAny(arg0, &result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    2156           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2157           0 :     return false;
    2158             :   }
    2159           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2160           0 :   JS::ExposeValueToActiveJS(result);
    2161           0 :   args.rval().set(result);
    2162           0 :   if (!MaybeWrapValue(cx, args.rval())) {
    2163           0 :     return false;
    2164             :   }
    2165           0 :   return true;
    2166             : }
    2167             : 
    2168             : static const JSJitInfo pingPongAny_methodinfo = {
    2169             :   { (JSJitGetterOp)pingPongAny },
    2170             :   { prototypes::id::TestInterfaceJS },
    2171             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    2172             :   JSJitInfo::Method,
    2173             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2174             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    2175             :   false,  /* isInfallible. False in setters. */
    2176             :   false,  /* isMovable.  Not relevant for setters. */
    2177             :   false, /* isEliminatable.  Not relevant for setters. */
    2178             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2179             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2180             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2181             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2182             : };
    2183             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2184             : static_assert(0 < 4, "There is no slot for us");
    2185             : 
    2186             : static bool
    2187           0 : pingPongObject(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    2188             : {
    2189           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    2190           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJS.pingPongObject");
    2191             :   }
    2192           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2193           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2194           0 :   if (objIsXray) {
    2195           0 :     unwrappedObj.emplace(cx, obj);
    2196             :   }
    2197           0 :   JS::Rooted<JSObject*> arg0(cx);
    2198           0 :   if (args[0].isObject()) {
    2199             : #ifdef __clang__
    2200             : #pragma clang diagnostic push
    2201             : #pragma clang diagnostic ignored "-Wunreachable-code"
    2202             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    2203             : #endif // __clang__
    2204           0 :     if ((true) && !CallerSubsumes(args[0])) {
    2205           0 :       ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "argument 1 of TestInterfaceJS.pingPongObject");
    2206           0 :       return false;
    2207             :     }
    2208             : #ifdef __clang__
    2209             : #pragma clang diagnostic pop
    2210             : #endif // __clang__
    2211           0 :     arg0 = &args[0].toObject();
    2212             :   } else {
    2213           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of TestInterfaceJS.pingPongObject");
    2214           0 :     return false;
    2215             :   }
    2216           0 :   if (objIsXray) {
    2217           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2218           0 :     if (!unwrappedObj.ref()) {
    2219           0 :       return false;
    2220             :     }
    2221             :   }
    2222           0 :   binding_detail::FastErrorResult rv;
    2223           0 :   JS::Rooted<JSObject*> result(cx);
    2224           0 :   self->PingPongObject(arg0, &result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    2225           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2226           0 :     return false;
    2227             :   }
    2228           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2229           0 :   JS::ExposeObjectToActiveJS(result);
    2230           0 :   args.rval().setObject(*result);
    2231           0 :   if (!MaybeWrapObjectValue(cx, args.rval())) {
    2232           0 :     return false;
    2233             :   }
    2234           0 :   return true;
    2235             : }
    2236             : 
    2237             : static const JSJitInfo pingPongObject_methodinfo = {
    2238             :   { (JSJitGetterOp)pingPongObject },
    2239             :   { prototypes::id::TestInterfaceJS },
    2240             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    2241             :   JSJitInfo::Method,
    2242             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2243             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    2244             :   false,  /* isInfallible. False in setters. */
    2245             :   false,  /* isMovable.  Not relevant for setters. */
    2246             :   false, /* isEliminatable.  Not relevant for setters. */
    2247             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2248             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2249             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2250             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2251             : };
    2252             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2253             : static_assert(0 < 4, "There is no slot for us");
    2254             : 
    2255             : static bool
    2256           0 : pingPongObjectOrString(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    2257             : {
    2258           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    2259           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJS.pingPongObjectOrString");
    2260             :   }
    2261           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2262           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2263           0 :   if (objIsXray) {
    2264           0 :     unwrappedObj.emplace(cx, obj);
    2265             :   }
    2266           0 :   ObjectOrString arg0;
    2267           0 :   ObjectOrStringArgument arg0_holder(arg0);
    2268             :   {
    2269           0 :     bool done = false, failed = false, tryNext;
    2270           0 :     if (args[0].isObject()) {
    2271           0 :       if (!arg0_holder.SetToObject(cx, &args[0].toObject(), true)) {
    2272           0 :         return false;
    2273             :       }
    2274           0 :       done = true;
    2275             :     } else {
    2276             :       do {
    2277           0 :         done = (failed = !arg0_holder.TrySetToString(cx, args[0], tryNext)) || !tryNext;
    2278           0 :         break;
    2279             :       } while (0);
    2280             :     }
    2281           0 :     if (failed) {
    2282           0 :       return false;
    2283             :     }
    2284           0 :     if (!done) {
    2285           0 :       ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 1 of TestInterfaceJS.pingPongObjectOrString", "Object");
    2286           0 :       return false;
    2287             :     }
    2288             :   }
    2289           0 :   if (objIsXray) {
    2290           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2291           0 :     if (!unwrappedObj.ref()) {
    2292           0 :       return false;
    2293             :     }
    2294             :   }
    2295           0 :   binding_detail::FastErrorResult rv;
    2296           0 :   JS::Rooted<JS::Value> result(cx);
    2297           0 :   self->PingPongObjectOrString(Constify(arg0), &result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    2298           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2299           0 :     return false;
    2300             :   }
    2301           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2302           0 :   JS::ExposeValueToActiveJS(result);
    2303           0 :   args.rval().set(result);
    2304           0 :   if (!MaybeWrapValue(cx, args.rval())) {
    2305           0 :     return false;
    2306             :   }
    2307           0 :   return true;
    2308             : }
    2309             : 
    2310             : static const JSJitInfo pingPongObjectOrString_methodinfo = {
    2311             :   { (JSJitGetterOp)pingPongObjectOrString },
    2312             :   { prototypes::id::TestInterfaceJS },
    2313             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    2314             :   JSJitInfo::Method,
    2315             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2316             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    2317             :   false,  /* isInfallible. False in setters. */
    2318             :   false,  /* isMovable.  Not relevant for setters. */
    2319             :   false, /* isEliminatable.  Not relevant for setters. */
    2320             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2321             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2322             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2323             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2324             : };
    2325             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2326             : static_assert(0 < 4, "There is no slot for us");
    2327             : 
    2328             : static bool
    2329           0 : pingPongDictionary(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    2330             : {
    2331           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2332           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2333           0 :   if (objIsXray) {
    2334           0 :     unwrappedObj.emplace(cx, obj);
    2335             :   }
    2336           0 :   RootedDictionary<binding_detail::FastTestInterfaceJSDictionary> arg0(cx);
    2337           0 :   if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue,  "Argument 1 of TestInterfaceJS.pingPongDictionary", true)) {
    2338           0 :     return false;
    2339             :   }
    2340           0 :   if (objIsXray) {
    2341           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2342           0 :     if (!unwrappedObj.ref()) {
    2343           0 :       return false;
    2344             :     }
    2345             :   }
    2346           0 :   binding_detail::FastErrorResult rv;
    2347           0 :   RootedDictionary<TestInterfaceJSDictionary> result(cx);
    2348           0 :   self->PingPongDictionary(Constify(arg0), result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    2349           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2350           0 :     return false;
    2351             :   }
    2352           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2353           0 :   if (!result.ToObjectInternal(cx, args.rval())) {
    2354           0 :     return false;
    2355             :   }
    2356           0 :   return true;
    2357             : }
    2358             : 
    2359             : static const JSJitInfo pingPongDictionary_methodinfo = {
    2360             :   { (JSJitGetterOp)pingPongDictionary },
    2361             :   { prototypes::id::TestInterfaceJS },
    2362             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    2363             :   JSJitInfo::Method,
    2364             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2365             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    2366             :   false,  /* isInfallible. False in setters. */
    2367             :   false,  /* isMovable.  Not relevant for setters. */
    2368             :   false, /* isEliminatable.  Not relevant for setters. */
    2369             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2370             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2371             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2372             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2373             : };
    2374             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2375             : static_assert(0 < 4, "There is no slot for us");
    2376             : 
    2377             : static bool
    2378           0 : pingPongDictionaryOrLong(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    2379             : {
    2380           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2381           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2382           0 :   if (objIsXray) {
    2383           0 :     unwrappedObj.emplace(cx, obj);
    2384             :   }
    2385           0 :   TestInterfaceJSUnionableDictionaryOrLong arg0;
    2386           0 :   TestInterfaceJSUnionableDictionaryOrLongArgument arg0_holder(arg0);
    2387           0 :   if (!(args.hasDefined(0))) {
    2388           0 :     if (!arg0.RawSetAsTestInterfaceJSUnionableDictionary(cx).Init(cx, JS::NullHandleValue, "Member of TestInterfaceJSUnionableDictionaryOrLong")) {
    2389           0 :       return false;
    2390             :     }
    2391             :   } else {
    2392             :     {
    2393           0 :       bool done = false, failed = false, tryNext;
    2394           0 :       if (!done) {
    2395           0 :         done = (failed = !arg0_holder.TrySetToTestInterfaceJSUnionableDictionary(cx, args[0], tryNext, true)) || !tryNext;
    2396             :       }
    2397           0 :       if (!done) {
    2398             :         do {
    2399           0 :           done = (failed = !arg0_holder.TrySetToLong(cx, args[0], tryNext)) || !tryNext;
    2400           0 :           break;
    2401             :         } while (0);
    2402             :       }
    2403           0 :       if (failed) {
    2404           0 :         return false;
    2405             :       }
    2406           0 :       if (!done) {
    2407           0 :         ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 1 of TestInterfaceJS.pingPongDictionaryOrLong", "TestInterfaceJSUnionableDictionary");
    2408           0 :         return false;
    2409             :       }
    2410             :     }
    2411             :   }
    2412           0 :   if (objIsXray) {
    2413           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2414           0 :     if (!unwrappedObj.ref()) {
    2415           0 :       return false;
    2416             :     }
    2417             :   }
    2418           0 :   binding_detail::FastErrorResult rv;
    2419           0 :   int32_t result(self->PingPongDictionaryOrLong(Constify(arg0), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
    2420           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2421           0 :     return false;
    2422             :   }
    2423           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2424           0 :   args.rval().setInt32(int32_t(result));
    2425           0 :   return true;
    2426             : }
    2427             : 
    2428             : static const JSJitInfo pingPongDictionaryOrLong_methodinfo = {
    2429             :   { (JSJitGetterOp)pingPongDictionaryOrLong },
    2430             :   { prototypes::id::TestInterfaceJS },
    2431             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    2432             :   JSJitInfo::Method,
    2433             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2434             :   JSVAL_TYPE_INT32,  /* returnType.  Not relevant for setters. */
    2435             :   false,  /* isInfallible. False in setters. */
    2436             :   false,  /* isMovable.  Not relevant for setters. */
    2437             :   false, /* isEliminatable.  Not relevant for setters. */
    2438             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2439             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2440             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2441             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2442             : };
    2443             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2444             : static_assert(0 < 4, "There is no slot for us");
    2445             : 
    2446             : static bool
    2447           0 : pingPongMap(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    2448             : {
    2449           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    2450           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJS.pingPongMap");
    2451             :   }
    2452           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2453           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2454           0 :   if (objIsXray) {
    2455           0 :     unwrappedObj.emplace(cx, obj);
    2456             :   }
    2457           0 :   Record<nsString, JS::Value> arg0;
    2458           0 :   RecordRooter<nsString, JS::Value> arg0_holder(cx, &arg0);
    2459           0 :   if (args[0].isObject()) {
    2460           0 :     auto& recordEntries = arg0.Entries();
    2461             : 
    2462           0 :     JS::Rooted<JSObject*> recordObj(cx, &args[0].toObject());
    2463           0 :     JS::AutoIdVector ids(cx);
    2464           0 :     if (!js::GetPropertyKeys(cx, recordObj,
    2465             :                              JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
    2466           0 :       return false;
    2467             :     }
    2468           0 :     if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
    2469           0 :       JS_ReportOutOfMemory(cx);
    2470           0 :       return false;
    2471             :     }
    2472           0 :     JS::Rooted<JS::Value> propNameValue(cx);
    2473           0 :     JS::Rooted<JS::Value> temp(cx);
    2474           0 :     JS::Rooted<jsid> curId(cx);
    2475           0 :     JS::Rooted<JS::Value> idVal(cx);
    2476             :     // Use a hashset to keep track of ids seen, to avoid
    2477             :     // introducing nasty O(N^2) behavior scanning for them all the
    2478             :     // time.  Ideally we'd use a data structure with O(1) lookup
    2479             :     // _and_ ordering for the MozMap, but we don't have one lying
    2480             :     // around.
    2481           0 :     nsTHashtable<nsStringHashKey> idsSeen;
    2482           0 :     for (size_t i = 0; i < ids.length(); ++i) {
    2483           0 :       curId = ids[i];
    2484             : 
    2485           0 :       JS::Rooted<JS::PropertyDescriptor> desc(cx);
    2486           0 :       if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
    2487             :                                            &desc)) {
    2488           0 :         return false;
    2489             :       }
    2490             : 
    2491           0 :       if (!desc.object() /* == undefined in spec terms */ ||
    2492           0 :           !desc.enumerable()) {
    2493           0 :         continue;
    2494             :       }
    2495             : 
    2496           0 :       idVal = js::IdToValue(curId);
    2497           0 :       nsString propName;
    2498             :       // This will just throw if idVal is a Symbol, like the spec says
    2499             :       // to do.
    2500           0 :       if (!ConvertJSValueToString(cx, idVal, propName)) {
    2501           0 :         return false;
    2502             :       }
    2503             : 
    2504           0 :       if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
    2505           0 :         return false;
    2506             :       }
    2507             : 
    2508             :       Record<nsString, JS::Value>::EntryType* entry;
    2509           0 :       if (!idsSeen.EnsureInserted(propName)) {
    2510             :         // Find the existing entry.
    2511           0 :         auto idx = recordEntries.IndexOf(propName);
    2512           0 :         MOZ_ASSERT(idx != recordEntries.NoIndex,
    2513             :                    "Why is it not found?");
    2514             :         // Now blow it away to make it look like it was just added
    2515             :         // to the array, because it's not obvious that it's
    2516             :         // safe to write to its already-initialized mValue via our
    2517             :         // normal codegen conversions.  For example, the value
    2518             :         // could be a union and this would change its type, but
    2519             :         // codegen assumes we won't do that.
    2520           0 :         entry = recordEntries.ReconstructElementAt(idx);
    2521             :       } else {
    2522             :         // Safe to do an infallible append here, because we did a
    2523             :         // SetCapacity above to the right capacity.
    2524           0 :         entry = recordEntries.AppendElement();
    2525             :       }
    2526           0 :       entry->mKey = propName;
    2527           0 :       JS::Value& slot = entry->mValue;
    2528             : #ifdef __clang__
    2529             : #pragma clang diagnostic push
    2530             : #pragma clang diagnostic ignored "-Wunreachable-code"
    2531             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    2532             : #endif // __clang__
    2533           0 :       if ((true) && !CallerSubsumes(temp)) {
    2534           0 :         ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "value in argument 1 of TestInterfaceJS.pingPongMap");
    2535           0 :         return false;
    2536             :       }
    2537             : #ifdef __clang__
    2538             : #pragma clang diagnostic pop
    2539             : #endif // __clang__
    2540           0 :       slot = temp;
    2541             :     }
    2542             :   } else {
    2543           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of TestInterfaceJS.pingPongMap");
    2544           0 :     return false;
    2545             :   }
    2546           0 :   if (objIsXray) {
    2547           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2548           0 :     if (!unwrappedObj.ref()) {
    2549           0 :       return false;
    2550             :     }
    2551             :   }
    2552           0 :   binding_detail::FastErrorResult rv;
    2553           0 :   DOMString result;
    2554           0 :   self->PingPongMap(Constify(arg0), result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    2555           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2556           0 :     return false;
    2557             :   }
    2558           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2559           0 :   if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    2560           0 :     return false;
    2561             :   }
    2562           0 :   return true;
    2563             : }
    2564             : 
    2565             : static const JSJitInfo pingPongMap_methodinfo = {
    2566             :   { (JSJitGetterOp)pingPongMap },
    2567             :   { prototypes::id::TestInterfaceJS },
    2568             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    2569             :   JSJitInfo::Method,
    2570             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2571             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
    2572             :   false,  /* isInfallible. False in setters. */
    2573             :   false,  /* isMovable.  Not relevant for setters. */
    2574             :   false, /* isEliminatable.  Not relevant for setters. */
    2575             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2576             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2577             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2578             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2579             : };
    2580             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2581             : static_assert(0 < 4, "There is no slot for us");
    2582             : 
    2583             : static bool
    2584           0 : objectSequenceLength(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    2585             : {
    2586           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    2587           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJS.objectSequenceLength");
    2588             :   }
    2589           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2590           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2591           0 :   if (objIsXray) {
    2592           0 :     unwrappedObj.emplace(cx, obj);
    2593             :   }
    2594           0 :   binding_detail::AutoSequence<JSObject*> arg0;
    2595           0 :   SequenceRooter<JSObject*> arg0_holder(cx, &arg0);
    2596           0 :   if (args[0].isObject()) {
    2597           0 :     JS::ForOfIterator iter(cx);
    2598           0 :     if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) {
    2599           0 :       return false;
    2600             :     }
    2601           0 :     if (!iter.valueIsIterable()) {
    2602           0 :       ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 1 of TestInterfaceJS.objectSequenceLength");
    2603           0 :       return false;
    2604             :     }
    2605           0 :     binding_detail::AutoSequence<JSObject*> &arr = arg0;
    2606           0 :     JS::Rooted<JS::Value> temp(cx);
    2607             :     while (true) {
    2608             :       bool done;
    2609           0 :       if (!iter.next(&temp, &done)) {
    2610           0 :         return false;
    2611             :       }
    2612           0 :       if (done) {
    2613           0 :         break;
    2614             :       }
    2615           0 :       JSObject** slotPtr = arr.AppendElement(mozilla::fallible);
    2616           0 :       if (!slotPtr) {
    2617           0 :         JS_ReportOutOfMemory(cx);
    2618           0 :         return false;
    2619             :       }
    2620           0 :       JSObject*& slot = *slotPtr;
    2621           0 :       if (temp.isObject()) {
    2622             : #ifdef __clang__
    2623             : #pragma clang diagnostic push
    2624             : #pragma clang diagnostic ignored "-Wunreachable-code"
    2625             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    2626             : #endif // __clang__
    2627           0 :         if ((true) && !CallerSubsumes(temp)) {
    2628           0 :           ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "element of argument 1 of TestInterfaceJS.objectSequenceLength");
    2629           0 :           return false;
    2630             :         }
    2631             : #ifdef __clang__
    2632             : #pragma clang diagnostic pop
    2633             : #endif // __clang__
    2634           0 :         slot = &temp.toObject();
    2635             :       } else {
    2636           0 :         ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Element of argument 1 of TestInterfaceJS.objectSequenceLength");
    2637           0 :         return false;
    2638             :       }
    2639           0 :     }
    2640             :   } else {
    2641           0 :     ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 1 of TestInterfaceJS.objectSequenceLength");
    2642           0 :     return false;
    2643             :   }
    2644           0 :   if (objIsXray) {
    2645           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2646           0 :     if (!unwrappedObj.ref()) {
    2647           0 :       return false;
    2648             :     }
    2649             :   }
    2650           0 :   binding_detail::FastErrorResult rv;
    2651           0 :   int32_t result(self->ObjectSequenceLength(Constify(arg0), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
    2652           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2653           0 :     return false;
    2654             :   }
    2655           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2656           0 :   args.rval().setInt32(int32_t(result));
    2657           0 :   return true;
    2658             : }
    2659             : 
    2660             : static const JSJitInfo objectSequenceLength_methodinfo = {
    2661             :   { (JSJitGetterOp)objectSequenceLength },
    2662             :   { prototypes::id::TestInterfaceJS },
    2663             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    2664             :   JSJitInfo::Method,
    2665             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2666             :   JSVAL_TYPE_INT32,  /* returnType.  Not relevant for setters. */
    2667             :   false,  /* isInfallible. False in setters. */
    2668             :   false,  /* isMovable.  Not relevant for setters. */
    2669             :   false, /* isEliminatable.  Not relevant for setters. */
    2670             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2671             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2672             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2673             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2674             : };
    2675             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2676             : static_assert(0 < 4, "There is no slot for us");
    2677             : 
    2678             : static bool
    2679           0 : anySequenceLength(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    2680             : {
    2681           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    2682           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJS.anySequenceLength");
    2683             :   }
    2684           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2685           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2686           0 :   if (objIsXray) {
    2687           0 :     unwrappedObj.emplace(cx, obj);
    2688             :   }
    2689           0 :   binding_detail::AutoSequence<JS::Value> arg0;
    2690           0 :   SequenceRooter<JS::Value> arg0_holder(cx, &arg0);
    2691           0 :   if (args[0].isObject()) {
    2692           0 :     JS::ForOfIterator iter(cx);
    2693           0 :     if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) {
    2694           0 :       return false;
    2695             :     }
    2696           0 :     if (!iter.valueIsIterable()) {
    2697           0 :       ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 1 of TestInterfaceJS.anySequenceLength");
    2698           0 :       return false;
    2699             :     }
    2700           0 :     binding_detail::AutoSequence<JS::Value> &arr = arg0;
    2701           0 :     JS::Rooted<JS::Value> temp(cx);
    2702             :     while (true) {
    2703             :       bool done;
    2704           0 :       if (!iter.next(&temp, &done)) {
    2705           0 :         return false;
    2706             :       }
    2707           0 :       if (done) {
    2708           0 :         break;
    2709             :       }
    2710           0 :       JS::Value* slotPtr = arr.AppendElement(mozilla::fallible);
    2711           0 :       if (!slotPtr) {
    2712           0 :         JS_ReportOutOfMemory(cx);
    2713           0 :         return false;
    2714             :       }
    2715           0 :       JS::Value& slot = *slotPtr;
    2716             : #ifdef __clang__
    2717             : #pragma clang diagnostic push
    2718             : #pragma clang diagnostic ignored "-Wunreachable-code"
    2719             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    2720             : #endif // __clang__
    2721           0 :       if ((true) && !CallerSubsumes(temp)) {
    2722           0 :         ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "element of argument 1 of TestInterfaceJS.anySequenceLength");
    2723           0 :         return false;
    2724             :       }
    2725             : #ifdef __clang__
    2726             : #pragma clang diagnostic pop
    2727             : #endif // __clang__
    2728           0 :       slot = temp;
    2729           0 :     }
    2730             :   } else {
    2731           0 :     ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 1 of TestInterfaceJS.anySequenceLength");
    2732           0 :     return false;
    2733             :   }
    2734           0 :   if (objIsXray) {
    2735           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2736           0 :     if (!unwrappedObj.ref()) {
    2737           0 :       return false;
    2738             :     }
    2739             :   }
    2740           0 :   binding_detail::FastErrorResult rv;
    2741           0 :   int32_t result(self->AnySequenceLength(Constify(arg0), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
    2742           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2743           0 :     return false;
    2744             :   }
    2745           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2746           0 :   args.rval().setInt32(int32_t(result));
    2747           0 :   return true;
    2748             : }
    2749             : 
    2750             : static const JSJitInfo anySequenceLength_methodinfo = {
    2751             :   { (JSJitGetterOp)anySequenceLength },
    2752             :   { prototypes::id::TestInterfaceJS },
    2753             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    2754             :   JSJitInfo::Method,
    2755             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2756             :   JSVAL_TYPE_INT32,  /* returnType.  Not relevant for setters. */
    2757             :   false,  /* isInfallible. False in setters. */
    2758             :   false,  /* isMovable.  Not relevant for setters. */
    2759             :   false, /* isEliminatable.  Not relevant for setters. */
    2760             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2761             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2762             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2763             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2764             : };
    2765             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2766             : static_assert(0 < 4, "There is no slot for us");
    2767             : 
    2768             : static bool
    2769           0 : getCallerPrincipal(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    2770             : {
    2771           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2772           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2773           0 :   if (objIsXray) {
    2774           0 :     unwrappedObj.emplace(cx, obj);
    2775             :   }
    2776           0 :   if (objIsXray) {
    2777           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2778           0 :     if (!unwrappedObj.ref()) {
    2779           0 :       return false;
    2780             :     }
    2781             :   }
    2782           0 :   binding_detail::FastErrorResult rv;
    2783           0 :   DOMString result;
    2784           0 :   self->GetCallerPrincipal(result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    2785           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2786           0 :     return false;
    2787             :   }
    2788           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2789           0 :   if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    2790           0 :     return false;
    2791             :   }
    2792           0 :   return true;
    2793             : }
    2794             : 
    2795             : static const JSJitInfo getCallerPrincipal_methodinfo = {
    2796             :   { (JSJitGetterOp)getCallerPrincipal },
    2797             :   { prototypes::id::TestInterfaceJS },
    2798             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    2799             :   JSJitInfo::Method,
    2800             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2801             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
    2802             :   false,  /* isInfallible. False in setters. */
    2803             :   false,  /* isMovable.  Not relevant for setters. */
    2804             :   false, /* isEliminatable.  Not relevant for setters. */
    2805             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2806             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2807             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2808             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2809             : };
    2810             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2811             : static_assert(0 < 4, "There is no slot for us");
    2812             : 
    2813             : static bool
    2814           0 : convertSVS(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    2815             : {
    2816           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    2817           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJS.convertSVS");
    2818             :   }
    2819           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2820           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2821           0 :   if (objIsXray) {
    2822           0 :     unwrappedObj.emplace(cx, obj);
    2823             :   }
    2824           0 :   binding_detail::FakeString arg0;
    2825           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    2826           0 :     return false;
    2827             :   }
    2828           0 :   NormalizeUSVString(arg0);
    2829           0 :   if (objIsXray) {
    2830           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2831           0 :     if (!unwrappedObj.ref()) {
    2832           0 :       return false;
    2833             :     }
    2834             :   }
    2835           0 :   binding_detail::FastErrorResult rv;
    2836           0 :   DOMString result;
    2837           0 :   self->ConvertSVS(Constify(arg0), result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    2838           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2839           0 :     return false;
    2840             :   }
    2841           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2842           0 :   if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    2843           0 :     return false;
    2844             :   }
    2845           0 :   return true;
    2846             : }
    2847             : 
    2848             : static const JSJitInfo convertSVS_methodinfo = {
    2849             :   { (JSJitGetterOp)convertSVS },
    2850             :   { prototypes::id::TestInterfaceJS },
    2851             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    2852             :   JSJitInfo::Method,
    2853             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2854             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
    2855             :   false,  /* isInfallible. False in setters. */
    2856             :   false,  /* isMovable.  Not relevant for setters. */
    2857             :   false, /* isEliminatable.  Not relevant for setters. */
    2858             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2859             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2860             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2861             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2862             : };
    2863             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2864             : static_assert(0 < 4, "There is no slot for us");
    2865             : 
    2866             : static bool
    2867           0 : pingPongUnion(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    2868             : {
    2869           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    2870           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJS.pingPongUnion");
    2871             :   }
    2872           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2873           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2874           0 :   if (objIsXray) {
    2875           0 :     unwrappedObj.emplace(cx, obj);
    2876             :   }
    2877           0 :   TestInterfaceJSOrLong arg0;
    2878           0 :   TestInterfaceJSOrLongArgument arg0_holder(arg0);
    2879             :   {
    2880           0 :     bool done = false, failed = false, tryNext;
    2881           0 :     if (args[0].isObject()) {
    2882           0 :       done = (failed = !arg0_holder.TrySetToTestInterfaceJS(cx, args[0], tryNext, true)) || !tryNext;
    2883             : 
    2884             :     }
    2885           0 :     if (!done) {
    2886             :       do {
    2887           0 :         done = (failed = !arg0_holder.TrySetToLong(cx, args[0], tryNext)) || !tryNext;
    2888           0 :         break;
    2889             :       } while (0);
    2890             :     }
    2891           0 :     if (failed) {
    2892           0 :       return false;
    2893             :     }
    2894           0 :     if (!done) {
    2895           0 :       ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 1 of TestInterfaceJS.pingPongUnion", "TestInterfaceJS");
    2896           0 :       return false;
    2897             :     }
    2898             :   }
    2899           0 :   if (objIsXray) {
    2900           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2901           0 :     if (!unwrappedObj.ref()) {
    2902           0 :       return false;
    2903             :     }
    2904             :   }
    2905           0 :   binding_detail::FastErrorResult rv;
    2906           0 :   OwningTestInterfaceJSOrLong result;
    2907           0 :   self->PingPongUnion(Constify(arg0), result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    2908           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2909           0 :     return false;
    2910             :   }
    2911           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2912           0 :   if (!result.ToJSVal(cx, obj, args.rval())) {
    2913           0 :     return false;
    2914             :   }
    2915           0 :   return true;
    2916             : }
    2917             : 
    2918             : static const JSJitInfo pingPongUnion_methodinfo = {
    2919             :   { (JSJitGetterOp)pingPongUnion },
    2920             :   { prototypes::id::TestInterfaceJS },
    2921             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    2922             :   JSJitInfo::Method,
    2923             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2924             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    2925             :   false,  /* isInfallible. False in setters. */
    2926             :   false,  /* isMovable.  Not relevant for setters. */
    2927             :   false, /* isEliminatable.  Not relevant for setters. */
    2928             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    2929             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    2930             :   false,  /* isTypedMethod.  Only relevant for methods. */
    2931             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    2932             : };
    2933             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    2934             : static_assert(0 < 4, "There is no slot for us");
    2935             : 
    2936             : static bool
    2937           0 : pingPongUnionContainingNull(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    2938             : {
    2939           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    2940           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJS.pingPongUnionContainingNull");
    2941             :   }
    2942           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    2943           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    2944           0 :   if (objIsXray) {
    2945           0 :     unwrappedObj.emplace(cx, obj);
    2946             :   }
    2947           0 :   TestInterfaceJSOrNullOrString arg0;
    2948           0 :   TestInterfaceJSOrNullOrStringArgument arg0_holder(arg0);
    2949           0 :   if (args[0].isNullOrUndefined()) {
    2950           0 :     arg0_holder.SetNull();
    2951             :   } else {
    2952             :     {
    2953           0 :       bool done = false, failed = false, tryNext;
    2954           0 :       if (args[0].isObject()) {
    2955           0 :         done = (failed = !arg0_holder.TrySetToTestInterfaceJS(cx, args[0], tryNext, true)) || !tryNext;
    2956             : 
    2957             :       }
    2958           0 :       if (!done) {
    2959             :         do {
    2960           0 :           done = (failed = !arg0_holder.TrySetToString(cx, args[0], tryNext)) || !tryNext;
    2961           0 :           break;
    2962             :         } while (0);
    2963             :       }
    2964           0 :       if (failed) {
    2965           0 :         return false;
    2966             :       }
    2967           0 :       if (!done) {
    2968           0 :         ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 1 of TestInterfaceJS.pingPongUnionContainingNull", "TestInterfaceJS");
    2969           0 :         return false;
    2970             :       }
    2971             :     }
    2972             :   }
    2973           0 :   if (objIsXray) {
    2974           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    2975           0 :     if (!unwrappedObj.ref()) {
    2976           0 :       return false;
    2977             :     }
    2978             :   }
    2979           0 :   binding_detail::FastErrorResult rv;
    2980           0 :   OwningStringOrTestInterfaceJSOrNull result;
    2981           0 :   self->PingPongUnionContainingNull(Constify(arg0), result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    2982           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2983           0 :     return false;
    2984             :   }
    2985           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2986           0 :   if (!result.ToJSVal(cx, obj, args.rval())) {
    2987           0 :     return false;
    2988             :   }
    2989           0 :   return true;
    2990             : }
    2991             : 
    2992             : static const JSJitInfo pingPongUnionContainingNull_methodinfo = {
    2993             :   { (JSJitGetterOp)pingPongUnionContainingNull },
    2994             :   { prototypes::id::TestInterfaceJS },
    2995             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    2996             :   JSJitInfo::Method,
    2997             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    2998             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    2999             :   false,  /* isInfallible. False in setters. */
    3000             :   false,  /* isMovable.  Not relevant for setters. */
    3001             :   false, /* isEliminatable.  Not relevant for setters. */
    3002             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3003             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3004             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3005             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3006             : };
    3007             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3008             : static_assert(0 < 4, "There is no slot for us");
    3009             : 
    3010             : static bool
    3011           0 : pingPongNullableUnion(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3012             : {
    3013           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    3014           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJS.pingPongNullableUnion");
    3015             :   }
    3016           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3017           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3018           0 :   if (objIsXray) {
    3019           0 :     unwrappedObj.emplace(cx, obj);
    3020             :   }
    3021           0 :   Nullable<TestInterfaceJSOrLong > arg0;
    3022           0 :   Maybe<TestInterfaceJSOrLongArgument> arg0_holder;
    3023           0 :   if (args[0].isNullOrUndefined()) {
    3024           0 :     arg0.SetNull();
    3025             :   } else {
    3026           0 :     arg0_holder.emplace(arg0.SetValue());
    3027             :     {
    3028           0 :       bool done = false, failed = false, tryNext;
    3029           0 :       if (args[0].isObject()) {
    3030           0 :         done = (failed = !arg0_holder.ref().TrySetToTestInterfaceJS(cx, args[0], tryNext, true)) || !tryNext;
    3031             : 
    3032             :       }
    3033           0 :       if (!done) {
    3034             :         do {
    3035           0 :           done = (failed = !arg0_holder.ref().TrySetToLong(cx, args[0], tryNext)) || !tryNext;
    3036           0 :           break;
    3037             :         } while (0);
    3038             :       }
    3039           0 :       if (failed) {
    3040           0 :         return false;
    3041             :       }
    3042           0 :       if (!done) {
    3043           0 :         ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 1 of TestInterfaceJS.pingPongNullableUnion", "TestInterfaceJS");
    3044           0 :         return false;
    3045             :       }
    3046             :     }
    3047             :   }
    3048           0 :   if (objIsXray) {
    3049           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3050           0 :     if (!unwrappedObj.ref()) {
    3051           0 :       return false;
    3052             :     }
    3053             :   }
    3054           0 :   binding_detail::FastErrorResult rv;
    3055           0 :   Nullable<OwningTestInterfaceJSOrLong> result;
    3056           0 :   self->PingPongNullableUnion(Constify(arg0), result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    3057           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3058           0 :     return false;
    3059             :   }
    3060           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3061           0 :   if (result.IsNull()) {
    3062           0 :     args.rval().setNull();
    3063           0 :     return true;
    3064             :   }
    3065           0 :   if (!result.Value().ToJSVal(cx, obj, args.rval())) {
    3066           0 :     return false;
    3067             :   }
    3068           0 :   return true;
    3069             : }
    3070             : 
    3071             : static const JSJitInfo pingPongNullableUnion_methodinfo = {
    3072             :   { (JSJitGetterOp)pingPongNullableUnion },
    3073             :   { prototypes::id::TestInterfaceJS },
    3074             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    3075             :   JSJitInfo::Method,
    3076             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3077             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    3078             :   false,  /* isInfallible. False in setters. */
    3079             :   false,  /* isMovable.  Not relevant for setters. */
    3080             :   false, /* isEliminatable.  Not relevant for setters. */
    3081             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3082             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3083             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3084             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3085             : };
    3086             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3087             : static_assert(0 < 4, "There is no slot for us");
    3088             : 
    3089             : static bool
    3090           0 : returnBadUnion(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3091             : {
    3092           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3093           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3094           0 :   if (objIsXray) {
    3095           0 :     unwrappedObj.emplace(cx, obj);
    3096             :   }
    3097           0 :   if (objIsXray) {
    3098           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3099           0 :     if (!unwrappedObj.ref()) {
    3100           0 :       return false;
    3101             :     }
    3102             :   }
    3103           0 :   binding_detail::FastErrorResult rv;
    3104           0 :   OwningLocationOrTestInterfaceJS result;
    3105           0 :   self->ReturnBadUnion(result, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    3106           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3107           0 :     return false;
    3108             :   }
    3109           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3110           0 :   if (!result.ToJSVal(cx, obj, args.rval())) {
    3111           0 :     return false;
    3112             :   }
    3113           0 :   return true;
    3114             : }
    3115             : 
    3116             : static const JSJitInfo returnBadUnion_methodinfo = {
    3117             :   { (JSJitGetterOp)returnBadUnion },
    3118             :   { prototypes::id::TestInterfaceJS },
    3119             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    3120             :   JSJitInfo::Method,
    3121             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3122             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    3123             :   false,  /* isInfallible. False in setters. */
    3124             :   false,  /* isMovable.  Not relevant for setters. */
    3125             :   false, /* isEliminatable.  Not relevant for setters. */
    3126             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3127             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3128             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3129             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3130             : };
    3131             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3132             : static_assert(0 < 4, "There is no slot for us");
    3133             : 
    3134             : static bool
    3135           0 : get_cachedAttr(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, JSJitGetterCallArgs args)
    3136             : {
    3137             :   // Have to either root across the getter call or reget after.
    3138             :   bool isXray;
    3139           0 :   JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
    3140           0 :   if (!slotStorage) {
    3141           0 :     return false;
    3142             :   }
    3143           0 :   const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 2) : (DOM_INSTANCE_RESERVED_SLOTS + 2);
    3144           0 :   MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
    3145             :   {
    3146             :     // Scope for cachedVal
    3147           0 :     JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
    3148           0 :     if (!cachedVal.isUndefined()) {
    3149           0 :       args.rval().set(cachedVal);
    3150             :       // The cached value is in the compartment of slotStorage,
    3151             :       // so wrap into the caller compartment as needed.
    3152           0 :       return MaybeWrapValue(cx, args.rval());
    3153             :     }
    3154             :   }
    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 :   if (objIsXray) {
    3162           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3163           0 :     if (!unwrappedObj.ref()) {
    3164           0 :       return false;
    3165             :     }
    3166             :   }
    3167           0 :   binding_detail::FastErrorResult rv;
    3168           0 :   int16_t result(self->GetCachedAttr(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
    3169           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3170           0 :     return false;
    3171             :   }
    3172           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3173             :   {
    3174           0 :     JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
    3175           0 :     JSAutoCompartment ac(cx, conversionScope);
    3176             :     do { // block we break out of when done wrapping
    3177           0 :       args.rval().setInt32(int32_t(result));
    3178           0 :       break;
    3179             :     } while (0);
    3180             :   }
    3181             :   { // And now store things in the compartment of our slotStorage.
    3182           0 :     JSAutoCompartment ac(cx, slotStorage);
    3183             :     // Make a copy so that we don't do unnecessary wrapping on args.rval().
    3184           0 :     JS::Rooted<JS::Value> storedVal(cx, args.rval());
    3185           0 :     if (!MaybeWrapValue(cx, &storedVal)) {
    3186           0 :       return false;
    3187             :     }
    3188           0 :     js::SetReservedSlot(slotStorage, slotIndex, storedVal);
    3189           0 :     if (!isXray) {
    3190             :       // In the Xray case we don't need to do this, because getting the
    3191             :       // expando object already preserved our wrapper.
    3192           0 :       PreserveWrapper(self);
    3193             :     }
    3194             :   }
    3195             :   // And now make sure args.rval() is in the caller compartment
    3196           0 :   return MaybeWrapValue(cx, args.rval());
    3197             : }
    3198             : 
    3199             : static const JSJitInfo cachedAttr_getterinfo = {
    3200             :   { (JSJitGetterOp)get_cachedAttr },
    3201             :   { prototypes::id::TestInterfaceJS },
    3202             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    3203             :   JSJitInfo::Getter,
    3204             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    3205             :   JSVAL_TYPE_INT32,  /* returnType.  Not relevant for setters. */
    3206             :   false,  /* isInfallible. False in setters. */
    3207             :   false,  /* isMovable.  Not relevant for setters. */
    3208             :   false, /* isEliminatable.  Not relevant for setters. */
    3209             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3210             :   true, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3211             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3212             :   (DOM_INSTANCE_RESERVED_SLOTS + 2)   /* Reserved slot index, if we're stored in a slot, else 0. */
    3213             : };
    3214             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 2) <= JSJitInfo::maxSlotIndex, "We won't fit");
    3215             : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 2) < 4, "There is no slot for us");
    3216             : 
    3217             : static bool
    3218           0 : setCachedAttr(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3219             : {
    3220           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    3221           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJS.setCachedAttr");
    3222             :   }
    3223           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3224           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3225           0 :   if (objIsXray) {
    3226           0 :     unwrappedObj.emplace(cx, obj);
    3227             :   }
    3228             :   int16_t arg0;
    3229           0 :   if (!ValueToPrimitive<int16_t, eDefault>(cx, args[0], &arg0)) {
    3230           0 :     return false;
    3231             :   }
    3232           0 :   if (objIsXray) {
    3233           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3234           0 :     if (!unwrappedObj.ref()) {
    3235           0 :       return false;
    3236             :     }
    3237             :   }
    3238           0 :   binding_detail::FastErrorResult rv;
    3239           0 :   self->SetCachedAttr(arg0, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    3240           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3241           0 :     return false;
    3242             :   }
    3243           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3244           0 :   args.rval().setUndefined();
    3245           0 :   return true;
    3246             : }
    3247             : 
    3248             : static const JSJitInfo setCachedAttr_methodinfo = {
    3249             :   { (JSJitGetterOp)setCachedAttr },
    3250             :   { prototypes::id::TestInterfaceJS },
    3251             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    3252             :   JSJitInfo::Method,
    3253             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3254             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    3255             :   false,  /* isInfallible. False in setters. */
    3256             :   false,  /* isMovable.  Not relevant for setters. */
    3257             :   false, /* isEliminatable.  Not relevant for setters. */
    3258             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3259             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3260             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3261             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3262             : };
    3263             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3264             : static_assert(0 < 4, "There is no slot for us");
    3265             : 
    3266             : static bool
    3267           0 : clearCachedAttrCache(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3268             : {
    3269           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3270           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3271           0 :   if (objIsXray) {
    3272           0 :     unwrappedObj.emplace(cx, obj);
    3273             :   }
    3274           0 :   if (objIsXray) {
    3275           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3276           0 :     if (!unwrappedObj.ref()) {
    3277           0 :       return false;
    3278             :     }
    3279             :   }
    3280           0 :   binding_detail::FastErrorResult rv;
    3281           0 :   self->ClearCachedAttrCache(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    3282           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3283           0 :     return false;
    3284             :   }
    3285           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3286           0 :   args.rval().setUndefined();
    3287           0 :   return true;
    3288             : }
    3289             : 
    3290             : static const JSJitInfo clearCachedAttrCache_methodinfo = {
    3291             :   { (JSJitGetterOp)clearCachedAttrCache },
    3292             :   { prototypes::id::TestInterfaceJS },
    3293             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    3294             :   JSJitInfo::Method,
    3295             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3296             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    3297             :   false,  /* isInfallible. False in setters. */
    3298             :   false,  /* isMovable.  Not relevant for setters. */
    3299             :   false, /* isEliminatable.  Not relevant for setters. */
    3300             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3301             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3302             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3303             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3304             : };
    3305             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3306             : static_assert(0 < 4, "There is no slot for us");
    3307             : 
    3308             : static bool
    3309           0 : testSequenceOverload(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3310             : {
    3311           0 :   unsigned argcount = std::min(args.length(), 1u);
    3312           0 :   switch (argcount) {
    3313             :     case 1: {
    3314           0 :       if (args[0].isObject()) {
    3315             :         do {
    3316           0 :           binding_detail::AutoSequence<nsString> arg0;
    3317           0 :           JS::ForOfIterator iter(cx);
    3318           0 :           if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) {
    3319           0 :             return false;
    3320             :           }
    3321           0 :           if (!iter.valueIsIterable()) {
    3322           0 :             break;
    3323             :           }
    3324           0 :           binding_detail::AutoSequence<nsString> &arr = arg0;
    3325           0 :           JS::Rooted<JS::Value> temp(cx);
    3326             :           while (true) {
    3327             :             bool done;
    3328           0 :             if (!iter.next(&temp, &done)) {
    3329           0 :               return false;
    3330             :             }
    3331           0 :             if (done) {
    3332           0 :               break;
    3333             :             }
    3334           0 :             nsString* slotPtr = arr.AppendElement(mozilla::fallible);
    3335           0 :             if (!slotPtr) {
    3336           0 :               JS_ReportOutOfMemory(cx);
    3337           0 :               return false;
    3338             :             }
    3339           0 :             nsString& slot = *slotPtr;
    3340           0 :             if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
    3341           0 :               return false;
    3342             :             }
    3343           0 :           }
    3344           0 :           Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3345           0 :           bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3346           0 :           if (objIsXray) {
    3347           0 :             unwrappedObj.emplace(cx, obj);
    3348             :           }
    3349           0 :           if (objIsXray) {
    3350           0 :             unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3351           0 :             if (!unwrappedObj.ref()) {
    3352           0 :               return false;
    3353             :             }
    3354             :           }
    3355           0 :           binding_detail::FastErrorResult rv;
    3356           0 :           self->TestSequenceOverload(Constify(arg0), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    3357           0 :           if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3358           0 :             return false;
    3359             :           }
    3360           0 :           MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3361           0 :           args.rval().setUndefined();
    3362           0 :           return true;
    3363             :         } while (0);
    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 :       binding_detail::FakeString arg0;
    3371           0 :       if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    3372           0 :         return false;
    3373             :       }
    3374           0 :       if (objIsXray) {
    3375           0 :         unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3376           0 :         if (!unwrappedObj.ref()) {
    3377           0 :           return false;
    3378             :         }
    3379             :       }
    3380           0 :       binding_detail::FastErrorResult rv;
    3381           0 :       self->TestSequenceOverload(NonNullHelper(Constify(arg0)), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    3382           0 :       if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3383           0 :         return false;
    3384             :       }
    3385           0 :       MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3386           0 :       args.rval().setUndefined();
    3387           0 :       return true;
    3388             :       break;
    3389             :     }
    3390             :     default: {
    3391           0 :       return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJS.testSequenceOverload");
    3392             :       break;
    3393             :     }
    3394             :   }
    3395             :   MOZ_CRASH("We have an always-returning default case");
    3396             :   return false;
    3397             : }
    3398             : 
    3399             : static const JSJitInfo testSequenceOverload_methodinfo = {
    3400             :   { (JSJitGetterOp)testSequenceOverload },
    3401             :   { prototypes::id::TestInterfaceJS },
    3402             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    3403             :   JSJitInfo::Method,
    3404             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3405             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    3406             :   false,  /* isInfallible. False in setters. */
    3407             :   false,  /* isMovable.  Not relevant for setters. */
    3408             :   false, /* isEliminatable.  Not relevant for setters. */
    3409             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3410             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3411             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3412             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3413             : };
    3414             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3415             : static_assert(0 < 4, "There is no slot for us");
    3416             : 
    3417             : static bool
    3418           0 : testSequenceUnion(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3419             : {
    3420           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    3421           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJS.testSequenceUnion");
    3422             :   }
    3423           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3424           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3425           0 :   if (objIsXray) {
    3426           0 :     unwrappedObj.emplace(cx, obj);
    3427             :   }
    3428           0 :   StringSequenceOrString arg0;
    3429           0 :   StringSequenceOrStringArgument arg0_holder(arg0);
    3430             :   {
    3431           0 :     bool done = false, failed = false, tryNext;
    3432           0 :     if (args[0].isObject()) {
    3433           0 :       done = (failed = !arg0_holder.TrySetToStringSequence(cx, args[0], tryNext, true)) || !tryNext;
    3434             :     }
    3435           0 :     if (!done) {
    3436             :       do {
    3437           0 :         done = (failed = !arg0_holder.TrySetToString(cx, args[0], tryNext)) || !tryNext;
    3438           0 :         break;
    3439             :       } while (0);
    3440             :     }
    3441           0 :     if (failed) {
    3442           0 :       return false;
    3443             :     }
    3444           0 :     if (!done) {
    3445           0 :       ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 1 of TestInterfaceJS.testSequenceUnion", "StringSequence");
    3446           0 :       return false;
    3447             :     }
    3448             :   }
    3449           0 :   if (objIsXray) {
    3450           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3451           0 :     if (!unwrappedObj.ref()) {
    3452           0 :       return false;
    3453             :     }
    3454             :   }
    3455           0 :   binding_detail::FastErrorResult rv;
    3456           0 :   self->TestSequenceUnion(Constify(arg0), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    3457           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3458           0 :     return false;
    3459             :   }
    3460           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3461           0 :   args.rval().setUndefined();
    3462           0 :   return true;
    3463             : }
    3464             : 
    3465             : static const JSJitInfo testSequenceUnion_methodinfo = {
    3466             :   { (JSJitGetterOp)testSequenceUnion },
    3467             :   { prototypes::id::TestInterfaceJS },
    3468             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    3469             :   JSJitInfo::Method,
    3470             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3471             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    3472             :   false,  /* isInfallible. False in setters. */
    3473             :   false,  /* isMovable.  Not relevant for setters. */
    3474             :   false, /* isEliminatable.  Not relevant for setters. */
    3475             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3476             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3477             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3478             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3479             : };
    3480             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3481             : static_assert(0 < 4, "There is no slot for us");
    3482             : 
    3483             : static bool
    3484           0 : testThrowError(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3485             : {
    3486           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3487           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3488           0 :   if (objIsXray) {
    3489           0 :     unwrappedObj.emplace(cx, obj);
    3490             :   }
    3491           0 :   if (objIsXray) {
    3492           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3493           0 :     if (!unwrappedObj.ref()) {
    3494           0 :       return false;
    3495             :     }
    3496             :   }
    3497           0 :   binding_detail::FastErrorResult rv;
    3498           0 :   self->TestThrowError(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    3499           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3500           0 :     return false;
    3501             :   }
    3502           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3503           0 :   args.rval().setUndefined();
    3504           0 :   return true;
    3505             : }
    3506             : 
    3507             : static const JSJitInfo testThrowError_methodinfo = {
    3508             :   { (JSJitGetterOp)testThrowError },
    3509             :   { prototypes::id::TestInterfaceJS },
    3510             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    3511             :   JSJitInfo::Method,
    3512             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3513             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    3514             :   false,  /* isInfallible. False in setters. */
    3515             :   false,  /* isMovable.  Not relevant for setters. */
    3516             :   false, /* isEliminatable.  Not relevant for setters. */
    3517             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3518             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3519             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3520             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3521             : };
    3522             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3523             : static_assert(0 < 4, "There is no slot for us");
    3524             : 
    3525             : static bool
    3526           0 : testThrowDOMException(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3527             : {
    3528           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3529           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3530           0 :   if (objIsXray) {
    3531           0 :     unwrappedObj.emplace(cx, obj);
    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 :   binding_detail::FastErrorResult rv;
    3540           0 :   self->TestThrowDOMException(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    3541           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3542           0 :     return false;
    3543             :   }
    3544           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3545           0 :   args.rval().setUndefined();
    3546           0 :   return true;
    3547             : }
    3548             : 
    3549             : static const JSJitInfo testThrowDOMException_methodinfo = {
    3550             :   { (JSJitGetterOp)testThrowDOMException },
    3551             :   { prototypes::id::TestInterfaceJS },
    3552             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    3553             :   JSJitInfo::Method,
    3554             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3555             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    3556             :   false,  /* isInfallible. False in setters. */
    3557             :   false,  /* isMovable.  Not relevant for setters. */
    3558             :   false, /* isEliminatable.  Not relevant for setters. */
    3559             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3560             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3561             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3562             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3563             : };
    3564             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3565             : static_assert(0 < 4, "There is no slot for us");
    3566             : 
    3567             : static bool
    3568           0 : testThrowTypeError(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3569             : {
    3570           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3571           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3572           0 :   if (objIsXray) {
    3573           0 :     unwrappedObj.emplace(cx, obj);
    3574             :   }
    3575           0 :   if (objIsXray) {
    3576           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3577           0 :     if (!unwrappedObj.ref()) {
    3578           0 :       return false;
    3579             :     }
    3580             :   }
    3581           0 :   binding_detail::FastErrorResult rv;
    3582           0 :   self->TestThrowTypeError(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    3583           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3584           0 :     return false;
    3585             :   }
    3586           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3587           0 :   args.rval().setUndefined();
    3588           0 :   return true;
    3589             : }
    3590             : 
    3591             : static const JSJitInfo testThrowTypeError_methodinfo = {
    3592             :   { (JSJitGetterOp)testThrowTypeError },
    3593             :   { prototypes::id::TestInterfaceJS },
    3594             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    3595             :   JSJitInfo::Method,
    3596             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3597             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    3598             :   false,  /* isInfallible. False in setters. */
    3599             :   false,  /* isMovable.  Not relevant for setters. */
    3600             :   false, /* isEliminatable.  Not relevant for setters. */
    3601             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3602             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3603             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3604             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3605             : };
    3606             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3607             : static_assert(0 < 4, "There is no slot for us");
    3608             : 
    3609             : static bool
    3610           0 : testThrowCallbackError(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3611             : {
    3612           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    3613           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJS.testThrowCallbackError");
    3614             :   }
    3615           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3616           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3617           0 :   if (objIsXray) {
    3618           0 :     unwrappedObj.emplace(cx, obj);
    3619             :   }
    3620           0 :   RootedCallback<OwningNonNull<binding_detail::FastFunction>> arg0(cx);
    3621           0 :   if (args[0].isObject()) {
    3622           0 :     if (JS::IsCallable(&args[0].toObject())) {
    3623             :     { // scope for tempRoot
    3624           0 :       JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
    3625           0 :       arg0 = new binding_detail::FastFunction(tempRoot);
    3626             :     }
    3627             :     } else {
    3628           0 :       ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "Argument 1 of TestInterfaceJS.testThrowCallbackError");
    3629           0 :       return false;
    3630             :     }
    3631             :   } else {
    3632           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of TestInterfaceJS.testThrowCallbackError");
    3633           0 :     return false;
    3634             :   }
    3635           0 :   if (objIsXray) {
    3636           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3637           0 :     if (!unwrappedObj.ref()) {
    3638           0 :       return false;
    3639             :     }
    3640             :   }
    3641           0 :   binding_detail::FastErrorResult rv;
    3642           0 :   self->TestThrowCallbackError(NonNullHelper(arg0), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    3643           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3644           0 :     return false;
    3645             :   }
    3646           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3647           0 :   args.rval().setUndefined();
    3648           0 :   return true;
    3649             : }
    3650             : 
    3651             : static const JSJitInfo testThrowCallbackError_methodinfo = {
    3652             :   { (JSJitGetterOp)testThrowCallbackError },
    3653             :   { prototypes::id::TestInterfaceJS },
    3654             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    3655             :   JSJitInfo::Method,
    3656             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3657             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    3658             :   false,  /* isInfallible. False in setters. */
    3659             :   false,  /* isMovable.  Not relevant for setters. */
    3660             :   false, /* isEliminatable.  Not relevant for setters. */
    3661             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3662             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3663             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3664             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3665             : };
    3666             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3667             : static_assert(0 < 4, "There is no slot for us");
    3668             : 
    3669             : static bool
    3670           0 : testThrowXraySelfHosted(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3671             : {
    3672           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3673           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3674           0 :   if (objIsXray) {
    3675           0 :     unwrappedObj.emplace(cx, obj);
    3676             :   }
    3677           0 :   if (objIsXray) {
    3678           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3679           0 :     if (!unwrappedObj.ref()) {
    3680           0 :       return false;
    3681             :     }
    3682             :   }
    3683           0 :   binding_detail::FastErrorResult rv;
    3684           0 :   self->TestThrowXraySelfHosted(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    3685           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3686           0 :     return false;
    3687             :   }
    3688           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3689           0 :   args.rval().setUndefined();
    3690           0 :   return true;
    3691             : }
    3692             : 
    3693             : static const JSJitInfo testThrowXraySelfHosted_methodinfo = {
    3694             :   { (JSJitGetterOp)testThrowXraySelfHosted },
    3695             :   { prototypes::id::TestInterfaceJS },
    3696             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    3697             :   JSJitInfo::Method,
    3698             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3699             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    3700             :   false,  /* isInfallible. False in setters. */
    3701             :   false,  /* isMovable.  Not relevant for setters. */
    3702             :   false, /* isEliminatable.  Not relevant for setters. */
    3703             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3704             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3705             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3706             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3707             : };
    3708             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3709             : static_assert(0 < 4, "There is no slot for us");
    3710             : 
    3711             : static bool
    3712           0 : testThrowSelfHosted(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3713             : {
    3714           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3715           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3716           0 :   if (objIsXray) {
    3717           0 :     unwrappedObj.emplace(cx, obj);
    3718             :   }
    3719           0 :   if (objIsXray) {
    3720           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3721           0 :     if (!unwrappedObj.ref()) {
    3722           0 :       return false;
    3723             :     }
    3724             :   }
    3725           0 :   binding_detail::FastErrorResult rv;
    3726           0 :   self->TestThrowSelfHosted(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    3727           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3728           0 :     return false;
    3729             :   }
    3730           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3731           0 :   args.rval().setUndefined();
    3732           0 :   return true;
    3733             : }
    3734             : 
    3735             : static const JSJitInfo testThrowSelfHosted_methodinfo = {
    3736             :   { (JSJitGetterOp)testThrowSelfHosted },
    3737             :   { prototypes::id::TestInterfaceJS },
    3738             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    3739             :   JSJitInfo::Method,
    3740             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3741             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    3742             :   false,  /* isInfallible. False in setters. */
    3743             :   false,  /* isMovable.  Not relevant for setters. */
    3744             :   false, /* isEliminatable.  Not relevant for setters. */
    3745             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3746             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3747             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3748             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3749             : };
    3750             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3751             : static_assert(0 < 4, "There is no slot for us");
    3752             : 
    3753             : static bool
    3754           0 : testPromiseWithThrowingChromePromiseInit(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3755             : {
    3756           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3757           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3758           0 :   if (objIsXray) {
    3759           0 :     unwrappedObj.emplace(cx, obj);
    3760             :   }
    3761           0 :   if (objIsXray) {
    3762           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3763           0 :     if (!unwrappedObj.ref()) {
    3764           0 :       return false;
    3765             :     }
    3766             :   }
    3767           0 :   binding_detail::FastErrorResult rv;
    3768           0 :   auto result(StrongOrRawPtr<Promise>(self->TestPromiseWithThrowingChromePromiseInit(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
    3769           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3770           0 :     return false;
    3771             :   }
    3772           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3773           0 :   if (!ToJSValue(cx, result, args.rval())) {
    3774           0 :     return false;
    3775             :   }
    3776           0 :   return true;
    3777             : }
    3778             : 
    3779             : static bool
    3780           0 : testPromiseWithThrowingChromePromiseInit_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3781             : {
    3782             :   // Make sure to save the callee before someone maybe messes
    3783             :   // with rval().
    3784           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
    3785           0 :   bool ok = testPromiseWithThrowingChromePromiseInit(cx, obj, self, args);
    3786           0 :   if (ok) {
    3787           0 :     return true;
    3788             :   }
    3789           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
    3790           0 :                                    args.rval());
    3791             : }
    3792             : 
    3793             : static const JSJitInfo testPromiseWithThrowingChromePromiseInit_methodinfo = {
    3794             :   { (JSJitGetterOp)testPromiseWithThrowingChromePromiseInit_promiseWrapper },
    3795             :   { prototypes::id::TestInterfaceJS },
    3796             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    3797             :   JSJitInfo::Method,
    3798             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3799             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    3800             :   false,  /* isInfallible. False in setters. */
    3801             :   false,  /* isMovable.  Not relevant for setters. */
    3802             :   false, /* isEliminatable.  Not relevant for setters. */
    3803             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3804             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3805             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3806             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3807             : };
    3808             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3809             : static_assert(0 < 4, "There is no slot for us");
    3810             : 
    3811             : static bool
    3812           0 : testPromiseWithThrowingContentPromiseInit(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3813             : {
    3814           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    3815           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJS.testPromiseWithThrowingContentPromiseInit");
    3816             :   }
    3817           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3818           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3819           0 :   if (objIsXray) {
    3820           0 :     unwrappedObj.emplace(cx, obj);
    3821             :   }
    3822           0 :   RootedCallback<OwningNonNull<binding_detail::FastFunction>> arg0(cx);
    3823           0 :   if (args[0].isObject()) {
    3824           0 :     if (JS::IsCallable(&args[0].toObject())) {
    3825             :     { // scope for tempRoot
    3826           0 :       JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
    3827           0 :       arg0 = new binding_detail::FastFunction(tempRoot);
    3828             :     }
    3829             :     } else {
    3830           0 :       ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "Argument 1 of TestInterfaceJS.testPromiseWithThrowingContentPromiseInit");
    3831           0 :       return false;
    3832             :     }
    3833             :   } else {
    3834           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of TestInterfaceJS.testPromiseWithThrowingContentPromiseInit");
    3835           0 :     return false;
    3836             :   }
    3837           0 :   if (objIsXray) {
    3838           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3839           0 :     if (!unwrappedObj.ref()) {
    3840           0 :       return false;
    3841             :     }
    3842             :   }
    3843           0 :   binding_detail::FastErrorResult rv;
    3844           0 :   auto result(StrongOrRawPtr<Promise>(self->TestPromiseWithThrowingContentPromiseInit(NonNullHelper(arg0), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
    3845           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3846           0 :     return false;
    3847             :   }
    3848           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3849           0 :   if (!ToJSValue(cx, result, args.rval())) {
    3850           0 :     return false;
    3851             :   }
    3852           0 :   return true;
    3853             : }
    3854             : 
    3855             : static bool
    3856           0 : testPromiseWithThrowingContentPromiseInit_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3857             : {
    3858             :   // Make sure to save the callee before someone maybe messes
    3859             :   // with rval().
    3860           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
    3861           0 :   bool ok = testPromiseWithThrowingContentPromiseInit(cx, obj, self, args);
    3862           0 :   if (ok) {
    3863           0 :     return true;
    3864             :   }
    3865           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
    3866           0 :                                    args.rval());
    3867             : }
    3868             : 
    3869             : static const JSJitInfo testPromiseWithThrowingContentPromiseInit_methodinfo = {
    3870             :   { (JSJitGetterOp)testPromiseWithThrowingContentPromiseInit_promiseWrapper },
    3871             :   { prototypes::id::TestInterfaceJS },
    3872             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    3873             :   JSJitInfo::Method,
    3874             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3875             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    3876             :   false,  /* isInfallible. False in setters. */
    3877             :   false,  /* isMovable.  Not relevant for setters. */
    3878             :   false, /* isEliminatable.  Not relevant for setters. */
    3879             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3880             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3881             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3882             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3883             : };
    3884             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3885             : static_assert(0 < 4, "There is no slot for us");
    3886             : 
    3887             : static bool
    3888           0 : testPromiseWithDOMExceptionThrowingPromiseInit(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3889             : {
    3890           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3891           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3892           0 :   if (objIsXray) {
    3893           0 :     unwrappedObj.emplace(cx, obj);
    3894             :   }
    3895           0 :   if (objIsXray) {
    3896           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3897           0 :     if (!unwrappedObj.ref()) {
    3898           0 :       return false;
    3899             :     }
    3900             :   }
    3901           0 :   binding_detail::FastErrorResult rv;
    3902           0 :   auto result(StrongOrRawPtr<Promise>(self->TestPromiseWithDOMExceptionThrowingPromiseInit(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
    3903           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3904           0 :     return false;
    3905             :   }
    3906           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3907           0 :   if (!ToJSValue(cx, result, args.rval())) {
    3908           0 :     return false;
    3909             :   }
    3910           0 :   return true;
    3911             : }
    3912             : 
    3913             : static bool
    3914           0 : testPromiseWithDOMExceptionThrowingPromiseInit_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3915             : {
    3916             :   // Make sure to save the callee before someone maybe messes
    3917             :   // with rval().
    3918           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
    3919           0 :   bool ok = testPromiseWithDOMExceptionThrowingPromiseInit(cx, obj, self, args);
    3920           0 :   if (ok) {
    3921           0 :     return true;
    3922             :   }
    3923           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
    3924           0 :                                    args.rval());
    3925             : }
    3926             : 
    3927             : static const JSJitInfo testPromiseWithDOMExceptionThrowingPromiseInit_methodinfo = {
    3928             :   { (JSJitGetterOp)testPromiseWithDOMExceptionThrowingPromiseInit_promiseWrapper },
    3929             :   { prototypes::id::TestInterfaceJS },
    3930             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    3931             :   JSJitInfo::Method,
    3932             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3933             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    3934             :   false,  /* isInfallible. False in setters. */
    3935             :   false,  /* isMovable.  Not relevant for setters. */
    3936             :   false, /* isEliminatable.  Not relevant for setters. */
    3937             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3938             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3939             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3940             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3941             : };
    3942             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    3943             : static_assert(0 < 4, "There is no slot for us");
    3944             : 
    3945             : static bool
    3946           0 : testPromiseWithThrowingChromeThenFunction(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3947             : {
    3948           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    3949           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    3950           0 :   if (objIsXray) {
    3951           0 :     unwrappedObj.emplace(cx, obj);
    3952             :   }
    3953           0 :   if (objIsXray) {
    3954           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    3955           0 :     if (!unwrappedObj.ref()) {
    3956           0 :       return false;
    3957             :     }
    3958             :   }
    3959           0 :   binding_detail::FastErrorResult rv;
    3960           0 :   auto result(StrongOrRawPtr<Promise>(self->TestPromiseWithThrowingChromeThenFunction(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
    3961           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    3962           0 :     return false;
    3963             :   }
    3964           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    3965           0 :   if (!ToJSValue(cx, result, args.rval())) {
    3966           0 :     return false;
    3967             :   }
    3968           0 :   return true;
    3969             : }
    3970             : 
    3971             : static bool
    3972           0 : testPromiseWithThrowingChromeThenFunction_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    3973             : {
    3974             :   // Make sure to save the callee before someone maybe messes
    3975             :   // with rval().
    3976           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
    3977           0 :   bool ok = testPromiseWithThrowingChromeThenFunction(cx, obj, self, args);
    3978           0 :   if (ok) {
    3979           0 :     return true;
    3980             :   }
    3981           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
    3982           0 :                                    args.rval());
    3983             : }
    3984             : 
    3985             : static const JSJitInfo testPromiseWithThrowingChromeThenFunction_methodinfo = {
    3986             :   { (JSJitGetterOp)testPromiseWithThrowingChromeThenFunction_promiseWrapper },
    3987             :   { prototypes::id::TestInterfaceJS },
    3988             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    3989             :   JSJitInfo::Method,
    3990             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    3991             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    3992             :   false,  /* isInfallible. False in setters. */
    3993             :   false,  /* isMovable.  Not relevant for setters. */
    3994             :   false, /* isEliminatable.  Not relevant for setters. */
    3995             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    3996             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    3997             :   false,  /* isTypedMethod.  Only relevant for methods. */
    3998             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    3999             : };
    4000             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    4001             : static_assert(0 < 4, "There is no slot for us");
    4002             : 
    4003             : static bool
    4004           0 : testPromiseWithThrowingContentThenFunction(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    4005             : {
    4006           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    4007           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJS.testPromiseWithThrowingContentThenFunction");
    4008             :   }
    4009           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    4010           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    4011           0 :   if (objIsXray) {
    4012           0 :     unwrappedObj.emplace(cx, obj);
    4013             :   }
    4014           0 :   RootedCallback<OwningNonNull<binding_detail::FastAnyCallback>> arg0(cx);
    4015           0 :   if (args[0].isObject()) {
    4016           0 :     if (JS::IsCallable(&args[0].toObject())) {
    4017             :     { // scope for tempRoot
    4018           0 :       JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
    4019           0 :       arg0 = new binding_detail::FastAnyCallback(tempRoot);
    4020             :     }
    4021             :     } else {
    4022           0 :       ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "Argument 1 of TestInterfaceJS.testPromiseWithThrowingContentThenFunction");
    4023           0 :       return false;
    4024             :     }
    4025             :   } else {
    4026           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of TestInterfaceJS.testPromiseWithThrowingContentThenFunction");
    4027           0 :     return false;
    4028             :   }
    4029           0 :   if (objIsXray) {
    4030           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    4031           0 :     if (!unwrappedObj.ref()) {
    4032           0 :       return false;
    4033             :     }
    4034             :   }
    4035           0 :   binding_detail::FastErrorResult rv;
    4036           0 :   auto result(StrongOrRawPtr<Promise>(self->TestPromiseWithThrowingContentThenFunction(NonNullHelper(arg0), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
    4037           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    4038           0 :     return false;
    4039             :   }
    4040           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    4041           0 :   if (!ToJSValue(cx, result, args.rval())) {
    4042           0 :     return false;
    4043             :   }
    4044           0 :   return true;
    4045             : }
    4046             : 
    4047             : static bool
    4048           0 : testPromiseWithThrowingContentThenFunction_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    4049             : {
    4050             :   // Make sure to save the callee before someone maybe messes
    4051             :   // with rval().
    4052           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
    4053           0 :   bool ok = testPromiseWithThrowingContentThenFunction(cx, obj, self, args);
    4054           0 :   if (ok) {
    4055           0 :     return true;
    4056             :   }
    4057           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
    4058           0 :                                    args.rval());
    4059             : }
    4060             : 
    4061             : static const JSJitInfo testPromiseWithThrowingContentThenFunction_methodinfo = {
    4062             :   { (JSJitGetterOp)testPromiseWithThrowingContentThenFunction_promiseWrapper },
    4063             :   { prototypes::id::TestInterfaceJS },
    4064             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    4065             :   JSJitInfo::Method,
    4066             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    4067             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    4068             :   false,  /* isInfallible. False in setters. */
    4069             :   false,  /* isMovable.  Not relevant for setters. */
    4070             :   false, /* isEliminatable.  Not relevant for setters. */
    4071             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    4072             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    4073             :   false,  /* isTypedMethod.  Only relevant for methods. */
    4074             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    4075             : };
    4076             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    4077             : static_assert(0 < 4, "There is no slot for us");
    4078             : 
    4079             : static bool
    4080           0 : testPromiseWithDOMExceptionThrowingThenFunction(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    4081             : {
    4082           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    4083           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    4084           0 :   if (objIsXray) {
    4085           0 :     unwrappedObj.emplace(cx, obj);
    4086             :   }
    4087           0 :   if (objIsXray) {
    4088           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    4089           0 :     if (!unwrappedObj.ref()) {
    4090           0 :       return false;
    4091             :     }
    4092             :   }
    4093           0 :   binding_detail::FastErrorResult rv;
    4094           0 :   auto result(StrongOrRawPtr<Promise>(self->TestPromiseWithDOMExceptionThrowingThenFunction(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
    4095           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    4096           0 :     return false;
    4097             :   }
    4098           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    4099           0 :   if (!ToJSValue(cx, result, args.rval())) {
    4100           0 :     return false;
    4101             :   }
    4102           0 :   return true;
    4103             : }
    4104             : 
    4105             : static bool
    4106           0 : testPromiseWithDOMExceptionThrowingThenFunction_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    4107             : {
    4108             :   // Make sure to save the callee before someone maybe messes
    4109             :   // with rval().
    4110           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
    4111           0 :   bool ok = testPromiseWithDOMExceptionThrowingThenFunction(cx, obj, self, args);
    4112           0 :   if (ok) {
    4113           0 :     return true;
    4114             :   }
    4115           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
    4116           0 :                                    args.rval());
    4117             : }
    4118             : 
    4119             : static const JSJitInfo testPromiseWithDOMExceptionThrowingThenFunction_methodinfo = {
    4120             :   { (JSJitGetterOp)testPromiseWithDOMExceptionThrowingThenFunction_promiseWrapper },
    4121             :   { prototypes::id::TestInterfaceJS },
    4122             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    4123             :   JSJitInfo::Method,
    4124             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    4125             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    4126             :   false,  /* isInfallible. False in setters. */
    4127             :   false,  /* isMovable.  Not relevant for setters. */
    4128             :   false, /* isEliminatable.  Not relevant for setters. */
    4129             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    4130             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    4131             :   false,  /* isTypedMethod.  Only relevant for methods. */
    4132             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    4133             : };
    4134             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    4135             : static_assert(0 < 4, "There is no slot for us");
    4136             : 
    4137             : static bool
    4138           0 : testPromiseWithThrowingChromeThenable(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    4139             : {
    4140           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    4141           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    4142           0 :   if (objIsXray) {
    4143           0 :     unwrappedObj.emplace(cx, obj);
    4144             :   }
    4145           0 :   if (objIsXray) {
    4146           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    4147           0 :     if (!unwrappedObj.ref()) {
    4148           0 :       return false;
    4149             :     }
    4150             :   }
    4151           0 :   binding_detail::FastErrorResult rv;
    4152           0 :   auto result(StrongOrRawPtr<Promise>(self->TestPromiseWithThrowingChromeThenable(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
    4153           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    4154           0 :     return false;
    4155             :   }
    4156           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    4157           0 :   if (!ToJSValue(cx, result, args.rval())) {
    4158           0 :     return false;
    4159             :   }
    4160           0 :   return true;
    4161             : }
    4162             : 
    4163             : static bool
    4164           0 : testPromiseWithThrowingChromeThenable_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    4165             : {
    4166             :   // Make sure to save the callee before someone maybe messes
    4167             :   // with rval().
    4168           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
    4169           0 :   bool ok = testPromiseWithThrowingChromeThenable(cx, obj, self, args);
    4170           0 :   if (ok) {
    4171           0 :     return true;
    4172             :   }
    4173           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
    4174           0 :                                    args.rval());
    4175             : }
    4176             : 
    4177             : static const JSJitInfo testPromiseWithThrowingChromeThenable_methodinfo = {
    4178             :   { (JSJitGetterOp)testPromiseWithThrowingChromeThenable_promiseWrapper },
    4179             :   { prototypes::id::TestInterfaceJS },
    4180             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    4181             :   JSJitInfo::Method,
    4182             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    4183             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    4184             :   false,  /* isInfallible. False in setters. */
    4185             :   false,  /* isMovable.  Not relevant for setters. */
    4186             :   false, /* isEliminatable.  Not relevant for setters. */
    4187             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    4188             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    4189             :   false,  /* isTypedMethod.  Only relevant for methods. */
    4190             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    4191             : };
    4192             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    4193             : static_assert(0 < 4, "There is no slot for us");
    4194             : 
    4195             : static bool
    4196           0 : testPromiseWithThrowingContentThenable(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    4197             : {
    4198           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    4199           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJS.testPromiseWithThrowingContentThenable");
    4200             :   }
    4201           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    4202           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    4203           0 :   if (objIsXray) {
    4204           0 :     unwrappedObj.emplace(cx, obj);
    4205             :   }
    4206           0 :   JS::Rooted<JSObject*> arg0(cx);
    4207           0 :   if (args[0].isObject()) {
    4208             : #ifdef __clang__
    4209             : #pragma clang diagnostic push
    4210             : #pragma clang diagnostic ignored "-Wunreachable-code"
    4211             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    4212             : #endif // __clang__
    4213           0 :     if ((true) && !CallerSubsumes(args[0])) {
    4214           0 :       ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "argument 1 of TestInterfaceJS.testPromiseWithThrowingContentThenable");
    4215           0 :       return false;
    4216             :     }
    4217             : #ifdef __clang__
    4218             : #pragma clang diagnostic pop
    4219             : #endif // __clang__
    4220           0 :     arg0 = &args[0].toObject();
    4221             :   } else {
    4222           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of TestInterfaceJS.testPromiseWithThrowingContentThenable");
    4223           0 :     return false;
    4224             :   }
    4225           0 :   if (objIsXray) {
    4226           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    4227           0 :     if (!unwrappedObj.ref()) {
    4228           0 :       return false;
    4229             :     }
    4230             :   }
    4231           0 :   binding_detail::FastErrorResult rv;
    4232           0 :   auto result(StrongOrRawPtr<Promise>(self->TestPromiseWithThrowingContentThenable(arg0, rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
    4233           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    4234           0 :     return false;
    4235             :   }
    4236           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    4237           0 :   if (!ToJSValue(cx, result, args.rval())) {
    4238           0 :     return false;
    4239             :   }
    4240           0 :   return true;
    4241             : }
    4242             : 
    4243             : static bool
    4244           0 : testPromiseWithThrowingContentThenable_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    4245             : {
    4246             :   // Make sure to save the callee before someone maybe messes
    4247             :   // with rval().
    4248           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
    4249           0 :   bool ok = testPromiseWithThrowingContentThenable(cx, obj, self, args);
    4250           0 :   if (ok) {
    4251           0 :     return true;
    4252             :   }
    4253           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
    4254           0 :                                    args.rval());
    4255             : }
    4256             : 
    4257             : static const JSJitInfo testPromiseWithThrowingContentThenable_methodinfo = {
    4258             :   { (JSJitGetterOp)testPromiseWithThrowingContentThenable_promiseWrapper },
    4259             :   { prototypes::id::TestInterfaceJS },
    4260             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    4261             :   JSJitInfo::Method,
    4262             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    4263             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    4264             :   false,  /* isInfallible. False in setters. */
    4265             :   false,  /* isMovable.  Not relevant for setters. */
    4266             :   false, /* isEliminatable.  Not relevant for setters. */
    4267             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    4268             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    4269             :   false,  /* isTypedMethod.  Only relevant for methods. */
    4270             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    4271             : };
    4272             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    4273             : static_assert(0 < 4, "There is no slot for us");
    4274             : 
    4275             : static bool
    4276           0 : testPromiseWithDOMExceptionThrowingThenable(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    4277             : {
    4278           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    4279           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    4280           0 :   if (objIsXray) {
    4281           0 :     unwrappedObj.emplace(cx, obj);
    4282             :   }
    4283           0 :   if (objIsXray) {
    4284           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    4285           0 :     if (!unwrappedObj.ref()) {
    4286           0 :       return false;
    4287             :     }
    4288             :   }
    4289           0 :   binding_detail::FastErrorResult rv;
    4290           0 :   auto result(StrongOrRawPtr<Promise>(self->TestPromiseWithDOMExceptionThrowingThenable(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj))));
    4291           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    4292           0 :     return false;
    4293             :   }
    4294           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    4295           0 :   if (!ToJSValue(cx, result, args.rval())) {
    4296           0 :     return false;
    4297             :   }
    4298           0 :   return true;
    4299             : }
    4300             : 
    4301             : static bool
    4302           0 : testPromiseWithDOMExceptionThrowingThenable_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, const JSJitMethodCallArgs& args)
    4303             : {
    4304             :   // Make sure to save the callee before someone maybe messes
    4305             :   // with rval().
    4306           0 :   JS::Rooted<JSObject*> callee(cx, &args.callee());
    4307           0 :   bool ok = testPromiseWithDOMExceptionThrowingThenable(cx, obj, self, args);
    4308           0 :   if (ok) {
    4309           0 :     return true;
    4310             :   }
    4311           0 :   return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
    4312           0 :                                    args.rval());
    4313             : }
    4314             : 
    4315             : static const JSJitInfo testPromiseWithDOMExceptionThrowingThenable_methodinfo = {
    4316             :   { (JSJitGetterOp)testPromiseWithDOMExceptionThrowingThenable_promiseWrapper },
    4317             :   { prototypes::id::TestInterfaceJS },
    4318             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    4319             :   JSJitInfo::Method,
    4320             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    4321             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    4322             :   false,  /* isInfallible. False in setters. */
    4323             :   false,  /* isMovable.  Not relevant for setters. */
    4324             :   false, /* isEliminatable.  Not relevant for setters. */
    4325             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    4326             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    4327             :   false,  /* isTypedMethod.  Only relevant for methods. */
    4328             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    4329             : };
    4330             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    4331             : static_assert(0 < 4, "There is no slot for us");
    4332             : 
    4333             : static bool
    4334           0 : get_onsomething(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, JSJitGetterCallArgs args)
    4335             : {
    4336           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    4337           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    4338           0 :   if (objIsXray) {
    4339           0 :     unwrappedObj.emplace(cx, obj);
    4340             :   }
    4341           0 :   if (objIsXray) {
    4342           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    4343           0 :     if (!unwrappedObj.ref()) {
    4344           0 :       return false;
    4345             :     }
    4346             :   }
    4347           0 :   binding_detail::FastErrorResult rv;
    4348           0 :   RefPtr<EventHandlerNonNull> result(self->GetOnsomething(rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)));
    4349           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    4350           0 :     return false;
    4351             :   }
    4352           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    4353           0 :   if (result) {
    4354           0 :     args.rval().setObjectOrNull(GetCallbackFromCallbackObject(result));
    4355           0 :     if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
    4356           0 :       return false;
    4357             :     }
    4358           0 :     return true;
    4359             :   } else {
    4360           0 :     args.rval().setNull();
    4361           0 :     return true;
    4362             :   }
    4363             : }
    4364             : 
    4365             : static bool
    4366           0 : set_onsomething(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::TestInterfaceJS* self, JSJitSetterCallArgs args)
    4367             : {
    4368           0 :   Maybe<JS::Rooted<JSObject*> > unwrappedObj;
    4369           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    4370           0 :   if (objIsXray) {
    4371           0 :     unwrappedObj.emplace(cx, obj);
    4372             :   }
    4373           0 :   RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
    4374           0 :   if (args[0].isObject()) {
    4375             :     { // scope for tempRoot
    4376           0 :       JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
    4377           0 :       arg0 = new binding_detail::FastEventHandlerNonNull(tempRoot);
    4378             :     }
    4379             :   } else {
    4380           0 :     arg0 = nullptr;
    4381             :   }
    4382           0 :   if (objIsXray) {
    4383           0 :     unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
    4384           0 :     if (!unwrappedObj.ref()) {
    4385           0 :       return false;
    4386             :     }
    4387             :   }
    4388           0 :   binding_detail::FastErrorResult rv;
    4389           0 :   self->SetOnsomething(Constify(arg0), rv, js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj));
    4390           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    4391           0 :     return false;
    4392             :   }
    4393           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    4394             : 
    4395           0 :   return true;
    4396             : }
    4397             : 
    4398             : static const JSJitInfo onsomething_getterinfo = {
    4399             :   { (JSJitGetterOp)get_onsomething },
    4400             :   { prototypes::id::TestInterfaceJS },
    4401             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    4402             :   JSJitInfo::Getter,
    4403             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    4404             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    4405             :   false,  /* isInfallible. False in setters. */
    4406             :   false,  /* isMovable.  Not relevant for setters. */
    4407             :   false, /* isEliminatable.  Not relevant for setters. */
    4408             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    4409             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    4410             :   false,  /* isTypedMethod.  Only relevant for methods. */
    4411             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    4412             : };
    4413             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    4414             : static_assert(0 < 4, "There is no slot for us");
    4415             : static const JSJitInfo onsomething_setterinfo = {
    4416             :   { (JSJitGetterOp)set_onsomething },
    4417             :   { prototypes::id::TestInterfaceJS },
    4418             :   { PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth },
    4419             :   JSJitInfo::Setter,
    4420             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    4421             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    4422             :   false,  /* isInfallible. False in setters. */
    4423             :   false,  /* isMovable.  Not relevant for setters. */
    4424             :   false, /* isEliminatable.  Not relevant for setters. */
    4425             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    4426             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    4427             :   false,  /* isTypedMethod.  Only relevant for methods. */
    4428             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    4429             : };
    4430             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    4431             : static_assert(0 < 4, "There is no slot for us");
    4432             : 
    4433             : static bool
    4434           0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
    4435             : {
    4436           0 :   mozilla::dom::TestInterfaceJS* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceJS>(obj);
    4437             :   // We don't want to preserve if we don't have a wrapper, and we
    4438             :   // obviously can't preserve if we're not initialized.
    4439           0 :   if (self && self->GetWrapperPreserveColor()) {
    4440           0 :     PreserveWrapper(self);
    4441             :   }
    4442           0 :   return true;
    4443             : }
    4444             : 
    4445             : static void
    4446           0 : _finalize(js::FreeOp* fop, JSObject* obj)
    4447             : {
    4448           0 :   mozilla::dom::TestInterfaceJS* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceJS>(obj);
    4449           0 :   if (self) {
    4450           0 :     ClearWrapper(self, self, obj);
    4451           0 :     AddForDeferredFinalization<mozilla::dom::TestInterfaceJS>(self);
    4452             :   }
    4453           0 : }
    4454             : 
    4455             : static void
    4456           0 : _objectMoved(JSObject* obj, const JSObject* old)
    4457             : {
    4458           0 :   mozilla::dom::TestInterfaceJS* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::TestInterfaceJS>(obj);
    4459           0 :   if (self) {
    4460           0 :     UpdateWrapper(self, self, obj, old);
    4461             :   }
    4462           0 : }
    4463             : 
    4464             : static bool
    4465           0 : _ClearCachedDictionaryArgValue(JSContext* cx, unsigned argc, JS::Value* vp)
    4466             : {
    4467           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    4468           0 :   if (!args.thisv().isObject()) {
    4469           0 :     return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "TestInterfaceJS");
    4470             :   }
    4471           0 :   JS::Rooted<JSObject*> obj(cx, &args.thisv().toObject());
    4472             : 
    4473             :   mozilla::dom::TestInterfaceJS* self;
    4474           0 :   JS::Rooted<JS::Value> rootSelf(cx, JS::ObjectValue(*obj));
    4475             :   {
    4476           0 :     nsresult rv = UnwrapObject<prototypes::id::TestInterfaceJS, mozilla::dom::TestInterfaceJS>(&rootSelf, self);
    4477           0 :     if (NS_FAILED(rv)) {
    4478           0 :       return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "TestInterfaceJS");
    4479             :     }
    4480             :   }
    4481           0 :   TestInterfaceJSBinding::ClearCachedDictionaryArgValue(self);
    4482           0 :   args.rval().setUndefined();
    4483           0 :   return true;
    4484             : }
    4485             : 
    4486             : static bool
    4487           0 : _ClearCachedDictionaryAttrValue(JSContext* cx, unsigned argc, JS::Value* vp)
    4488             : {
    4489           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    4490           0 :   if (!args.thisv().isObject()) {
    4491           0 :     return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "TestInterfaceJS");
    4492             :   }
    4493           0 :   JS::Rooted<JSObject*> obj(cx, &args.thisv().toObject());
    4494             : 
    4495             :   mozilla::dom::TestInterfaceJS* self;
    4496           0 :   JS::Rooted<JS::Value> rootSelf(cx, JS::ObjectValue(*obj));
    4497             :   {
    4498           0 :     nsresult rv = UnwrapObject<prototypes::id::TestInterfaceJS, mozilla::dom::TestInterfaceJS>(&rootSelf, self);
    4499           0 :     if (NS_FAILED(rv)) {
    4500           0 :       return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "TestInterfaceJS");
    4501             :     }
    4502             :   }
    4503           0 :   TestInterfaceJSBinding::ClearCachedDictionaryAttrValue(self);
    4504           0 :   args.rval().setUndefined();
    4505           0 :   return true;
    4506             : }
    4507             : 
    4508             : static bool
    4509           0 : _ClearCachedCachedAttrValue(JSContext* cx, unsigned argc, JS::Value* vp)
    4510             : {
    4511           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    4512           0 :   if (!args.thisv().isObject()) {
    4513           0 :     return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "TestInterfaceJS");
    4514             :   }
    4515           0 :   JS::Rooted<JSObject*> obj(cx, &args.thisv().toObject());
    4516             : 
    4517             :   mozilla::dom::TestInterfaceJS* self;
    4518           0 :   JS::Rooted<JS::Value> rootSelf(cx, JS::ObjectValue(*obj));
    4519             :   {
    4520           0 :     nsresult rv = UnwrapObject<prototypes::id::TestInterfaceJS, mozilla::dom::TestInterfaceJS>(&rootSelf, self);
    4521           0 :     if (NS_FAILED(rv)) {
    4522           0 :       return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "TestInterfaceJS");
    4523             :     }
    4524             :   }
    4525           0 :   TestInterfaceJSBinding::ClearCachedCachedAttrValue(self);
    4526           0 :   args.rval().setUndefined();
    4527           0 :   return true;
    4528             : }
    4529             : 
    4530             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    4531             : #if defined(__clang__)
    4532             : #pragma clang diagnostic push
    4533             : #pragma clang diagnostic ignored "-Wmissing-braces"
    4534             : #endif
    4535             : static const JSFunctionSpec sChromeStaticMethods_specs[] = {
    4536             :   JS_FNSPEC("_create", TestInterfaceJS::_Create, nullptr, 2, 0, nullptr),
    4537             :   JS_FS_END
    4538             : };
    4539             : #if defined(__clang__)
    4540             : #pragma clang diagnostic pop
    4541             : #endif
    4542             : 
    4543             : 
    4544             : // Can't be const because the pref-enabled boolean needs to be writable
    4545             : static Prefable<const JSFunctionSpec> sChromeStaticMethods[] = {
    4546             :   { nullptr, &sChromeStaticMethods_specs[0] },
    4547             :   { nullptr, nullptr }
    4548             : };
    4549             : 
    4550             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    4551             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    4552             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    4553             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    4554             : 
    4555             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    4556             : #if defined(__clang__)
    4557             : #pragma clang diagnostic push
    4558             : #pragma clang diagnostic ignored "-Wmissing-braces"
    4559             : #endif
    4560             : static const JSFunctionSpec sMethods_specs[] = {
    4561             :   JS_FNSPEC("pingPongAny", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&pingPongAny_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    4562             :   JS_FNSPEC("pingPongObject", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&pingPongObject_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    4563             :   JS_FNSPEC("pingPongObjectOrString", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&pingPongObjectOrString_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    4564             :   JS_FNSPEC("pingPongDictionary", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&pingPongDictionary_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    4565             :   JS_FNSPEC("pingPongDictionaryOrLong", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&pingPongDictionaryOrLong_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    4566             :   JS_FNSPEC("pingPongMap", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&pingPongMap_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    4567             :   JS_FNSPEC("objectSequenceLength", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&objectSequenceLength_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    4568             :   JS_FNSPEC("anySequenceLength", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&anySequenceLength_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    4569             :   JS_FNSPEC("getCallerPrincipal", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&getCallerPrincipal_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    4570             :   JS_FNSPEC("convertSVS", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&convertSVS_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    4571             :   JS_FNSPEC("pingPongUnion", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&pingPongUnion_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    4572             :   JS_FNSPEC("pingPongUnionContainingNull", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&pingPongUnionContainingNull_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    4573             :   JS_FNSPEC("pingPongNullableUnion", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&pingPongNullableUnion_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    4574             :   JS_FNSPEC("returnBadUnion", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&returnBadUnion_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    4575             :   JS_FNSPEC("setCachedAttr", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&setCachedAttr_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    4576             :   JS_FNSPEC("clearCachedAttrCache", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&clearCachedAttrCache_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    4577             :   JS_FNSPEC("testSequenceOverload", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&testSequenceOverload_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    4578             :   JS_FNSPEC("testSequenceUnion", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&testSequenceUnion_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    4579             :   JS_FNSPEC("testThrowError", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&testThrowError_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    4580             :   JS_FNSPEC("testThrowDOMException", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&testThrowDOMException_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    4581             :   JS_FNSPEC("testThrowTypeError", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&testThrowTypeError_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    4582             :   JS_FNSPEC("testThrowCallbackError", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&testThrowCallbackError_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    4583             :   JS_FNSPEC("testThrowXraySelfHosted", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&testThrowXraySelfHosted_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    4584             :   JS_FNSPEC("testThrowSelfHosted", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&testThrowSelfHosted_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    4585             :   JS_FNSPEC("testPromiseWithThrowingChromePromiseInit", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&testPromiseWithThrowingChromePromiseInit_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    4586             :   JS_FNSPEC("testPromiseWithThrowingContentPromiseInit", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&testPromiseWithThrowingContentPromiseInit_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    4587             :   JS_FNSPEC("testPromiseWithDOMExceptionThrowingPromiseInit", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&testPromiseWithDOMExceptionThrowingPromiseInit_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    4588             :   JS_FNSPEC("testPromiseWithThrowingChromeThenFunction", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&testPromiseWithThrowingChromeThenFunction_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    4589             :   JS_FNSPEC("testPromiseWithThrowingContentThenFunction", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&testPromiseWithThrowingContentThenFunction_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    4590             :   JS_FNSPEC("testPromiseWithDOMExceptionThrowingThenFunction", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&testPromiseWithDOMExceptionThrowingThenFunction_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    4591             :   JS_FNSPEC("testPromiseWithThrowingChromeThenable", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&testPromiseWithThrowingChromeThenable_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    4592             :   JS_FNSPEC("testPromiseWithThrowingContentThenable", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&testPromiseWithThrowingContentThenable_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    4593             :   JS_FNSPEC("testPromiseWithDOMExceptionThrowingThenable", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&testPromiseWithDOMExceptionThrowingThenable_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    4594             :   JS_FS_END
    4595             : };
    4596             : #if defined(__clang__)
    4597             : #pragma clang diagnostic pop
    4598             : #endif
    4599             : 
    4600             : 
    4601             : // Can't be const because the pref-enabled boolean needs to be writable
    4602             : static Prefable<const JSFunctionSpec> sMethods[] = {
    4603             :   { nullptr, &sMethods_specs[0] },
    4604             :   { nullptr, nullptr }
    4605             : };
    4606             : 
    4607             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    4608             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    4609             : static_assert(33 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    4610             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    4611             : 
    4612             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    4613             : #if defined(__clang__)
    4614             : #pragma clang diagnostic push
    4615             : #pragma clang diagnostic ignored "-Wmissing-braces"
    4616             : #endif
    4617             : static const JSFunctionSpec sChromeMethods_specs[] = {
    4618             :   JS_FNSPEC("_clearCachedDictionaryArgValue", _ClearCachedDictionaryArgValue, nullptr, 0, 0, nullptr),
    4619             :   JS_FNSPEC("_clearCachedDictionaryAttrValue", _ClearCachedDictionaryAttrValue, nullptr, 0, 0, nullptr),
    4620             :   JS_FNSPEC("_clearCachedCachedAttrValue", _ClearCachedCachedAttrValue, nullptr, 0, 0, nullptr),
    4621             :   JS_FS_END
    4622             : };
    4623             : #if defined(__clang__)
    4624             : #pragma clang diagnostic pop
    4625             : #endif
    4626             : 
    4627             : 
    4628             : // Can't be const because the pref-enabled boolean needs to be writable
    4629             : static Prefable<const JSFunctionSpec> sChromeMethods[] = {
    4630             :   { nullptr, &sChromeMethods_specs[0] },
    4631             :   { nullptr, nullptr }
    4632             : };
    4633             : 
    4634             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    4635             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    4636             : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    4637             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    4638             : 
    4639             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    4640             : #if defined(__clang__)
    4641             : #pragma clang diagnostic push
    4642             : #pragma clang diagnostic ignored "-Wmissing-braces"
    4643             : #endif
    4644             : static const JSPropertySpec sAttributes_specs[] = {
    4645             :   { "anyArg", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &anyArg_getterinfo, nullptr, nullptr },
    4646             :   { "objectArg", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &objectArg_getterinfo, nullptr, nullptr },
    4647             :   { "dictionaryArg", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &dictionaryArg_getterinfo, nullptr, nullptr },
    4648             :   { "anyAttr", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &anyAttr_getterinfo, GenericBindingSetter, &anyAttr_setterinfo },
    4649             :   { "objectAttr", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &objectAttr_getterinfo, GenericBindingSetter, &objectAttr_setterinfo },
    4650             :   { "dictionaryAttr", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &dictionaryAttr_getterinfo, GenericBindingSetter, &dictionaryAttr_setterinfo },
    4651             :   { "cachedAttr", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &cachedAttr_getterinfo, nullptr, nullptr },
    4652             :   { "onsomething", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &onsomething_getterinfo, GenericBindingSetter, &onsomething_setterinfo },
    4653             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
    4654             : };
    4655             : #if defined(__clang__)
    4656             : #pragma clang diagnostic pop
    4657             : #endif
    4658             : 
    4659             : 
    4660             : // Can't be const because the pref-enabled boolean needs to be writable
    4661             : static Prefable<const JSPropertySpec> sAttributes[] = {
    4662             :   { nullptr, &sAttributes_specs[0] },
    4663             :   { nullptr, nullptr }
    4664             : };
    4665             : 
    4666             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    4667             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    4668             : static_assert(8 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    4669             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    4670             : 
    4671             : 
    4672             : static uint16_t sNativeProperties_sortedPropertyIndices[41];
    4673             : static PropertyInfo sNativeProperties_propertyInfos[41];
    4674             : 
    4675             : static const NativePropertiesN<2> sNativeProperties = {
    4676             :   false, 0,
    4677             :   false, 0,
    4678             :   true,  0 /* sMethods */,
    4679             :   true,  1 /* sAttributes */,
    4680             :   false, 0,
    4681             :   false, 0,
    4682             :   false, 0,
    4683             :   -1,
    4684             :   41,
    4685             :   sNativeProperties_sortedPropertyIndices,
    4686             :   {
    4687             :     { sMethods, &sNativeProperties_propertyInfos[0] },
    4688             :     { sAttributes, &sNativeProperties_propertyInfos[33] }
    4689             :   }
    4690             : };
    4691             : static_assert(41 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
    4692             :     "We have a property info count that is oversized");
    4693             : 
    4694             : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[4];
    4695             : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[4];
    4696             : 
    4697             : static const NativePropertiesN<2> sChromeOnlyNativeProperties = {
    4698             :   true,  0 /* sChromeStaticMethods */,
    4699             :   false, 0,
    4700             :   true,  1 /* sChromeMethods */,
    4701             :   false, 0,
    4702             :   false, 0,
    4703             :   false, 0,
    4704             :   false, 0,
    4705             :   -1,
    4706             :   4,
    4707             :   sChromeOnlyNativeProperties_sortedPropertyIndices,
    4708             :   {
    4709             :     { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] },
    4710             :     { sChromeMethods, &sChromeOnlyNativeProperties_propertyInfos[1] }
    4711             :   }
    4712             : };
    4713             : static_assert(4 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
    4714             :     "We have a property info count that is oversized");
    4715             : 
    4716             : static bool
    4717           0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
    4718             : {
    4719           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    4720           0 :   JS::Rooted<JSObject*> obj(cx, &args.callee());
    4721           0 :   if (!args.isConstructing()) {
    4722             :     // XXXbz wish I could get the name from the callee instead of
    4723             :     // Adding more relocations
    4724           0 :     return ThrowConstructorWithoutNew(cx, "TestInterfaceJS");
    4725             :   }
    4726             : 
    4727           0 :   GlobalObject global(cx, obj);
    4728           0 :   if (global.Failed()) {
    4729           0 :     return false;
    4730             :   }
    4731             : 
    4732           0 :   JS::Rooted<JSObject*> desiredProto(cx);
    4733           0 :   if (!GetDesiredProto(cx, args, &desiredProto)) {
    4734           0 :     return false;
    4735             :   }
    4736             : 
    4737           0 :   bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
    4738           0 :   JS::Rooted<JS::Value> arg0(cx);
    4739           0 :   if (args.hasDefined(0)) {
    4740             : #ifdef __clang__
    4741             : #pragma clang diagnostic push
    4742             : #pragma clang diagnostic ignored "-Wunreachable-code"
    4743             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    4744             : #endif // __clang__
    4745           0 :     if ((true) && !CallerSubsumes(args[0])) {
    4746           0 :       ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "argument 1 of TestInterfaceJS.constructor");
    4747           0 :       return false;
    4748             :     }
    4749             : #ifdef __clang__
    4750             : #pragma clang diagnostic pop
    4751             : #endif // __clang__
    4752           0 :     arg0 = args[0];
    4753             :   } else {
    4754           0 :     arg0 = JS::UndefinedValue();
    4755             :   }
    4756           0 :   Optional<JS::Handle<JSObject*>> arg1;
    4757           0 :   if (args.hasDefined(1)) {
    4758           0 :     arg1.Construct(cx);
    4759           0 :     if (args[1].isObject()) {
    4760             : #ifdef __clang__
    4761             : #pragma clang diagnostic push
    4762             : #pragma clang diagnostic ignored "-Wunreachable-code"
    4763             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    4764             : #endif // __clang__
    4765           0 :       if ((true) && !CallerSubsumes(args[1])) {
    4766           0 :         ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "argument 2 of TestInterfaceJS.constructor");
    4767           0 :         return false;
    4768             :       }
    4769             : #ifdef __clang__
    4770             : #pragma clang diagnostic pop
    4771             : #endif // __clang__
    4772           0 :       arg1.Value() = &args[1].toObject();
    4773             :     } else {
    4774           0 :       ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of TestInterfaceJS.constructor");
    4775           0 :       return false;
    4776             :     }
    4777             :   }
    4778           0 :   RootedDictionary<binding_detail::FastTestInterfaceJSDictionary> arg2(cx);
    4779           0 :   if (!arg2.Init(cx, (args.hasDefined(2)) ? args[2] : JS::NullHandleValue,  "Argument 3 of TestInterfaceJS.constructor", true)) {
    4780           0 :     return false;
    4781             :   }
    4782           0 :   Maybe<JSAutoCompartment> ac;
    4783           0 :   if (objIsXray) {
    4784           0 :     obj = js::CheckedUnwrap(obj);
    4785           0 :     if (!obj) {
    4786           0 :       return false;
    4787             :     }
    4788           0 :     ac.emplace(cx, obj);
    4789           0 :     if (!JS_WrapObject(cx, &desiredProto)) {
    4790           0 :       return false;
    4791             :     }
    4792           0 :     if (!JS_WrapValue(cx, &arg0)) {
    4793           0 :       return false;
    4794             :     }
    4795           0 :     if (arg1.WasPassed()) {
    4796           0 :       if (!JS_WrapObject(cx, &arg1.Value())) {
    4797           0 :         return false;
    4798             :       }
    4799             :     }
    4800           0 :     if (!JS_WrapValue(cx, JS::MutableHandle<JS::Value>::fromMarkedLocation(&arg2.mAnyMember))) {
    4801           0 :       return false;
    4802             :     }
    4803           0 :     if (arg2.mAnySequenceMember.WasPassed()) {
    4804           0 :       for (uint32_t indexName0 = 0; indexName0 < arg2.mAnySequenceMember.Value().Length(); ++indexName0) {
    4805           0 :         if (!JS_WrapValue(cx, JS::MutableHandle<JS::Value>::fromMarkedLocation(&arg2.mAnySequenceMember.Value()[indexName0]))) {
    4806           0 :           return false;
    4807             :         }
    4808             :       }
    4809             :     }
    4810           0 :     if (arg2.mInnerDictionary.mInnerObject.WasPassed()) {
    4811           0 :       if (!JS_WrapObject(cx, JS::MutableHandle<JSObject*>::fromMarkedLocation(&arg2.mInnerDictionary.mInnerObject.Value()))) {
    4812           0 :         return false;
    4813             :       }
    4814             :     }
    4815           0 :     if (arg2.mObjectMember.WasPassed()) {
    4816           0 :       if (!JS_WrapObject(cx, JS::MutableHandle<JSObject*>::fromMarkedLocation(&arg2.mObjectMember.Value()))) {
    4817           0 :         return false;
    4818             :       }
    4819             :     }
    4820           0 :     if (arg2.mObjectOrStringMember.WasPassed()) {
    4821           0 :       if (arg2.mObjectOrStringMember.Value().IsObject()) {
    4822           0 :         if (!JS_WrapObject(cx, JS::MutableHandle<JSObject*>::fromMarkedLocation(&arg2.mObjectOrStringMember.Value().GetAsObject()))) {
    4823           0 :           return false;
    4824             :         }
    4825             :       }
    4826             :     }
    4827             :   }
    4828           0 :   binding_detail::FastErrorResult rv;
    4829           0 :   auto result(StrongOrRawPtr<mozilla::dom::TestInterfaceJS>(mozilla::dom::TestInterfaceJS::Constructor(global, cx, arg0, Constify(arg1), Constify(arg2), rv)));
    4830           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    4831           0 :     return false;
    4832             :   }
    4833           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    4834             :   static_assert(!IsPointer<decltype(result)>::value,
    4835             :                 "NewObject implies that we need to keep the object alive with a strong reference.");
    4836           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
    4837           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    4838           0 :     return false;
    4839             :   }
    4840           0 :   return true;
    4841             : }
    4842             : 
    4843             : static const js::ClassOps sInterfaceObjectClassOps = {
    4844             :     nullptr,               /* addProperty */
    4845             :     nullptr,               /* delProperty */
    4846             :     nullptr,               /* getProperty */
    4847             :     nullptr,               /* setProperty */
    4848             :     nullptr,               /* enumerate */
    4849             :     nullptr,               /* newEnumerate */
    4850             :     nullptr,               /* resolve */
    4851             :     nullptr,               /* mayResolve */
    4852             :     nullptr,               /* finalize */
    4853             :     _constructor, /* call */
    4854             :     nullptr,               /* hasInstance */
    4855             :     _constructor, /* construct */
    4856             :     nullptr,               /* trace */
    4857             : };
    4858             : 
    4859             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
    4860             :   {
    4861             :     "Function",
    4862             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
    4863             :     &sInterfaceObjectClassOps,
    4864             :     JS_NULL_CLASS_SPEC,
    4865             :     JS_NULL_CLASS_EXT,
    4866             :     &sInterfaceObjectClassObjectOps
    4867             :   },
    4868             :   eInterface,
    4869             :   true,
    4870             :   prototypes::id::TestInterfaceJS,
    4871             :   PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth,
    4872             :   sNativePropertyHooks,
    4873             :   "function TestInterfaceJS() {\n    [native code]\n}",
    4874             :   EventTargetBinding::GetConstructorObject
    4875             : };
    4876             : 
    4877             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
    4878             :   {
    4879             :     "TestInterfaceJSPrototype",
    4880             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    4881             :     JS_NULL_CLASS_OPS,
    4882             :     JS_NULL_CLASS_SPEC,
    4883             :     JS_NULL_CLASS_EXT,
    4884             :     JS_NULL_OBJECT_OPS
    4885             :   },
    4886             :   eInterfacePrototype,
    4887             :   false,
    4888             :   prototypes::id::TestInterfaceJS,
    4889             :   PrototypeTraits<prototypes::id::TestInterfaceJS>::Depth,
    4890             :   sNativePropertyHooks,
    4891             :   "[object TestInterfaceJSPrototype]",
    4892             :   EventTargetBinding::GetProtoObject
    4893             : };
    4894             : 
    4895             : bool
    4896           0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
    4897             : {
    4898             :   static bool sPrefValue;
    4899             :   static bool sPrefCacheSetUp = false;
    4900           0 :   if (!sPrefCacheSetUp) {
    4901           0 :     sPrefCacheSetUp = true;
    4902           0 :     Preferences::AddBoolVarCache(&sPrefValue, "dom.expose_test_interfaces");
    4903             :   }
    4904             : 
    4905           0 :   return sPrefValue;
    4906             : }
    4907             : 
    4908             : JSObject*
    4909           0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
    4910             : {
    4911           0 :   return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
    4912             : }
    4913             : 
    4914             : static const js::ClassOps sClassOps = {
    4915             :   _addProperty, /* addProperty */
    4916             :   nullptr,               /* delProperty */
    4917             :   nullptr,               /* getProperty */
    4918             :   nullptr,               /* setProperty */
    4919             :   nullptr,               /* enumerate */
    4920             :   nullptr, /* newEnumerate */
    4921             :   nullptr, /* resolve */
    4922             :   nullptr, /* mayResolve */
    4923             :   _finalize, /* finalize */
    4924             :   nullptr, /* call */
    4925             :   nullptr,               /* hasInstance */
    4926             :   nullptr,               /* construct */
    4927             :   nullptr, /* trace */
    4928             : };
    4929             : 
    4930             : static const js::ClassExtension sClassExtension = {
    4931             :   nullptr, /* weakmapKeyDelegateOp */
    4932             :   _objectMoved /* objectMovedOp */
    4933             : };
    4934             : 
    4935             : static const DOMJSClass sClass = {
    4936             :   { "TestInterfaceJS",
    4937             :     JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(4),
    4938             :     &sClassOps,
    4939             :     JS_NULL_CLASS_SPEC,
    4940             :     &sClassExtension,
    4941             :     JS_NULL_OBJECT_OPS
    4942             :   },
    4943             :   { prototypes::id::EventTarget, prototypes::id::TestInterfaceJS, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
    4944             :   IsBaseOf<nsISupports, mozilla::dom::TestInterfaceJS >::value,
    4945             :   sNativePropertyHooks,
    4946             :   FindAssociatedGlobalForNative<mozilla::dom::TestInterfaceJS>::Get,
    4947             :   GetProtoObjectHandle,
    4948             :   GetCCParticipant<mozilla::dom::TestInterfaceJS>::Get()
    4949             : };
    4950             : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
    4951             :               "Must have the right minimal number of reserved slots.");
    4952             : static_assert(4 >= 4,
    4953             :               "Must have enough reserved slots.");
    4954             : 
    4955             : const JSClass*
    4956           0 : GetJSClass()
    4957             : {
    4958           0 :   return sClass.ToJSClass();
    4959             : }
    4960             : 
    4961             : bool
    4962           0 : Wrap(JSContext* aCx, mozilla::dom::TestInterfaceJS* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
    4963             : {
    4964             :   MOZ_ASSERT(static_cast<mozilla::dom::TestInterfaceJS*>(aObject) ==
    4965             :              reinterpret_cast<mozilla::dom::TestInterfaceJS*>(aObject),
    4966             :              "Multiple inheritance for mozilla::dom::TestInterfaceJS is broken.");
    4967             :   MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
    4968             :              reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
    4969             :              "Multiple inheritance for mozilla::dom::EventTarget is broken.");
    4970           0 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
    4971           0 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
    4972           0 :   MOZ_ASSERT(!aCache->GetWrapper(),
    4973             :              "You should probably not be using Wrap() directly; use "
    4974             :              "GetOrCreateDOMReflector instead");
    4975             : 
    4976           0 :   MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
    4977             :              "nsISupports must be on our primary inheritance chain");
    4978             : 
    4979           0 :   JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
    4980           0 :   if (!global) {
    4981           0 :     return false;
    4982             :   }
    4983           0 :   MOZ_ASSERT(JS_IsGlobalObject(global));
    4984           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(global));
    4985             : 
    4986             :   // That might have ended up wrapping us already, due to the wonders
    4987             :   // of XBL.  Check for that, and bail out as needed.
    4988           0 :   aReflector.set(aCache->GetWrapper());
    4989           0 :   if (aReflector) {
    4990             : #ifdef DEBUG
    4991           0 :     binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
    4992             : #endif // DEBUG
    4993           0 :     return true;
    4994             :   }
    4995             : 
    4996           0 :   JSAutoCompartment ac(aCx, global);
    4997           0 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
    4998           0 :   if (!canonicalProto) {
    4999           0 :     return false;
    5000             :   }
    5001           0 :   JS::Rooted<JSObject*> proto(aCx);
    5002           0 :   if (aGivenProto) {
    5003           0 :     proto = aGivenProto;
    5004             :     // Unfortunately, while aGivenProto was in the compartment of aCx
    5005             :     // coming in, we changed compartments to that of "parent" so may need
    5006             :     // to wrap the proto here.
    5007           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
    5008           0 :       if (!JS_WrapObject(aCx, &proto)) {
    5009           0 :         return false;
    5010             :       }
    5011             :     }
    5012             :   } else {
    5013           0 :     proto = canonicalProto;
    5014             :   }
    5015             : 
    5016           0 :   BindingJSObjectCreator<mozilla::dom::TestInterfaceJS> creator(aCx);
    5017           0 :   creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
    5018           0 :   if (!aReflector) {
    5019           0 :     return false;
    5020             :   }
    5021             : 
    5022           0 :   aCache->SetWrapper(aReflector);
    5023           0 :   creator.InitializationSucceeded();
    5024             : 
    5025           0 :   MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
    5026             :              aCache->GetWrapperPreserveColor() == aReflector);
    5027             :   // If proto != canonicalProto, we have to preserve our wrapper;
    5028             :   // otherwise we won't be able to properly recreate it later, since
    5029             :   // we won't know what proto to use.  Note that we don't check
    5030             :   // aGivenProto here, since it's entirely possible (and even
    5031             :   // somewhat common) to have a non-null aGivenProto which is the
    5032             :   // same as canonicalProto.
    5033           0 :   if (proto != canonicalProto) {
    5034           0 :     PreserveWrapper(aObject);
    5035             :   }
    5036             : 
    5037           0 :   return true;
    5038             : }
    5039             : 
    5040             : // This may allocate too many slots, because we only really need
    5041             : // slots for our non-interface-typed members that we cache.  But
    5042             : // allocating slots only for those would make the slot index
    5043             : // computations much more complicated, so let's do this the simple
    5044             : // way for now.
    5045             : DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 3);
    5046             : 
    5047             : const NativePropertyHooks sNativePropertyHooks[] = { {
    5048             :   nullptr,
    5049             :   nullptr,
    5050             :   nullptr,
    5051             :   { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
    5052             :   prototypes::id::TestInterfaceJS,
    5053             :   constructors::id::TestInterfaceJS,
    5054             :   EventTargetBinding::sNativePropertyHooks,
    5055             :   &sXrayExpandoObjectClass
    5056             : } };
    5057             : 
    5058             : void
    5059           0 : ClearCachedDictionaryArgValue(mozilla::dom::TestInterfaceJS* aObject)
    5060             : {
    5061             :   JSObject* obj;
    5062           0 :   obj = aObject->GetWrapper();
    5063           0 :   if (!obj) {
    5064           0 :     return;
    5065             :   }
    5066           0 :   js::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), JS::UndefinedValue());
    5067           0 :   xpc::ClearXrayExpandoSlots(obj, (xpc::JSSLOT_EXPANDO_COUNT + 0));
    5068             : }
    5069             : 
    5070             : void
    5071           0 : ClearCachedDictionaryAttrValue(mozilla::dom::TestInterfaceJS* aObject)
    5072             : {
    5073             :   JSObject* obj;
    5074           0 :   obj = aObject->GetWrapper();
    5075           0 :   if (!obj) {
    5076           0 :     return;
    5077             :   }
    5078           0 :   js::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 1), JS::UndefinedValue());
    5079           0 :   xpc::ClearXrayExpandoSlots(obj, (xpc::JSSLOT_EXPANDO_COUNT + 1));
    5080             : }
    5081             : 
    5082             : void
    5083           0 : ClearCachedCachedAttrValue(mozilla::dom::TestInterfaceJS* aObject)
    5084             : {
    5085             :   JSObject* obj;
    5086           0 :   obj = aObject->GetWrapper();
    5087           0 :   if (!obj) {
    5088           0 :     return;
    5089             :   }
    5090           0 :   js::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 2), JS::UndefinedValue());
    5091           0 :   xpc::ClearXrayExpandoSlots(obj, (xpc::JSSLOT_EXPANDO_COUNT + 2));
    5092             : }
    5093             : 
    5094             : void
    5095           0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    5096             : {
    5097           0 :   JS::Handle<JSObject*> parentProto(EventTargetBinding::GetProtoObjectHandle(aCx));
    5098           0 :   if (!parentProto) {
    5099           0 :     return;
    5100             :   }
    5101             : 
    5102           0 :   JS::Handle<JSObject*> constructorProto(EventTargetBinding::GetConstructorObjectHandle(aCx));
    5103           0 :   if (!constructorProto) {
    5104           0 :     return;
    5105             :   }
    5106             : 
    5107             :   static bool sIdsInited = false;
    5108           0 :   if (!sIdsInited && NS_IsMainThread()) {
    5109           0 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
    5110           0 :       return;
    5111             :     }
    5112           0 :     if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
    5113           0 :       return;
    5114             :     }
    5115           0 :     sIdsInited = true;
    5116             :   }
    5117             : 
    5118           0 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::TestInterfaceJS);
    5119           0 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::TestInterfaceJS);
    5120           0 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    5121             :                               &sPrototypeClass.mBase, protoCache,
    5122             :                               constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
    5123             :                               interfaceCache,
    5124             :                               sNativeProperties.Upcast(),
    5125           0 :                               nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
    5126             :                               "TestInterfaceJS", aDefineOnGlobal,
    5127             :                               nullptr,
    5128           0 :                               false);
    5129             : }
    5130             : 
    5131             : JS::Handle<JSObject*>
    5132           0 : GetProtoObjectHandle(JSContext* aCx)
    5133             : {
    5134             :   /* Get the interface prototype object for this class.  This will create the
    5135             :      object as needed. */
    5136           0 :   bool aDefineOnGlobal = true;
    5137             : 
    5138             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    5139           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    5140           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    5141           0 :     return nullptr;
    5142             :   }
    5143             : 
    5144             :   /* Check to see whether the interface objects are already installed */
    5145           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    5146           0 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::TestInterfaceJS)) {
    5147           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    5148           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    5149             :   }
    5150             : 
    5151             :   /*
    5152             :    * The object might _still_ be null, but that's OK.
    5153             :    *
    5154             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    5155             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    5156             :    * changed after they have been set.
    5157             :    *
    5158             :    * Calling address() avoids the read read barrier that does gray
    5159             :    * unmarking, but it's not possible for the object to be gray here.
    5160             :    */
    5161             : 
    5162           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::TestInterfaceJS);
    5163           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    5164           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    5165             : }
    5166             : 
    5167             : JS::Handle<JSObject*>
    5168           0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
    5169             : {
    5170             :   /* Get the interface object for this class.  This will create the object as
    5171             :      needed. */
    5172             : 
    5173             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    5174           0 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    5175           0 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    5176           0 :     return nullptr;
    5177             :   }
    5178             : 
    5179             :   /* Check to see whether the interface objects are already installed */
    5180           0 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    5181           0 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::TestInterfaceJS)) {
    5182           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    5183           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    5184             :   }
    5185             : 
    5186             :   /*
    5187             :    * The object might _still_ be null, but that's OK.
    5188             :    *
    5189             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    5190             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    5191             :    * changed after they have been set.
    5192             :    *
    5193             :    * Calling address() avoids the read read barrier that does gray
    5194             :    * unmarking, but it's not possible for the object to be gray here.
    5195             :    */
    5196             : 
    5197           0 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::TestInterfaceJS);
    5198           0 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    5199           0 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    5200             : }
    5201             : 
    5202             : JSObject*
    5203           0 : GetConstructorObject(JSContext* aCx)
    5204             : {
    5205           0 :   return GetConstructorObjectHandle(aCx);
    5206             : }
    5207             : 
    5208             : } // namespace TestInterfaceJSBinding
    5209             : 
    5210             : 
    5211             : 
    5212             : void
    5213           0 : TestInterfaceJSJSImpl::PingPongAny(JS::Handle<JS::Value> arg, JS::MutableHandle<JS::Value> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    5214             : {
    5215           0 :   CallSetup s(this, aRv, "TestInterfaceJS.pingPongAny", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    5216           0 :   JSContext* cx = s.GetContext();
    5217           0 :   if (!cx) {
    5218           0 :     MOZ_ASSERT(aRv.Failed());
    5219           0 :     return;
    5220             :   }
    5221           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    5222           0 :   JS::AutoValueVector argv(cx);
    5223           0 :   if (!argv.resize(1)) {
    5224           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    5225           0 :     return;
    5226             :   }
    5227           0 :   unsigned argc = 1;
    5228             : 
    5229             :   do {
    5230           0 :     JS::ExposeValueToActiveJS(arg);
    5231           0 :     argv[0].set(arg);
    5232           0 :     if (!MaybeWrapValue(cx, argv[0])) {
    5233           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5234           0 :       return;
    5235             :     }
    5236           0 :     break;
    5237             :   } while (0);
    5238             : 
    5239           0 :   JS::Rooted<JS::Value> callable(cx);
    5240           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    5241           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    5242           0 :       !GetCallableProperty(cx, atomsCache->pingPongAny_id, &callable)) {
    5243           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5244           0 :     return;
    5245             :   }
    5246           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    5247           0 :   if (!JS::Call(cx, thisValue, callable,
    5248           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    5249           0 :     aRv.NoteJSContextException(cx);
    5250           0 :     return;
    5251             :   }
    5252           0 :   JS::Rooted<JS::Value> rvalDecl(cx);
    5253             : #ifdef __clang__
    5254             : #pragma clang diagnostic push
    5255             : #pragma clang diagnostic ignored "-Wunreachable-code"
    5256             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    5257             : #endif // __clang__
    5258           0 :   if ((false) && !CallerSubsumes(rval)) {
    5259           0 :     ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "return value of TestInterfaceJS.pingPongAny");
    5260           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5261           0 :     return;
    5262             :   }
    5263             : #ifdef __clang__
    5264             : #pragma clang diagnostic pop
    5265             : #endif // __clang__
    5266           0 :   rvalDecl = rval;
    5267           0 :   aRetVal.set(rvalDecl);
    5268             : }
    5269             : 
    5270             : void
    5271           0 : TestInterfaceJSJSImpl::PingPongObject(JS::Handle<JSObject*> obj, JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    5272             : {
    5273           0 :   CallSetup s(this, aRv, "TestInterfaceJS.pingPongObject", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    5274           0 :   JSContext* cx = s.GetContext();
    5275           0 :   if (!cx) {
    5276           0 :     MOZ_ASSERT(aRv.Failed());
    5277           0 :     return;
    5278             :   }
    5279           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    5280           0 :   JS::AutoValueVector argv(cx);
    5281           0 :   if (!argv.resize(1)) {
    5282           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    5283           0 :     return;
    5284             :   }
    5285           0 :   unsigned argc = 1;
    5286             : 
    5287             :   do {
    5288           0 :     JS::ExposeObjectToActiveJS(obj);
    5289           0 :     argv[0].setObject(*obj);
    5290           0 :     if (!MaybeWrapObjectValue(cx, argv[0])) {
    5291           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5292           0 :       return;
    5293             :     }
    5294           0 :     break;
    5295             :   } while (0);
    5296             : 
    5297           0 :   JS::Rooted<JS::Value> callable(cx);
    5298           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    5299           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    5300           0 :       !GetCallableProperty(cx, atomsCache->pingPongObject_id, &callable)) {
    5301           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5302           0 :     return;
    5303             :   }
    5304           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    5305           0 :   if (!JS::Call(cx, thisValue, callable,
    5306           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    5307           0 :     aRv.NoteJSContextException(cx);
    5308           0 :     return;
    5309             :   }
    5310           0 :   JS::Rooted<JSObject*> rvalDecl(cx);
    5311           0 :   if (rval.isObject()) {
    5312             : #ifdef __clang__
    5313             : #pragma clang diagnostic push
    5314             : #pragma clang diagnostic ignored "-Wunreachable-code"
    5315             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    5316             : #endif // __clang__
    5317           0 :     if ((false) && !CallerSubsumes(rval)) {
    5318           0 :       ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "return value of TestInterfaceJS.pingPongObject");
    5319           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5320           0 :       return;
    5321             :     }
    5322             : #ifdef __clang__
    5323             : #pragma clang diagnostic pop
    5324             : #endif // __clang__
    5325           0 :     rvalDecl = &rval.toObject();
    5326             :   } else {
    5327           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of TestInterfaceJS.pingPongObject");
    5328           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5329           0 :     return;
    5330             :   }
    5331           0 :   aRetVal.set(rvalDecl);
    5332             : }
    5333             : 
    5334             : void
    5335           0 : TestInterfaceJSJSImpl::PingPongObjectOrString(const ObjectOrString& objOrString, JS::MutableHandle<JS::Value> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    5336             : {
    5337           0 :   CallSetup s(this, aRv, "TestInterfaceJS.pingPongObjectOrString", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    5338           0 :   JSContext* cx = s.GetContext();
    5339           0 :   if (!cx) {
    5340           0 :     MOZ_ASSERT(aRv.Failed());
    5341           0 :     return;
    5342             :   }
    5343           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    5344           0 :   JS::AutoValueVector argv(cx);
    5345           0 :   if (!argv.resize(1)) {
    5346           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    5347           0 :     return;
    5348             :   }
    5349           0 :   unsigned argc = 1;
    5350             : 
    5351             :   do {
    5352           0 :     if (!objOrString.ToJSVal(cx, CallbackKnownNotGray(), argv[0])) {
    5353           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5354           0 :       return;
    5355             :     }
    5356           0 :     break;
    5357             :   } while (0);
    5358             : 
    5359           0 :   JS::Rooted<JS::Value> callable(cx);
    5360           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    5361           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    5362           0 :       !GetCallableProperty(cx, atomsCache->pingPongObjectOrString_id, &callable)) {
    5363           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5364           0 :     return;
    5365             :   }
    5366           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    5367           0 :   if (!JS::Call(cx, thisValue, callable,
    5368           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    5369           0 :     aRv.NoteJSContextException(cx);
    5370           0 :     return;
    5371             :   }
    5372           0 :   JS::Rooted<JS::Value> rvalDecl(cx);
    5373             : #ifdef __clang__
    5374             : #pragma clang diagnostic push
    5375             : #pragma clang diagnostic ignored "-Wunreachable-code"
    5376             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    5377             : #endif // __clang__
    5378           0 :   if ((false) && !CallerSubsumes(rval)) {
    5379           0 :     ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "return value of TestInterfaceJS.pingPongObjectOrString");
    5380           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5381           0 :     return;
    5382             :   }
    5383             : #ifdef __clang__
    5384             : #pragma clang diagnostic pop
    5385             : #endif // __clang__
    5386           0 :   rvalDecl = rval;
    5387           0 :   aRetVal.set(rvalDecl);
    5388             : }
    5389             : 
    5390             : void
    5391           0 : TestInterfaceJSJSImpl::PingPongDictionary(const TestInterfaceJSDictionary& dict, TestInterfaceJSDictionary& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    5392             : {
    5393           0 :   CallSetup s(this, aRv, "TestInterfaceJS.pingPongDictionary", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    5394           0 :   JSContext* cx = s.GetContext();
    5395           0 :   if (!cx) {
    5396           0 :     MOZ_ASSERT(aRv.Failed());
    5397           0 :     return;
    5398             :   }
    5399           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    5400           0 :   JS::AutoValueVector argv(cx);
    5401           0 :   if (!argv.resize(1)) {
    5402           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    5403           0 :     return;
    5404             :   }
    5405           0 :   unsigned argc = 1;
    5406             : 
    5407             :   do {
    5408           0 :     if (!dict.ToObjectInternal(cx, argv[0])) {
    5409           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5410           0 :       return;
    5411             :     }
    5412           0 :     break;
    5413             :   } while (0);
    5414             : 
    5415           0 :   JS::Rooted<JS::Value> callable(cx);
    5416           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    5417           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    5418           0 :       !GetCallableProperty(cx, atomsCache->pingPongDictionary_id, &callable)) {
    5419           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5420           0 :     return;
    5421             :   }
    5422           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    5423           0 :   if (!JS::Call(cx, thisValue, callable,
    5424           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    5425           0 :     aRv.NoteJSContextException(cx);
    5426           0 :     return;
    5427             :   }
    5428           0 :   TestInterfaceJSDictionary& rvalDecl(aRetVal);
    5429           0 :   if (!rvalDecl.Init(cx, rval,  "Return value of TestInterfaceJS.pingPongDictionary", false)) {
    5430           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5431           0 :     return;
    5432             :   }
    5433             : }
    5434             : 
    5435             : int32_t
    5436           0 : TestInterfaceJSJSImpl::PingPongDictionaryOrLong(const TestInterfaceJSUnionableDictionaryOrLong& dictOrLong, ErrorResult& aRv, JSCompartment* aCompartment)
    5437             : {
    5438           0 :   CallSetup s(this, aRv, "TestInterfaceJS.pingPongDictionaryOrLong", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    5439           0 :   JSContext* cx = s.GetContext();
    5440           0 :   if (!cx) {
    5441           0 :     MOZ_ASSERT(aRv.Failed());
    5442           0 :     return int32_t(0);
    5443             :   }
    5444           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    5445           0 :   JS::AutoValueVector argv(cx);
    5446           0 :   if (!argv.resize(1)) {
    5447           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    5448           0 :     return int32_t(0);
    5449             :   }
    5450           0 :   unsigned argc = 1;
    5451             : 
    5452             :   do {
    5453           0 :     if (!dictOrLong.ToJSVal(cx, CallbackKnownNotGray(), argv[0])) {
    5454           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5455           0 :       return int32_t(0);
    5456             :     }
    5457           0 :     break;
    5458             :   } while (0);
    5459             : 
    5460           0 :   JS::Rooted<JS::Value> callable(cx);
    5461           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    5462           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    5463           0 :       !GetCallableProperty(cx, atomsCache->pingPongDictionaryOrLong_id, &callable)) {
    5464           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5465           0 :     return int32_t(0);
    5466             :   }
    5467           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    5468           0 :   if (!JS::Call(cx, thisValue, callable,
    5469           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    5470           0 :     aRv.NoteJSContextException(cx);
    5471           0 :     return int32_t(0);
    5472             :   }
    5473             :   int32_t rvalDecl;
    5474           0 :   if (!ValueToPrimitive<int32_t, eDefault>(cx, rval, &rvalDecl)) {
    5475           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5476           0 :     return int32_t(0);
    5477             :   }
    5478           0 :   return rvalDecl;
    5479             : }
    5480             : 
    5481             : void
    5482           0 : TestInterfaceJSJSImpl::PingPongMap(const Record<nsString, JS::Value>& map, nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    5483             : {
    5484           0 :   CallSetup s(this, aRv, "TestInterfaceJS.pingPongMap", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    5485           0 :   JSContext* cx = s.GetContext();
    5486           0 :   if (!cx) {
    5487           0 :     MOZ_ASSERT(aRv.Failed());
    5488           0 :     return;
    5489             :   }
    5490           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    5491           0 :   JS::AutoValueVector argv(cx);
    5492           0 :   if (!argv.resize(1)) {
    5493           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    5494           0 :     return;
    5495             :   }
    5496           0 :   unsigned argc = 1;
    5497             : 
    5498             :   do {
    5499             : 
    5500           0 :     JS::Rooted<JSObject*> returnObj(cx, JS_NewPlainObject(cx));
    5501           0 :     if (!returnObj) {
    5502           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5503           0 :       return;
    5504             :     }
    5505             :     // Scope for 'tmp'
    5506             :     {
    5507           0 :       JS::Rooted<JS::Value> tmp(cx);
    5508           0 :       for (auto& entry : map.Entries()) {
    5509           0 :         auto& recordValue0 = entry.mValue;
    5510             :         // Control block to let us common up the JS_DefineUCProperty calls when there
    5511             :         // are different ways to succeed at wrapping the value.
    5512             :         do {
    5513           0 :           JS::ExposeValueToActiveJS(recordValue0);
    5514           0 :           tmp.set(recordValue0);
    5515           0 :           if (!MaybeWrapValue(cx, &tmp)) {
    5516           0 :             aRv.Throw(NS_ERROR_UNEXPECTED);
    5517           0 :             return;
    5518             :           }
    5519           0 :           break;
    5520             :         } while (0);
    5521           0 :         if (!JS_DefineUCProperty(cx, returnObj,
    5522             :                                  entry.mKey.BeginReading(),
    5523           0 :                                  entry.mKey.Length(), tmp,
    5524             :                                  JSPROP_ENUMERATE)) {
    5525           0 :           aRv.Throw(NS_ERROR_UNEXPECTED);
    5526           0 :           return;
    5527             :         }
    5528             :       }
    5529             :     }
    5530           0 :     argv[0].setObject(*returnObj);
    5531           0 :     break;
    5532             :   } while (0);
    5533             : 
    5534           0 :   JS::Rooted<JS::Value> callable(cx);
    5535           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    5536           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    5537           0 :       !GetCallableProperty(cx, atomsCache->pingPongMap_id, &callable)) {
    5538           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5539           0 :     return;
    5540             :   }
    5541           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    5542           0 :   if (!JS::Call(cx, thisValue, callable,
    5543           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    5544           0 :     aRv.NoteJSContextException(cx);
    5545           0 :     return;
    5546             :   }
    5547           0 :   binding_detail::FakeString rvalDecl;
    5548           0 :   if (!ConvertJSValueToString(cx, rval, eStringify, eStringify, rvalDecl)) {
    5549           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5550           0 :     return;
    5551             :   }
    5552           0 :   aRetVal = rvalDecl;
    5553             : }
    5554             : 
    5555             : int32_t
    5556           0 : TestInterfaceJSJSImpl::ObjectSequenceLength(const Sequence<JSObject*>& seq, ErrorResult& aRv, JSCompartment* aCompartment)
    5557             : {
    5558           0 :   CallSetup s(this, aRv, "TestInterfaceJS.objectSequenceLength", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    5559           0 :   JSContext* cx = s.GetContext();
    5560           0 :   if (!cx) {
    5561           0 :     MOZ_ASSERT(aRv.Failed());
    5562           0 :     return int32_t(0);
    5563             :   }
    5564           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    5565           0 :   JS::AutoValueVector argv(cx);
    5566           0 :   if (!argv.resize(1)) {
    5567           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    5568           0 :     return int32_t(0);
    5569             :   }
    5570           0 :   unsigned argc = 1;
    5571             : 
    5572             :   do {
    5573             : 
    5574           0 :     uint32_t length = seq.Length();
    5575           0 :     JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
    5576           0 :     if (!returnArray) {
    5577           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5578           0 :       return int32_t(0);
    5579             :     }
    5580             :     // Scope for 'tmp'
    5581             :     {
    5582           0 :       JS::Rooted<JS::Value> tmp(cx);
    5583           0 :       for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
    5584             :         // Control block to let us common up the JS_DefineElement calls when there
    5585             :         // are different ways to succeed at wrapping the object.
    5586             :         do {
    5587           0 :           JS::ExposeObjectToActiveJS(seq[sequenceIdx0]);
    5588           0 :           tmp.setObject(*seq[sequenceIdx0]);
    5589           0 :           if (!MaybeWrapObjectValue(cx, &tmp)) {
    5590           0 :             aRv.Throw(NS_ERROR_UNEXPECTED);
    5591           0 :             return int32_t(0);
    5592             :           }
    5593           0 :           break;
    5594             :         } while (0);
    5595           0 :         if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
    5596             :                               JSPROP_ENUMERATE)) {
    5597           0 :           aRv.Throw(NS_ERROR_UNEXPECTED);
    5598           0 :           return int32_t(0);
    5599             :         }
    5600             :       }
    5601             :     }
    5602           0 :     argv[0].setObject(*returnArray);
    5603           0 :     break;
    5604             :   } while (0);
    5605             : 
    5606           0 :   JS::Rooted<JS::Value> callable(cx);
    5607           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    5608           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    5609           0 :       !GetCallableProperty(cx, atomsCache->objectSequenceLength_id, &callable)) {
    5610           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5611           0 :     return int32_t(0);
    5612             :   }
    5613           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    5614           0 :   if (!JS::Call(cx, thisValue, callable,
    5615           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    5616           0 :     aRv.NoteJSContextException(cx);
    5617           0 :     return int32_t(0);
    5618             :   }
    5619             :   int32_t rvalDecl;
    5620           0 :   if (!ValueToPrimitive<int32_t, eDefault>(cx, rval, &rvalDecl)) {
    5621           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5622           0 :     return int32_t(0);
    5623             :   }
    5624           0 :   return rvalDecl;
    5625             : }
    5626             : 
    5627             : int32_t
    5628           0 : TestInterfaceJSJSImpl::AnySequenceLength(const Sequence<JS::Value>& seq, ErrorResult& aRv, JSCompartment* aCompartment)
    5629             : {
    5630           0 :   CallSetup s(this, aRv, "TestInterfaceJS.anySequenceLength", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    5631           0 :   JSContext* cx = s.GetContext();
    5632           0 :   if (!cx) {
    5633           0 :     MOZ_ASSERT(aRv.Failed());
    5634           0 :     return int32_t(0);
    5635             :   }
    5636           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    5637           0 :   JS::AutoValueVector argv(cx);
    5638           0 :   if (!argv.resize(1)) {
    5639           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    5640           0 :     return int32_t(0);
    5641             :   }
    5642           0 :   unsigned argc = 1;
    5643             : 
    5644             :   do {
    5645             : 
    5646           0 :     uint32_t length = seq.Length();
    5647           0 :     JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
    5648           0 :     if (!returnArray) {
    5649           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5650           0 :       return int32_t(0);
    5651             :     }
    5652             :     // Scope for 'tmp'
    5653             :     {
    5654           0 :       JS::Rooted<JS::Value> tmp(cx);
    5655           0 :       for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
    5656             :         // Control block to let us common up the JS_DefineElement calls when there
    5657             :         // are different ways to succeed at wrapping the object.
    5658             :         do {
    5659           0 :           JS::ExposeValueToActiveJS(seq[sequenceIdx0]);
    5660           0 :           tmp.set(seq[sequenceIdx0]);
    5661           0 :           if (!MaybeWrapValue(cx, &tmp)) {
    5662           0 :             aRv.Throw(NS_ERROR_UNEXPECTED);
    5663           0 :             return int32_t(0);
    5664             :           }
    5665           0 :           break;
    5666             :         } while (0);
    5667           0 :         if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
    5668             :                               JSPROP_ENUMERATE)) {
    5669           0 :           aRv.Throw(NS_ERROR_UNEXPECTED);
    5670           0 :           return int32_t(0);
    5671             :         }
    5672             :       }
    5673             :     }
    5674           0 :     argv[0].setObject(*returnArray);
    5675           0 :     break;
    5676             :   } while (0);
    5677             : 
    5678           0 :   JS::Rooted<JS::Value> callable(cx);
    5679           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    5680           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    5681           0 :       !GetCallableProperty(cx, atomsCache->anySequenceLength_id, &callable)) {
    5682           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5683           0 :     return int32_t(0);
    5684             :   }
    5685           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    5686           0 :   if (!JS::Call(cx, thisValue, callable,
    5687           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    5688           0 :     aRv.NoteJSContextException(cx);
    5689           0 :     return int32_t(0);
    5690             :   }
    5691             :   int32_t rvalDecl;
    5692           0 :   if (!ValueToPrimitive<int32_t, eDefault>(cx, rval, &rvalDecl)) {
    5693           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5694           0 :     return int32_t(0);
    5695             :   }
    5696           0 :   return rvalDecl;
    5697             : }
    5698             : 
    5699             : void
    5700           0 : TestInterfaceJSJSImpl::GetCallerPrincipal(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    5701             : {
    5702           0 :   CallSetup s(this, aRv, "TestInterfaceJS.getCallerPrincipal", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    5703           0 :   JSContext* cx = s.GetContext();
    5704           0 :   if (!cx) {
    5705           0 :     MOZ_ASSERT(aRv.Failed());
    5706           0 :     return;
    5707             :   }
    5708           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    5709             : 
    5710           0 :   JS::Rooted<JS::Value> callable(cx);
    5711           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    5712           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    5713           0 :       !GetCallableProperty(cx, atomsCache->getCallerPrincipal_id, &callable)) {
    5714           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5715           0 :     return;
    5716             :   }
    5717           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    5718           0 :   if (!JS::Call(cx, thisValue, callable,
    5719           0 :                 JS::HandleValueArray::empty(), &rval)) {
    5720           0 :     aRv.NoteJSContextException(cx);
    5721           0 :     return;
    5722             :   }
    5723           0 :   binding_detail::FakeString rvalDecl;
    5724           0 :   if (!ConvertJSValueToString(cx, rval, eStringify, eStringify, rvalDecl)) {
    5725           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5726           0 :     return;
    5727             :   }
    5728           0 :   aRetVal = rvalDecl;
    5729             : }
    5730             : 
    5731             : void
    5732           0 : TestInterfaceJSJSImpl::ConvertSVS(const nsAString& svs, nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    5733             : {
    5734           0 :   CallSetup s(this, aRv, "TestInterfaceJS.convertSVS", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    5735           0 :   JSContext* cx = s.GetContext();
    5736           0 :   if (!cx) {
    5737           0 :     MOZ_ASSERT(aRv.Failed());
    5738           0 :     return;
    5739             :   }
    5740           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    5741           0 :   JS::AutoValueVector argv(cx);
    5742           0 :   if (!argv.resize(1)) {
    5743           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    5744           0 :     return;
    5745             :   }
    5746           0 :   unsigned argc = 1;
    5747             : 
    5748             :   do {
    5749           0 :     if (!xpc::NonVoidStringToJsval(cx, svs, argv[0])) {
    5750           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5751           0 :       return;
    5752             :     }
    5753           0 :     break;
    5754             :   } while (0);
    5755             : 
    5756           0 :   JS::Rooted<JS::Value> callable(cx);
    5757           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    5758           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    5759           0 :       !GetCallableProperty(cx, atomsCache->convertSVS_id, &callable)) {
    5760           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5761           0 :     return;
    5762             :   }
    5763           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    5764           0 :   if (!JS::Call(cx, thisValue, callable,
    5765           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    5766           0 :     aRv.NoteJSContextException(cx);
    5767           0 :     return;
    5768             :   }
    5769           0 :   binding_detail::FakeString rvalDecl;
    5770           0 :   if (!ConvertJSValueToString(cx, rval, eStringify, eStringify, rvalDecl)) {
    5771           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5772           0 :     return;
    5773             :   }
    5774           0 :   aRetVal = rvalDecl;
    5775             : }
    5776             : 
    5777             : void
    5778           0 : TestInterfaceJSJSImpl::PingPongUnion(const TestInterfaceJSOrLong& something, OwningTestInterfaceJSOrLong& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    5779             : {
    5780           0 :   CallSetup s(this, aRv, "TestInterfaceJS.pingPongUnion", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    5781           0 :   JSContext* cx = s.GetContext();
    5782           0 :   if (!cx) {
    5783           0 :     MOZ_ASSERT(aRv.Failed());
    5784           0 :     return;
    5785             :   }
    5786           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    5787           0 :   JS::AutoValueVector argv(cx);
    5788           0 :   if (!argv.resize(1)) {
    5789           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    5790           0 :     return;
    5791             :   }
    5792           0 :   unsigned argc = 1;
    5793             : 
    5794             :   do {
    5795           0 :     if (!something.ToJSVal(cx, CallbackKnownNotGray(), argv[0])) {
    5796           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5797           0 :       return;
    5798             :     }
    5799           0 :     break;
    5800             :   } while (0);
    5801             : 
    5802           0 :   JS::Rooted<JS::Value> callable(cx);
    5803           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    5804           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    5805           0 :       !GetCallableProperty(cx, atomsCache->pingPongUnion_id, &callable)) {
    5806           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5807           0 :     return;
    5808             :   }
    5809           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    5810           0 :   if (!JS::Call(cx, thisValue, callable,
    5811           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    5812           0 :     aRv.NoteJSContextException(cx);
    5813           0 :     return;
    5814             :   }
    5815           0 :   OwningTestInterfaceJSOrLong& rvalDecl(aRetVal);
    5816             :   {
    5817           0 :     bool done = false, failed = false, tryNext;
    5818           0 :     if (rval.isObject()) {
    5819           0 :       done = (failed = !rvalDecl.TrySetToTestInterfaceJS(cx, rval, tryNext, false)) || !tryNext;
    5820             : 
    5821             :     }
    5822           0 :     if (!done) {
    5823             :       do {
    5824           0 :         done = (failed = !rvalDecl.TrySetToLong(cx, rval, tryNext)) || !tryNext;
    5825           0 :         break;
    5826             :       } while (0);
    5827             :     }
    5828           0 :     if (failed) {
    5829           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5830           0 :       return;
    5831             :     }
    5832           0 :     if (!done) {
    5833           0 :       ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Return value of TestInterfaceJS.pingPongUnion", "TestInterfaceJS");
    5834           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5835           0 :       return;
    5836             :     }
    5837             :   }
    5838             : }
    5839             : 
    5840             : void
    5841           0 : TestInterfaceJSJSImpl::PingPongUnionContainingNull(const TestInterfaceJSOrNullOrString& something, OwningStringOrTestInterfaceJSOrNull& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    5842             : {
    5843           0 :   CallSetup s(this, aRv, "TestInterfaceJS.pingPongUnionContainingNull", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    5844           0 :   JSContext* cx = s.GetContext();
    5845           0 :   if (!cx) {
    5846           0 :     MOZ_ASSERT(aRv.Failed());
    5847           0 :     return;
    5848             :   }
    5849           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    5850           0 :   JS::AutoValueVector argv(cx);
    5851           0 :   if (!argv.resize(1)) {
    5852           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    5853           0 :     return;
    5854             :   }
    5855           0 :   unsigned argc = 1;
    5856             : 
    5857             :   do {
    5858           0 :     if (!something.ToJSVal(cx, CallbackKnownNotGray(), argv[0])) {
    5859           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5860           0 :       return;
    5861             :     }
    5862           0 :     break;
    5863             :   } while (0);
    5864             : 
    5865           0 :   JS::Rooted<JS::Value> callable(cx);
    5866           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    5867           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    5868           0 :       !GetCallableProperty(cx, atomsCache->pingPongUnionContainingNull_id, &callable)) {
    5869           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5870           0 :     return;
    5871             :   }
    5872           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    5873           0 :   if (!JS::Call(cx, thisValue, callable,
    5874           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    5875           0 :     aRv.NoteJSContextException(cx);
    5876           0 :     return;
    5877             :   }
    5878           0 :   OwningStringOrTestInterfaceJSOrNull& rvalDecl(aRetVal);
    5879           0 :   if (rval.isNullOrUndefined()) {
    5880           0 :     rvalDecl.SetNull();
    5881             :   } else {
    5882             :     {
    5883           0 :       bool done = false, failed = false, tryNext;
    5884           0 :       if (rval.isObject()) {
    5885           0 :         done = (failed = !rvalDecl.TrySetToTestInterfaceJS(cx, rval, tryNext, false)) || !tryNext;
    5886             : 
    5887             :       }
    5888           0 :       if (!done) {
    5889             :         do {
    5890           0 :           done = (failed = !rvalDecl.TrySetToString(cx, rval, tryNext)) || !tryNext;
    5891           0 :           break;
    5892             :         } while (0);
    5893             :       }
    5894           0 :       if (failed) {
    5895           0 :         aRv.Throw(NS_ERROR_UNEXPECTED);
    5896           0 :         return;
    5897             :       }
    5898           0 :       if (!done) {
    5899           0 :         ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Return value of TestInterfaceJS.pingPongUnionContainingNull", "TestInterfaceJS");
    5900           0 :         aRv.Throw(NS_ERROR_UNEXPECTED);
    5901           0 :         return;
    5902             :       }
    5903             :     }
    5904             :   }
    5905             : }
    5906             : 
    5907             : void
    5908           0 : TestInterfaceJSJSImpl::PingPongNullableUnion(const Nullable<TestInterfaceJSOrLong>& something, Nullable<OwningTestInterfaceJSOrLong>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    5909             : {
    5910           0 :   CallSetup s(this, aRv, "TestInterfaceJS.pingPongNullableUnion", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    5911           0 :   JSContext* cx = s.GetContext();
    5912           0 :   if (!cx) {
    5913           0 :     MOZ_ASSERT(aRv.Failed());
    5914           0 :     return;
    5915             :   }
    5916           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    5917           0 :   JS::AutoValueVector argv(cx);
    5918           0 :   if (!argv.resize(1)) {
    5919           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    5920           0 :     return;
    5921             :   }
    5922           0 :   unsigned argc = 1;
    5923             : 
    5924             :   do {
    5925           0 :     if (something.IsNull()) {
    5926           0 :       argv[0].setNull();
    5927           0 :       break;
    5928             :     }
    5929           0 :     if (!something.Value().ToJSVal(cx, CallbackKnownNotGray(), argv[0])) {
    5930           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    5931           0 :       return;
    5932             :     }
    5933           0 :     break;
    5934             :   } while (0);
    5935             : 
    5936           0 :   JS::Rooted<JS::Value> callable(cx);
    5937           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    5938           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    5939           0 :       !GetCallableProperty(cx, atomsCache->pingPongNullableUnion_id, &callable)) {
    5940           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5941           0 :     return;
    5942             :   }
    5943           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    5944           0 :   if (!JS::Call(cx, thisValue, callable,
    5945           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    5946           0 :     aRv.NoteJSContextException(cx);
    5947           0 :     return;
    5948             :   }
    5949           0 :   Nullable<OwningTestInterfaceJSOrLong >& rvalDecl(aRetVal);
    5950           0 :   if (rval.isNullOrUndefined()) {
    5951           0 :     rvalDecl.SetNull();
    5952             :   } else {
    5953             :     {
    5954           0 :       bool done = false, failed = false, tryNext;
    5955           0 :       if (rval.isObject()) {
    5956           0 :         done = (failed = !rvalDecl.SetValue().TrySetToTestInterfaceJS(cx, rval, tryNext, false)) || !tryNext;
    5957             : 
    5958             :       }
    5959           0 :       if (!done) {
    5960             :         do {
    5961           0 :           done = (failed = !rvalDecl.SetValue().TrySetToLong(cx, rval, tryNext)) || !tryNext;
    5962           0 :           break;
    5963             :         } while (0);
    5964             :       }
    5965           0 :       if (failed) {
    5966           0 :         aRv.Throw(NS_ERROR_UNEXPECTED);
    5967           0 :         return;
    5968             :       }
    5969           0 :       if (!done) {
    5970           0 :         ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Return value of TestInterfaceJS.pingPongNullableUnion", "TestInterfaceJS");
    5971           0 :         aRv.Throw(NS_ERROR_UNEXPECTED);
    5972           0 :         return;
    5973             :       }
    5974             :     }
    5975             :   }
    5976             : }
    5977             : 
    5978             : void
    5979           0 : TestInterfaceJSJSImpl::ReturnBadUnion(OwningLocationOrTestInterfaceJS& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    5980             : {
    5981           0 :   CallSetup s(this, aRv, "TestInterfaceJS.returnBadUnion", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    5982           0 :   JSContext* cx = s.GetContext();
    5983           0 :   if (!cx) {
    5984           0 :     MOZ_ASSERT(aRv.Failed());
    5985           0 :     return;
    5986             :   }
    5987           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    5988             : 
    5989           0 :   JS::Rooted<JS::Value> callable(cx);
    5990           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    5991           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    5992           0 :       !GetCallableProperty(cx, atomsCache->returnBadUnion_id, &callable)) {
    5993           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    5994           0 :     return;
    5995             :   }
    5996           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    5997           0 :   if (!JS::Call(cx, thisValue, callable,
    5998           0 :                 JS::HandleValueArray::empty(), &rval)) {
    5999           0 :     aRv.NoteJSContextException(cx);
    6000           0 :     return;
    6001             :   }
    6002           0 :   OwningLocationOrTestInterfaceJS& rvalDecl(aRetVal);
    6003             :   {
    6004           0 :     bool done = false, failed = false, tryNext;
    6005           0 :     if (rval.isObject()) {
    6006           0 :       done = (failed = !rvalDecl.TrySetToLocation(cx, rval, tryNext, false)) || !tryNext ||
    6007           0 :              (failed = !rvalDecl.TrySetToTestInterfaceJS(cx, rval, tryNext, false)) || !tryNext;
    6008             : 
    6009             :     }
    6010           0 :     if (failed) {
    6011           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6012           0 :       return;
    6013             :     }
    6014           0 :     if (!done) {
    6015           0 :       ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Return value of TestInterfaceJS.returnBadUnion", "Location, TestInterfaceJS");
    6016           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6017           0 :       return;
    6018             :     }
    6019             :   }
    6020             : }
    6021             : 
    6022             : void
    6023           0 : TestInterfaceJSJSImpl::SetCachedAttr(int16_t n, ErrorResult& aRv, JSCompartment* aCompartment)
    6024             : {
    6025           0 :   CallSetup s(this, aRv, "TestInterfaceJS.setCachedAttr", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6026           0 :   JSContext* cx = s.GetContext();
    6027           0 :   if (!cx) {
    6028           0 :     MOZ_ASSERT(aRv.Failed());
    6029           0 :     return;
    6030             :   }
    6031           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6032           0 :   JS::AutoValueVector argv(cx);
    6033           0 :   if (!argv.resize(1)) {
    6034           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    6035           0 :     return;
    6036             :   }
    6037           0 :   unsigned argc = 1;
    6038             : 
    6039             :   do {
    6040           0 :     argv[0].setInt32(int32_t(n));
    6041           0 :     break;
    6042             :   } while (0);
    6043             : 
    6044           0 :   JS::Rooted<JS::Value> callable(cx);
    6045           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6046           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6047           0 :       !GetCallableProperty(cx, atomsCache->setCachedAttr_id, &callable)) {
    6048           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6049           0 :     return;
    6050             :   }
    6051           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6052           0 :   if (!JS::Call(cx, thisValue, callable,
    6053           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    6054           0 :     aRv.NoteJSContextException(cx);
    6055           0 :     return;
    6056             :   }
    6057             : }
    6058             : 
    6059             : void
    6060           0 : TestInterfaceJSJSImpl::ClearCachedAttrCache(ErrorResult& aRv, JSCompartment* aCompartment)
    6061             : {
    6062           0 :   CallSetup s(this, aRv, "TestInterfaceJS.clearCachedAttrCache", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6063           0 :   JSContext* cx = s.GetContext();
    6064           0 :   if (!cx) {
    6065           0 :     MOZ_ASSERT(aRv.Failed());
    6066           0 :     return;
    6067             :   }
    6068           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6069             : 
    6070           0 :   JS::Rooted<JS::Value> callable(cx);
    6071           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6072           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6073           0 :       !GetCallableProperty(cx, atomsCache->clearCachedAttrCache_id, &callable)) {
    6074           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6075           0 :     return;
    6076             :   }
    6077           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6078           0 :   if (!JS::Call(cx, thisValue, callable,
    6079           0 :                 JS::HandleValueArray::empty(), &rval)) {
    6080           0 :     aRv.NoteJSContextException(cx);
    6081           0 :     return;
    6082             :   }
    6083             : }
    6084             : 
    6085             : void
    6086           0 : TestInterfaceJSJSImpl::TestSequenceOverload(const Sequence<nsString>& arg, ErrorResult& aRv, JSCompartment* aCompartment)
    6087             : {
    6088           0 :   CallSetup s(this, aRv, "TestInterfaceJS.testSequenceOverload", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6089           0 :   JSContext* cx = s.GetContext();
    6090           0 :   if (!cx) {
    6091           0 :     MOZ_ASSERT(aRv.Failed());
    6092           0 :     return;
    6093             :   }
    6094           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6095           0 :   JS::AutoValueVector argv(cx);
    6096           0 :   if (!argv.resize(1)) {
    6097           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    6098           0 :     return;
    6099             :   }
    6100           0 :   unsigned argc = 1;
    6101             : 
    6102             :   do {
    6103             : 
    6104           0 :     uint32_t length = arg.Length();
    6105           0 :     JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
    6106           0 :     if (!returnArray) {
    6107           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6108           0 :       return;
    6109             :     }
    6110             :     // Scope for 'tmp'
    6111             :     {
    6112           0 :       JS::Rooted<JS::Value> tmp(cx);
    6113           0 :       for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
    6114             :         // Control block to let us common up the JS_DefineElement calls when there
    6115             :         // are different ways to succeed at wrapping the object.
    6116             :         do {
    6117           0 :           if (!xpc::NonVoidStringToJsval(cx, arg[sequenceIdx0], &tmp)) {
    6118           0 :             aRv.Throw(NS_ERROR_UNEXPECTED);
    6119           0 :             return;
    6120             :           }
    6121           0 :           break;
    6122             :         } while (0);
    6123           0 :         if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
    6124             :                               JSPROP_ENUMERATE)) {
    6125           0 :           aRv.Throw(NS_ERROR_UNEXPECTED);
    6126           0 :           return;
    6127             :         }
    6128             :       }
    6129             :     }
    6130           0 :     argv[0].setObject(*returnArray);
    6131           0 :     break;
    6132             :   } while (0);
    6133             : 
    6134           0 :   JS::Rooted<JS::Value> callable(cx);
    6135           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6136           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6137           0 :       !GetCallableProperty(cx, atomsCache->testSequenceOverload_id, &callable)) {
    6138           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6139           0 :     return;
    6140             :   }
    6141           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6142           0 :   if (!JS::Call(cx, thisValue, callable,
    6143           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    6144           0 :     aRv.NoteJSContextException(cx);
    6145           0 :     return;
    6146             :   }
    6147             : }
    6148             : 
    6149             : void
    6150           0 : TestInterfaceJSJSImpl::TestSequenceOverload(const nsAString& arg, ErrorResult& aRv, JSCompartment* aCompartment)
    6151             : {
    6152           0 :   CallSetup s(this, aRv, "TestInterfaceJS.testSequenceOverload", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6153           0 :   JSContext* cx = s.GetContext();
    6154           0 :   if (!cx) {
    6155           0 :     MOZ_ASSERT(aRv.Failed());
    6156           0 :     return;
    6157             :   }
    6158           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6159           0 :   JS::AutoValueVector argv(cx);
    6160           0 :   if (!argv.resize(1)) {
    6161           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    6162           0 :     return;
    6163             :   }
    6164           0 :   unsigned argc = 1;
    6165             : 
    6166             :   do {
    6167           0 :     nsString mutableStr(arg);
    6168           0 :     if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
    6169           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6170           0 :       return;
    6171             :     }
    6172           0 :     break;
    6173             :   } while (0);
    6174             : 
    6175           0 :   JS::Rooted<JS::Value> callable(cx);
    6176           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6177           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6178           0 :       !GetCallableProperty(cx, atomsCache->testSequenceOverload_id, &callable)) {
    6179           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6180           0 :     return;
    6181             :   }
    6182           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6183           0 :   if (!JS::Call(cx, thisValue, callable,
    6184           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    6185           0 :     aRv.NoteJSContextException(cx);
    6186           0 :     return;
    6187             :   }
    6188             : }
    6189             : 
    6190             : void
    6191           0 : TestInterfaceJSJSImpl::TestSequenceUnion(const StringSequenceOrString& arg, ErrorResult& aRv, JSCompartment* aCompartment)
    6192             : {
    6193           0 :   CallSetup s(this, aRv, "TestInterfaceJS.testSequenceUnion", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6194           0 :   JSContext* cx = s.GetContext();
    6195           0 :   if (!cx) {
    6196           0 :     MOZ_ASSERT(aRv.Failed());
    6197           0 :     return;
    6198             :   }
    6199           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6200           0 :   JS::AutoValueVector argv(cx);
    6201           0 :   if (!argv.resize(1)) {
    6202           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    6203           0 :     return;
    6204             :   }
    6205           0 :   unsigned argc = 1;
    6206             : 
    6207             :   do {
    6208           0 :     if (!arg.ToJSVal(cx, CallbackKnownNotGray(), argv[0])) {
    6209           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6210           0 :       return;
    6211             :     }
    6212           0 :     break;
    6213             :   } while (0);
    6214             : 
    6215           0 :   JS::Rooted<JS::Value> callable(cx);
    6216           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6217           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6218           0 :       !GetCallableProperty(cx, atomsCache->testSequenceUnion_id, &callable)) {
    6219           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6220           0 :     return;
    6221             :   }
    6222           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6223           0 :   if (!JS::Call(cx, thisValue, callable,
    6224           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    6225           0 :     aRv.NoteJSContextException(cx);
    6226           0 :     return;
    6227             :   }
    6228             : }
    6229             : 
    6230             : void
    6231           0 : TestInterfaceJSJSImpl::TestThrowError(ErrorResult& aRv, JSCompartment* aCompartment)
    6232             : {
    6233           0 :   CallSetup s(this, aRv, "TestInterfaceJS.testThrowError", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6234           0 :   JSContext* cx = s.GetContext();
    6235           0 :   if (!cx) {
    6236           0 :     MOZ_ASSERT(aRv.Failed());
    6237           0 :     return;
    6238             :   }
    6239           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6240             : 
    6241           0 :   JS::Rooted<JS::Value> callable(cx);
    6242           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6243           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6244           0 :       !GetCallableProperty(cx, atomsCache->testThrowError_id, &callable)) {
    6245           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6246           0 :     return;
    6247             :   }
    6248           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6249           0 :   if (!JS::Call(cx, thisValue, callable,
    6250           0 :                 JS::HandleValueArray::empty(), &rval)) {
    6251           0 :     aRv.NoteJSContextException(cx);
    6252           0 :     return;
    6253             :   }
    6254             : }
    6255             : 
    6256             : void
    6257           0 : TestInterfaceJSJSImpl::TestThrowDOMException(ErrorResult& aRv, JSCompartment* aCompartment)
    6258             : {
    6259           0 :   CallSetup s(this, aRv, "TestInterfaceJS.testThrowDOMException", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6260           0 :   JSContext* cx = s.GetContext();
    6261           0 :   if (!cx) {
    6262           0 :     MOZ_ASSERT(aRv.Failed());
    6263           0 :     return;
    6264             :   }
    6265           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6266             : 
    6267           0 :   JS::Rooted<JS::Value> callable(cx);
    6268           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6269           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6270           0 :       !GetCallableProperty(cx, atomsCache->testThrowDOMException_id, &callable)) {
    6271           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6272           0 :     return;
    6273             :   }
    6274           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6275           0 :   if (!JS::Call(cx, thisValue, callable,
    6276           0 :                 JS::HandleValueArray::empty(), &rval)) {
    6277           0 :     aRv.NoteJSContextException(cx);
    6278           0 :     return;
    6279             :   }
    6280             : }
    6281             : 
    6282             : void
    6283           0 : TestInterfaceJSJSImpl::TestThrowTypeError(ErrorResult& aRv, JSCompartment* aCompartment)
    6284             : {
    6285           0 :   CallSetup s(this, aRv, "TestInterfaceJS.testThrowTypeError", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6286           0 :   JSContext* cx = s.GetContext();
    6287           0 :   if (!cx) {
    6288           0 :     MOZ_ASSERT(aRv.Failed());
    6289           0 :     return;
    6290             :   }
    6291           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6292             : 
    6293           0 :   JS::Rooted<JS::Value> callable(cx);
    6294           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6295           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6296           0 :       !GetCallableProperty(cx, atomsCache->testThrowTypeError_id, &callable)) {
    6297           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6298           0 :     return;
    6299             :   }
    6300           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6301           0 :   if (!JS::Call(cx, thisValue, callable,
    6302           0 :                 JS::HandleValueArray::empty(), &rval)) {
    6303           0 :     aRv.NoteJSContextException(cx);
    6304           0 :     return;
    6305             :   }
    6306             : }
    6307             : 
    6308             : void
    6309           0 : TestInterfaceJSJSImpl::TestThrowCallbackError(Function& callback, ErrorResult& aRv, JSCompartment* aCompartment)
    6310             : {
    6311           0 :   CallSetup s(this, aRv, "TestInterfaceJS.testThrowCallbackError", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6312           0 :   JSContext* cx = s.GetContext();
    6313           0 :   if (!cx) {
    6314           0 :     MOZ_ASSERT(aRv.Failed());
    6315           0 :     return;
    6316             :   }
    6317           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6318           0 :   JS::AutoValueVector argv(cx);
    6319           0 :   if (!argv.resize(1)) {
    6320           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    6321           0 :     return;
    6322             :   }
    6323           0 :   unsigned argc = 1;
    6324             : 
    6325             :   do {
    6326           0 :     argv[0].setObjectOrNull(GetCallbackFromCallbackObject(callback));
    6327           0 :     if (!MaybeWrapObjectValue(cx, argv[0])) {
    6328           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6329           0 :       return;
    6330             :     }
    6331           0 :     break;
    6332             :   } while (0);
    6333             : 
    6334           0 :   JS::Rooted<JS::Value> callable(cx);
    6335           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6336           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6337           0 :       !GetCallableProperty(cx, atomsCache->testThrowCallbackError_id, &callable)) {
    6338           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6339           0 :     return;
    6340             :   }
    6341           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6342           0 :   if (!JS::Call(cx, thisValue, callable,
    6343           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    6344           0 :     aRv.NoteJSContextException(cx);
    6345           0 :     return;
    6346             :   }
    6347             : }
    6348             : 
    6349             : void
    6350           0 : TestInterfaceJSJSImpl::TestThrowXraySelfHosted(ErrorResult& aRv, JSCompartment* aCompartment)
    6351             : {
    6352           0 :   CallSetup s(this, aRv, "TestInterfaceJS.testThrowXraySelfHosted", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6353           0 :   JSContext* cx = s.GetContext();
    6354           0 :   if (!cx) {
    6355           0 :     MOZ_ASSERT(aRv.Failed());
    6356           0 :     return;
    6357             :   }
    6358           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6359             : 
    6360           0 :   JS::Rooted<JS::Value> callable(cx);
    6361           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6362           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6363           0 :       !GetCallableProperty(cx, atomsCache->testThrowXraySelfHosted_id, &callable)) {
    6364           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6365           0 :     return;
    6366             :   }
    6367           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6368           0 :   if (!JS::Call(cx, thisValue, callable,
    6369           0 :                 JS::HandleValueArray::empty(), &rval)) {
    6370           0 :     aRv.NoteJSContextException(cx);
    6371           0 :     return;
    6372             :   }
    6373             : }
    6374             : 
    6375             : void
    6376           0 : TestInterfaceJSJSImpl::TestThrowSelfHosted(ErrorResult& aRv, JSCompartment* aCompartment)
    6377             : {
    6378           0 :   CallSetup s(this, aRv, "TestInterfaceJS.testThrowSelfHosted", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6379           0 :   JSContext* cx = s.GetContext();
    6380           0 :   if (!cx) {
    6381           0 :     MOZ_ASSERT(aRv.Failed());
    6382           0 :     return;
    6383             :   }
    6384           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6385             : 
    6386           0 :   JS::Rooted<JS::Value> callable(cx);
    6387           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6388           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6389           0 :       !GetCallableProperty(cx, atomsCache->testThrowSelfHosted_id, &callable)) {
    6390           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6391           0 :     return;
    6392             :   }
    6393           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6394           0 :   if (!JS::Call(cx, thisValue, callable,
    6395           0 :                 JS::HandleValueArray::empty(), &rval)) {
    6396           0 :     aRv.NoteJSContextException(cx);
    6397           0 :     return;
    6398             :   }
    6399             : }
    6400             : 
    6401             : already_AddRefed<Promise>
    6402           0 : TestInterfaceJSJSImpl::TestPromiseWithThrowingChromePromiseInit(ErrorResult& aRv, JSCompartment* aCompartment)
    6403             : {
    6404           0 :   CallSetup s(this, aRv, "TestInterfaceJS.testPromiseWithThrowingChromePromiseInit", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6405           0 :   JSContext* cx = s.GetContext();
    6406           0 :   if (!cx) {
    6407           0 :     MOZ_ASSERT(aRv.Failed());
    6408           0 :     return nullptr;
    6409             :   }
    6410           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6411             : 
    6412           0 :   JS::Rooted<JS::Value> callable(cx);
    6413           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6414           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6415           0 :       !GetCallableProperty(cx, atomsCache->testPromiseWithThrowingChromePromiseInit_id, &callable)) {
    6416           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6417           0 :     return nullptr;
    6418             :   }
    6419           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6420           0 :   if (!JS::Call(cx, thisValue, callable,
    6421           0 :                 JS::HandleValueArray::empty(), &rval)) {
    6422           0 :     aRv.NoteJSContextException(cx);
    6423           0 :     return nullptr;
    6424             :   }
    6425           0 :   RefPtr<Promise> rvalDecl;
    6426             :   { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
    6427             :     // etc.
    6428             : 
    6429           0 :     JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
    6430           0 :     if (!rval.isObject()) {
    6431           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of TestInterfaceJS.testPromiseWithThrowingChromePromiseInit"));
    6432           0 :       return nullptr;
    6433             :     }
    6434           0 :     JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
    6435           0 :     if (!unwrappedVal) {
    6436             :       // A slight lie, but not much of one, for a dead object wrapper.
    6437           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of TestInterfaceJS.testPromiseWithThrowingChromePromiseInit"));
    6438           0 :       return nullptr;
    6439             :     }
    6440           0 :     globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
    6441           0 :     JSAutoCompartment ac(cx, globalObj);
    6442           0 :     GlobalObject promiseGlobal(cx, globalObj);
    6443           0 :     if (promiseGlobal.Failed()) {
    6444           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6445           0 :       return nullptr;
    6446             :     }
    6447             : 
    6448           0 :     JS::Rooted<JS::Value> valueToResolve(cx, rval);
    6449           0 :     if (!JS_WrapValue(cx, &valueToResolve)) {
    6450           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6451           0 :       return nullptr;
    6452             :     }
    6453           0 :     binding_detail::FastErrorResult promiseRv;
    6454             :     nsCOMPtr<nsIGlobalObject> global =
    6455           0 :       do_QueryInterface(promiseGlobal.GetAsSupports());
    6456           0 :     if (!global) {
    6457           0 :       promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
    6458           0 :       MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
    6459           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6460           0 :       return nullptr;
    6461             :     }
    6462           0 :     rvalDecl = Promise::Resolve(global, cx, valueToResolve,
    6463           0 :                                     promiseRv);
    6464           0 :     if (promiseRv.MaybeSetPendingException(cx)) {
    6465           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6466           0 :       return nullptr;
    6467             :     }
    6468             :   }
    6469           0 :   return rvalDecl.forget();
    6470             : }
    6471             : 
    6472             : already_AddRefed<Promise>
    6473           0 : TestInterfaceJSJSImpl::TestPromiseWithThrowingContentPromiseInit(Function& func, ErrorResult& aRv, JSCompartment* aCompartment)
    6474             : {
    6475           0 :   CallSetup s(this, aRv, "TestInterfaceJS.testPromiseWithThrowingContentPromiseInit", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6476           0 :   JSContext* cx = s.GetContext();
    6477           0 :   if (!cx) {
    6478           0 :     MOZ_ASSERT(aRv.Failed());
    6479           0 :     return nullptr;
    6480             :   }
    6481           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6482           0 :   JS::AutoValueVector argv(cx);
    6483           0 :   if (!argv.resize(1)) {
    6484           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    6485           0 :     return nullptr;
    6486             :   }
    6487           0 :   unsigned argc = 1;
    6488             : 
    6489             :   do {
    6490           0 :     argv[0].setObjectOrNull(GetCallbackFromCallbackObject(func));
    6491           0 :     if (!MaybeWrapObjectValue(cx, argv[0])) {
    6492           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6493           0 :       return nullptr;
    6494             :     }
    6495           0 :     break;
    6496             :   } while (0);
    6497             : 
    6498           0 :   JS::Rooted<JS::Value> callable(cx);
    6499           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6500           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6501           0 :       !GetCallableProperty(cx, atomsCache->testPromiseWithThrowingContentPromiseInit_id, &callable)) {
    6502           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6503           0 :     return nullptr;
    6504             :   }
    6505           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6506           0 :   if (!JS::Call(cx, thisValue, callable,
    6507           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    6508           0 :     aRv.NoteJSContextException(cx);
    6509           0 :     return nullptr;
    6510             :   }
    6511           0 :   RefPtr<Promise> rvalDecl;
    6512             :   { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
    6513             :     // etc.
    6514             : 
    6515           0 :     JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
    6516           0 :     if (!rval.isObject()) {
    6517           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of TestInterfaceJS.testPromiseWithThrowingContentPromiseInit"));
    6518           0 :       return nullptr;
    6519             :     }
    6520           0 :     JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
    6521           0 :     if (!unwrappedVal) {
    6522             :       // A slight lie, but not much of one, for a dead object wrapper.
    6523           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of TestInterfaceJS.testPromiseWithThrowingContentPromiseInit"));
    6524           0 :       return nullptr;
    6525             :     }
    6526           0 :     globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
    6527           0 :     JSAutoCompartment ac(cx, globalObj);
    6528           0 :     GlobalObject promiseGlobal(cx, globalObj);
    6529           0 :     if (promiseGlobal.Failed()) {
    6530           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6531           0 :       return nullptr;
    6532             :     }
    6533             : 
    6534           0 :     JS::Rooted<JS::Value> valueToResolve(cx, rval);
    6535           0 :     if (!JS_WrapValue(cx, &valueToResolve)) {
    6536           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6537           0 :       return nullptr;
    6538             :     }
    6539           0 :     binding_detail::FastErrorResult promiseRv;
    6540             :     nsCOMPtr<nsIGlobalObject> global =
    6541           0 :       do_QueryInterface(promiseGlobal.GetAsSupports());
    6542           0 :     if (!global) {
    6543           0 :       promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
    6544           0 :       MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
    6545           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6546           0 :       return nullptr;
    6547             :     }
    6548           0 :     rvalDecl = Promise::Resolve(global, cx, valueToResolve,
    6549           0 :                                     promiseRv);
    6550           0 :     if (promiseRv.MaybeSetPendingException(cx)) {
    6551           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6552           0 :       return nullptr;
    6553             :     }
    6554             :   }
    6555           0 :   return rvalDecl.forget();
    6556             : }
    6557             : 
    6558             : already_AddRefed<Promise>
    6559           0 : TestInterfaceJSJSImpl::TestPromiseWithDOMExceptionThrowingPromiseInit(ErrorResult& aRv, JSCompartment* aCompartment)
    6560             : {
    6561           0 :   CallSetup s(this, aRv, "TestInterfaceJS.testPromiseWithDOMExceptionThrowingPromiseInit", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6562           0 :   JSContext* cx = s.GetContext();
    6563           0 :   if (!cx) {
    6564           0 :     MOZ_ASSERT(aRv.Failed());
    6565           0 :     return nullptr;
    6566             :   }
    6567           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6568             : 
    6569           0 :   JS::Rooted<JS::Value> callable(cx);
    6570           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6571           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6572           0 :       !GetCallableProperty(cx, atomsCache->testPromiseWithDOMExceptionThrowingPromiseInit_id, &callable)) {
    6573           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6574           0 :     return nullptr;
    6575             :   }
    6576           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6577           0 :   if (!JS::Call(cx, thisValue, callable,
    6578           0 :                 JS::HandleValueArray::empty(), &rval)) {
    6579           0 :     aRv.NoteJSContextException(cx);
    6580           0 :     return nullptr;
    6581             :   }
    6582           0 :   RefPtr<Promise> rvalDecl;
    6583             :   { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
    6584             :     // etc.
    6585             : 
    6586           0 :     JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
    6587           0 :     if (!rval.isObject()) {
    6588           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of TestInterfaceJS.testPromiseWithDOMExceptionThrowingPromiseInit"));
    6589           0 :       return nullptr;
    6590             :     }
    6591           0 :     JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
    6592           0 :     if (!unwrappedVal) {
    6593             :       // A slight lie, but not much of one, for a dead object wrapper.
    6594           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of TestInterfaceJS.testPromiseWithDOMExceptionThrowingPromiseInit"));
    6595           0 :       return nullptr;
    6596             :     }
    6597           0 :     globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
    6598           0 :     JSAutoCompartment ac(cx, globalObj);
    6599           0 :     GlobalObject promiseGlobal(cx, globalObj);
    6600           0 :     if (promiseGlobal.Failed()) {
    6601           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6602           0 :       return nullptr;
    6603             :     }
    6604             : 
    6605           0 :     JS::Rooted<JS::Value> valueToResolve(cx, rval);
    6606           0 :     if (!JS_WrapValue(cx, &valueToResolve)) {
    6607           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6608           0 :       return nullptr;
    6609             :     }
    6610           0 :     binding_detail::FastErrorResult promiseRv;
    6611             :     nsCOMPtr<nsIGlobalObject> global =
    6612           0 :       do_QueryInterface(promiseGlobal.GetAsSupports());
    6613           0 :     if (!global) {
    6614           0 :       promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
    6615           0 :       MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
    6616           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6617           0 :       return nullptr;
    6618             :     }
    6619           0 :     rvalDecl = Promise::Resolve(global, cx, valueToResolve,
    6620           0 :                                     promiseRv);
    6621           0 :     if (promiseRv.MaybeSetPendingException(cx)) {
    6622           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6623           0 :       return nullptr;
    6624             :     }
    6625             :   }
    6626           0 :   return rvalDecl.forget();
    6627             : }
    6628             : 
    6629             : already_AddRefed<Promise>
    6630           0 : TestInterfaceJSJSImpl::TestPromiseWithThrowingChromeThenFunction(ErrorResult& aRv, JSCompartment* aCompartment)
    6631             : {
    6632           0 :   CallSetup s(this, aRv, "TestInterfaceJS.testPromiseWithThrowingChromeThenFunction", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6633           0 :   JSContext* cx = s.GetContext();
    6634           0 :   if (!cx) {
    6635           0 :     MOZ_ASSERT(aRv.Failed());
    6636           0 :     return nullptr;
    6637             :   }
    6638           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6639             : 
    6640           0 :   JS::Rooted<JS::Value> callable(cx);
    6641           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6642           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6643           0 :       !GetCallableProperty(cx, atomsCache->testPromiseWithThrowingChromeThenFunction_id, &callable)) {
    6644           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6645           0 :     return nullptr;
    6646             :   }
    6647           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6648           0 :   if (!JS::Call(cx, thisValue, callable,
    6649           0 :                 JS::HandleValueArray::empty(), &rval)) {
    6650           0 :     aRv.NoteJSContextException(cx);
    6651           0 :     return nullptr;
    6652             :   }
    6653           0 :   RefPtr<Promise> rvalDecl;
    6654             :   { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
    6655             :     // etc.
    6656             : 
    6657           0 :     JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
    6658           0 :     if (!rval.isObject()) {
    6659           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of TestInterfaceJS.testPromiseWithThrowingChromeThenFunction"));
    6660           0 :       return nullptr;
    6661             :     }
    6662           0 :     JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
    6663           0 :     if (!unwrappedVal) {
    6664             :       // A slight lie, but not much of one, for a dead object wrapper.
    6665           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of TestInterfaceJS.testPromiseWithThrowingChromeThenFunction"));
    6666           0 :       return nullptr;
    6667             :     }
    6668           0 :     globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
    6669           0 :     JSAutoCompartment ac(cx, globalObj);
    6670           0 :     GlobalObject promiseGlobal(cx, globalObj);
    6671           0 :     if (promiseGlobal.Failed()) {
    6672           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6673           0 :       return nullptr;
    6674             :     }
    6675             : 
    6676           0 :     JS::Rooted<JS::Value> valueToResolve(cx, rval);
    6677           0 :     if (!JS_WrapValue(cx, &valueToResolve)) {
    6678           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6679           0 :       return nullptr;
    6680             :     }
    6681           0 :     binding_detail::FastErrorResult promiseRv;
    6682             :     nsCOMPtr<nsIGlobalObject> global =
    6683           0 :       do_QueryInterface(promiseGlobal.GetAsSupports());
    6684           0 :     if (!global) {
    6685           0 :       promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
    6686           0 :       MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
    6687           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6688           0 :       return nullptr;
    6689             :     }
    6690           0 :     rvalDecl = Promise::Resolve(global, cx, valueToResolve,
    6691           0 :                                     promiseRv);
    6692           0 :     if (promiseRv.MaybeSetPendingException(cx)) {
    6693           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6694           0 :       return nullptr;
    6695             :     }
    6696             :   }
    6697           0 :   return rvalDecl.forget();
    6698             : }
    6699             : 
    6700             : already_AddRefed<Promise>
    6701           0 : TestInterfaceJSJSImpl::TestPromiseWithThrowingContentThenFunction(AnyCallback& func, ErrorResult& aRv, JSCompartment* aCompartment)
    6702             : {
    6703           0 :   CallSetup s(this, aRv, "TestInterfaceJS.testPromiseWithThrowingContentThenFunction", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6704           0 :   JSContext* cx = s.GetContext();
    6705           0 :   if (!cx) {
    6706           0 :     MOZ_ASSERT(aRv.Failed());
    6707           0 :     return nullptr;
    6708             :   }
    6709           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6710           0 :   JS::AutoValueVector argv(cx);
    6711           0 :   if (!argv.resize(1)) {
    6712           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    6713           0 :     return nullptr;
    6714             :   }
    6715           0 :   unsigned argc = 1;
    6716             : 
    6717             :   do {
    6718           0 :     argv[0].setObjectOrNull(GetCallbackFromCallbackObject(func));
    6719           0 :     if (!MaybeWrapObjectValue(cx, argv[0])) {
    6720           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6721           0 :       return nullptr;
    6722             :     }
    6723           0 :     break;
    6724             :   } while (0);
    6725             : 
    6726           0 :   JS::Rooted<JS::Value> callable(cx);
    6727           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6728           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6729           0 :       !GetCallableProperty(cx, atomsCache->testPromiseWithThrowingContentThenFunction_id, &callable)) {
    6730           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6731           0 :     return nullptr;
    6732             :   }
    6733           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6734           0 :   if (!JS::Call(cx, thisValue, callable,
    6735           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    6736           0 :     aRv.NoteJSContextException(cx);
    6737           0 :     return nullptr;
    6738             :   }
    6739           0 :   RefPtr<Promise> rvalDecl;
    6740             :   { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
    6741             :     // etc.
    6742             : 
    6743           0 :     JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
    6744           0 :     if (!rval.isObject()) {
    6745           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of TestInterfaceJS.testPromiseWithThrowingContentThenFunction"));
    6746           0 :       return nullptr;
    6747             :     }
    6748           0 :     JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
    6749           0 :     if (!unwrappedVal) {
    6750             :       // A slight lie, but not much of one, for a dead object wrapper.
    6751           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of TestInterfaceJS.testPromiseWithThrowingContentThenFunction"));
    6752           0 :       return nullptr;
    6753             :     }
    6754           0 :     globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
    6755           0 :     JSAutoCompartment ac(cx, globalObj);
    6756           0 :     GlobalObject promiseGlobal(cx, globalObj);
    6757           0 :     if (promiseGlobal.Failed()) {
    6758           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6759           0 :       return nullptr;
    6760             :     }
    6761             : 
    6762           0 :     JS::Rooted<JS::Value> valueToResolve(cx, rval);
    6763           0 :     if (!JS_WrapValue(cx, &valueToResolve)) {
    6764           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6765           0 :       return nullptr;
    6766             :     }
    6767           0 :     binding_detail::FastErrorResult promiseRv;
    6768             :     nsCOMPtr<nsIGlobalObject> global =
    6769           0 :       do_QueryInterface(promiseGlobal.GetAsSupports());
    6770           0 :     if (!global) {
    6771           0 :       promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
    6772           0 :       MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
    6773           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6774           0 :       return nullptr;
    6775             :     }
    6776           0 :     rvalDecl = Promise::Resolve(global, cx, valueToResolve,
    6777           0 :                                     promiseRv);
    6778           0 :     if (promiseRv.MaybeSetPendingException(cx)) {
    6779           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6780           0 :       return nullptr;
    6781             :     }
    6782             :   }
    6783           0 :   return rvalDecl.forget();
    6784             : }
    6785             : 
    6786             : already_AddRefed<Promise>
    6787           0 : TestInterfaceJSJSImpl::TestPromiseWithDOMExceptionThrowingThenFunction(ErrorResult& aRv, JSCompartment* aCompartment)
    6788             : {
    6789           0 :   CallSetup s(this, aRv, "TestInterfaceJS.testPromiseWithDOMExceptionThrowingThenFunction", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6790           0 :   JSContext* cx = s.GetContext();
    6791           0 :   if (!cx) {
    6792           0 :     MOZ_ASSERT(aRv.Failed());
    6793           0 :     return nullptr;
    6794             :   }
    6795           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6796             : 
    6797           0 :   JS::Rooted<JS::Value> callable(cx);
    6798           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6799           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6800           0 :       !GetCallableProperty(cx, atomsCache->testPromiseWithDOMExceptionThrowingThenFunction_id, &callable)) {
    6801           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6802           0 :     return nullptr;
    6803             :   }
    6804           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6805           0 :   if (!JS::Call(cx, thisValue, callable,
    6806           0 :                 JS::HandleValueArray::empty(), &rval)) {
    6807           0 :     aRv.NoteJSContextException(cx);
    6808           0 :     return nullptr;
    6809             :   }
    6810           0 :   RefPtr<Promise> rvalDecl;
    6811             :   { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
    6812             :     // etc.
    6813             : 
    6814           0 :     JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
    6815           0 :     if (!rval.isObject()) {
    6816           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of TestInterfaceJS.testPromiseWithDOMExceptionThrowingThenFunction"));
    6817           0 :       return nullptr;
    6818             :     }
    6819           0 :     JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
    6820           0 :     if (!unwrappedVal) {
    6821             :       // A slight lie, but not much of one, for a dead object wrapper.
    6822           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of TestInterfaceJS.testPromiseWithDOMExceptionThrowingThenFunction"));
    6823           0 :       return nullptr;
    6824             :     }
    6825           0 :     globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
    6826           0 :     JSAutoCompartment ac(cx, globalObj);
    6827           0 :     GlobalObject promiseGlobal(cx, globalObj);
    6828           0 :     if (promiseGlobal.Failed()) {
    6829           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6830           0 :       return nullptr;
    6831             :     }
    6832             : 
    6833           0 :     JS::Rooted<JS::Value> valueToResolve(cx, rval);
    6834           0 :     if (!JS_WrapValue(cx, &valueToResolve)) {
    6835           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6836           0 :       return nullptr;
    6837             :     }
    6838           0 :     binding_detail::FastErrorResult promiseRv;
    6839             :     nsCOMPtr<nsIGlobalObject> global =
    6840           0 :       do_QueryInterface(promiseGlobal.GetAsSupports());
    6841           0 :     if (!global) {
    6842           0 :       promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
    6843           0 :       MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
    6844           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6845           0 :       return nullptr;
    6846             :     }
    6847           0 :     rvalDecl = Promise::Resolve(global, cx, valueToResolve,
    6848           0 :                                     promiseRv);
    6849           0 :     if (promiseRv.MaybeSetPendingException(cx)) {
    6850           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6851           0 :       return nullptr;
    6852             :     }
    6853             :   }
    6854           0 :   return rvalDecl.forget();
    6855             : }
    6856             : 
    6857             : already_AddRefed<Promise>
    6858           0 : TestInterfaceJSJSImpl::TestPromiseWithThrowingChromeThenable(ErrorResult& aRv, JSCompartment* aCompartment)
    6859             : {
    6860           0 :   CallSetup s(this, aRv, "TestInterfaceJS.testPromiseWithThrowingChromeThenable", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6861           0 :   JSContext* cx = s.GetContext();
    6862           0 :   if (!cx) {
    6863           0 :     MOZ_ASSERT(aRv.Failed());
    6864           0 :     return nullptr;
    6865             :   }
    6866           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6867             : 
    6868           0 :   JS::Rooted<JS::Value> callable(cx);
    6869           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6870           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6871           0 :       !GetCallableProperty(cx, atomsCache->testPromiseWithThrowingChromeThenable_id, &callable)) {
    6872           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6873           0 :     return nullptr;
    6874             :   }
    6875           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6876           0 :   if (!JS::Call(cx, thisValue, callable,
    6877           0 :                 JS::HandleValueArray::empty(), &rval)) {
    6878           0 :     aRv.NoteJSContextException(cx);
    6879           0 :     return nullptr;
    6880             :   }
    6881           0 :   RefPtr<Promise> rvalDecl;
    6882             :   { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
    6883             :     // etc.
    6884             : 
    6885           0 :     JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
    6886           0 :     if (!rval.isObject()) {
    6887           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of TestInterfaceJS.testPromiseWithThrowingChromeThenable"));
    6888           0 :       return nullptr;
    6889             :     }
    6890           0 :     JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
    6891           0 :     if (!unwrappedVal) {
    6892             :       // A slight lie, but not much of one, for a dead object wrapper.
    6893           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of TestInterfaceJS.testPromiseWithThrowingChromeThenable"));
    6894           0 :       return nullptr;
    6895             :     }
    6896           0 :     globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
    6897           0 :     JSAutoCompartment ac(cx, globalObj);
    6898           0 :     GlobalObject promiseGlobal(cx, globalObj);
    6899           0 :     if (promiseGlobal.Failed()) {
    6900           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6901           0 :       return nullptr;
    6902             :     }
    6903             : 
    6904           0 :     JS::Rooted<JS::Value> valueToResolve(cx, rval);
    6905           0 :     if (!JS_WrapValue(cx, &valueToResolve)) {
    6906           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6907           0 :       return nullptr;
    6908             :     }
    6909           0 :     binding_detail::FastErrorResult promiseRv;
    6910             :     nsCOMPtr<nsIGlobalObject> global =
    6911           0 :       do_QueryInterface(promiseGlobal.GetAsSupports());
    6912           0 :     if (!global) {
    6913           0 :       promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
    6914           0 :       MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
    6915           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6916           0 :       return nullptr;
    6917             :     }
    6918           0 :     rvalDecl = Promise::Resolve(global, cx, valueToResolve,
    6919           0 :                                     promiseRv);
    6920           0 :     if (promiseRv.MaybeSetPendingException(cx)) {
    6921           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6922           0 :       return nullptr;
    6923             :     }
    6924             :   }
    6925           0 :   return rvalDecl.forget();
    6926             : }
    6927             : 
    6928             : already_AddRefed<Promise>
    6929           0 : TestInterfaceJSJSImpl::TestPromiseWithThrowingContentThenable(JS::Handle<JSObject*> thenable, ErrorResult& aRv, JSCompartment* aCompartment)
    6930             : {
    6931           0 :   CallSetup s(this, aRv, "TestInterfaceJS.testPromiseWithThrowingContentThenable", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    6932           0 :   JSContext* cx = s.GetContext();
    6933           0 :   if (!cx) {
    6934           0 :     MOZ_ASSERT(aRv.Failed());
    6935           0 :     return nullptr;
    6936             :   }
    6937           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    6938           0 :   JS::AutoValueVector argv(cx);
    6939           0 :   if (!argv.resize(1)) {
    6940           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    6941           0 :     return nullptr;
    6942             :   }
    6943           0 :   unsigned argc = 1;
    6944             : 
    6945             :   do {
    6946           0 :     JS::ExposeObjectToActiveJS(thenable);
    6947           0 :     argv[0].setObject(*thenable);
    6948           0 :     if (!MaybeWrapObjectValue(cx, argv[0])) {
    6949           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6950           0 :       return nullptr;
    6951             :     }
    6952           0 :     break;
    6953             :   } while (0);
    6954             : 
    6955           0 :   JS::Rooted<JS::Value> callable(cx);
    6956           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    6957           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    6958           0 :       !GetCallableProperty(cx, atomsCache->testPromiseWithThrowingContentThenable_id, &callable)) {
    6959           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    6960           0 :     return nullptr;
    6961             :   }
    6962           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    6963           0 :   if (!JS::Call(cx, thisValue, callable,
    6964           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    6965           0 :     aRv.NoteJSContextException(cx);
    6966           0 :     return nullptr;
    6967             :   }
    6968           0 :   RefPtr<Promise> rvalDecl;
    6969             :   { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
    6970             :     // etc.
    6971             : 
    6972           0 :     JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
    6973           0 :     if (!rval.isObject()) {
    6974           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of TestInterfaceJS.testPromiseWithThrowingContentThenable"));
    6975           0 :       return nullptr;
    6976             :     }
    6977           0 :     JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
    6978           0 :     if (!unwrappedVal) {
    6979             :       // A slight lie, but not much of one, for a dead object wrapper.
    6980           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of TestInterfaceJS.testPromiseWithThrowingContentThenable"));
    6981           0 :       return nullptr;
    6982             :     }
    6983           0 :     globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
    6984           0 :     JSAutoCompartment ac(cx, globalObj);
    6985           0 :     GlobalObject promiseGlobal(cx, globalObj);
    6986           0 :     if (promiseGlobal.Failed()) {
    6987           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6988           0 :       return nullptr;
    6989             :     }
    6990             : 
    6991           0 :     JS::Rooted<JS::Value> valueToResolve(cx, rval);
    6992           0 :     if (!JS_WrapValue(cx, &valueToResolve)) {
    6993           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    6994           0 :       return nullptr;
    6995             :     }
    6996           0 :     binding_detail::FastErrorResult promiseRv;
    6997             :     nsCOMPtr<nsIGlobalObject> global =
    6998           0 :       do_QueryInterface(promiseGlobal.GetAsSupports());
    6999           0 :     if (!global) {
    7000           0 :       promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
    7001           0 :       MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
    7002           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    7003           0 :       return nullptr;
    7004             :     }
    7005           0 :     rvalDecl = Promise::Resolve(global, cx, valueToResolve,
    7006           0 :                                     promiseRv);
    7007           0 :     if (promiseRv.MaybeSetPendingException(cx)) {
    7008           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    7009           0 :       return nullptr;
    7010             :     }
    7011             :   }
    7012           0 :   return rvalDecl.forget();
    7013             : }
    7014             : 
    7015             : already_AddRefed<Promise>
    7016           0 : TestInterfaceJSJSImpl::TestPromiseWithDOMExceptionThrowingThenable(ErrorResult& aRv, JSCompartment* aCompartment)
    7017             : {
    7018           0 :   CallSetup s(this, aRv, "TestInterfaceJS.testPromiseWithDOMExceptionThrowingThenable", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    7019           0 :   JSContext* cx = s.GetContext();
    7020           0 :   if (!cx) {
    7021           0 :     MOZ_ASSERT(aRv.Failed());
    7022           0 :     return nullptr;
    7023             :   }
    7024           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    7025             : 
    7026           0 :   JS::Rooted<JS::Value> callable(cx);
    7027           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    7028           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    7029           0 :       !GetCallableProperty(cx, atomsCache->testPromiseWithDOMExceptionThrowingThenable_id, &callable)) {
    7030           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7031           0 :     return nullptr;
    7032             :   }
    7033           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    7034           0 :   if (!JS::Call(cx, thisValue, callable,
    7035           0 :                 JS::HandleValueArray::empty(), &rval)) {
    7036           0 :     aRv.NoteJSContextException(cx);
    7037           0 :     return nullptr;
    7038             :   }
    7039           0 :   RefPtr<Promise> rvalDecl;
    7040             :   { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
    7041             :     // etc.
    7042             : 
    7043           0 :     JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
    7044           0 :     if (!rval.isObject()) {
    7045           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of TestInterfaceJS.testPromiseWithDOMExceptionThrowingThenable"));
    7046           0 :       return nullptr;
    7047             :     }
    7048           0 :     JSObject* unwrappedVal = js::CheckedUnwrap(&rval.toObject());
    7049           0 :     if (!unwrappedVal) {
    7050             :       // A slight lie, but not much of one, for a dead object wrapper.
    7051           0 :       aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("return value of TestInterfaceJS.testPromiseWithDOMExceptionThrowingThenable"));
    7052           0 :       return nullptr;
    7053             :     }
    7054           0 :     globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
    7055           0 :     JSAutoCompartment ac(cx, globalObj);
    7056           0 :     GlobalObject promiseGlobal(cx, globalObj);
    7057           0 :     if (promiseGlobal.Failed()) {
    7058           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    7059           0 :       return nullptr;
    7060             :     }
    7061             : 
    7062           0 :     JS::Rooted<JS::Value> valueToResolve(cx, rval);
    7063           0 :     if (!JS_WrapValue(cx, &valueToResolve)) {
    7064           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    7065           0 :       return nullptr;
    7066             :     }
    7067           0 :     binding_detail::FastErrorResult promiseRv;
    7068             :     nsCOMPtr<nsIGlobalObject> global =
    7069           0 :       do_QueryInterface(promiseGlobal.GetAsSupports());
    7070           0 :     if (!global) {
    7071           0 :       promiseRv.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
    7072           0 :       MOZ_ALWAYS_TRUE(promiseRv.MaybeSetPendingException(cx));
    7073           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    7074           0 :       return nullptr;
    7075             :     }
    7076           0 :     rvalDecl = Promise::Resolve(global, cx, valueToResolve,
    7077           0 :                                     promiseRv);
    7078           0 :     if (promiseRv.MaybeSetPendingException(cx)) {
    7079           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    7080           0 :       return nullptr;
    7081             :     }
    7082             :   }
    7083           0 :   return rvalDecl.forget();
    7084             : }
    7085             : 
    7086             : void
    7087           0 : TestInterfaceJSJSImpl::__Init(JS::Handle<JS::Value> anyArg, const Optional<JS::Handle<JSObject*>>& objectArg, const TestInterfaceJSDictionary& dictionaryArg, ErrorResult& aRv, JSCompartment* aCompartment)
    7088             : {
    7089           0 :   CallSetup s(this, aRv, "__init", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    7090           0 :   JSContext* cx = s.GetContext();
    7091           0 :   if (!cx) {
    7092           0 :     MOZ_ASSERT(aRv.Failed());
    7093           0 :     return;
    7094             :   }
    7095           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    7096           0 :   JS::AutoValueVector argv(cx);
    7097           0 :   if (!argv.resize(3)) {
    7098           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    7099           0 :     return;
    7100             :   }
    7101           0 :   unsigned argc = 3;
    7102             : 
    7103             :   do {
    7104           0 :     if (!dictionaryArg.ToObjectInternal(cx, argv[2])) {
    7105           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    7106           0 :       return;
    7107             :     }
    7108           0 :     break;
    7109             :   } while (0);
    7110             : 
    7111             :   do {
    7112           0 :     if (objectArg.WasPassed()) {
    7113           0 :       JS::ExposeObjectToActiveJS(objectArg.Value());
    7114           0 :       argv[1].setObject(*objectArg.Value());
    7115           0 :       if (!MaybeWrapObjectValue(cx, argv[1])) {
    7116           0 :         aRv.Throw(NS_ERROR_UNEXPECTED);
    7117           0 :         return;
    7118             :       }
    7119           0 :       break;
    7120           0 :     } else if (argc == 2) {
    7121             :       // This is our current trailing argument; reduce argc
    7122           0 :       --argc;
    7123             :     } else {
    7124           0 :       argv[1].setUndefined();
    7125             :     }
    7126             :   } while (0);
    7127             : 
    7128             :   do {
    7129           0 :     JS::ExposeValueToActiveJS(anyArg);
    7130           0 :     argv[0].set(anyArg);
    7131           0 :     if (!MaybeWrapValue(cx, argv[0])) {
    7132           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    7133           0 :       return;
    7134             :     }
    7135           0 :     break;
    7136             :   } while (0);
    7137             : 
    7138           0 :   JS::Rooted<JS::Value> callable(cx);
    7139           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    7140           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    7141           0 :       !GetCallableProperty(cx, atomsCache->__init_id, &callable)) {
    7142           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7143           0 :     return;
    7144             :   }
    7145           0 :   JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
    7146           0 :   if (!JS::Call(cx, thisValue, callable,
    7147           0 :                 JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
    7148           0 :     aRv.NoteJSContextException(cx);
    7149           0 :     return;
    7150             :   }
    7151             : }
    7152             : 
    7153             : bool
    7154           0 : TestInterfaceJSJSImpl::InitIds(JSContext* cx, TestInterfaceJSAtoms* atomsCache)
    7155             : {
    7156           0 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
    7157             : 
    7158             :   // Initialize these in reverse order so that any failure leaves the first one
    7159             :   // uninitialized.
    7160           0 :   if (!atomsCache->__init_id.init(cx, "__init") ||
    7161           0 :       !atomsCache->onsomething_id.init(cx, "onsomething") ||
    7162           0 :       !atomsCache->testPromiseWithDOMExceptionThrowingThenable_id.init(cx, "testPromiseWithDOMExceptionThrowingThenable") ||
    7163           0 :       !atomsCache->testPromiseWithThrowingContentThenable_id.init(cx, "testPromiseWithThrowingContentThenable") ||
    7164           0 :       !atomsCache->testPromiseWithThrowingChromeThenable_id.init(cx, "testPromiseWithThrowingChromeThenable") ||
    7165           0 :       !atomsCache->testPromiseWithDOMExceptionThrowingThenFunction_id.init(cx, "testPromiseWithDOMExceptionThrowingThenFunction") ||
    7166           0 :       !atomsCache->testPromiseWithThrowingContentThenFunction_id.init(cx, "testPromiseWithThrowingContentThenFunction") ||
    7167           0 :       !atomsCache->testPromiseWithThrowingChromeThenFunction_id.init(cx, "testPromiseWithThrowingChromeThenFunction") ||
    7168           0 :       !atomsCache->testPromiseWithDOMExceptionThrowingPromiseInit_id.init(cx, "testPromiseWithDOMExceptionThrowingPromiseInit") ||
    7169           0 :       !atomsCache->testPromiseWithThrowingContentPromiseInit_id.init(cx, "testPromiseWithThrowingContentPromiseInit") ||
    7170           0 :       !atomsCache->testPromiseWithThrowingChromePromiseInit_id.init(cx, "testPromiseWithThrowingChromePromiseInit") ||
    7171           0 :       !atomsCache->testThrowSelfHosted_id.init(cx, "testThrowSelfHosted") ||
    7172           0 :       !atomsCache->testThrowXraySelfHosted_id.init(cx, "testThrowXraySelfHosted") ||
    7173           0 :       !atomsCache->testThrowCallbackError_id.init(cx, "testThrowCallbackError") ||
    7174           0 :       !atomsCache->testThrowTypeError_id.init(cx, "testThrowTypeError") ||
    7175           0 :       !atomsCache->testThrowDOMException_id.init(cx, "testThrowDOMException") ||
    7176           0 :       !atomsCache->testThrowError_id.init(cx, "testThrowError") ||
    7177           0 :       !atomsCache->testSequenceUnion_id.init(cx, "testSequenceUnion") ||
    7178           0 :       !atomsCache->testSequenceOverload_id.init(cx, "testSequenceOverload") ||
    7179           0 :       !atomsCache->clearCachedAttrCache_id.init(cx, "clearCachedAttrCache") ||
    7180           0 :       !atomsCache->setCachedAttr_id.init(cx, "setCachedAttr") ||
    7181           0 :       !atomsCache->cachedAttr_id.init(cx, "cachedAttr") ||
    7182           0 :       !atomsCache->returnBadUnion_id.init(cx, "returnBadUnion") ||
    7183           0 :       !atomsCache->pingPongNullableUnion_id.init(cx, "pingPongNullableUnion") ||
    7184           0 :       !atomsCache->pingPongUnionContainingNull_id.init(cx, "pingPongUnionContainingNull") ||
    7185           0 :       !atomsCache->pingPongUnion_id.init(cx, "pingPongUnion") ||
    7186           0 :       !atomsCache->convertSVS_id.init(cx, "convertSVS") ||
    7187           0 :       !atomsCache->getCallerPrincipal_id.init(cx, "getCallerPrincipal") ||
    7188           0 :       !atomsCache->anySequenceLength_id.init(cx, "anySequenceLength") ||
    7189           0 :       !atomsCache->objectSequenceLength_id.init(cx, "objectSequenceLength") ||
    7190           0 :       !atomsCache->pingPongMap_id.init(cx, "pingPongMap") ||
    7191           0 :       !atomsCache->pingPongDictionaryOrLong_id.init(cx, "pingPongDictionaryOrLong") ||
    7192           0 :       !atomsCache->pingPongDictionary_id.init(cx, "pingPongDictionary") ||
    7193           0 :       !atomsCache->pingPongObjectOrString_id.init(cx, "pingPongObjectOrString") ||
    7194           0 :       !atomsCache->pingPongObject_id.init(cx, "pingPongObject") ||
    7195           0 :       !atomsCache->pingPongAny_id.init(cx, "pingPongAny") ||
    7196           0 :       !atomsCache->dictionaryAttr_id.init(cx, "dictionaryAttr") ||
    7197           0 :       !atomsCache->objectAttr_id.init(cx, "objectAttr") ||
    7198           0 :       !atomsCache->anyAttr_id.init(cx, "anyAttr") ||
    7199           0 :       !atomsCache->dictionaryArg_id.init(cx, "dictionaryArg") ||
    7200           0 :       !atomsCache->objectArg_id.init(cx, "objectArg") ||
    7201           0 :       !atomsCache->anyArg_id.init(cx, "anyArg")) {
    7202           0 :     return false;
    7203             :   }
    7204           0 :   return true;
    7205             : }
    7206             : 
    7207             : 
    7208             : void
    7209           0 : TestInterfaceJSJSImpl::GetAnyArg(JS::MutableHandle<JS::Value> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    7210             : {
    7211           0 :   CallSetup s(this, aRv, "TestInterfaceJS.anyArg", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    7212           0 :   JSContext* cx = s.GetContext();
    7213           0 :   if (!cx) {
    7214           0 :     MOZ_ASSERT(aRv.Failed());
    7215           0 :     return;
    7216             :   }
    7217           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    7218             : 
    7219           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    7220           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    7221           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    7222           0 :       !JS_GetPropertyById(cx, callback, atomsCache->anyArg_id, &rval)) {
    7223           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7224           0 :     return;
    7225             :   }
    7226           0 :   JS::Rooted<JS::Value> rvalDecl(cx);
    7227             : #ifdef __clang__
    7228             : #pragma clang diagnostic push
    7229             : #pragma clang diagnostic ignored "-Wunreachable-code"
    7230             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    7231             : #endif // __clang__
    7232           0 :   if ((false) && !CallerSubsumes(rval)) {
    7233           0 :     ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "return value of TestInterfaceJS.anyArg");
    7234           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7235           0 :     return;
    7236             :   }
    7237             : #ifdef __clang__
    7238             : #pragma clang diagnostic pop
    7239             : #endif // __clang__
    7240           0 :   rvalDecl = rval;
    7241           0 :   aRetVal.set(rvalDecl);
    7242             : }
    7243             : 
    7244             : void
    7245           0 : TestInterfaceJSJSImpl::GetObjectArg(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    7246             : {
    7247           0 :   CallSetup s(this, aRv, "TestInterfaceJS.objectArg", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    7248           0 :   JSContext* cx = s.GetContext();
    7249           0 :   if (!cx) {
    7250           0 :     MOZ_ASSERT(aRv.Failed());
    7251           0 :     return;
    7252             :   }
    7253           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    7254             : 
    7255           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    7256           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    7257           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    7258           0 :       !JS_GetPropertyById(cx, callback, atomsCache->objectArg_id, &rval)) {
    7259           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7260           0 :     return;
    7261             :   }
    7262           0 :   JS::Rooted<JSObject*> rvalDecl(cx);
    7263           0 :   if (rval.isObject()) {
    7264             : #ifdef __clang__
    7265             : #pragma clang diagnostic push
    7266             : #pragma clang diagnostic ignored "-Wunreachable-code"
    7267             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    7268             : #endif // __clang__
    7269           0 :     if ((false) && !CallerSubsumes(rval)) {
    7270           0 :       ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "return value of TestInterfaceJS.objectArg");
    7271           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    7272           0 :       return;
    7273             :     }
    7274             : #ifdef __clang__
    7275             : #pragma clang diagnostic pop
    7276             : #endif // __clang__
    7277           0 :     rvalDecl = &rval.toObject();
    7278             :   } else {
    7279           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of TestInterfaceJS.objectArg");
    7280           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7281           0 :     return;
    7282             :   }
    7283           0 :   aRetVal.set(rvalDecl);
    7284             : }
    7285             : 
    7286             : void
    7287           0 : TestInterfaceJSJSImpl::GetDictionaryArg(TestInterfaceJSDictionary& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    7288             : {
    7289           0 :   CallSetup s(this, aRv, "TestInterfaceJS.dictionaryArg", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    7290           0 :   JSContext* cx = s.GetContext();
    7291           0 :   if (!cx) {
    7292           0 :     MOZ_ASSERT(aRv.Failed());
    7293           0 :     return;
    7294             :   }
    7295           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    7296             : 
    7297           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    7298           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    7299           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    7300           0 :       !JS_GetPropertyById(cx, callback, atomsCache->dictionaryArg_id, &rval)) {
    7301           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7302           0 :     return;
    7303             :   }
    7304           0 :   TestInterfaceJSDictionary& rvalDecl(aRetVal);
    7305           0 :   if (!rvalDecl.Init(cx, rval,  "Return value of TestInterfaceJS.dictionaryArg", false)) {
    7306           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7307           0 :     return;
    7308             :   }
    7309             : }
    7310             : 
    7311             : void
    7312           0 : TestInterfaceJSJSImpl::GetAnyAttr(JS::MutableHandle<JS::Value> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    7313             : {
    7314           0 :   CallSetup s(this, aRv, "TestInterfaceJS.anyAttr", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    7315           0 :   JSContext* cx = s.GetContext();
    7316           0 :   if (!cx) {
    7317           0 :     MOZ_ASSERT(aRv.Failed());
    7318           0 :     return;
    7319             :   }
    7320           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    7321             : 
    7322           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    7323           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    7324           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    7325           0 :       !JS_GetPropertyById(cx, callback, atomsCache->anyAttr_id, &rval)) {
    7326           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7327           0 :     return;
    7328             :   }
    7329           0 :   JS::Rooted<JS::Value> rvalDecl(cx);
    7330             : #ifdef __clang__
    7331             : #pragma clang diagnostic push
    7332             : #pragma clang diagnostic ignored "-Wunreachable-code"
    7333             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    7334             : #endif // __clang__
    7335           0 :   if ((false) && !CallerSubsumes(rval)) {
    7336           0 :     ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "return value of TestInterfaceJS.anyAttr");
    7337           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7338           0 :     return;
    7339             :   }
    7340             : #ifdef __clang__
    7341             : #pragma clang diagnostic pop
    7342             : #endif // __clang__
    7343           0 :   rvalDecl = rval;
    7344           0 :   aRetVal.set(rvalDecl);
    7345             : }
    7346             : 
    7347             : void
    7348           0 : TestInterfaceJSJSImpl::GetObjectAttr(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    7349             : {
    7350           0 :   CallSetup s(this, aRv, "TestInterfaceJS.objectAttr", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    7351           0 :   JSContext* cx = s.GetContext();
    7352           0 :   if (!cx) {
    7353           0 :     MOZ_ASSERT(aRv.Failed());
    7354           0 :     return;
    7355             :   }
    7356           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    7357             : 
    7358           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    7359           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    7360           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    7361           0 :       !JS_GetPropertyById(cx, callback, atomsCache->objectAttr_id, &rval)) {
    7362           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7363           0 :     return;
    7364             :   }
    7365           0 :   JS::Rooted<JSObject*> rvalDecl(cx);
    7366           0 :   if (rval.isObject()) {
    7367             : #ifdef __clang__
    7368             : #pragma clang diagnostic push
    7369             : #pragma clang diagnostic ignored "-Wunreachable-code"
    7370             : #pragma clang diagnostic ignored "-Wunreachable-code-return"
    7371             : #endif // __clang__
    7372           0 :     if ((false) && !CallerSubsumes(rval)) {
    7373           0 :       ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "return value of TestInterfaceJS.objectAttr");
    7374           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    7375           0 :       return;
    7376             :     }
    7377             : #ifdef __clang__
    7378             : #pragma clang diagnostic pop
    7379             : #endif // __clang__
    7380           0 :     rvalDecl = &rval.toObject();
    7381             :   } else {
    7382           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Return value of TestInterfaceJS.objectAttr");
    7383           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7384           0 :     return;
    7385             :   }
    7386           0 :   aRetVal.set(rvalDecl);
    7387             : }
    7388             : 
    7389             : void
    7390           0 : TestInterfaceJSJSImpl::GetDictionaryAttr(TestInterfaceJSDictionary& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    7391             : {
    7392           0 :   CallSetup s(this, aRv, "TestInterfaceJS.dictionaryAttr", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    7393           0 :   JSContext* cx = s.GetContext();
    7394           0 :   if (!cx) {
    7395           0 :     MOZ_ASSERT(aRv.Failed());
    7396           0 :     return;
    7397             :   }
    7398           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    7399             : 
    7400           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    7401           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    7402           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    7403           0 :       !JS_GetPropertyById(cx, callback, atomsCache->dictionaryAttr_id, &rval)) {
    7404           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7405           0 :     return;
    7406             :   }
    7407           0 :   TestInterfaceJSDictionary& rvalDecl(aRetVal);
    7408           0 :   if (!rvalDecl.Init(cx, rval,  "Return value of TestInterfaceJS.dictionaryAttr", false)) {
    7409           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7410           0 :     return;
    7411             :   }
    7412             : }
    7413             : 
    7414             : int16_t
    7415           0 : TestInterfaceJSJSImpl::GetCachedAttr(ErrorResult& aRv, JSCompartment* aCompartment)
    7416             : {
    7417           0 :   CallSetup s(this, aRv, "TestInterfaceJS.cachedAttr", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    7418           0 :   JSContext* cx = s.GetContext();
    7419           0 :   if (!cx) {
    7420           0 :     MOZ_ASSERT(aRv.Failed());
    7421           0 :     return int16_t(0);
    7422             :   }
    7423           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    7424             : 
    7425           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    7426           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    7427           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    7428           0 :       !JS_GetPropertyById(cx, callback, atomsCache->cachedAttr_id, &rval)) {
    7429           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7430           0 :     return int16_t(0);
    7431             :   }
    7432             :   int16_t rvalDecl;
    7433           0 :   if (!ValueToPrimitive<int16_t, eDefault>(cx, rval, &rvalDecl)) {
    7434           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7435           0 :     return int16_t(0);
    7436             :   }
    7437           0 :   return rvalDecl;
    7438             : }
    7439             : 
    7440             : already_AddRefed<EventHandlerNonNull>
    7441           0 : TestInterfaceJSJSImpl::GetOnsomething(ErrorResult& aRv, JSCompartment* aCompartment)
    7442             : {
    7443           0 :   CallSetup s(this, aRv, "TestInterfaceJS.onsomething", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    7444           0 :   JSContext* cx = s.GetContext();
    7445           0 :   if (!cx) {
    7446           0 :     MOZ_ASSERT(aRv.Failed());
    7447           0 :     return nullptr;
    7448             :   }
    7449           0 :   JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
    7450             : 
    7451           0 :   JS::Rooted<JSObject *> callback(cx, mCallback);
    7452           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    7453           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    7454           0 :       !JS_GetPropertyById(cx, callback, atomsCache->onsomething_id, &rval)) {
    7455           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7456           0 :     return nullptr;
    7457             :   }
    7458           0 :   RefPtr<EventHandlerNonNull> rvalDecl;
    7459           0 :   if (rval.isObject()) {
    7460             :     { // scope for tempRoot
    7461           0 :       JS::Rooted<JSObject*> tempRoot(cx, &rval.toObject());
    7462           0 :       rvalDecl = new EventHandlerNonNull(cx, tempRoot, GetIncumbentGlobal());
    7463             :     }
    7464             :   } else {
    7465           0 :     rvalDecl = nullptr;
    7466             :   }
    7467           0 :   return rvalDecl.forget();
    7468             : }
    7469             : 
    7470             : void
    7471           0 : TestInterfaceJSJSImpl::SetAnyAttr(JS::Handle<JS::Value> arg, ErrorResult& aRv, JSCompartment* aCompartment)
    7472             : {
    7473           0 :   CallSetup s(this, aRv, "TestInterfaceJS.anyAttr", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    7474           0 :   JSContext* cx = s.GetContext();
    7475           0 :   if (!cx) {
    7476           0 :     MOZ_ASSERT(aRv.Failed());
    7477           0 :     return;
    7478             :   }
    7479           0 :   JS::AutoValueVector argv(cx);
    7480           0 :   if (!argv.resize(1)) {
    7481           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    7482           0 :     return;
    7483             :   }
    7484             :   do {
    7485           0 :     JS::ExposeValueToActiveJS(arg);
    7486           0 :     argv[0].set(arg);
    7487           0 :     if (!MaybeWrapValue(cx, argv[0])) {
    7488           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    7489           0 :       return;
    7490             :     }
    7491           0 :     break;
    7492             :   } while (0);
    7493             : 
    7494           0 :   MOZ_ASSERT(argv.length() == 1);
    7495           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    7496           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    7497           0 :       !JS_SetPropertyById(cx, CallbackKnownNotGray(), atomsCache->anyAttr_id, argv[0])) {
    7498           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7499           0 :     return;
    7500             :   }
    7501             : }
    7502             : 
    7503             : void
    7504           0 : TestInterfaceJSJSImpl::SetObjectAttr(JS::Handle<JSObject*> arg, ErrorResult& aRv, JSCompartment* aCompartment)
    7505             : {
    7506           0 :   CallSetup s(this, aRv, "TestInterfaceJS.objectAttr", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    7507           0 :   JSContext* cx = s.GetContext();
    7508           0 :   if (!cx) {
    7509           0 :     MOZ_ASSERT(aRv.Failed());
    7510           0 :     return;
    7511             :   }
    7512           0 :   JS::AutoValueVector argv(cx);
    7513           0 :   if (!argv.resize(1)) {
    7514           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    7515           0 :     return;
    7516             :   }
    7517             :   do {
    7518           0 :     JS::ExposeObjectToActiveJS(arg);
    7519           0 :     argv[0].setObject(*arg);
    7520           0 :     if (!MaybeWrapObjectValue(cx, argv[0])) {
    7521           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    7522           0 :       return;
    7523             :     }
    7524           0 :     break;
    7525             :   } while (0);
    7526             : 
    7527           0 :   MOZ_ASSERT(argv.length() == 1);
    7528           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    7529           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    7530           0 :       !JS_SetPropertyById(cx, CallbackKnownNotGray(), atomsCache->objectAttr_id, argv[0])) {
    7531           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7532           0 :     return;
    7533             :   }
    7534             : }
    7535             : 
    7536             : void
    7537           0 : TestInterfaceJSJSImpl::SetDictionaryAttr(const TestInterfaceJSDictionary& arg, ErrorResult& aRv, JSCompartment* aCompartment)
    7538             : {
    7539           0 :   CallSetup s(this, aRv, "TestInterfaceJS.dictionaryAttr", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    7540           0 :   JSContext* cx = s.GetContext();
    7541           0 :   if (!cx) {
    7542           0 :     MOZ_ASSERT(aRv.Failed());
    7543           0 :     return;
    7544             :   }
    7545           0 :   JS::AutoValueVector argv(cx);
    7546           0 :   if (!argv.resize(1)) {
    7547           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    7548           0 :     return;
    7549             :   }
    7550             :   do {
    7551           0 :     if (!arg.ToObjectInternal(cx, argv[0])) {
    7552           0 :       aRv.Throw(NS_ERROR_UNEXPECTED);
    7553           0 :       return;
    7554             :     }
    7555           0 :     break;
    7556             :   } while (0);
    7557             : 
    7558           0 :   MOZ_ASSERT(argv.length() == 1);
    7559           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    7560           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    7561           0 :       !JS_SetPropertyById(cx, CallbackKnownNotGray(), atomsCache->dictionaryAttr_id, argv[0])) {
    7562           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7563           0 :     return;
    7564             :   }
    7565             : }
    7566             : 
    7567             : void
    7568           0 : TestInterfaceJSJSImpl::SetOnsomething(EventHandlerNonNull* arg, ErrorResult& aRv, JSCompartment* aCompartment)
    7569             : {
    7570           0 :   CallSetup s(this, aRv, "TestInterfaceJS.onsomething", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ true);
    7571           0 :   JSContext* cx = s.GetContext();
    7572           0 :   if (!cx) {
    7573           0 :     MOZ_ASSERT(aRv.Failed());
    7574           0 :     return;
    7575             :   }
    7576           0 :   JS::AutoValueVector argv(cx);
    7577           0 :   if (!argv.resize(1)) {
    7578           0 :     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
    7579           0 :     return;
    7580             :   }
    7581             :   do {
    7582           0 :     if (arg) {
    7583           0 :       argv[0].setObjectOrNull(GetCallbackFromCallbackObject(arg));
    7584           0 :       if (!MaybeWrapObjectOrNullValue(cx, argv[0])) {
    7585           0 :         aRv.Throw(NS_ERROR_UNEXPECTED);
    7586           0 :         return;
    7587             :       }
    7588           0 :       break;
    7589             :     } else {
    7590           0 :       argv[0].setNull();
    7591           0 :       break;
    7592             :     }
    7593             :   } while (0);
    7594             : 
    7595           0 :   MOZ_ASSERT(argv.length() == 1);
    7596           0 :   TestInterfaceJSAtoms* atomsCache = GetAtomCache<TestInterfaceJSAtoms>(cx);
    7597           0 :   if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
    7598           0 :       !JS_SetPropertyById(cx, CallbackKnownNotGray(), atomsCache->onsomething_id, argv[0])) {
    7599           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7600           0 :     return;
    7601             :   }
    7602             : }
    7603             : 
    7604             : 
    7605           0 : NS_IMPL_CYCLE_COLLECTION_INHERITED(TestInterfaceJS, mozilla::DOMEventTargetHelper, mImpl, mParent)
    7606           0 : NS_IMPL_ADDREF_INHERITED(TestInterfaceJS, mozilla::DOMEventTargetHelper)
    7607           0 : NS_IMPL_RELEASE_INHERITED(TestInterfaceJS, mozilla::DOMEventTargetHelper)
    7608           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TestInterfaceJS)
    7609           0 : NS_INTERFACE_MAP_END_INHERITING(mozilla::DOMEventTargetHelper)
    7610             : 
    7611           0 : TestInterfaceJS::TestInterfaceJS(JS::Handle<JSObject*> aJSImplObject, nsIGlobalObject* aParent)
    7612             :   : mozilla::DOMEventTargetHelper(aParent),
    7613           0 :     mImpl(new TestInterfaceJSJSImpl(nullptr, aJSImplObject, /* aIncumbentGlobal = */ nullptr)),
    7614           0 :     mParent(aParent)
    7615             : {
    7616           0 : }
    7617             : 
    7618             : 
    7619           0 : TestInterfaceJS::~TestInterfaceJS()
    7620             : {
    7621           0 : }
    7622             : 
    7623             : nsISupports*
    7624           0 : TestInterfaceJS::GetParentObject() const
    7625             : {
    7626           0 :   return mParent;
    7627             : }
    7628             : 
    7629             : JSObject*
    7630           0 : TestInterfaceJS::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
    7631             : {
    7632           0 :   JS::Rooted<JSObject*> obj(aCx, TestInterfaceJSBinding::Wrap(aCx, this, aGivenProto));
    7633           0 :   if (!obj) {
    7634           0 :     return nullptr;
    7635             :   }
    7636             : 
    7637             :   // Now define it on our chrome object
    7638           0 :   JSAutoCompartment ac(aCx, mImpl->CallbackOrNull());
    7639           0 :   if (!JS_WrapObject(aCx, &obj)) {
    7640           0 :     return nullptr;
    7641             :   }
    7642           0 :   if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
    7643           0 :     return nullptr;
    7644             :   }
    7645           0 :   return obj;
    7646             : }
    7647             : 
    7648             : already_AddRefed<TestInterfaceJS>
    7649           0 : TestInterfaceJS::Constructor(const GlobalObject& global, JSContext* cx, JS::Handle<JS::Value> anyArg, const Optional<JS::Handle<JSObject*>>& objectArg, const TestInterfaceJSDictionary& dictionaryArg, ErrorResult& aRv)
    7650             : {
    7651           0 :   JS::Rooted<JSObject*> jsImplObj(cx);
    7652             :   nsCOMPtr<nsIGlobalObject> globalHolder =
    7653           0 :     ConstructJSImplementation("@mozilla.org/dom/test-interface-js;1", global, &jsImplObj, aRv);
    7654           0 :   if (aRv.Failed()) {
    7655           0 :     return nullptr;
    7656             :   }
    7657             :   // Build the C++ implementation.
    7658           0 :   RefPtr<TestInterfaceJS> impl = new TestInterfaceJS(jsImplObj, globalHolder);
    7659             :   // Wrap the object before calling __Init so that __DOM_IMPL__ is available.
    7660           0 :   JS::Rooted<JSObject*> scopeObj(cx, globalHolder->GetGlobalJSObject());
    7661           0 :   MOZ_ASSERT(js::IsObjectInContextCompartment(scopeObj, cx));
    7662           0 :   JS::Rooted<JS::Value> wrappedVal(cx);
    7663           0 :   if (!GetOrCreateDOMReflector(cx, impl, &wrappedVal)) {
    7664             :     //XXX Assertion disabled for now, see bug 991271.
    7665           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    7666           0 :     aRv.Throw(NS_ERROR_UNEXPECTED);
    7667           0 :     return nullptr;
    7668             :   }
    7669             :   // Initialize the object with the constructor arguments.
    7670           0 :   impl->mImpl->__Init(anyArg, objectArg, dictionaryArg, aRv, js::GetObjectCompartment(scopeObj));
    7671           0 :   if (aRv.Failed()) {
    7672           0 :     return nullptr;
    7673             :   }
    7674           0 :   return impl.forget();
    7675             : }
    7676             : 
    7677             : void
    7678           0 : TestInterfaceJS::GetAnyArg(JS::MutableHandle<JS::Value> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment) const
    7679             : {
    7680           0 :   return mImpl->GetAnyArg(aRetVal, aRv, aCompartment);
    7681             : }
    7682             : 
    7683             : void
    7684           0 : TestInterfaceJS::GetObjectArg(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment) const
    7685             : {
    7686           0 :   return mImpl->GetObjectArg(aRetVal, aRv, aCompartment);
    7687             : }
    7688             : 
    7689             : void
    7690           0 : TestInterfaceJS::GetDictionaryArg(TestInterfaceJSDictionary& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment) const
    7691             : {
    7692           0 :   return mImpl->GetDictionaryArg(aRetVal, aRv, aCompartment);
    7693             : }
    7694             : 
    7695             : void
    7696           0 : TestInterfaceJS::GetAnyAttr(JS::MutableHandle<JS::Value> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment) const
    7697             : {
    7698           0 :   return mImpl->GetAnyAttr(aRetVal, aRv, aCompartment);
    7699             : }
    7700             : 
    7701             : void
    7702           0 : TestInterfaceJS::SetAnyAttr(JS::Handle<JS::Value> arg, ErrorResult& aRv, JSCompartment* aCompartment)
    7703             : {
    7704           0 :   mImpl->SetAnyAttr(arg, aRv, aCompartment);
    7705           0 : }
    7706             : 
    7707             : void
    7708           0 : TestInterfaceJS::GetObjectAttr(JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment) const
    7709             : {
    7710           0 :   return mImpl->GetObjectAttr(aRetVal, aRv, aCompartment);
    7711             : }
    7712             : 
    7713             : void
    7714           0 : TestInterfaceJS::SetObjectAttr(JS::Handle<JSObject*> arg, ErrorResult& aRv, JSCompartment* aCompartment)
    7715             : {
    7716           0 :   mImpl->SetObjectAttr(arg, aRv, aCompartment);
    7717           0 : }
    7718             : 
    7719             : void
    7720           0 : TestInterfaceJS::GetDictionaryAttr(TestInterfaceJSDictionary& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment) const
    7721             : {
    7722           0 :   return mImpl->GetDictionaryAttr(aRetVal, aRv, aCompartment);
    7723             : }
    7724             : 
    7725             : void
    7726           0 : TestInterfaceJS::SetDictionaryAttr(const TestInterfaceJSDictionary& arg, ErrorResult& aRv, JSCompartment* aCompartment)
    7727             : {
    7728           0 :   mImpl->SetDictionaryAttr(arg, aRv, aCompartment);
    7729           0 : }
    7730             : 
    7731             : void
    7732           0 : TestInterfaceJS::PingPongAny(JS::Handle<JS::Value> arg, JS::MutableHandle<JS::Value> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    7733             : {
    7734           0 :   return mImpl->PingPongAny(arg, aRetVal, aRv, aCompartment);
    7735             : }
    7736             : 
    7737             : void
    7738           0 : TestInterfaceJS::PingPongObject(JS::Handle<JSObject*> obj, JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    7739             : {
    7740           0 :   return mImpl->PingPongObject(obj, aRetVal, aRv, aCompartment);
    7741             : }
    7742             : 
    7743             : void
    7744           0 : TestInterfaceJS::PingPongObjectOrString(const ObjectOrString& objOrString, JS::MutableHandle<JS::Value> aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    7745             : {
    7746           0 :   return mImpl->PingPongObjectOrString(objOrString, aRetVal, aRv, aCompartment);
    7747             : }
    7748             : 
    7749             : void
    7750           0 : TestInterfaceJS::PingPongDictionary(const TestInterfaceJSDictionary& dict, TestInterfaceJSDictionary& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    7751             : {
    7752           0 :   return mImpl->PingPongDictionary(dict, aRetVal, aRv, aCompartment);
    7753             : }
    7754             : 
    7755             : int32_t
    7756           0 : TestInterfaceJS::PingPongDictionaryOrLong(const TestInterfaceJSUnionableDictionaryOrLong& dictOrLong, ErrorResult& aRv, JSCompartment* aCompartment)
    7757             : {
    7758           0 :   return mImpl->PingPongDictionaryOrLong(dictOrLong, aRv, aCompartment);
    7759             : }
    7760             : 
    7761             : void
    7762           0 : TestInterfaceJS::PingPongMap(const Record<nsString, JS::Value>& map, nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    7763             : {
    7764           0 :   return mImpl->PingPongMap(map, aRetVal, aRv, aCompartment);
    7765             : }
    7766             : 
    7767             : int32_t
    7768           0 : TestInterfaceJS::ObjectSequenceLength(const Sequence<JSObject*>& seq, ErrorResult& aRv, JSCompartment* aCompartment)
    7769             : {
    7770           0 :   return mImpl->ObjectSequenceLength(seq, aRv, aCompartment);
    7771             : }
    7772             : 
    7773             : int32_t
    7774           0 : TestInterfaceJS::AnySequenceLength(const Sequence<JS::Value>& seq, ErrorResult& aRv, JSCompartment* aCompartment)
    7775             : {
    7776           0 :   return mImpl->AnySequenceLength(seq, aRv, aCompartment);
    7777             : }
    7778             : 
    7779             : void
    7780           0 : TestInterfaceJS::GetCallerPrincipal(nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    7781             : {
    7782           0 :   return mImpl->GetCallerPrincipal(aRetVal, aRv, aCompartment);
    7783             : }
    7784             : 
    7785             : void
    7786           0 : TestInterfaceJS::ConvertSVS(const nsAString& svs, nsString& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    7787             : {
    7788           0 :   return mImpl->ConvertSVS(svs, aRetVal, aRv, aCompartment);
    7789             : }
    7790             : 
    7791             : void
    7792           0 : TestInterfaceJS::PingPongUnion(const TestInterfaceJSOrLong& something, OwningTestInterfaceJSOrLong& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    7793             : {
    7794           0 :   return mImpl->PingPongUnion(something, aRetVal, aRv, aCompartment);
    7795             : }
    7796             : 
    7797             : void
    7798           0 : TestInterfaceJS::PingPongUnionContainingNull(const TestInterfaceJSOrNullOrString& something, OwningStringOrTestInterfaceJSOrNull& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    7799             : {
    7800           0 :   return mImpl->PingPongUnionContainingNull(something, aRetVal, aRv, aCompartment);
    7801             : }
    7802             : 
    7803             : void
    7804           0 : TestInterfaceJS::PingPongNullableUnion(const Nullable<TestInterfaceJSOrLong>& something, Nullable<OwningTestInterfaceJSOrLong>& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    7805             : {
    7806           0 :   return mImpl->PingPongNullableUnion(something, aRetVal, aRv, aCompartment);
    7807             : }
    7808             : 
    7809             : void
    7810           0 : TestInterfaceJS::ReturnBadUnion(OwningLocationOrTestInterfaceJS& aRetVal, ErrorResult& aRv, JSCompartment* aCompartment)
    7811             : {
    7812           0 :   return mImpl->ReturnBadUnion(aRetVal, aRv, aCompartment);
    7813             : }
    7814             : 
    7815             : int16_t
    7816           0 : TestInterfaceJS::GetCachedAttr(ErrorResult& aRv, JSCompartment* aCompartment) const
    7817             : {
    7818           0 :   return mImpl->GetCachedAttr(aRv, aCompartment);
    7819             : }
    7820             : 
    7821             : void
    7822           0 : TestInterfaceJS::SetCachedAttr(int16_t n, ErrorResult& aRv, JSCompartment* aCompartment)
    7823             : {
    7824           0 :   return mImpl->SetCachedAttr(n, aRv, aCompartment);
    7825             : }
    7826             : 
    7827             : void
    7828           0 : TestInterfaceJS::ClearCachedAttrCache(ErrorResult& aRv, JSCompartment* aCompartment)
    7829             : {
    7830           0 :   return mImpl->ClearCachedAttrCache(aRv, aCompartment);
    7831             : }
    7832             : 
    7833             : void
    7834           0 : TestInterfaceJS::TestSequenceOverload(const Sequence<nsString>& arg, ErrorResult& aRv, JSCompartment* aCompartment)
    7835             : {
    7836           0 :   return mImpl->TestSequenceOverload(arg, aRv, aCompartment);
    7837             : }
    7838             : 
    7839             : void
    7840           0 : TestInterfaceJS::TestSequenceOverload(const nsAString& arg, ErrorResult& aRv, JSCompartment* aCompartment)
    7841             : {
    7842           0 :   return mImpl->TestSequenceOverload(arg, aRv, aCompartment);
    7843             : }
    7844             : 
    7845             : void
    7846           0 : TestInterfaceJS::TestSequenceUnion(const StringSequenceOrString& arg, ErrorResult& aRv, JSCompartment* aCompartment)
    7847             : {
    7848           0 :   return mImpl->TestSequenceUnion(arg, aRv, aCompartment);
    7849             : }
    7850             : 
    7851             : void
    7852           0 : TestInterfaceJS::TestThrowError(ErrorResult& aRv, JSCompartment* aCompartment)
    7853             : {
    7854           0 :   return mImpl->TestThrowError(aRv, aCompartment);
    7855             : }
    7856             : 
    7857             : void
    7858           0 : TestInterfaceJS::TestThrowDOMException(ErrorResult& aRv, JSCompartment* aCompartment)
    7859             : {
    7860           0 :   return mImpl->TestThrowDOMException(aRv, aCompartment);
    7861             : }
    7862             : 
    7863             : void
    7864           0 : TestInterfaceJS::TestThrowTypeError(ErrorResult& aRv, JSCompartment* aCompartment)
    7865             : {
    7866           0 :   return mImpl->TestThrowTypeError(aRv, aCompartment);
    7867             : }
    7868             : 
    7869             : void
    7870           0 : TestInterfaceJS::TestThrowCallbackError(Function& callback, ErrorResult& aRv, JSCompartment* aCompartment)
    7871             : {
    7872           0 :   return mImpl->TestThrowCallbackError(callback, aRv, aCompartment);
    7873             : }
    7874             : 
    7875             : void
    7876           0 : TestInterfaceJS::TestThrowXraySelfHosted(ErrorResult& aRv, JSCompartment* aCompartment)
    7877             : {
    7878           0 :   return mImpl->TestThrowXraySelfHosted(aRv, aCompartment);
    7879             : }
    7880             : 
    7881             : void
    7882           0 : TestInterfaceJS::TestThrowSelfHosted(ErrorResult& aRv, JSCompartment* aCompartment)
    7883             : {
    7884           0 :   return mImpl->TestThrowSelfHosted(aRv, aCompartment);
    7885             : }
    7886             : 
    7887             : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
    7888             : already_AddRefed<Promise>
    7889           0 : TestInterfaceJS::TestPromiseWithThrowingChromePromiseInit(ErrorResult& aRv, JSCompartment* aCompartment)
    7890             : {
    7891           0 :   return mImpl->TestPromiseWithThrowingChromePromiseInit(aRv, aCompartment);
    7892             : }
    7893             : 
    7894             : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
    7895             : already_AddRefed<Promise>
    7896           0 : TestInterfaceJS::TestPromiseWithThrowingContentPromiseInit(Function& func, ErrorResult& aRv, JSCompartment* aCompartment)
    7897             : {
    7898           0 :   return mImpl->TestPromiseWithThrowingContentPromiseInit(func, aRv, aCompartment);
    7899             : }
    7900             : 
    7901             : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
    7902             : already_AddRefed<Promise>
    7903           0 : TestInterfaceJS::TestPromiseWithDOMExceptionThrowingPromiseInit(ErrorResult& aRv, JSCompartment* aCompartment)
    7904             : {
    7905           0 :   return mImpl->TestPromiseWithDOMExceptionThrowingPromiseInit(aRv, aCompartment);
    7906             : }
    7907             : 
    7908             : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
    7909             : already_AddRefed<Promise>
    7910           0 : TestInterfaceJS::TestPromiseWithThrowingChromeThenFunction(ErrorResult& aRv, JSCompartment* aCompartment)
    7911             : {
    7912           0 :   return mImpl->TestPromiseWithThrowingChromeThenFunction(aRv, aCompartment);
    7913             : }
    7914             : 
    7915             : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
    7916             : already_AddRefed<Promise>
    7917           0 : TestInterfaceJS::TestPromiseWithThrowingContentThenFunction(AnyCallback& func, ErrorResult& aRv, JSCompartment* aCompartment)
    7918             : {
    7919           0 :   return mImpl->TestPromiseWithThrowingContentThenFunction(func, aRv, aCompartment);
    7920             : }
    7921             : 
    7922             : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
    7923             : already_AddRefed<Promise>
    7924           0 : TestInterfaceJS::TestPromiseWithDOMExceptionThrowingThenFunction(ErrorResult& aRv, JSCompartment* aCompartment)
    7925             : {
    7926           0 :   return mImpl->TestPromiseWithDOMExceptionThrowingThenFunction(aRv, aCompartment);
    7927             : }
    7928             : 
    7929             : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
    7930             : already_AddRefed<Promise>
    7931           0 : TestInterfaceJS::TestPromiseWithThrowingChromeThenable(ErrorResult& aRv, JSCompartment* aCompartment)
    7932             : {
    7933           0 :   return mImpl->TestPromiseWithThrowingChromeThenable(aRv, aCompartment);
    7934             : }
    7935             : 
    7936             : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
    7937             : already_AddRefed<Promise>
    7938           0 : TestInterfaceJS::TestPromiseWithThrowingContentThenable(JS::Handle<JSObject*> thenable, ErrorResult& aRv, JSCompartment* aCompartment)
    7939             : {
    7940           0 :   return mImpl->TestPromiseWithThrowingContentThenable(thenable, aRv, aCompartment);
    7941             : }
    7942             : 
    7943             : // Return a raw pointer here to avoid refcounting, but make sure it's safe (the object should be kept alive by the callee).
    7944             : already_AddRefed<Promise>
    7945           0 : TestInterfaceJS::TestPromiseWithDOMExceptionThrowingThenable(ErrorResult& aRv, JSCompartment* aCompartment)
    7946             : {
    7947           0 :   return mImpl->TestPromiseWithDOMExceptionThrowingThenable(aRv, aCompartment);
    7948             : }
    7949             : 
    7950             : already_AddRefed<EventHandlerNonNull>
    7951           0 : TestInterfaceJS::GetOnsomething(ErrorResult& aRv, JSCompartment* aCompartment) const
    7952             : {
    7953           0 :   return mImpl->GetOnsomething(aRv, aCompartment);
    7954             : }
    7955             : 
    7956             : void
    7957           0 : TestInterfaceJS::SetOnsomething(EventHandlerNonNull* arg, ErrorResult& aRv, JSCompartment* aCompartment)
    7958             : {
    7959           0 :   mImpl->SetOnsomething(arg, aRv, aCompartment);
    7960           0 : }
    7961             : 
    7962             : bool
    7963           0 : TestInterfaceJS::_Create(JSContext* cx, unsigned argc, JS::Value* vp)
    7964             : {
    7965           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    7966           0 :   if (args.length() < 2) {
    7967           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "TestInterfaceJS._create");
    7968             :   }
    7969           0 :   if (!args[0].isObject()) {
    7970           0 :     return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of TestInterfaceJS._create");
    7971             :   }
    7972           0 :   if (!args[1].isObject()) {
    7973           0 :     return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of TestInterfaceJS._create");
    7974             :   }
    7975             : 
    7976             :   // GlobalObject will go through wrappers as needed for us, and
    7977             :   // is simpler than the right UnwrapArg incantation.
    7978           0 :   GlobalObject global(cx, &args[0].toObject());
    7979           0 :   if (global.Failed()) {
    7980           0 :     return false;
    7981             :   }
    7982           0 :   nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports());
    7983           0 :   MOZ_ASSERT(globalHolder);
    7984           0 :   JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
    7985           0 :   RefPtr<TestInterfaceJS> impl = new TestInterfaceJS(arg, globalHolder);
    7986           0 :   MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
    7987           0 :   return GetOrCreateDOMReflector(cx, impl, args.rval());
    7988             : }
    7989             : 
    7990             : 
    7991             : } // namespace dom
    7992             : } // namespace mozilla

Generated by: LCOV version 1.13