LCOV - code coverage report
Current view: top level - obj-x86_64-pc-linux-gnu/dom/bindings - EventTargetBinding.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 206 610 33.8 %
Date: 2017-07-14 16:53:18 Functions: 15 57 26.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* THIS FILE IS AUTOGENERATED FROM EventTarget.webidl BY Codegen.py - DO NOT EDIT */
       2             : 
       3             : #include "AtomList.h"
       4             : #include "EventHandlerBinding.h"
       5             : #include "EventListenerBinding.h"
       6             : #include "EventTargetBinding.h"
       7             : #include "WrapperFactory.h"
       8             : #include "mozilla/OwningNonNull.h"
       9             : #include "mozilla/dom/BindingUtils.h"
      10             : #include "mozilla/dom/DOMJSClass.h"
      11             : #include "mozilla/dom/Event.h"
      12             : #include "mozilla/dom/EventTarget.h"
      13             : #include "mozilla/dom/NonRefcountedDOMObject.h"
      14             : #include "mozilla/dom/Nullable.h"
      15             : #include "mozilla/dom/PrimitiveConversions.h"
      16             : #include "mozilla/dom/ScriptSettings.h"
      17             : #include "mozilla/dom/SimpleGlobalObject.h"
      18             : #include "mozilla/dom/UnionConversions.h"
      19             : #include "mozilla/dom/XrayExpandoClass.h"
      20             : #include "nsContentUtils.h"
      21             : #include "nsIDOMEventTarget.h"
      22             : #include "nsPIDOMWindow.h"
      23             : #include "xpcprivate.h"
      24             : 
      25             : namespace mozilla {
      26             : namespace dom {
      27             : 
      28             : 
      29           0 : EventListenerOptions::EventListenerOptions()
      30             : {
      31             :   // Safe to pass a null context if we pass a null value
      32           0 :   Init(nullptr, JS::NullHandleValue);
      33           0 : }
      34             : 
      35             : 
      36             : 
      37             : bool
      38           2 : EventListenerOptions::InitIds(JSContext* cx, EventListenerOptionsAtoms* atomsCache)
      39             : {
      40           2 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
      41             : 
      42             :   // Initialize these in reverse order so that any failure leaves the first one
      43             :   // uninitialized.
      44           4 :   if (!atomsCache->mozSystemGroup_id.init(cx, "mozSystemGroup") ||
      45           2 :       !atomsCache->capture_id.init(cx, "capture")) {
      46           0 :     return false;
      47             :   }
      48           2 :   return true;
      49             : }
      50             : 
      51             : bool
      52         143 : EventListenerOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
      53             : {
      54             :   // Passing a null JSContext is OK only if we're initing from null,
      55             :   // Since in that case we will not have to do any property gets
      56             :   // Also evaluate isNullOrUndefined in order to avoid false-positive
      57             :   // checkers by static analysis tools
      58         143 :   MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
      59         143 :   EventListenerOptionsAtoms* atomsCache = nullptr;
      60         143 :   if (cx) {
      61         143 :     atomsCache = GetAtomCache<EventListenerOptionsAtoms>(cx);
      62         143 :     if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
      63           0 :       return false;
      64             :     }
      65             :   }
      66             : 
      67         143 :   if (!IsConvertibleToDictionary(val)) {
      68           0 :     return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
      69             :   }
      70             : 
      71         143 :   bool isNull = val.isNullOrUndefined();
      72             :   // We only need these if !isNull, in which case we have |cx|.
      73         286 :   Maybe<JS::Rooted<JSObject *> > object;
      74         286 :   Maybe<JS::Rooted<JS::Value> > temp;
      75         143 :   if (!isNull) {
      76           6 :     MOZ_ASSERT(cx);
      77           6 :     object.emplace(cx, &val.toObject());
      78           6 :     temp.emplace(cx);
      79             :   }
      80         143 :   if (!isNull) {
      81           6 :     if (!JS_GetPropertyById(cx, *object, atomsCache->capture_id, temp.ptr())) {
      82           0 :       return false;
      83             :     }
      84             :   }
      85         143 :   if (!isNull && !temp->isUndefined()) {
      86           0 :     if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mCapture)) {
      87           0 :       return false;
      88             :     }
      89             :   } else {
      90         143 :     mCapture = false;
      91             :   }
      92         143 :   mIsAnyMemberPresent = true;
      93             : 
      94         143 :   if (!isNull) {
      95           6 :     if (ThreadSafeIsChromeOrXBL(cx, *object)) {
      96           5 :       if (!JS_GetPropertyById(cx, *object, atomsCache->mozSystemGroup_id, temp.ptr())) {
      97           0 :         return false;
      98             :       }
      99             :     } else {
     100           1 :       temp->setUndefined();
     101             :     }
     102             :   }
     103         143 :   if (!isNull && !temp->isUndefined()) {
     104           0 :     if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mMozSystemGroup)) {
     105           0 :       return false;
     106             :     }
     107             :   } else {
     108         143 :     mMozSystemGroup = false;
     109             :   }
     110         143 :   mIsAnyMemberPresent = true;
     111         143 :   return true;
     112             : }
     113             : 
     114             : bool
     115           0 : EventListenerOptions::Init(const nsAString& aJSON)
     116             : {
     117           0 :   AutoJSAPI jsapi;
     118           0 :   JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
     119           0 :   if (!cleanGlobal) {
     120           0 :     return false;
     121             :   }
     122           0 :   if (!jsapi.Init(cleanGlobal)) {
     123           0 :     return false;
     124             :   }
     125           0 :   JSContext* cx = jsapi.cx();
     126           0 :   JS::Rooted<JS::Value> json(cx);
     127           0 :   bool ok = ParseJSON(cx, aJSON, &json);
     128           0 :   NS_ENSURE_TRUE(ok, false);
     129           0 :   return Init(cx, json);
     130             : }
     131             : 
     132             : bool
     133           0 : EventListenerOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
     134             : {
     135           0 :   EventListenerOptionsAtoms* atomsCache = GetAtomCache<EventListenerOptionsAtoms>(cx);
     136           0 :   if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     137           0 :     return false;
     138             :   }
     139             : 
     140           0 :   JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
     141           0 :   if (!obj) {
     142           0 :     return false;
     143             :   }
     144           0 :   rval.set(JS::ObjectValue(*obj));
     145             : 
     146             :   do {
     147             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     148           0 :     JS::Rooted<JS::Value> temp(cx);
     149           0 :     bool const & currentValue = mCapture;
     150           0 :     temp.setBoolean(currentValue);
     151           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->capture_id, temp, JSPROP_ENUMERATE)) {
     152           0 :       return false;
     153             :     }
     154           0 :     break;
     155             :   } while(0);
     156             : 
     157           0 :   if (ThreadSafeIsChromeOrXBL(cx, obj)) {
     158             :     do {
     159             :       // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     160           0 :       JS::Rooted<JS::Value> temp(cx);
     161           0 :       bool const & currentValue = mMozSystemGroup;
     162           0 :       temp.setBoolean(currentValue);
     163           0 :       if (!JS_DefinePropertyById(cx, obj, atomsCache->mozSystemGroup_id, temp, JSPROP_ENUMERATE)) {
     164           0 :         return false;
     165             :       }
     166           0 :       break;
     167             :     } while(0);
     168             :   }
     169             : 
     170           0 :   return true;
     171             : }
     172             : 
     173             : bool
     174           0 : EventListenerOptions::ToJSON(nsAString& aJSON) const
     175             : {
     176           0 :   AutoJSAPI jsapi;
     177           0 :   jsapi.Init();
     178           0 :   JSContext *cx = jsapi.cx();
     179             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
     180             :   // because we'll only be creating objects, in ways that have no
     181             :   // side-effects, followed by a call to JS::ToJSONMaybeSafely,
     182             :   // which likewise guarantees no side-effects for the sorts of
     183             :   // things we will pass it.
     184           0 :   JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
     185           0 :   JS::Rooted<JS::Value> val(cx);
     186           0 :   if (!ToObjectInternal(cx, &val)) {
     187           0 :     return false;
     188             :   }
     189           0 :   JS::Rooted<JSObject*> obj(cx, &val.toObject());
     190           0 :   return StringifyToJSON(cx, obj, aJSON);
     191             : }
     192             : 
     193             : void
     194           0 : EventListenerOptions::TraceDictionary(JSTracer* trc)
     195             : {
     196           0 : }
     197             : 
     198             : EventListenerOptions&
     199           0 : EventListenerOptions::operator=(const EventListenerOptions& aOther)
     200             : {
     201           0 :   mCapture = aOther.mCapture;
     202           0 :   mMozSystemGroup = aOther.mMozSystemGroup;
     203           0 :   return *this;
     204             : }
     205             : 
     206             : namespace binding_detail {
     207             : } // namespace binding_detail
     208             : 
     209             : 
     210             : 
     211           0 : AddEventListenerOptions::AddEventListenerOptions()
     212           0 :   : EventListenerOptions(FastDictionaryInitializer())
     213             : {
     214             :   // Safe to pass a null context if we pass a null value
     215           0 :   Init(nullptr, JS::NullHandleValue);
     216           0 : }
     217             : 
     218             : 
     219             : 
     220             : bool
     221           2 : AddEventListenerOptions::InitIds(JSContext* cx, AddEventListenerOptionsAtoms* atomsCache)
     222             : {
     223           2 :   MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
     224             : 
     225             :   // Initialize these in reverse order so that any failure leaves the first one
     226             :   // uninitialized.
     227           4 :   if (!atomsCache->passive_id.init(cx, "passive") ||
     228           2 :       !atomsCache->once_id.init(cx, "once")) {
     229           0 :     return false;
     230             :   }
     231           2 :   return true;
     232             : }
     233             : 
     234             : bool
     235         135 : AddEventListenerOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
     236             : {
     237             :   // Passing a null JSContext is OK only if we're initing from null,
     238             :   // Since in that case we will not have to do any property gets
     239             :   // Also evaluate isNullOrUndefined in order to avoid false-positive
     240             :   // checkers by static analysis tools
     241         135 :   MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
     242         135 :   AddEventListenerOptionsAtoms* atomsCache = nullptr;
     243         135 :   if (cx) {
     244         135 :     atomsCache = GetAtomCache<AddEventListenerOptionsAtoms>(cx);
     245         135 :     if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     246           0 :       return false;
     247             :     }
     248             :   }
     249             : 
     250             :   // Per spec, we init the parent's members first
     251         135 :   if (!EventListenerOptions::Init(cx, val)) {
     252           0 :     return false;
     253             :   }
     254             : 
     255         135 :   bool isNull = val.isNullOrUndefined();
     256             :   // We only need these if !isNull, in which case we have |cx|.
     257         270 :   Maybe<JS::Rooted<JSObject *> > object;
     258         270 :   Maybe<JS::Rooted<JS::Value> > temp;
     259         135 :   if (!isNull) {
     260           6 :     MOZ_ASSERT(cx);
     261           6 :     object.emplace(cx, &val.toObject());
     262           6 :     temp.emplace(cx);
     263             :   }
     264         135 :   if (!isNull) {
     265           6 :     if (!JS_GetPropertyById(cx, *object, atomsCache->once_id, temp.ptr())) {
     266           0 :       return false;
     267             :     }
     268             :   }
     269         135 :   if (!isNull && !temp->isUndefined()) {
     270           6 :     if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mOnce)) {
     271           0 :       return false;
     272             :     }
     273             :   } else {
     274         129 :     mOnce = false;
     275             :   }
     276         135 :   mIsAnyMemberPresent = true;
     277             : 
     278         135 :   if (!isNull) {
     279           6 :     if (!JS_GetPropertyById(cx, *object, atomsCache->passive_id, temp.ptr())) {
     280           0 :       return false;
     281             :     }
     282             :   }
     283         135 :   if (!isNull && !temp->isUndefined()) {
     284           0 :     if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mPassive)) {
     285           0 :       return false;
     286             :     }
     287             :   } else {
     288         135 :     mPassive = false;
     289             :   }
     290         135 :   mIsAnyMemberPresent = true;
     291         135 :   return true;
     292             : }
     293             : 
     294             : bool
     295           0 : AddEventListenerOptions::Init(const nsAString& aJSON)
     296             : {
     297           0 :   AutoJSAPI jsapi;
     298           0 :   JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
     299           0 :   if (!cleanGlobal) {
     300           0 :     return false;
     301             :   }
     302           0 :   if (!jsapi.Init(cleanGlobal)) {
     303           0 :     return false;
     304             :   }
     305           0 :   JSContext* cx = jsapi.cx();
     306           0 :   JS::Rooted<JS::Value> json(cx);
     307           0 :   bool ok = ParseJSON(cx, aJSON, &json);
     308           0 :   NS_ENSURE_TRUE(ok, false);
     309           0 :   return Init(cx, json);
     310             : }
     311             : 
     312             : bool
     313           0 : AddEventListenerOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
     314             : {
     315           0 :   AddEventListenerOptionsAtoms* atomsCache = GetAtomCache<AddEventListenerOptionsAtoms>(cx);
     316           0 :   if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
     317           0 :     return false;
     318             :   }
     319             : 
     320             :   // Per spec, we define the parent's members first
     321           0 :   if (!EventListenerOptions::ToObjectInternal(cx, rval)) {
     322           0 :     return false;
     323             :   }
     324           0 :   JS::Rooted<JSObject*> obj(cx, &rval.toObject());
     325             : 
     326             :   do {
     327             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     328           0 :     JS::Rooted<JS::Value> temp(cx);
     329           0 :     bool const & currentValue = mOnce;
     330           0 :     temp.setBoolean(currentValue);
     331           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->once_id, temp, JSPROP_ENUMERATE)) {
     332           0 :       return false;
     333             :     }
     334           0 :     break;
     335             :   } while(0);
     336             : 
     337             :   do {
     338             :     // block for our 'break' successCode and scope for 'temp' and 'currentValue'
     339           0 :     JS::Rooted<JS::Value> temp(cx);
     340           0 :     bool const & currentValue = mPassive;
     341           0 :     temp.setBoolean(currentValue);
     342           0 :     if (!JS_DefinePropertyById(cx, obj, atomsCache->passive_id, temp, JSPROP_ENUMERATE)) {
     343           0 :       return false;
     344             :     }
     345           0 :     break;
     346             :   } while(0);
     347             : 
     348           0 :   return true;
     349             : }
     350             : 
     351             : bool
     352           0 : AddEventListenerOptions::ToJSON(nsAString& aJSON) const
     353             : {
     354           0 :   AutoJSAPI jsapi;
     355           0 :   jsapi.Init();
     356           0 :   JSContext *cx = jsapi.cx();
     357             :   // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
     358             :   // because we'll only be creating objects, in ways that have no
     359             :   // side-effects, followed by a call to JS::ToJSONMaybeSafely,
     360             :   // which likewise guarantees no side-effects for the sorts of
     361             :   // things we will pass it.
     362           0 :   JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
     363           0 :   JS::Rooted<JS::Value> val(cx);
     364           0 :   if (!ToObjectInternal(cx, &val)) {
     365           0 :     return false;
     366             :   }
     367           0 :   JS::Rooted<JSObject*> obj(cx, &val.toObject());
     368           0 :   return StringifyToJSON(cx, obj, aJSON);
     369             : }
     370             : 
     371             : void
     372           0 : AddEventListenerOptions::TraceDictionary(JSTracer* trc)
     373             : {
     374           0 :   EventListenerOptions::TraceDictionary(trc);
     375           0 : }
     376             : 
     377             : AddEventListenerOptions&
     378           0 : AddEventListenerOptions::operator=(const AddEventListenerOptions& aOther)
     379             : {
     380           0 :   EventListenerOptions::operator=(aOther);
     381           0 :   mOnce = aOther.mOnce;
     382           0 :   mPassive = aOther.mPassive;
     383           0 :   return *this;
     384             : }
     385             : 
     386             : namespace binding_detail {
     387             : } // namespace binding_detail
     388             : 
     389             : 
     390             : bool
     391           0 : EventListenerOptionsOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
     392             : {
     393           0 :   switch (mType) {
     394             :     case eUninitialized: {
     395           0 :       return false;
     396             :       break;
     397             :     }
     398             :     case eEventListenerOptions: {
     399           0 :       if (!mValue.mEventListenerOptions.Value().ToObjectInternal(cx, rval)) {
     400           0 :         return false;
     401             :       }
     402           0 :       return true;
     403             :       break;
     404             :     }
     405             :     case eBoolean: {
     406           0 :       rval.setBoolean(mValue.mBoolean.Value());
     407           0 :       return true;
     408             :       break;
     409             :     }
     410             :     default: {
     411           0 :       return false;
     412             :       break;
     413             :     }
     414             :   }
     415             : 
     416             :   return false;
     417             : }
     418             : 
     419             : 
     420             : EventListenerOptions&
     421           0 : OwningEventListenerOptionsOrBoolean::RawSetAsEventListenerOptions()
     422             : {
     423           0 :   if (mType == eEventListenerOptions) {
     424           0 :     return mValue.mEventListenerOptions.Value();
     425             :   }
     426           0 :   MOZ_ASSERT(mType == eUninitialized);
     427           0 :   mType = eEventListenerOptions;
     428           0 :   return mValue.mEventListenerOptions.SetValue();
     429             : }
     430             : 
     431             : EventListenerOptions&
     432           0 : OwningEventListenerOptionsOrBoolean::SetAsEventListenerOptions()
     433             : {
     434           0 :   if (mType == eEventListenerOptions) {
     435           0 :     return mValue.mEventListenerOptions.Value();
     436             :   }
     437           0 :   Uninit();
     438           0 :   mType = eEventListenerOptions;
     439           0 :   return mValue.mEventListenerOptions.SetValue();
     440             : }
     441             : 
     442             : bool
     443           0 : OwningEventListenerOptionsOrBoolean::TrySetToEventListenerOptions(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
     444             : {
     445           0 :   tryNext = false;
     446             :   { // scope for memberSlot
     447           0 :     EventListenerOptions& memberSlot = RawSetAsEventListenerOptions();
     448           0 :     if (!IsConvertibleToDictionary(value)) {
     449           0 :       DestroyEventListenerOptions();
     450           0 :       tryNext = true;
     451           0 :       return true;
     452             :     }
     453           0 :     if (!memberSlot.Init(cx, value,  "Member of EventListenerOptionsOrBoolean", passedToJSImpl)) {
     454           0 :       return false;
     455             :     }
     456             :   }
     457           0 :   return true;
     458             : }
     459             : 
     460             : void
     461           0 : OwningEventListenerOptionsOrBoolean::DestroyEventListenerOptions()
     462             : {
     463           0 :   MOZ_ASSERT(IsEventListenerOptions(), "Wrong type!");
     464           0 :   mValue.mEventListenerOptions.Destroy();
     465           0 :   mType = eUninitialized;
     466           0 : }
     467             : 
     468             : 
     469             : 
     470             : 
     471             : bool&
     472           0 : OwningEventListenerOptionsOrBoolean::RawSetAsBoolean()
     473             : {
     474           0 :   if (mType == eBoolean) {
     475           0 :     return mValue.mBoolean.Value();
     476             :   }
     477           0 :   MOZ_ASSERT(mType == eUninitialized);
     478           0 :   mType = eBoolean;
     479           0 :   return mValue.mBoolean.SetValue();
     480             : }
     481             : 
     482             : bool&
     483           0 : OwningEventListenerOptionsOrBoolean::SetAsBoolean()
     484             : {
     485           0 :   if (mType == eBoolean) {
     486           0 :     return mValue.mBoolean.Value();
     487             :   }
     488           0 :   Uninit();
     489           0 :   mType = eBoolean;
     490           0 :   return mValue.mBoolean.SetValue();
     491             : }
     492             : 
     493             : bool
     494           0 : OwningEventListenerOptionsOrBoolean::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
     495             : {
     496           0 :   tryNext = false;
     497             :   { // scope for memberSlot
     498           0 :     bool& memberSlot = RawSetAsBoolean();
     499           0 :     if (!ValueToPrimitive<bool, eDefault>(cx, value, &memberSlot)) {
     500           0 :       return false;
     501             :     }
     502             :   }
     503           0 :   return true;
     504             : }
     505             : 
     506             : void
     507           0 : OwningEventListenerOptionsOrBoolean::DestroyBoolean()
     508             : {
     509           0 :   MOZ_ASSERT(IsBoolean(), "Wrong type!");
     510           0 :   mValue.mBoolean.Destroy();
     511           0 :   mType = eUninitialized;
     512           0 : }
     513             : 
     514             : 
     515             : 
     516             : 
     517             : void
     518           0 : OwningEventListenerOptionsOrBoolean::Uninit()
     519             : {
     520           0 :   switch (mType) {
     521             :     case eUninitialized: {
     522           0 :       break;
     523             :     }
     524             :     case eEventListenerOptions: {
     525           0 :       DestroyEventListenerOptions();
     526           0 :       break;
     527             :     }
     528             :     case eBoolean: {
     529           0 :       DestroyBoolean();
     530           0 :       break;
     531             :     }
     532             :   }
     533           0 : }
     534             : 
     535             : bool
     536           0 : OwningEventListenerOptionsOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
     537             : {
     538           0 :   switch (mType) {
     539             :     case eUninitialized: {
     540           0 :       return false;
     541             :       break;
     542             :     }
     543             :     case eEventListenerOptions: {
     544           0 :       if (!mValue.mEventListenerOptions.Value().ToObjectInternal(cx, rval)) {
     545           0 :         return false;
     546             :       }
     547           0 :       return true;
     548             :       break;
     549             :     }
     550             :     case eBoolean: {
     551           0 :       rval.setBoolean(mValue.mBoolean.Value());
     552           0 :       return true;
     553             :       break;
     554             :     }
     555             :     default: {
     556           0 :       return false;
     557             :       break;
     558             :     }
     559             :   }
     560             : 
     561             :   return false;
     562             : }
     563             : 
     564             : void
     565           0 : OwningEventListenerOptionsOrBoolean::TraceUnion(JSTracer* trc)
     566             : {
     567           0 : }
     568             : 
     569             : OwningEventListenerOptionsOrBoolean&
     570           0 : OwningEventListenerOptionsOrBoolean::operator=(const OwningEventListenerOptionsOrBoolean& aOther)
     571             : {
     572           0 :   switch (aOther.mType) {
     573             :     case eUninitialized: {
     574           0 :       MOZ_ASSERT(mType == eUninitialized,
     575             :                  "We need to destroy ourselves?");
     576           0 :       break;
     577             :     }
     578             :     case eEventListenerOptions: {
     579           0 :       SetAsEventListenerOptions() = aOther.GetAsEventListenerOptions();
     580           0 :       break;
     581             :     }
     582             :     case eBoolean: {
     583           0 :       SetAsBoolean() = aOther.GetAsBoolean();
     584           0 :       break;
     585             :     }
     586             :   }
     587           0 :   return *this;
     588             : }
     589             : 
     590             : 
     591             : bool
     592           0 : AddEventListenerOptionsOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
     593             : {
     594           0 :   switch (mType) {
     595             :     case eUninitialized: {
     596           0 :       return false;
     597             :       break;
     598             :     }
     599             :     case eAddEventListenerOptions: {
     600           0 :       if (!mValue.mAddEventListenerOptions.Value().ToObjectInternal(cx, rval)) {
     601           0 :         return false;
     602             :       }
     603           0 :       return true;
     604             :       break;
     605             :     }
     606             :     case eBoolean: {
     607           0 :       rval.setBoolean(mValue.mBoolean.Value());
     608           0 :       return true;
     609             :       break;
     610             :     }
     611             :     default: {
     612           0 :       return false;
     613             :       break;
     614             :     }
     615             :   }
     616             : 
     617             :   return false;
     618             : }
     619             : 
     620             : 
     621             : AddEventListenerOptions&
     622           0 : OwningAddEventListenerOptionsOrBoolean::RawSetAsAddEventListenerOptions()
     623             : {
     624           0 :   if (mType == eAddEventListenerOptions) {
     625           0 :     return mValue.mAddEventListenerOptions.Value();
     626             :   }
     627           0 :   MOZ_ASSERT(mType == eUninitialized);
     628           0 :   mType = eAddEventListenerOptions;
     629           0 :   return mValue.mAddEventListenerOptions.SetValue();
     630             : }
     631             : 
     632             : AddEventListenerOptions&
     633           0 : OwningAddEventListenerOptionsOrBoolean::SetAsAddEventListenerOptions()
     634             : {
     635           0 :   if (mType == eAddEventListenerOptions) {
     636           0 :     return mValue.mAddEventListenerOptions.Value();
     637             :   }
     638           0 :   Uninit();
     639           0 :   mType = eAddEventListenerOptions;
     640           0 :   return mValue.mAddEventListenerOptions.SetValue();
     641             : }
     642             : 
     643             : bool
     644           0 : OwningAddEventListenerOptionsOrBoolean::TrySetToAddEventListenerOptions(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
     645             : {
     646           0 :   tryNext = false;
     647             :   { // scope for memberSlot
     648           0 :     AddEventListenerOptions& memberSlot = RawSetAsAddEventListenerOptions();
     649           0 :     if (!IsConvertibleToDictionary(value)) {
     650           0 :       DestroyAddEventListenerOptions();
     651           0 :       tryNext = true;
     652           0 :       return true;
     653             :     }
     654           0 :     if (!memberSlot.Init(cx, value,  "Member of AddEventListenerOptionsOrBoolean", passedToJSImpl)) {
     655           0 :       return false;
     656             :     }
     657             :   }
     658           0 :   return true;
     659             : }
     660             : 
     661             : void
     662           0 : OwningAddEventListenerOptionsOrBoolean::DestroyAddEventListenerOptions()
     663             : {
     664           0 :   MOZ_ASSERT(IsAddEventListenerOptions(), "Wrong type!");
     665           0 :   mValue.mAddEventListenerOptions.Destroy();
     666           0 :   mType = eUninitialized;
     667           0 : }
     668             : 
     669             : 
     670             : 
     671             : 
     672             : bool&
     673           0 : OwningAddEventListenerOptionsOrBoolean::RawSetAsBoolean()
     674             : {
     675           0 :   if (mType == eBoolean) {
     676           0 :     return mValue.mBoolean.Value();
     677             :   }
     678           0 :   MOZ_ASSERT(mType == eUninitialized);
     679           0 :   mType = eBoolean;
     680           0 :   return mValue.mBoolean.SetValue();
     681             : }
     682             : 
     683             : bool&
     684           0 : OwningAddEventListenerOptionsOrBoolean::SetAsBoolean()
     685             : {
     686           0 :   if (mType == eBoolean) {
     687           0 :     return mValue.mBoolean.Value();
     688             :   }
     689           0 :   Uninit();
     690           0 :   mType = eBoolean;
     691           0 :   return mValue.mBoolean.SetValue();
     692             : }
     693             : 
     694             : bool
     695           0 : OwningAddEventListenerOptionsOrBoolean::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
     696             : {
     697           0 :   tryNext = false;
     698             :   { // scope for memberSlot
     699           0 :     bool& memberSlot = RawSetAsBoolean();
     700           0 :     if (!ValueToPrimitive<bool, eDefault>(cx, value, &memberSlot)) {
     701           0 :       return false;
     702             :     }
     703             :   }
     704           0 :   return true;
     705             : }
     706             : 
     707             : void
     708           0 : OwningAddEventListenerOptionsOrBoolean::DestroyBoolean()
     709             : {
     710           0 :   MOZ_ASSERT(IsBoolean(), "Wrong type!");
     711           0 :   mValue.mBoolean.Destroy();
     712           0 :   mType = eUninitialized;
     713           0 : }
     714             : 
     715             : 
     716             : 
     717             : 
     718             : void
     719           0 : OwningAddEventListenerOptionsOrBoolean::Uninit()
     720             : {
     721           0 :   switch (mType) {
     722             :     case eUninitialized: {
     723           0 :       break;
     724             :     }
     725             :     case eAddEventListenerOptions: {
     726           0 :       DestroyAddEventListenerOptions();
     727           0 :       break;
     728             :     }
     729             :     case eBoolean: {
     730           0 :       DestroyBoolean();
     731           0 :       break;
     732             :     }
     733             :   }
     734           0 : }
     735             : 
     736             : bool
     737           0 : OwningAddEventListenerOptionsOrBoolean::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
     738             : {
     739           0 :   switch (mType) {
     740             :     case eUninitialized: {
     741           0 :       return false;
     742             :       break;
     743             :     }
     744             :     case eAddEventListenerOptions: {
     745           0 :       if (!mValue.mAddEventListenerOptions.Value().ToObjectInternal(cx, rval)) {
     746           0 :         return false;
     747             :       }
     748           0 :       return true;
     749             :       break;
     750             :     }
     751             :     case eBoolean: {
     752           0 :       rval.setBoolean(mValue.mBoolean.Value());
     753           0 :       return true;
     754             :       break;
     755             :     }
     756             :     default: {
     757           0 :       return false;
     758             :       break;
     759             :     }
     760             :   }
     761             : 
     762             :   return false;
     763             : }
     764             : 
     765             : void
     766           0 : OwningAddEventListenerOptionsOrBoolean::TraceUnion(JSTracer* trc)
     767             : {
     768           0 : }
     769             : 
     770             : OwningAddEventListenerOptionsOrBoolean&
     771           0 : OwningAddEventListenerOptionsOrBoolean::operator=(const OwningAddEventListenerOptionsOrBoolean& aOther)
     772             : {
     773           0 :   switch (aOther.mType) {
     774             :     case eUninitialized: {
     775           0 :       MOZ_ASSERT(mType == eUninitialized,
     776             :                  "We need to destroy ourselves?");
     777           0 :       break;
     778             :     }
     779             :     case eAddEventListenerOptions: {
     780           0 :       SetAsAddEventListenerOptions() = aOther.GetAsAddEventListenerOptions();
     781           0 :       break;
     782             :     }
     783             :     case eBoolean: {
     784           0 :       SetAsBoolean() = aOther.GetAsBoolean();
     785           0 :       break;
     786             :     }
     787             :   }
     788           0 :   return *this;
     789             : }
     790             : 
     791             : 
     792             : namespace EventTargetBinding {
     793             : 
     794             : static bool
     795         176 : addEventListener(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::EventTarget* self, const JSJitMethodCallArgs& args)
     796             : {
     797         176 :   if (MOZ_UNLIKELY(args.length() < 2)) {
     798           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "EventTarget.addEventListener");
     799             :   }
     800         352 :   binding_detail::FakeString arg0;
     801         176 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
     802           0 :     return false;
     803             :   }
     804         352 :   RootedCallback<RefPtr<binding_detail::FastEventListener>> arg1(cx);
     805         176 :   if (args[1].isObject()) {
     806             :     { // scope for tempRoot
     807         352 :       JS::Rooted<JSObject*> tempRoot(cx, &args[1].toObject());
     808         352 :       arg1 = new binding_detail::FastEventListener(tempRoot);
     809             :     }
     810           0 :   } else if (args[1].isNullOrUndefined()) {
     811           0 :     arg1 = nullptr;
     812             :   } else {
     813           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of EventTarget.addEventListener");
     814           0 :     return false;
     815             :   }
     816         352 :   AddEventListenerOptionsOrBoolean arg2;
     817         176 :   AddEventListenerOptionsOrBooleanArgument arg2_holder(arg2);
     818         176 :   if (!(args.hasDefined(2))) {
     819         129 :     if (!arg2.RawSetAsAddEventListenerOptions().Init(cx, JS::NullHandleValue, "Member of AddEventListenerOptionsOrBoolean")) {
     820           0 :       return false;
     821             :     }
     822             :   } else {
     823             :     {
     824          47 :       bool done = false, failed = false, tryNext;
     825          47 :       if (!done) {
     826          47 :         done = (failed = !arg2_holder.TrySetToAddEventListenerOptions(cx, args[2], tryNext, false)) || !tryNext;
     827             :       }
     828          47 :       if (!done) {
     829             :         do {
     830          41 :           done = (failed = !arg2_holder.TrySetToBoolean(cx, args[2], tryNext)) || !tryNext;
     831          41 :           break;
     832             :         } while (0);
     833             :       }
     834          47 :       if (failed) {
     835           0 :         return false;
     836             :       }
     837          47 :       if (!done) {
     838           0 :         ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 3 of EventTarget.addEventListener", "AddEventListenerOptions");
     839           0 :         return false;
     840             :       }
     841             :     }
     842             :   }
     843         352 :   Nullable<bool> arg3;
     844         176 :   if (!(args.hasDefined(3)) || args[3].isNullOrUndefined()) {
     845         173 :     arg3.SetNull();
     846           3 :   } else if (!ValueToPrimitive<bool, eDefault>(cx, args[3], &arg3.SetValue())) {
     847           0 :     return false;
     848             :   }
     849         352 :   binding_detail::FastErrorResult rv;
     850         176 :   self->AddEventListener(NonNullHelper(Constify(arg0)), Constify(arg1), Constify(arg2), Constify(arg3), rv);
     851         176 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     852           0 :     return false;
     853             :   }
     854         176 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     855         176 :   args.rval().setUndefined();
     856         176 :   return true;
     857             : }
     858             : 
     859             : static const JSJitInfo addEventListener_methodinfo = {
     860             :   { (JSJitGetterOp)addEventListener },
     861             :   { prototypes::id::EventTarget },
     862             :   { PrototypeTraits<prototypes::id::EventTarget>::Depth },
     863             :   JSJitInfo::Method,
     864             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     865             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
     866             :   false,  /* isInfallible. False in setters. */
     867             :   false,  /* isMovable.  Not relevant for setters. */
     868             :   false, /* isEliminatable.  Not relevant for setters. */
     869             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     870             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     871             :   false,  /* isTypedMethod.  Only relevant for methods. */
     872             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     873             : };
     874             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     875             : static_assert(0 < 1, "There is no slot for us");
     876             : 
     877             : static bool
     878          15 : removeEventListener(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::EventTarget* self, const JSJitMethodCallArgs& args)
     879             : {
     880          15 :   if (MOZ_UNLIKELY(args.length() < 2)) {
     881           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "EventTarget.removeEventListener");
     882             :   }
     883          30 :   binding_detail::FakeString arg0;
     884          15 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
     885           0 :     return false;
     886             :   }
     887          30 :   RootedCallback<RefPtr<binding_detail::FastEventListener>> arg1(cx);
     888          15 :   if (args[1].isObject()) {
     889             :     { // scope for tempRoot
     890          30 :       JS::Rooted<JSObject*> tempRoot(cx, &args[1].toObject());
     891          30 :       arg1 = new binding_detail::FastEventListener(tempRoot);
     892             :     }
     893           0 :   } else if (args[1].isNullOrUndefined()) {
     894           0 :     arg1 = nullptr;
     895             :   } else {
     896           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of EventTarget.removeEventListener");
     897           0 :     return false;
     898             :   }
     899          30 :   EventListenerOptionsOrBoolean arg2;
     900          15 :   EventListenerOptionsOrBooleanArgument arg2_holder(arg2);
     901          15 :   if (!(args.hasDefined(2))) {
     902           8 :     if (!arg2.RawSetAsEventListenerOptions().Init(cx, JS::NullHandleValue, "Member of EventListenerOptionsOrBoolean")) {
     903           0 :       return false;
     904             :     }
     905             :   } else {
     906             :     {
     907           7 :       bool done = false, failed = false, tryNext;
     908           7 :       if (!done) {
     909           7 :         done = (failed = !arg2_holder.TrySetToEventListenerOptions(cx, args[2], tryNext, false)) || !tryNext;
     910             :       }
     911           7 :       if (!done) {
     912             :         do {
     913           7 :           done = (failed = !arg2_holder.TrySetToBoolean(cx, args[2], tryNext)) || !tryNext;
     914           7 :           break;
     915             :         } while (0);
     916             :       }
     917           7 :       if (failed) {
     918           0 :         return false;
     919             :       }
     920           7 :       if (!done) {
     921           0 :         ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 3 of EventTarget.removeEventListener", "EventListenerOptions");
     922           0 :         return false;
     923             :       }
     924             :     }
     925             :   }
     926          30 :   binding_detail::FastErrorResult rv;
     927          15 :   self->RemoveEventListener(NonNullHelper(Constify(arg0)), Constify(arg1), Constify(arg2), rv);
     928          15 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     929           0 :     return false;
     930             :   }
     931          15 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     932          15 :   args.rval().setUndefined();
     933          15 :   return true;
     934             : }
     935             : 
     936             : static const JSJitInfo removeEventListener_methodinfo = {
     937             :   { (JSJitGetterOp)removeEventListener },
     938             :   { prototypes::id::EventTarget },
     939             :   { PrototypeTraits<prototypes::id::EventTarget>::Depth },
     940             :   JSJitInfo::Method,
     941             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     942             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
     943             :   false,  /* isInfallible. False in setters. */
     944             :   false,  /* isMovable.  Not relevant for setters. */
     945             :   false, /* isEliminatable.  Not relevant for setters. */
     946             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     947             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     948             :   false,  /* isTypedMethod.  Only relevant for methods. */
     949             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     950             : };
     951             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     952             : static_assert(0 < 1, "There is no slot for us");
     953             : 
     954             : static bool
     955          12 : dispatchEvent(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::EventTarget* self, const JSJitMethodCallArgs& args)
     956             : {
     957          12 :   if (MOZ_UNLIKELY(args.length() < 1)) {
     958           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "EventTarget.dispatchEvent");
     959             :   }
     960          12 :   NonNull<mozilla::dom::Event> arg0;
     961          12 :   if (args[0].isObject()) {
     962             :     {
     963          12 :       nsresult rv = UnwrapObject<prototypes::id::Event, mozilla::dom::Event>(args[0], arg0);
     964          12 :       if (NS_FAILED(rv)) {
     965           0 :         ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of EventTarget.dispatchEvent", "Event");
     966           0 :         return false;
     967             :       }
     968             :     }
     969             :   } else {
     970           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of EventTarget.dispatchEvent");
     971           0 :     return false;
     972             :   }
     973          24 :   binding_detail::FastErrorResult rv;
     974          12 :   bool result(self->DispatchEvent(NonNullHelper(arg0), nsContentUtils::ThreadsafeIsSystemCaller(cx) ? CallerType::System : CallerType::NonSystem, rv));
     975          12 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     976           0 :     return false;
     977             :   }
     978          12 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     979          12 :   args.rval().setBoolean(result);
     980          12 :   return true;
     981             : }
     982             : 
     983             : static const JSJitInfo dispatchEvent_methodinfo = {
     984             :   { (JSJitGetterOp)dispatchEvent },
     985             :   { prototypes::id::EventTarget },
     986             :   { PrototypeTraits<prototypes::id::EventTarget>::Depth },
     987             :   JSJitInfo::Method,
     988             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     989             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
     990             :   false,  /* isInfallible. False in setters. */
     991             :   false,  /* isMovable.  Not relevant for setters. */
     992             :   false, /* isEliminatable.  Not relevant for setters. */
     993             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     994             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     995             :   false,  /* isTypedMethod.  Only relevant for methods. */
     996             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     997             : };
     998             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     999             : static_assert(0 < 1, "There is no slot for us");
    1000             : 
    1001             : static bool
    1002           0 : setEventHandler(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::EventTarget* self, const JSJitMethodCallArgs& args)
    1003             : {
    1004           0 :   if (MOZ_UNLIKELY(args.length() < 2)) {
    1005           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "EventTarget.setEventHandler");
    1006             :   }
    1007           0 :   binding_detail::FakeString arg0;
    1008           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    1009           0 :     return false;
    1010             :   }
    1011           0 :   RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg1(cx);
    1012           0 :   if (args[1].isObject()) {
    1013             :     { // scope for tempRoot
    1014           0 :       JS::Rooted<JSObject*> tempRoot(cx, &args[1].toObject());
    1015           0 :       arg1 = new binding_detail::FastEventHandlerNonNull(tempRoot);
    1016             :     }
    1017             :   } else {
    1018           0 :     arg1 = nullptr;
    1019             :   }
    1020           0 :   binding_detail::FastErrorResult rv;
    1021           0 :   self->SetEventHandler(NonNullHelper(Constify(arg0)), Constify(arg1), rv);
    1022           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1023           0 :     return false;
    1024             :   }
    1025           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1026           0 :   args.rval().setUndefined();
    1027           0 :   return true;
    1028             : }
    1029             : 
    1030             : static const JSJitInfo setEventHandler_methodinfo = {
    1031             :   { (JSJitGetterOp)setEventHandler },
    1032             :   { prototypes::id::EventTarget },
    1033             :   { PrototypeTraits<prototypes::id::EventTarget>::Depth },
    1034             :   JSJitInfo::Method,
    1035             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1036             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    1037             :   false,  /* isInfallible. False in setters. */
    1038             :   false,  /* isMovable.  Not relevant for setters. */
    1039             :   false, /* isEliminatable.  Not relevant for setters. */
    1040             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1041             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1042             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1043             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1044             : };
    1045             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1046             : static_assert(0 < 1, "There is no slot for us");
    1047             : 
    1048             : static bool
    1049           0 : getEventHandler(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::EventTarget* self, const JSJitMethodCallArgs& args)
    1050             : {
    1051           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    1052           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "EventTarget.getEventHandler");
    1053             :   }
    1054           0 :   binding_detail::FakeString arg0;
    1055           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    1056           0 :     return false;
    1057             :   }
    1058           0 :   RefPtr<EventHandlerNonNull> result(self->GetEventHandler(NonNullHelper(Constify(arg0))));
    1059           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1060           0 :   if (result) {
    1061           0 :     args.rval().setObjectOrNull(GetCallbackFromCallbackObject(result));
    1062           0 :     if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
    1063           0 :       return false;
    1064             :     }
    1065           0 :     return true;
    1066             :   } else {
    1067           0 :     args.rval().setNull();
    1068           0 :     return true;
    1069             :   }
    1070             : }
    1071             : 
    1072             : static const JSJitInfo getEventHandler_methodinfo = {
    1073             :   { (JSJitGetterOp)getEventHandler },
    1074             :   { prototypes::id::EventTarget },
    1075             :   { PrototypeTraits<prototypes::id::EventTarget>::Depth },
    1076             :   JSJitInfo::Method,
    1077             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1078             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    1079             :   false,  /* isInfallible. False in setters. */
    1080             :   false,  /* isMovable.  Not relevant for setters. */
    1081             :   false, /* isEliminatable.  Not relevant for setters. */
    1082             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1083             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1084             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1085             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1086             : };
    1087             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1088             : static_assert(0 < 1, "There is no slot for us");
    1089             : 
    1090             : static bool
    1091          35 : get_ownerGlobal(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::EventTarget* self, JSJitGetterCallArgs args)
    1092             : {
    1093          35 :   auto result(StrongOrRawPtr<nsPIDOMWindowOuter>(self->GetOwnerGlobalForBindings()));
    1094          35 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1095          35 :   if (!result) {
    1096           0 :     args.rval().setNull();
    1097           0 :     return true;
    1098             :   }
    1099          35 :   if (!WrapObject(cx, result, args.rval())) {
    1100           0 :     return false;
    1101             :   }
    1102          35 :   return true;
    1103             : }
    1104             : 
    1105             : static const JSJitInfo ownerGlobal_getterinfo = {
    1106             :   { (JSJitGetterOp)get_ownerGlobal },
    1107             :   { prototypes::id::EventTarget },
    1108             :   { PrototypeTraits<prototypes::id::EventTarget>::Depth },
    1109             :   JSJitInfo::Getter,
    1110             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1111             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    1112             :   false,  /* isInfallible. False in setters. */
    1113             :   false,  /* isMovable.  Not relevant for setters. */
    1114             :   false, /* isEliminatable.  Not relevant for setters. */
    1115             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1116             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1117             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1118             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1119             : };
    1120             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1121             : static_assert(0 < 1, "There is no slot for us");
    1122             : 
    1123             : static bool
    1124         203 : genericMethod(JSContext* cx, unsigned argc, JS::Value* vp)
    1125             : {
    1126         203 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    1127         203 :   if (!args.thisv().isNullOrUndefined() && !args.thisv().isObject()) {
    1128           0 :     return ThrowInvalidThis(cx, args, false, "EventTarget");
    1129             :   }
    1130         406 :   JS::Rooted<JSObject*> obj(cx, args.thisv().isObject() ? &args.thisv().toObject() : js::GetGlobalForObjectCrossCompartment(&args.callee()));
    1131             : 
    1132             :   mozilla::dom::EventTarget* self;
    1133         406 :   JS::Rooted<JS::Value> rootSelf(cx, JS::ObjectValue(*obj));
    1134             :   {
    1135         203 :     nsresult rv = UnwrapObject<prototypes::id::EventTarget, mozilla::dom::EventTarget>(&rootSelf, self);
    1136         203 :     if (NS_FAILED(rv)) {
    1137           0 :       RefPtr<mozilla::dom::EventTarget> objPtr;
    1138           0 :       nsresult rv = UnwrapXPConnect<mozilla::dom::EventTarget>(cx, &rootSelf, getter_AddRefs(objPtr));
    1139           0 :       if (NS_FAILED(rv)) {
    1140           0 :         return ThrowInvalidThis(cx, args, rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO, "EventTarget");
    1141             :       }
    1142             :       // We should have an object
    1143           0 :       MOZ_ASSERT(objPtr);
    1144           0 :       self = objPtr;
    1145             :     }
    1146             :   }
    1147         203 :   const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
    1148         203 :   MOZ_ASSERT(info->type() == JSJitInfo::Method);
    1149         203 :   JSJitMethodOp method = info->method;
    1150         203 :   bool ok = method(cx, obj, self, JSJitMethodCallArgs(args));
    1151             : #ifdef DEBUG
    1152         203 :   if (ok) {
    1153         203 :     AssertReturnTypeMatchesJitinfo(info, args.rval());
    1154             :   }
    1155             : #endif
    1156         203 :   return ok;
    1157             : }
    1158             : 
    1159             : static bool
    1160          35 : genericGetter(JSContext* cx, unsigned argc, JS::Value* vp)
    1161             : {
    1162          35 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    1163          35 :   if (!args.thisv().isNullOrUndefined() && !args.thisv().isObject()) {
    1164           0 :     return ThrowInvalidThis(cx, args, false, "EventTarget");
    1165             :   }
    1166          70 :   JS::Rooted<JSObject*> obj(cx, args.thisv().isObject() ? &args.thisv().toObject() : js::GetGlobalForObjectCrossCompartment(&args.callee()));
    1167             : 
    1168             :   mozilla::dom::EventTarget* self;
    1169          70 :   JS::Rooted<JS::Value> rootSelf(cx, JS::ObjectValue(*obj));
    1170             :   {
    1171          35 :     nsresult rv = UnwrapObject<prototypes::id::EventTarget, mozilla::dom::EventTarget>(&rootSelf, self);
    1172          35 :     if (NS_FAILED(rv)) {
    1173           0 :       RefPtr<mozilla::dom::EventTarget> objPtr;
    1174           0 :       nsresult rv = UnwrapXPConnect<mozilla::dom::EventTarget>(cx, &rootSelf, getter_AddRefs(objPtr));
    1175           0 :       if (NS_FAILED(rv)) {
    1176           0 :         return ThrowInvalidThis(cx, args, rv == NS_ERROR_XPC_SECURITY_MANAGER_VETO, "EventTarget");
    1177             :       }
    1178             :       // We should have an object
    1179           0 :       MOZ_ASSERT(objPtr);
    1180           0 :       self = objPtr;
    1181             :     }
    1182             :   }
    1183          35 :   const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
    1184          35 :   MOZ_ASSERT(info->type() == JSJitInfo::Getter);
    1185          35 :   JSJitGetterOp getter = info->getter;
    1186          35 :   bool ok = getter(cx, obj, self, JSJitGetterCallArgs(args));
    1187             : #ifdef DEBUG
    1188          35 :   if (ok) {
    1189          35 :     AssertReturnTypeMatchesJitinfo(info, args.rval());
    1190             :   }
    1191             : #endif
    1192          35 :   return ok;
    1193             : }
    1194             : 
    1195             : static bool
    1196           0 : _hasInstance(JSContext* cx, unsigned argc, JS::Value* vp)
    1197             : {
    1198           0 :   JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
    1199           0 :   if (!args.get(0).isObject()) {
    1200           0 :     args.rval().setBoolean(false);
    1201           0 :     return true;
    1202             :   }
    1203             : 
    1204           0 :   JS::Rooted<JSObject*> instance(cx, &args[0].toObject());
    1205             : 
    1206             :   static_assert(IsBaseOf<nsISupports, mozilla::dom::EventTarget>::value,
    1207             :                 "HasInstance only works for nsISupports-based classes.");
    1208             : 
    1209           0 :   bool ok = InterfaceHasInstance(cx, argc, vp);
    1210           0 :   if (!ok || args.rval().toBoolean()) {
    1211           0 :     return ok;
    1212             :   }
    1213             : 
    1214             :   // FIXME Limit this to chrome by checking xpc::AccessCheck::isChrome(obj).
    1215             :   nsCOMPtr<nsISupports> native =
    1216           0 :     xpc::UnwrapReflectorToISupports(js::UncheckedUnwrap(instance, /* stopAtWindowProxy = */ false));
    1217           0 :   nsCOMPtr<nsIDOMEventTarget> qiResult = do_QueryInterface(native);
    1218           0 :   args.rval().setBoolean(!!qiResult);
    1219           0 :   return true;
    1220             : }
    1221             : 
    1222             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    1223             : #if defined(__clang__)
    1224             : #pragma clang diagnostic push
    1225             : #pragma clang diagnostic ignored "-Wmissing-braces"
    1226             : #endif
    1227             : static const JSFunctionSpec sStaticMethods_specs[] = {
    1228             :   JS_SYM_FNSPEC(hasInstance, _hasInstance, nullptr, 1, JSPROP_READONLY | JSPROP_PERMANENT, nullptr),
    1229             :   JS_FS_END
    1230             : };
    1231             : #if defined(__clang__)
    1232             : #pragma clang diagnostic pop
    1233             : #endif
    1234             : 
    1235             : 
    1236             : // Can't be const because the pref-enabled boolean needs to be writable
    1237             : static Prefable<const JSFunctionSpec> sStaticMethods[] = {
    1238             :   { nullptr, &sStaticMethods_specs[0] },
    1239             :   { nullptr, nullptr }
    1240             : };
    1241             : 
    1242             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    1243             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    1244             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    1245             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    1246             : 
    1247             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    1248             : #if defined(__clang__)
    1249             : #pragma clang diagnostic push
    1250             : #pragma clang diagnostic ignored "-Wmissing-braces"
    1251             : #endif
    1252             : static const JSFunctionSpec sMethods_specs[] = {
    1253             :   JS_FNSPEC("addEventListener", genericMethod, reinterpret_cast<const JSJitInfo*>(&addEventListener_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
    1254             :   JS_FNSPEC("removeEventListener", genericMethod, reinterpret_cast<const JSJitInfo*>(&removeEventListener_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
    1255             :   JS_FNSPEC("dispatchEvent", genericMethod, reinterpret_cast<const JSJitInfo*>(&dispatchEvent_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    1256             :   JS_FS_END
    1257             : };
    1258             : #if defined(__clang__)
    1259             : #pragma clang diagnostic pop
    1260             : #endif
    1261             : 
    1262             : 
    1263             : // Can't be const because the pref-enabled boolean needs to be writable
    1264             : static Prefable<const JSFunctionSpec> sMethods[] = {
    1265             :   { nullptr, &sMethods_specs[0] },
    1266             :   { nullptr, nullptr }
    1267             : };
    1268             : 
    1269             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    1270             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    1271             : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    1272             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    1273             : 
    1274             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    1275             : #if defined(__clang__)
    1276             : #pragma clang diagnostic push
    1277             : #pragma clang diagnostic ignored "-Wmissing-braces"
    1278             : #endif
    1279             : static const JSFunctionSpec sChromeMethods_specs[] = {
    1280             :   JS_FNSPEC("setEventHandler", genericMethod, reinterpret_cast<const JSJitInfo*>(&setEventHandler_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
    1281             :   JS_FNSPEC("getEventHandler", genericMethod, reinterpret_cast<const JSJitInfo*>(&getEventHandler_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    1282             :   JS_FS_END
    1283             : };
    1284             : #if defined(__clang__)
    1285             : #pragma clang diagnostic pop
    1286             : #endif
    1287             : 
    1288             : 
    1289             : // Can't be const because the pref-enabled boolean needs to be writable
    1290             : static Prefable<const JSFunctionSpec> sChromeMethods[] = {
    1291             :   { nullptr, &sChromeMethods_specs[0] },
    1292             :   { nullptr, nullptr }
    1293             : };
    1294             : 
    1295             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    1296             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    1297             : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    1298             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    1299             : 
    1300             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    1301             : #if defined(__clang__)
    1302             : #pragma clang diagnostic push
    1303             : #pragma clang diagnostic ignored "-Wmissing-braces"
    1304             : #endif
    1305             : static const JSPropertySpec sChromeAttributes_specs[] = {
    1306             :   { "ownerGlobal", JSPROP_SHARED | JSPROP_ENUMERATE, genericGetter, &ownerGlobal_getterinfo, nullptr, nullptr },
    1307             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
    1308             : };
    1309             : #if defined(__clang__)
    1310             : #pragma clang diagnostic pop
    1311             : #endif
    1312             : 
    1313             : static PrefableDisablers sChromeAttributes_disablers0 = {
    1314             :   true, false, GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope | GlobalNames::WorkerDebuggerGlobalScope, nullptr
    1315             : };
    1316             : 
    1317             : // Can't be const because the pref-enabled boolean needs to be writable
    1318             : static Prefable<const JSPropertySpec> sChromeAttributes[] = {
    1319             :   { &sChromeAttributes_disablers0, &sChromeAttributes_specs[0] },
    1320             :   { nullptr, nullptr }
    1321             : };
    1322             : 
    1323             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    1324             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    1325             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    1326             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    1327             : 
    1328             : 
    1329             : static uint16_t sNativeProperties_sortedPropertyIndices[4];
    1330             : static PropertyInfo sNativeProperties_propertyInfos[4];
    1331             : 
    1332             : static const NativePropertiesN<2> sNativeProperties = {
    1333             :   true,  0 /* sStaticMethods */,
    1334             :   false, 0,
    1335             :   true,  1 /* sMethods */,
    1336             :   false, 0,
    1337             :   false, 0,
    1338             :   false, 0,
    1339             :   false, 0,
    1340             :   -1,
    1341             :   4,
    1342             :   sNativeProperties_sortedPropertyIndices,
    1343             :   {
    1344             :     { sStaticMethods, &sNativeProperties_propertyInfos[0] },
    1345             :     { sMethods, &sNativeProperties_propertyInfos[1] }
    1346             :   }
    1347             : };
    1348             : static_assert(4 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
    1349             :     "We have a property info count that is oversized");
    1350             : 
    1351             : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[3];
    1352             : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[3];
    1353             : 
    1354             : static const NativePropertiesN<2> sChromeOnlyNativeProperties = {
    1355             :   false, 0,
    1356             :   false, 0,
    1357             :   true,  0 /* sChromeMethods */,
    1358             :   true,  1 /* sChromeAttributes */,
    1359             :   false, 0,
    1360             :   false, 0,
    1361             :   false, 0,
    1362             :   -1,
    1363             :   3,
    1364             :   sChromeOnlyNativeProperties_sortedPropertyIndices,
    1365             :   {
    1366             :     { sChromeMethods, &sChromeOnlyNativeProperties_propertyInfos[0] },
    1367             :     { sChromeAttributes, &sChromeOnlyNativeProperties_propertyInfos[2] }
    1368             :   }
    1369             : };
    1370             : static_assert(3 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
    1371             :     "We have a property info count that is oversized");
    1372             : 
    1373             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
    1374             :   {
    1375             :     "Function",
    1376             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
    1377             :     &sBoringInterfaceObjectClassClassOps,
    1378             :     JS_NULL_CLASS_SPEC,
    1379             :     JS_NULL_CLASS_EXT,
    1380             :     &sInterfaceObjectClassObjectOps
    1381             :   },
    1382             :   eInterface,
    1383             :   false,
    1384             :   prototypes::id::EventTarget,
    1385             :   PrototypeTraits<prototypes::id::EventTarget>::Depth,
    1386             :   sNativePropertyHooks,
    1387             :   "function EventTarget() {\n    [native code]\n}",
    1388             :   JS::GetRealmFunctionPrototype
    1389             : };
    1390             : 
    1391             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
    1392             :   {
    1393             :     "EventTargetPrototype",
    1394             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    1395             :     JS_NULL_CLASS_OPS,
    1396             :     JS_NULL_CLASS_SPEC,
    1397             :     JS_NULL_CLASS_EXT,
    1398             :     JS_NULL_OBJECT_OPS
    1399             :   },
    1400             :   eInterfacePrototype,
    1401             :   false,
    1402             :   prototypes::id::EventTarget,
    1403             :   PrototypeTraits<prototypes::id::EventTarget>::Depth,
    1404             :   sNativePropertyHooks,
    1405             :   "[object EventTargetPrototype]",
    1406             :   JS::GetRealmObjectPrototype
    1407             : };
    1408             : 
    1409             : JSObject*
    1410           0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
    1411             : {
    1412           0 :   return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
    1413             : }
    1414             : 
    1415             : const NativePropertyHooks sNativePropertyHooks[] = { {
    1416             :   nullptr,
    1417             :   nullptr,
    1418             :   nullptr,
    1419             :   { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
    1420             :   prototypes::id::EventTarget,
    1421             :   constructors::id::EventTarget,
    1422             :   nullptr,
    1423             :   &DefaultXrayExpandoObjectClass
    1424             : } };
    1425             : 
    1426             : void
    1427          34 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    1428             : {
    1429          68 :   JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
    1430          34 :   if (!parentProto) {
    1431           0 :     return;
    1432             :   }
    1433             : 
    1434          68 :   JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
    1435          34 :   if (!constructorProto) {
    1436           0 :     return;
    1437             :   }
    1438             : 
    1439             :   static bool sIdsInited = false;
    1440          34 :   if (!sIdsInited && NS_IsMainThread()) {
    1441           3 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
    1442           0 :       return;
    1443             :     }
    1444           3 :     if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
    1445           0 :       return;
    1446             :     }
    1447           3 :     sIdsInited = true;
    1448             :   }
    1449             : 
    1450          34 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::EventTarget);
    1451          34 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::EventTarget);
    1452         102 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    1453             :                               &sPrototypeClass.mBase, protoCache,
    1454             :                               constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
    1455             :                               interfaceCache,
    1456             :                               sNativeProperties.Upcast(),
    1457          34 :                               nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
    1458             :                               "EventTarget", aDefineOnGlobal,
    1459             :                               nullptr,
    1460          34 :                               false);
    1461             : 
    1462          34 :   if (*&aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::EventTarget)) {
    1463             :     bool succeeded;
    1464          34 :     JS::Handle<JSObject*> prot = GetProtoObjectHandle(aCx);
    1465          34 :     if (!JS_SetImmutablePrototype(aCx, prot, &succeeded)) {
    1466           0 :       *protoCache = nullptr;
    1467           0 :       if (interfaceCache) {
    1468           0 :         *interfaceCache = nullptr;
    1469             :       }
    1470           0 :       return;
    1471             :     }
    1472             : 
    1473          34 :     MOZ_ASSERT(succeeded,
    1474             :                "making a fresh prototype object's [[Prototype]] "
    1475             :                "immutable can internally fail, but it should "
    1476             :                "never be unsuccessful");
    1477             :   }
    1478             : }
    1479             : 
    1480             : JS::Handle<JSObject*>
    1481         135 : GetProtoObjectHandle(JSContext* aCx)
    1482             : {
    1483             :   /* Get the interface prototype object for this class.  This will create the
    1484             :      object as needed. */
    1485         135 :   bool aDefineOnGlobal = true;
    1486             : 
    1487             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    1488         135 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    1489         135 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    1490           0 :     return nullptr;
    1491             :   }
    1492             : 
    1493             :   /* Check to see whether the interface objects are already installed */
    1494         135 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    1495         135 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::EventTarget)) {
    1496          68 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    1497          34 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    1498             :   }
    1499             : 
    1500             :   /*
    1501             :    * The object might _still_ be null, but that's OK.
    1502             :    *
    1503             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    1504             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    1505             :    * changed after they have been set.
    1506             :    *
    1507             :    * Calling address() avoids the read read barrier that does gray
    1508             :    * unmarking, but it's not possible for the object to be gray here.
    1509             :    */
    1510             : 
    1511         135 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::EventTarget);
    1512         135 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    1513         135 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    1514             : }
    1515             : 
    1516             : JSObject*
    1517           1 : GetProtoObject(JSContext* aCx)
    1518             : {
    1519           1 :   return GetProtoObjectHandle(aCx);
    1520             : }
    1521             : 
    1522             : JS::Handle<JSObject*>
    1523         101 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
    1524             : {
    1525             :   /* Get the interface object for this class.  This will create the object as
    1526             :      needed. */
    1527             : 
    1528             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    1529         101 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    1530         101 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    1531           0 :     return nullptr;
    1532             :   }
    1533             : 
    1534             :   /* Check to see whether the interface objects are already installed */
    1535         101 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    1536         101 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::EventTarget)) {
    1537           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    1538           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    1539             :   }
    1540             : 
    1541             :   /*
    1542             :    * The object might _still_ be null, but that's OK.
    1543             :    *
    1544             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    1545             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    1546             :    * changed after they have been set.
    1547             :    *
    1548             :    * Calling address() avoids the read read barrier that does gray
    1549             :    * unmarking, but it's not possible for the object to be gray here.
    1550             :    */
    1551             : 
    1552         101 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::EventTarget);
    1553         101 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    1554         101 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    1555             : }
    1556             : 
    1557             : JSObject*
    1558           1 : GetConstructorObject(JSContext* aCx)
    1559             : {
    1560           1 :   return GetConstructorObjectHandle(aCx);
    1561             : }
    1562             : 
    1563             : } // namespace EventTargetBinding
    1564             : 
    1565             : 
    1566             : 
    1567             : } // namespace dom
    1568             : } // namespace mozilla

Generated by: LCOV version 1.13