LCOV - code coverage report
Current view: top level - obj-x86_64-pc-linux-gnu/dom/bindings - HTMLDocumentBinding.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 131 829 15.8 %
Date: 2017-07-14 16:53:18 Functions: 14 69 20.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* THIS FILE IS AUTOGENERATED FROM HTMLDocument.webidl BY Codegen.py - DO NOT EDIT */
       2             : 
       3             : #include "DocumentBinding.h"
       4             : #include "HTMLDocumentBinding.h"
       5             : #include "WrapperFactory.h"
       6             : #include "mozilla/OwningNonNull.h"
       7             : #include "mozilla/dom/BindingUtils.h"
       8             : #include "mozilla/dom/CustomElementRegistry.h"
       9             : #include "mozilla/dom/DOMJSClass.h"
      10             : #include "mozilla/dom/DOMJSProxyHandler.h"
      11             : #include "mozilla/dom/HTMLAllCollection.h"
      12             : #include "mozilla/dom/HTMLSharedElement.h"
      13             : #include "mozilla/dom/Location.h"
      14             : #include "mozilla/dom/NonRefcountedDOMObject.h"
      15             : #include "mozilla/dom/Nullable.h"
      16             : #include "mozilla/dom/PrimitiveConversions.h"
      17             : #include "mozilla/dom/Selection.h"
      18             : #include "mozilla/dom/XrayExpandoClass.h"
      19             : #include "nsContentList.h"
      20             : #include "nsContentUtils.h"
      21             : #include "nsGenericHTMLElement.h"
      22             : #include "nsHTMLDocument.h"
      23             : #include "nsIDocument.h"
      24             : #include "nsINodeList.h"
      25             : #include "nsPIDOMWindow.h"
      26             : 
      27             : namespace mozilla {
      28             : namespace dom {
      29             : 
      30             : namespace HTMLDocumentBinding {
      31             : 
      32             : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<DocumentBinding::NativeType>::value,
      33             :               "Can't inherit from an interface with a different ownership model.");
      34             : 
      35             : static bool
      36           0 : get_domain(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
      37             : {
      38           0 :   DOMString result;
      39           0 :   self->GetDomain(result);
      40           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
      41           0 :   if (!xpc::StringToJsval(cx, result, args.rval())) {
      42           0 :     return false;
      43             :   }
      44           0 :   return true;
      45             : }
      46             : 
      47             : static bool
      48           0 : set_domain(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitSetterCallArgs args)
      49             : {
      50           0 :   binding_detail::FakeString arg0;
      51           0 :   if (!ConvertJSValueToString(cx, args[0], eNull, eNull, arg0)) {
      52           0 :     return false;
      53             :   }
      54           0 :   binding_detail::FastErrorResult rv;
      55           0 :   self->SetDomain(NonNullHelper(Constify(arg0)), rv);
      56           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
      57           0 :     return false;
      58             :   }
      59           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
      60             : 
      61           0 :   return true;
      62             : }
      63             : 
      64             : static const JSJitInfo domain_getterinfo = {
      65             :   { (JSJitGetterOp)get_domain },
      66             :   { prototypes::id::HTMLDocument },
      67             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
      68             :   JSJitInfo::Getter,
      69             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
      70             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
      71             :   false,  /* isInfallible. False in setters. */
      72             :   false,  /* isMovable.  Not relevant for setters. */
      73             :   false, /* isEliminatable.  Not relevant for setters. */
      74             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
      75             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
      76             :   false,  /* isTypedMethod.  Only relevant for methods. */
      77             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
      78             : };
      79             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
      80             : static_assert(0 < 1, "There is no slot for us");
      81             : static const JSJitInfo domain_setterinfo = {
      82             :   { (JSJitGetterOp)set_domain },
      83             :   { prototypes::id::HTMLDocument },
      84             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
      85             :   JSJitInfo::Setter,
      86             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
      87             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
      88             :   false,  /* isInfallible. False in setters. */
      89             :   false,  /* isMovable.  Not relevant for setters. */
      90             :   false, /* isEliminatable.  Not relevant for setters. */
      91             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
      92             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
      93             :   false,  /* isTypedMethod.  Only relevant for methods. */
      94             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
      95             : };
      96             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
      97             : static_assert(0 < 1, "There is no slot for us");
      98             : 
      99             : static bool
     100           0 : get_cookie(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
     101             : {
     102           0 :   binding_detail::FastErrorResult rv;
     103           0 :   DOMString result;
     104           0 :   self->GetCookie(result, rv);
     105           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     106           0 :     return false;
     107             :   }
     108           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     109           0 :   if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
     110           0 :     return false;
     111             :   }
     112           0 :   return true;
     113             : }
     114             : 
     115             : static bool
     116           0 : set_cookie(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitSetterCallArgs args)
     117             : {
     118           0 :   binding_detail::FakeString arg0;
     119           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
     120           0 :     return false;
     121             :   }
     122           0 :   binding_detail::FastErrorResult rv;
     123           0 :   self->SetCookie(NonNullHelper(Constify(arg0)), rv);
     124           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     125           0 :     return false;
     126             :   }
     127           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     128             : 
     129           0 :   return true;
     130             : }
     131             : 
     132             : static const JSJitInfo cookie_getterinfo = {
     133             :   { (JSJitGetterOp)get_cookie },
     134             :   { prototypes::id::HTMLDocument },
     135             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     136             :   JSJitInfo::Getter,
     137             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     138             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
     139             :   false,  /* isInfallible. False in setters. */
     140             :   false,  /* isMovable.  Not relevant for setters. */
     141             :   false, /* isEliminatable.  Not relevant for setters. */
     142             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     143             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     144             :   false,  /* isTypedMethod.  Only relevant for methods. */
     145             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     146             : };
     147             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     148             : static_assert(0 < 1, "There is no slot for us");
     149             : static const JSJitInfo cookie_setterinfo = {
     150             :   { (JSJitGetterOp)set_cookie },
     151             :   { prototypes::id::HTMLDocument },
     152             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     153             :   JSJitInfo::Setter,
     154             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     155             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
     156             :   false,  /* isInfallible. False in setters. */
     157             :   false,  /* isMovable.  Not relevant for setters. */
     158             :   false, /* isEliminatable.  Not relevant for setters. */
     159             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     160             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     161             :   false,  /* isTypedMethod.  Only relevant for methods. */
     162             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     163             : };
     164             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     165             : static_assert(0 < 1, "There is no slot for us");
     166             : 
     167             : static bool
     168           2 : get_body(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
     169             : {
     170           2 :   auto result(StrongOrRawPtr<nsGenericHTMLElement>(self->GetBody()));
     171           2 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     172           2 :   if (!result) {
     173           0 :     args.rval().setNull();
     174           0 :     return true;
     175             :   }
     176           2 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
     177           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     178           0 :     return false;
     179             :   }
     180           2 :   return true;
     181             : }
     182             : 
     183             : static bool
     184           0 : set_body(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitSetterCallArgs args)
     185             : {
     186             :   nsGenericHTMLElement* arg0;
     187           0 :   if (args[0].isObject()) {
     188             :     {
     189           0 :       nsresult rv = UnwrapObject<prototypes::id::HTMLElement, nsGenericHTMLElement>(args[0], arg0);
     190           0 :       if (NS_FAILED(rv)) {
     191           0 :         ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Value being assigned to HTMLDocument.body", "HTMLElement");
     192           0 :         return false;
     193             :       }
     194             :     }
     195           0 :   } else if (args[0].isNullOrUndefined()) {
     196           0 :     arg0 = nullptr;
     197             :   } else {
     198           0 :     ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Value being assigned to HTMLDocument.body");
     199           0 :     return false;
     200             :   }
     201           0 :   CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
     202           0 :   Maybe<AutoCEReaction> ceReaction;
     203           0 :   if (reactionsStack) {
     204           0 :     ceReaction.emplace(reactionsStack);
     205             :   }
     206           0 :   binding_detail::FastErrorResult rv;
     207           0 :   self->SetBody(Constify(arg0), rv);
     208           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     209           0 :     return false;
     210             :   }
     211           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     212             : 
     213           0 :   return true;
     214             : }
     215             : 
     216             : static const JSJitInfo body_getterinfo = {
     217             :   { (JSJitGetterOp)get_body },
     218             :   { prototypes::id::HTMLDocument },
     219             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     220             :   JSJitInfo::Getter,
     221             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
     222             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
     223             :   false,  /* isInfallible. False in setters. */
     224             :   true,  /* isMovable.  Not relevant for setters. */
     225             :   true, /* isEliminatable.  Not relevant for setters. */
     226             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     227             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     228             :   false,  /* isTypedMethod.  Only relevant for methods. */
     229             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     230             : };
     231             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     232             : static_assert(0 < 1, "There is no slot for us");
     233             : static const JSJitInfo body_setterinfo = {
     234             :   { (JSJitGetterOp)set_body },
     235             :   { prototypes::id::HTMLDocument },
     236             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     237             :   JSJitInfo::Setter,
     238             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     239             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
     240             :   false,  /* isInfallible. False in setters. */
     241             :   false,  /* isMovable.  Not relevant for setters. */
     242             :   false, /* isEliminatable.  Not relevant for setters. */
     243             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     244             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     245             :   false,  /* isTypedMethod.  Only relevant for methods. */
     246             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     247             : };
     248             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     249             : static_assert(0 < 1, "There is no slot for us");
     250             : 
     251             : static bool
     252           0 : get_head(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
     253             : {
     254           0 :   auto result(StrongOrRawPtr<mozilla::dom::HTMLSharedElement>(self->GetHead()));
     255           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     256           0 :   if (!result) {
     257           0 :     args.rval().setNull();
     258           0 :     return true;
     259             :   }
     260           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
     261           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     262           0 :     return false;
     263             :   }
     264           0 :   return true;
     265             : }
     266             : 
     267             : static const JSJitInfo head_getterinfo = {
     268             :   { (JSJitGetterOp)get_head },
     269             :   { prototypes::id::HTMLDocument },
     270             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     271             :   JSJitInfo::Getter,
     272             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
     273             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
     274             :   false,  /* isInfallible. False in setters. */
     275             :   true,  /* isMovable.  Not relevant for setters. */
     276             :   true, /* isEliminatable.  Not relevant for setters. */
     277             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     278             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     279             :   false,  /* isTypedMethod.  Only relevant for methods. */
     280             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     281             : };
     282             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     283             : static_assert(0 < 1, "There is no slot for us");
     284             : 
     285             : static bool
     286           0 : get_images(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
     287             : {
     288           0 :   auto result(StrongOrRawPtr<nsIHTMLCollection>(self->Images()));
     289           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     290           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
     291           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     292           0 :     return false;
     293             :   }
     294           0 :   return true;
     295             : }
     296             : 
     297             : static const JSJitInfo images_getterinfo = {
     298             :   { (JSJitGetterOp)get_images },
     299             :   { prototypes::id::HTMLDocument },
     300             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     301             :   JSJitInfo::Getter,
     302             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
     303             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     304             :   false,  /* isInfallible. False in setters. */
     305             :   true,  /* isMovable.  Not relevant for setters. */
     306             :   true, /* isEliminatable.  Not relevant for setters. */
     307             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     308             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     309             :   false,  /* isTypedMethod.  Only relevant for methods. */
     310             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     311             : };
     312             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     313             : static_assert(0 < 1, "There is no slot for us");
     314             : 
     315             : static bool
     316           0 : get_embeds(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
     317             : {
     318           0 :   auto result(StrongOrRawPtr<nsIHTMLCollection>(self->Embeds()));
     319           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     320           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
     321           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     322           0 :     return false;
     323             :   }
     324           0 :   return true;
     325             : }
     326             : 
     327             : static const JSJitInfo embeds_getterinfo = {
     328             :   { (JSJitGetterOp)get_embeds },
     329             :   { prototypes::id::HTMLDocument },
     330             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     331             :   JSJitInfo::Getter,
     332             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
     333             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     334             :   false,  /* isInfallible. False in setters. */
     335             :   true,  /* isMovable.  Not relevant for setters. */
     336             :   true, /* isEliminatable.  Not relevant for setters. */
     337             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     338             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     339             :   false,  /* isTypedMethod.  Only relevant for methods. */
     340             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     341             : };
     342             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     343             : static_assert(0 < 1, "There is no slot for us");
     344             : 
     345             : static bool
     346           0 : get_plugins(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
     347             : {
     348           0 :   auto result(StrongOrRawPtr<nsIHTMLCollection>(self->Plugins()));
     349           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     350           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
     351           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     352           0 :     return false;
     353             :   }
     354           0 :   return true;
     355             : }
     356             : 
     357             : static const JSJitInfo plugins_getterinfo = {
     358             :   { (JSJitGetterOp)get_plugins },
     359             :   { prototypes::id::HTMLDocument },
     360             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     361             :   JSJitInfo::Getter,
     362             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
     363             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     364             :   false,  /* isInfallible. False in setters. */
     365             :   true,  /* isMovable.  Not relevant for setters. */
     366             :   true, /* isEliminatable.  Not relevant for setters. */
     367             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     368             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     369             :   false,  /* isTypedMethod.  Only relevant for methods. */
     370             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     371             : };
     372             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     373             : static_assert(0 < 1, "There is no slot for us");
     374             : 
     375             : static bool
     376           0 : get_links(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
     377             : {
     378           0 :   auto result(StrongOrRawPtr<nsIHTMLCollection>(self->Links()));
     379           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     380           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
     381           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     382           0 :     return false;
     383             :   }
     384           0 :   return true;
     385             : }
     386             : 
     387             : static const JSJitInfo links_getterinfo = {
     388             :   { (JSJitGetterOp)get_links },
     389             :   { prototypes::id::HTMLDocument },
     390             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     391             :   JSJitInfo::Getter,
     392             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
     393             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     394             :   false,  /* isInfallible. False in setters. */
     395             :   true,  /* isMovable.  Not relevant for setters. */
     396             :   true, /* isEliminatable.  Not relevant for setters. */
     397             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     398             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     399             :   false,  /* isTypedMethod.  Only relevant for methods. */
     400             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     401             : };
     402             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     403             : static_assert(0 < 1, "There is no slot for us");
     404             : 
     405             : static bool
     406           0 : get_forms(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
     407             : {
     408           0 :   auto result(StrongOrRawPtr<nsIHTMLCollection>(self->Forms()));
     409           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     410           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
     411           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     412           0 :     return false;
     413             :   }
     414           0 :   return true;
     415             : }
     416             : 
     417             : static const JSJitInfo forms_getterinfo = {
     418             :   { (JSJitGetterOp)get_forms },
     419             :   { prototypes::id::HTMLDocument },
     420             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     421             :   JSJitInfo::Getter,
     422             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
     423             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     424             :   false,  /* isInfallible. False in setters. */
     425             :   true,  /* isMovable.  Not relevant for setters. */
     426             :   true, /* isEliminatable.  Not relevant for setters. */
     427             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     428             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     429             :   false,  /* isTypedMethod.  Only relevant for methods. */
     430             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     431             : };
     432             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     433             : static_assert(0 < 1, "There is no slot for us");
     434             : 
     435             : static bool
     436           0 : get_scripts(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
     437             : {
     438           0 :   auto result(StrongOrRawPtr<nsIHTMLCollection>(self->Scripts()));
     439           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     440           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
     441           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     442           0 :     return false;
     443             :   }
     444           0 :   return true;
     445             : }
     446             : 
     447             : static const JSJitInfo scripts_getterinfo = {
     448             :   { (JSJitGetterOp)get_scripts },
     449             :   { prototypes::id::HTMLDocument },
     450             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     451             :   JSJitInfo::Getter,
     452             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
     453             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     454             :   false,  /* isInfallible. False in setters. */
     455             :   true,  /* isMovable.  Not relevant for setters. */
     456             :   true, /* isEliminatable.  Not relevant for setters. */
     457             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     458             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     459             :   false,  /* isTypedMethod.  Only relevant for methods. */
     460             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     461             : };
     462             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     463             : static_assert(0 < 1, "There is no slot for us");
     464             : 
     465             : static bool
     466           0 : getElementsByName(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, const JSJitMethodCallArgs& args)
     467             : {
     468           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
     469           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "HTMLDocument.getElementsByName");
     470             :   }
     471           0 :   binding_detail::FakeString arg0;
     472           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
     473           0 :     return false;
     474             :   }
     475           0 :   auto result(StrongOrRawPtr<nsINodeList>(self->GetElementsByName(NonNullHelper(Constify(arg0)))));
     476           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     477           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
     478           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     479           0 :     return false;
     480             :   }
     481           0 :   return true;
     482             : }
     483             : 
     484             : static const JSJitInfo getElementsByName_methodinfo = {
     485             :   { (JSJitGetterOp)getElementsByName },
     486             :   { prototypes::id::HTMLDocument },
     487             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     488             :   JSJitInfo::Method,
     489             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     490             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
     491             :   false,  /* isInfallible. False in setters. */
     492             :   false,  /* isMovable.  Not relevant for setters. */
     493             :   false, /* isEliminatable.  Not relevant for setters. */
     494             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     495             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     496             :   false,  /* isTypedMethod.  Only relevant for methods. */
     497             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     498             : };
     499             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     500             : static_assert(0 < 1, "There is no slot for us");
     501             : 
     502             : static bool
     503           0 : open(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, const JSJitMethodCallArgs& args)
     504             : {
     505           0 :   unsigned argcount = std::min(args.length(), 4u);
     506           0 :   switch (argcount) {
     507             :     case 0: {
     508             :       MOZ_FALLTHROUGH;
     509             :     }
     510             :     case 1: {
     511             :       MOZ_FALLTHROUGH;
     512             :     }
     513             :     case 2: {
     514           0 :       binding_detail::FakeString arg0;
     515           0 :       if (args.hasDefined(0)) {
     516           0 :         if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
     517           0 :           return false;
     518             :         }
     519             :       } else {
     520             :         static const char16_t data[] = { 't', 'e', 'x', 't', '/', 'h', 't', 'm', 'l', 0 };
     521           0 :         arg0.Rebind(data, ArrayLength(data) - 1);
     522             :       }
     523           0 :       binding_detail::FakeString arg1;
     524           0 :       if (args.hasDefined(1)) {
     525           0 :         if (!ConvertJSValueToString(cx, args[1], eStringify, eStringify, arg1)) {
     526           0 :           return false;
     527             :         }
     528             :       } else {
     529             :         static const char16_t data[] = { 0 };
     530           0 :         arg1.Rebind(data, ArrayLength(data) - 1);
     531             :       }
     532           0 :       CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
     533           0 :       Maybe<AutoCEReaction> ceReaction;
     534           0 :       if (reactionsStack) {
     535           0 :         ceReaction.emplace(reactionsStack);
     536             :       }
     537           0 :       binding_detail::FastErrorResult rv;
     538           0 :       auto result(StrongOrRawPtr<nsIDocument>(self->Open(cx, NonNullHelper(Constify(arg0)), NonNullHelper(Constify(arg1)), rv)));
     539           0 :       if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     540           0 :         return false;
     541             :       }
     542           0 :       MOZ_ASSERT(!JS_IsExceptionPending(cx));
     543           0 :       if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
     544           0 :         MOZ_ASSERT(true || JS_IsExceptionPending(cx));
     545           0 :         return false;
     546             :       }
     547           0 :       return true;
     548             :       break;
     549             :     }
     550             :     case 3: {
     551             :       MOZ_FALLTHROUGH;
     552             :     }
     553             :     case 4: {
     554           0 :       binding_detail::FakeString arg0;
     555           0 :       if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
     556           0 :         return false;
     557             :       }
     558           0 :       binding_detail::FakeString arg1;
     559           0 :       if (!ConvertJSValueToString(cx, args[1], eStringify, eStringify, arg1)) {
     560           0 :         return false;
     561             :       }
     562           0 :       binding_detail::FakeString arg2;
     563           0 :       if (!ConvertJSValueToString(cx, args[2], eStringify, eStringify, arg2)) {
     564           0 :         return false;
     565             :       }
     566             :       bool arg3;
     567           0 :       if (args.hasDefined(3)) {
     568           0 :         if (!ValueToPrimitive<bool, eDefault>(cx, args[3], &arg3)) {
     569           0 :           return false;
     570             :         }
     571             :       } else {
     572           0 :         arg3 = false;
     573             :       }
     574           0 :       CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
     575           0 :       Maybe<AutoCEReaction> ceReaction;
     576           0 :       if (reactionsStack) {
     577           0 :         ceReaction.emplace(reactionsStack);
     578             :       }
     579           0 :       binding_detail::FastErrorResult rv;
     580           0 :       auto result(StrongOrRawPtr<nsPIDOMWindowOuter>(self->Open(cx, NonNullHelper(Constify(arg0)), NonNullHelper(Constify(arg1)), NonNullHelper(Constify(arg2)), arg3, rv)));
     581           0 :       if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     582           0 :         return false;
     583             :       }
     584           0 :       MOZ_ASSERT(!JS_IsExceptionPending(cx));
     585           0 :       if (!result) {
     586           0 :         args.rval().setNull();
     587           0 :         return true;
     588             :       }
     589           0 :       if (!WrapObject(cx, result, args.rval())) {
     590           0 :         return false;
     591             :       }
     592           0 :       return true;
     593             :       break;
     594             :     }
     595             :     default: {
     596           0 :       return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "HTMLDocument.open");
     597             :       break;
     598             :     }
     599             :   }
     600             :   MOZ_CRASH("We have an always-returning default case");
     601             :   return false;
     602             : }
     603             : 
     604             : static const JSJitInfo open_methodinfo = {
     605             :   { (JSJitGetterOp)open },
     606             :   { prototypes::id::HTMLDocument },
     607             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     608             :   JSJitInfo::Method,
     609             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     610             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
     611             :   false,  /* isInfallible. False in setters. */
     612             :   false,  /* isMovable.  Not relevant for setters. */
     613             :   false, /* isEliminatable.  Not relevant for setters. */
     614             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     615             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     616             :   false,  /* isTypedMethod.  Only relevant for methods. */
     617             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     618             : };
     619             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     620             : static_assert(0 < 1, "There is no slot for us");
     621             : 
     622             : static bool
     623           0 : close(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, const JSJitMethodCallArgs& args)
     624             : {
     625           0 :   CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
     626           0 :   Maybe<AutoCEReaction> ceReaction;
     627           0 :   if (reactionsStack) {
     628           0 :     ceReaction.emplace(reactionsStack);
     629             :   }
     630           0 :   binding_detail::FastErrorResult rv;
     631           0 :   self->Close(rv);
     632           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     633           0 :     return false;
     634             :   }
     635           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     636           0 :   args.rval().setUndefined();
     637           0 :   return true;
     638             : }
     639             : 
     640             : static const JSJitInfo close_methodinfo = {
     641             :   { (JSJitGetterOp)close },
     642             :   { prototypes::id::HTMLDocument },
     643             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     644             :   JSJitInfo::Method,
     645             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     646             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
     647             :   false,  /* isInfallible. False in setters. */
     648             :   false,  /* isMovable.  Not relevant for setters. */
     649             :   false, /* isEliminatable.  Not relevant for setters. */
     650             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     651             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     652             :   false,  /* isTypedMethod.  Only relevant for methods. */
     653             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     654             : };
     655             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     656             : static_assert(0 < 1, "There is no slot for us");
     657             : 
     658             : static bool
     659           0 : write(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, const JSJitMethodCallArgs& args)
     660             : {
     661           0 :   binding_detail::AutoSequence<nsString> arg0;
     662           0 :   if (args.length() > 0) {
     663           0 :     if (!arg0.SetCapacity(args.length() - 0, mozilla::fallible)) {
     664           0 :       JS_ReportOutOfMemory(cx);
     665           0 :       return false;
     666             :     }
     667           0 :     for (uint32_t variadicArg = 0; variadicArg < args.length(); ++variadicArg) {
     668           0 :       nsString& slot = *arg0.AppendElement(mozilla::fallible);
     669           0 :       if (!ConvertJSValueToString(cx, args[variadicArg], eStringify, eStringify, slot)) {
     670           0 :         return false;
     671             :       }
     672             :     }
     673             :   }
     674           0 :   CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
     675           0 :   Maybe<AutoCEReaction> ceReaction;
     676           0 :   if (reactionsStack) {
     677           0 :     ceReaction.emplace(reactionsStack);
     678             :   }
     679           0 :   binding_detail::FastErrorResult rv;
     680           0 :   self->Write(cx, NonNullHelper(Constify(arg0)), rv);
     681           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     682           0 :     return false;
     683             :   }
     684           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     685           0 :   args.rval().setUndefined();
     686           0 :   return true;
     687             : }
     688             : 
     689             : static const JSJitInfo write_methodinfo = {
     690             :   { (JSJitGetterOp)write },
     691             :   { prototypes::id::HTMLDocument },
     692             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     693             :   JSJitInfo::Method,
     694             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     695             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
     696             :   false,  /* isInfallible. False in setters. */
     697             :   false,  /* isMovable.  Not relevant for setters. */
     698             :   false, /* isEliminatable.  Not relevant for setters. */
     699             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     700             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     701             :   false,  /* isTypedMethod.  Only relevant for methods. */
     702             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     703             : };
     704             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     705             : static_assert(0 < 1, "There is no slot for us");
     706             : 
     707             : static bool
     708           0 : writeln(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, const JSJitMethodCallArgs& args)
     709             : {
     710           0 :   binding_detail::AutoSequence<nsString> arg0;
     711           0 :   if (args.length() > 0) {
     712           0 :     if (!arg0.SetCapacity(args.length() - 0, mozilla::fallible)) {
     713           0 :       JS_ReportOutOfMemory(cx);
     714           0 :       return false;
     715             :     }
     716           0 :     for (uint32_t variadicArg = 0; variadicArg < args.length(); ++variadicArg) {
     717           0 :       nsString& slot = *arg0.AppendElement(mozilla::fallible);
     718           0 :       if (!ConvertJSValueToString(cx, args[variadicArg], eStringify, eStringify, slot)) {
     719           0 :         return false;
     720             :       }
     721             :     }
     722             :   }
     723           0 :   CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
     724           0 :   Maybe<AutoCEReaction> ceReaction;
     725           0 :   if (reactionsStack) {
     726           0 :     ceReaction.emplace(reactionsStack);
     727             :   }
     728           0 :   binding_detail::FastErrorResult rv;
     729           0 :   self->Writeln(cx, NonNullHelper(Constify(arg0)), rv);
     730           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     731           0 :     return false;
     732             :   }
     733           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     734           0 :   args.rval().setUndefined();
     735           0 :   return true;
     736             : }
     737             : 
     738             : static const JSJitInfo writeln_methodinfo = {
     739             :   { (JSJitGetterOp)writeln },
     740             :   { prototypes::id::HTMLDocument },
     741             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     742             :   JSJitInfo::Method,
     743             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     744             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
     745             :   false,  /* isInfallible. False in setters. */
     746             :   false,  /* isMovable.  Not relevant for setters. */
     747             :   false, /* isEliminatable.  Not relevant for setters. */
     748             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     749             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     750             :   false,  /* isTypedMethod.  Only relevant for methods. */
     751             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     752             : };
     753             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     754             : static_assert(0 < 1, "There is no slot for us");
     755             : 
     756             : static bool
     757           0 : get_designMode(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
     758             : {
     759           0 :   JSCompartment* compartment = js::GetContextCompartment(cx);
     760           0 :   MOZ_ASSERT(compartment);
     761           0 :   JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
     762             :   // Initializing a nonnull is pretty darn annoying...
     763           0 :   NonNull<nsIPrincipal> subjectPrincipal;
     764           0 :   subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
     765           0 :   DOMString result;
     766           0 :   self->GetDesignMode(result, subjectPrincipal);
     767           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     768           0 :   if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
     769           0 :     return false;
     770             :   }
     771           0 :   return true;
     772             : }
     773             : 
     774             : static bool
     775           0 : set_designMode(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitSetterCallArgs args)
     776             : {
     777           0 :   binding_detail::FakeString arg0;
     778           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
     779           0 :     return false;
     780             :   }
     781           0 :   CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
     782           0 :   Maybe<AutoCEReaction> ceReaction;
     783           0 :   if (reactionsStack) {
     784           0 :     ceReaction.emplace(reactionsStack);
     785             :   }
     786           0 :   binding_detail::FastErrorResult rv;
     787           0 :   JSCompartment* compartment = js::GetContextCompartment(cx);
     788           0 :   MOZ_ASSERT(compartment);
     789           0 :   JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
     790             :   // Initializing a nonnull is pretty darn annoying...
     791           0 :   NonNull<nsIPrincipal> subjectPrincipal;
     792           0 :   subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
     793           0 :   self->SetDesignMode(NonNullHelper(Constify(arg0)), subjectPrincipal, rv);
     794           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     795           0 :     return false;
     796             :   }
     797           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     798             : 
     799           0 :   return true;
     800             : }
     801             : 
     802             : static const JSJitInfo designMode_getterinfo = {
     803             :   { (JSJitGetterOp)get_designMode },
     804             :   { prototypes::id::HTMLDocument },
     805             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     806             :   JSJitInfo::Getter,
     807             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     808             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
     809             :   false,  /* isInfallible. False in setters. */
     810             :   false,  /* isMovable.  Not relevant for setters. */
     811             :   false, /* isEliminatable.  Not relevant for setters. */
     812             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     813             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     814             :   false,  /* isTypedMethod.  Only relevant for methods. */
     815             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     816             : };
     817             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     818             : static_assert(0 < 1, "There is no slot for us");
     819             : static const JSJitInfo designMode_setterinfo = {
     820             :   { (JSJitGetterOp)set_designMode },
     821             :   { prototypes::id::HTMLDocument },
     822             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     823             :   JSJitInfo::Setter,
     824             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     825             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
     826             :   false,  /* isInfallible. False in setters. */
     827             :   false,  /* isMovable.  Not relevant for setters. */
     828             :   false, /* isEliminatable.  Not relevant for setters. */
     829             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     830             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     831             :   false,  /* isTypedMethod.  Only relevant for methods. */
     832             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     833             : };
     834             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     835             : static_assert(0 < 1, "There is no slot for us");
     836             : 
     837             : static bool
     838           0 : execCommand(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, const JSJitMethodCallArgs& args)
     839             : {
     840           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
     841           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "HTMLDocument.execCommand");
     842             :   }
     843           0 :   binding_detail::FakeString arg0;
     844           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
     845           0 :     return false;
     846             :   }
     847             :   bool arg1;
     848           0 :   if (args.hasDefined(1)) {
     849           0 :     if (!ValueToPrimitive<bool, eDefault>(cx, args[1], &arg1)) {
     850           0 :       return false;
     851             :     }
     852             :   } else {
     853           0 :     arg1 = false;
     854             :   }
     855           0 :   binding_detail::FakeString arg2;
     856           0 :   if (args.hasDefined(2)) {
     857           0 :     if (!ConvertJSValueToString(cx, args[2], eStringify, eStringify, arg2)) {
     858           0 :       return false;
     859             :     }
     860             :   } else {
     861             :     static const char16_t data[] = { 0 };
     862           0 :     arg2.Rebind(data, ArrayLength(data) - 1);
     863             :   }
     864           0 :   CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
     865           0 :   Maybe<AutoCEReaction> ceReaction;
     866           0 :   if (reactionsStack) {
     867           0 :     ceReaction.emplace(reactionsStack);
     868             :   }
     869           0 :   binding_detail::FastErrorResult rv;
     870           0 :   JSCompartment* compartment = js::GetContextCompartment(cx);
     871           0 :   MOZ_ASSERT(compartment);
     872           0 :   JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
     873             :   // Initializing a nonnull is pretty darn annoying...
     874           0 :   NonNull<nsIPrincipal> subjectPrincipal;
     875           0 :   subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
     876           0 :   bool result(self->ExecCommand(NonNullHelper(Constify(arg0)), arg1, NonNullHelper(Constify(arg2)), subjectPrincipal, rv));
     877           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     878           0 :     return false;
     879             :   }
     880           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     881           0 :   args.rval().setBoolean(result);
     882           0 :   return true;
     883             : }
     884             : 
     885             : static const JSJitInfo execCommand_methodinfo = {
     886             :   { (JSJitGetterOp)execCommand },
     887             :   { prototypes::id::HTMLDocument },
     888             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     889             :   JSJitInfo::Method,
     890             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     891             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
     892             :   false,  /* isInfallible. False in setters. */
     893             :   false,  /* isMovable.  Not relevant for setters. */
     894             :   false, /* isEliminatable.  Not relevant for setters. */
     895             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     896             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     897             :   false,  /* isTypedMethod.  Only relevant for methods. */
     898             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     899             : };
     900             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     901             : static_assert(0 < 1, "There is no slot for us");
     902             : 
     903             : static bool
     904           0 : queryCommandEnabled(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, const JSJitMethodCallArgs& args)
     905             : {
     906           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
     907           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "HTMLDocument.queryCommandEnabled");
     908             :   }
     909           0 :   binding_detail::FakeString arg0;
     910           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
     911           0 :     return false;
     912             :   }
     913           0 :   binding_detail::FastErrorResult rv;
     914           0 :   JSCompartment* compartment = js::GetContextCompartment(cx);
     915           0 :   MOZ_ASSERT(compartment);
     916           0 :   JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
     917             :   // Initializing a nonnull is pretty darn annoying...
     918           0 :   NonNull<nsIPrincipal> subjectPrincipal;
     919           0 :   subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
     920           0 :   bool result(self->QueryCommandEnabled(NonNullHelper(Constify(arg0)), subjectPrincipal, rv));
     921           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     922           0 :     return false;
     923             :   }
     924           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     925           0 :   args.rval().setBoolean(result);
     926           0 :   return true;
     927             : }
     928             : 
     929             : static const JSJitInfo queryCommandEnabled_methodinfo = {
     930             :   { (JSJitGetterOp)queryCommandEnabled },
     931             :   { prototypes::id::HTMLDocument },
     932             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     933             :   JSJitInfo::Method,
     934             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     935             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
     936             :   false,  /* isInfallible. False in setters. */
     937             :   false,  /* isMovable.  Not relevant for setters. */
     938             :   false, /* isEliminatable.  Not relevant for setters. */
     939             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     940             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     941             :   false,  /* isTypedMethod.  Only relevant for methods. */
     942             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     943             : };
     944             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     945             : static_assert(0 < 1, "There is no slot for us");
     946             : 
     947             : static bool
     948           0 : queryCommandIndeterm(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, const JSJitMethodCallArgs& args)
     949             : {
     950           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
     951           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "HTMLDocument.queryCommandIndeterm");
     952             :   }
     953           0 :   binding_detail::FakeString arg0;
     954           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
     955           0 :     return false;
     956             :   }
     957           0 :   binding_detail::FastErrorResult rv;
     958           0 :   bool result(self->QueryCommandIndeterm(NonNullHelper(Constify(arg0)), rv));
     959           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     960           0 :     return false;
     961             :   }
     962           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
     963           0 :   args.rval().setBoolean(result);
     964           0 :   return true;
     965             : }
     966             : 
     967             : static const JSJitInfo queryCommandIndeterm_methodinfo = {
     968             :   { (JSJitGetterOp)queryCommandIndeterm },
     969             :   { prototypes::id::HTMLDocument },
     970             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
     971             :   JSJitInfo::Method,
     972             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
     973             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
     974             :   false,  /* isInfallible. False in setters. */
     975             :   false,  /* isMovable.  Not relevant for setters. */
     976             :   false, /* isEliminatable.  Not relevant for setters. */
     977             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
     978             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
     979             :   false,  /* isTypedMethod.  Only relevant for methods. */
     980             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
     981             : };
     982             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
     983             : static_assert(0 < 1, "There is no slot for us");
     984             : 
     985             : static bool
     986           0 : queryCommandState(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, const JSJitMethodCallArgs& args)
     987             : {
     988           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
     989           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "HTMLDocument.queryCommandState");
     990             :   }
     991           0 :   binding_detail::FakeString arg0;
     992           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
     993           0 :     return false;
     994             :   }
     995           0 :   binding_detail::FastErrorResult rv;
     996           0 :   bool result(self->QueryCommandState(NonNullHelper(Constify(arg0)), rv));
     997           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
     998           0 :     return false;
     999             :   }
    1000           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1001           0 :   args.rval().setBoolean(result);
    1002           0 :   return true;
    1003             : }
    1004             : 
    1005             : static const JSJitInfo queryCommandState_methodinfo = {
    1006             :   { (JSJitGetterOp)queryCommandState },
    1007             :   { prototypes::id::HTMLDocument },
    1008             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1009             :   JSJitInfo::Method,
    1010             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1011             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    1012             :   false,  /* isInfallible. False in setters. */
    1013             :   false,  /* isMovable.  Not relevant for setters. */
    1014             :   false, /* isEliminatable.  Not relevant for setters. */
    1015             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1016             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1017             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1018             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1019             : };
    1020             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1021             : static_assert(0 < 1, "There is no slot for us");
    1022             : 
    1023             : static bool
    1024           0 : queryCommandSupported(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, const JSJitMethodCallArgs& args)
    1025             : {
    1026           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    1027           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "HTMLDocument.queryCommandSupported");
    1028             :   }
    1029           0 :   binding_detail::FakeString arg0;
    1030           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    1031           0 :     return false;
    1032             :   }
    1033           0 :   bool result(self->QueryCommandSupported(NonNullHelper(Constify(arg0)), nsContentUtils::IsSystemCaller(cx) ? CallerType::System : CallerType::NonSystem));
    1034           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1035           0 :   args.rval().setBoolean(result);
    1036           0 :   return true;
    1037             : }
    1038             : 
    1039             : static const JSJitInfo queryCommandSupported_methodinfo = {
    1040             :   { (JSJitGetterOp)queryCommandSupported },
    1041             :   { prototypes::id::HTMLDocument },
    1042             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1043             :   JSJitInfo::Method,
    1044             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1045             :   JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
    1046             :   false,  /* isInfallible. False in setters. */
    1047             :   false,  /* isMovable.  Not relevant for setters. */
    1048             :   false, /* isEliminatable.  Not relevant for setters. */
    1049             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1050             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1051             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1052             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1053             : };
    1054             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1055             : static_assert(0 < 1, "There is no slot for us");
    1056             : 
    1057             : static bool
    1058           0 : queryCommandValue(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, const JSJitMethodCallArgs& args)
    1059             : {
    1060           0 :   if (MOZ_UNLIKELY(args.length() < 1)) {
    1061           0 :     return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "HTMLDocument.queryCommandValue");
    1062             :   }
    1063           0 :   binding_detail::FakeString arg0;
    1064           0 :   if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    1065           0 :     return false;
    1066             :   }
    1067           0 :   binding_detail::FastErrorResult rv;
    1068           0 :   DOMString result;
    1069           0 :   self->QueryCommandValue(NonNullHelper(Constify(arg0)), result, rv);
    1070           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1071           0 :     return false;
    1072             :   }
    1073           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1074           0 :   if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    1075           0 :     return false;
    1076             :   }
    1077           0 :   return true;
    1078             : }
    1079             : 
    1080             : static const JSJitInfo queryCommandValue_methodinfo = {
    1081             :   { (JSJitGetterOp)queryCommandValue },
    1082             :   { prototypes::id::HTMLDocument },
    1083             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1084             :   JSJitInfo::Method,
    1085             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1086             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
    1087             :   false,  /* isInfallible. False in setters. */
    1088             :   false,  /* isMovable.  Not relevant for setters. */
    1089             :   false, /* isEliminatable.  Not relevant for setters. */
    1090             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1091             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1092             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1093             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1094             : };
    1095             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1096             : static_assert(0 < 1, "There is no slot for us");
    1097             : 
    1098             : static bool
    1099           0 : get_fgColor(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
    1100             : {
    1101           0 :   DOMString result;
    1102           0 :   self->GetFgColor(result);
    1103           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1104           0 :   if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    1105           0 :     return false;
    1106             :   }
    1107           0 :   return true;
    1108             : }
    1109             : 
    1110             : static bool
    1111           0 : set_fgColor(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitSetterCallArgs args)
    1112             : {
    1113           0 :   binding_detail::FakeString arg0;
    1114           0 :   if (!ConvertJSValueToString(cx, args[0], eEmpty, eStringify, arg0)) {
    1115           0 :     return false;
    1116             :   }
    1117           0 :   CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
    1118           0 :   Maybe<AutoCEReaction> ceReaction;
    1119           0 :   if (reactionsStack) {
    1120           0 :     ceReaction.emplace(reactionsStack);
    1121             :   }
    1122           0 :   self->SetFgColor(NonNullHelper(Constify(arg0)));
    1123           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1124             : 
    1125           0 :   return true;
    1126             : }
    1127             : 
    1128             : static const JSJitInfo fgColor_getterinfo = {
    1129             :   { (JSJitGetterOp)get_fgColor },
    1130             :   { prototypes::id::HTMLDocument },
    1131             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1132             :   JSJitInfo::Getter,
    1133             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1134             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
    1135             :   false,  /* isInfallible. False in setters. */
    1136             :   false,  /* isMovable.  Not relevant for setters. */
    1137             :   false, /* isEliminatable.  Not relevant for setters. */
    1138             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1139             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1140             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1141             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1142             : };
    1143             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1144             : static_assert(0 < 1, "There is no slot for us");
    1145             : static const JSJitInfo fgColor_setterinfo = {
    1146             :   { (JSJitGetterOp)set_fgColor },
    1147             :   { prototypes::id::HTMLDocument },
    1148             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1149             :   JSJitInfo::Setter,
    1150             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1151             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    1152             :   false,  /* isInfallible. False in setters. */
    1153             :   false,  /* isMovable.  Not relevant for setters. */
    1154             :   false, /* isEliminatable.  Not relevant for setters. */
    1155             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1156             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1157             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1158             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1159             : };
    1160             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1161             : static_assert(0 < 1, "There is no slot for us");
    1162             : 
    1163             : static bool
    1164           0 : get_linkColor(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
    1165             : {
    1166           0 :   DOMString result;
    1167           0 :   self->GetLinkColor(result);
    1168           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1169           0 :   if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    1170           0 :     return false;
    1171             :   }
    1172           0 :   return true;
    1173             : }
    1174             : 
    1175             : static bool
    1176           0 : set_linkColor(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitSetterCallArgs args)
    1177             : {
    1178           0 :   binding_detail::FakeString arg0;
    1179           0 :   if (!ConvertJSValueToString(cx, args[0], eEmpty, eStringify, arg0)) {
    1180           0 :     return false;
    1181             :   }
    1182           0 :   CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
    1183           0 :   Maybe<AutoCEReaction> ceReaction;
    1184           0 :   if (reactionsStack) {
    1185           0 :     ceReaction.emplace(reactionsStack);
    1186             :   }
    1187           0 :   self->SetLinkColor(NonNullHelper(Constify(arg0)));
    1188           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1189             : 
    1190           0 :   return true;
    1191             : }
    1192             : 
    1193             : static const JSJitInfo linkColor_getterinfo = {
    1194             :   { (JSJitGetterOp)get_linkColor },
    1195             :   { prototypes::id::HTMLDocument },
    1196             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1197             :   JSJitInfo::Getter,
    1198             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1199             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
    1200             :   false,  /* isInfallible. False in setters. */
    1201             :   false,  /* isMovable.  Not relevant for setters. */
    1202             :   false, /* isEliminatable.  Not relevant for setters. */
    1203             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1204             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1205             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1206             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1207             : };
    1208             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1209             : static_assert(0 < 1, "There is no slot for us");
    1210             : static const JSJitInfo linkColor_setterinfo = {
    1211             :   { (JSJitGetterOp)set_linkColor },
    1212             :   { prototypes::id::HTMLDocument },
    1213             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1214             :   JSJitInfo::Setter,
    1215             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1216             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    1217             :   false,  /* isInfallible. False in setters. */
    1218             :   false,  /* isMovable.  Not relevant for setters. */
    1219             :   false, /* isEliminatable.  Not relevant for setters. */
    1220             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1221             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1222             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1223             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1224             : };
    1225             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1226             : static_assert(0 < 1, "There is no slot for us");
    1227             : 
    1228             : static bool
    1229           0 : get_vlinkColor(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
    1230             : {
    1231           0 :   DOMString result;
    1232           0 :   self->GetVlinkColor(result);
    1233           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1234           0 :   if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    1235           0 :     return false;
    1236             :   }
    1237           0 :   return true;
    1238             : }
    1239             : 
    1240             : static bool
    1241           0 : set_vlinkColor(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitSetterCallArgs args)
    1242             : {
    1243           0 :   binding_detail::FakeString arg0;
    1244           0 :   if (!ConvertJSValueToString(cx, args[0], eEmpty, eStringify, arg0)) {
    1245           0 :     return false;
    1246             :   }
    1247           0 :   CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
    1248           0 :   Maybe<AutoCEReaction> ceReaction;
    1249           0 :   if (reactionsStack) {
    1250           0 :     ceReaction.emplace(reactionsStack);
    1251             :   }
    1252           0 :   self->SetVlinkColor(NonNullHelper(Constify(arg0)));
    1253           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1254             : 
    1255           0 :   return true;
    1256             : }
    1257             : 
    1258             : static const JSJitInfo vlinkColor_getterinfo = {
    1259             :   { (JSJitGetterOp)get_vlinkColor },
    1260             :   { prototypes::id::HTMLDocument },
    1261             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1262             :   JSJitInfo::Getter,
    1263             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1264             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
    1265             :   false,  /* isInfallible. False in setters. */
    1266             :   false,  /* isMovable.  Not relevant for setters. */
    1267             :   false, /* isEliminatable.  Not relevant for setters. */
    1268             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1269             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1270             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1271             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1272             : };
    1273             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1274             : static_assert(0 < 1, "There is no slot for us");
    1275             : static const JSJitInfo vlinkColor_setterinfo = {
    1276             :   { (JSJitGetterOp)set_vlinkColor },
    1277             :   { prototypes::id::HTMLDocument },
    1278             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1279             :   JSJitInfo::Setter,
    1280             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1281             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    1282             :   false,  /* isInfallible. False in setters. */
    1283             :   false,  /* isMovable.  Not relevant for setters. */
    1284             :   false, /* isEliminatable.  Not relevant for setters. */
    1285             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1286             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1287             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1288             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1289             : };
    1290             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1291             : static_assert(0 < 1, "There is no slot for us");
    1292             : 
    1293             : static bool
    1294           0 : get_alinkColor(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
    1295             : {
    1296           0 :   DOMString result;
    1297           0 :   self->GetAlinkColor(result);
    1298           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1299           0 :   if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    1300           0 :     return false;
    1301             :   }
    1302           0 :   return true;
    1303             : }
    1304             : 
    1305             : static bool
    1306           0 : set_alinkColor(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitSetterCallArgs args)
    1307             : {
    1308           0 :   binding_detail::FakeString arg0;
    1309           0 :   if (!ConvertJSValueToString(cx, args[0], eEmpty, eStringify, arg0)) {
    1310           0 :     return false;
    1311             :   }
    1312           0 :   CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
    1313           0 :   Maybe<AutoCEReaction> ceReaction;
    1314           0 :   if (reactionsStack) {
    1315           0 :     ceReaction.emplace(reactionsStack);
    1316             :   }
    1317           0 :   self->SetAlinkColor(NonNullHelper(Constify(arg0)));
    1318           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1319             : 
    1320           0 :   return true;
    1321             : }
    1322             : 
    1323             : static const JSJitInfo alinkColor_getterinfo = {
    1324             :   { (JSJitGetterOp)get_alinkColor },
    1325             :   { prototypes::id::HTMLDocument },
    1326             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1327             :   JSJitInfo::Getter,
    1328             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1329             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
    1330             :   false,  /* isInfallible. False in setters. */
    1331             :   false,  /* isMovable.  Not relevant for setters. */
    1332             :   false, /* isEliminatable.  Not relevant for setters. */
    1333             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1334             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1335             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1336             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1337             : };
    1338             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1339             : static_assert(0 < 1, "There is no slot for us");
    1340             : static const JSJitInfo alinkColor_setterinfo = {
    1341             :   { (JSJitGetterOp)set_alinkColor },
    1342             :   { prototypes::id::HTMLDocument },
    1343             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1344             :   JSJitInfo::Setter,
    1345             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1346             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    1347             :   false,  /* isInfallible. False in setters. */
    1348             :   false,  /* isMovable.  Not relevant for setters. */
    1349             :   false, /* isEliminatable.  Not relevant for setters. */
    1350             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1351             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1352             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1353             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1354             : };
    1355             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1356             : static_assert(0 < 1, "There is no slot for us");
    1357             : 
    1358             : static bool
    1359           0 : get_bgColor(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
    1360             : {
    1361           0 :   DOMString result;
    1362           0 :   self->GetBgColor(result);
    1363           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1364           0 :   if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    1365           0 :     return false;
    1366             :   }
    1367           0 :   return true;
    1368             : }
    1369             : 
    1370             : static bool
    1371           0 : set_bgColor(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitSetterCallArgs args)
    1372             : {
    1373           0 :   binding_detail::FakeString arg0;
    1374           0 :   if (!ConvertJSValueToString(cx, args[0], eEmpty, eStringify, arg0)) {
    1375           0 :     return false;
    1376             :   }
    1377           0 :   CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
    1378           0 :   Maybe<AutoCEReaction> ceReaction;
    1379           0 :   if (reactionsStack) {
    1380           0 :     ceReaction.emplace(reactionsStack);
    1381             :   }
    1382           0 :   self->SetBgColor(NonNullHelper(Constify(arg0)));
    1383           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1384             : 
    1385           0 :   return true;
    1386             : }
    1387             : 
    1388             : static const JSJitInfo bgColor_getterinfo = {
    1389             :   { (JSJitGetterOp)get_bgColor },
    1390             :   { prototypes::id::HTMLDocument },
    1391             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1392             :   JSJitInfo::Getter,
    1393             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1394             :   JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
    1395             :   false,  /* isInfallible. False in setters. */
    1396             :   false,  /* isMovable.  Not relevant for setters. */
    1397             :   false, /* isEliminatable.  Not relevant for setters. */
    1398             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1399             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1400             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1401             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1402             : };
    1403             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1404             : static_assert(0 < 1, "There is no slot for us");
    1405             : static const JSJitInfo bgColor_setterinfo = {
    1406             :   { (JSJitGetterOp)set_bgColor },
    1407             :   { prototypes::id::HTMLDocument },
    1408             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1409             :   JSJitInfo::Setter,
    1410             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1411             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    1412             :   false,  /* isInfallible. False in setters. */
    1413             :   false,  /* isMovable.  Not relevant for setters. */
    1414             :   false, /* isEliminatable.  Not relevant for setters. */
    1415             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1416             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1417             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1418             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1419             : };
    1420             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1421             : static_assert(0 < 1, "There is no slot for us");
    1422             : 
    1423             : static bool
    1424           0 : get_anchors(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
    1425             : {
    1426           0 :   auto result(StrongOrRawPtr<nsIHTMLCollection>(self->Anchors()));
    1427           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1428           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    1429           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1430           0 :     return false;
    1431             :   }
    1432           0 :   return true;
    1433             : }
    1434             : 
    1435             : static const JSJitInfo anchors_getterinfo = {
    1436             :   { (JSJitGetterOp)get_anchors },
    1437             :   { prototypes::id::HTMLDocument },
    1438             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1439             :   JSJitInfo::Getter,
    1440             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    1441             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1442             :   false,  /* isInfallible. False in setters. */
    1443             :   true,  /* isMovable.  Not relevant for setters. */
    1444             :   true, /* isEliminatable.  Not relevant for setters. */
    1445             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1446             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1447             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1448             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1449             : };
    1450             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1451             : static_assert(0 < 1, "There is no slot for us");
    1452             : 
    1453             : static bool
    1454           0 : get_applets(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
    1455             : {
    1456           0 :   auto result(StrongOrRawPtr<nsIHTMLCollection>(self->Applets()));
    1457           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1458           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    1459           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1460           0 :     return false;
    1461             :   }
    1462           0 :   return true;
    1463             : }
    1464             : 
    1465             : static const JSJitInfo applets_getterinfo = {
    1466             :   { (JSJitGetterOp)get_applets },
    1467             :   { prototypes::id::HTMLDocument },
    1468             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1469             :   JSJitInfo::Getter,
    1470             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    1471             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1472             :   false,  /* isInfallible. False in setters. */
    1473             :   true,  /* isMovable.  Not relevant for setters. */
    1474             :   true, /* isEliminatable.  Not relevant for setters. */
    1475             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1476             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1477             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1478             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1479             : };
    1480             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1481             : static_assert(0 < 1, "There is no slot for us");
    1482             : 
    1483             : static bool
    1484           0 : clear(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, const JSJitMethodCallArgs& args)
    1485             : {
    1486           0 :   self->Clear();
    1487           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1488           0 :   args.rval().setUndefined();
    1489           0 :   return true;
    1490             : }
    1491             : 
    1492             : static const JSJitInfo clear_methodinfo = {
    1493             :   { (JSJitGetterOp)clear },
    1494             :   { prototypes::id::HTMLDocument },
    1495             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1496             :   JSJitInfo::Method,
    1497             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1498             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    1499             :   true,  /* isInfallible. False in setters. */
    1500             :   false,  /* isMovable.  Not relevant for setters. */
    1501             :   false, /* isEliminatable.  Not relevant for setters. */
    1502             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1503             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1504             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1505             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1506             : };
    1507             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1508             : static_assert(0 < 1, "There is no slot for us");
    1509             : 
    1510             : static bool
    1511           0 : get_all(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
    1512             : {
    1513           0 :   auto result(StrongOrRawPtr<mozilla::dom::HTMLAllCollection>(self->All()));
    1514           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1515           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    1516           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1517           0 :     return false;
    1518             :   }
    1519           0 :   return true;
    1520             : }
    1521             : 
    1522             : static const JSJitInfo all_getterinfo = {
    1523             :   { (JSJitGetterOp)get_all },
    1524             :   { prototypes::id::HTMLDocument },
    1525             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1526             :   JSJitInfo::Getter,
    1527             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1528             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1529             :   false,  /* isInfallible. False in setters. */
    1530             :   false,  /* isMovable.  Not relevant for setters. */
    1531             :   false, /* isEliminatable.  Not relevant for setters. */
    1532             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1533             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1534             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1535             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1536             : };
    1537             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1538             : static_assert(0 < 1, "There is no slot for us");
    1539             : 
    1540             : static bool
    1541           0 : getSelection(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, const JSJitMethodCallArgs& args)
    1542             : {
    1543           0 :   binding_detail::FastErrorResult rv;
    1544           0 :   auto result(StrongOrRawPtr<mozilla::dom::Selection>(self->GetSelection(rv)));
    1545           0 :   if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    1546           0 :     return false;
    1547             :   }
    1548           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1549           0 :   if (!result) {
    1550           0 :     args.rval().setNull();
    1551           0 :     return true;
    1552             :   }
    1553           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    1554           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1555           0 :     return false;
    1556             :   }
    1557           0 :   return true;
    1558             : }
    1559             : 
    1560             : static const JSJitInfo getSelection_methodinfo = {
    1561             :   { (JSJitGetterOp)getSelection },
    1562             :   { prototypes::id::HTMLDocument },
    1563             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1564             :   JSJitInfo::Method,
    1565             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1566             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    1567             :   false,  /* isInfallible. False in setters. */
    1568             :   false,  /* isMovable.  Not relevant for setters. */
    1569             :   false, /* isEliminatable.  Not relevant for setters. */
    1570             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1571             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1572             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1573             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1574             : };
    1575             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1576             : static_assert(0 < 1, "There is no slot for us");
    1577             : 
    1578             : static bool
    1579           0 : captureEvents(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, const JSJitMethodCallArgs& args)
    1580             : {
    1581           0 :   self->CaptureEvents();
    1582           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1583           0 :   args.rval().setUndefined();
    1584           0 :   return true;
    1585             : }
    1586             : 
    1587             : static const JSJitInfo captureEvents_methodinfo = {
    1588             :   { (JSJitGetterOp)captureEvents },
    1589             :   { prototypes::id::HTMLDocument },
    1590             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1591             :   JSJitInfo::Method,
    1592             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1593             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    1594             :   true,  /* isInfallible. False in setters. */
    1595             :   false,  /* isMovable.  Not relevant for setters. */
    1596             :   false, /* isEliminatable.  Not relevant for setters. */
    1597             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1598             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1599             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1600             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1601             : };
    1602             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1603             : static_assert(0 < 1, "There is no slot for us");
    1604             : 
    1605             : static bool
    1606           0 : releaseEvents(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, const JSJitMethodCallArgs& args)
    1607             : {
    1608           0 :   self->ReleaseEvents();
    1609           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1610           0 :   args.rval().setUndefined();
    1611           0 :   return true;
    1612             : }
    1613             : 
    1614             : static const JSJitInfo releaseEvents_methodinfo = {
    1615             :   { (JSJitGetterOp)releaseEvents },
    1616             :   { prototypes::id::HTMLDocument },
    1617             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1618             :   JSJitInfo::Method,
    1619             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1620             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    1621             :   true,  /* isInfallible. False in setters. */
    1622             :   false,  /* isMovable.  Not relevant for setters. */
    1623             :   false, /* isEliminatable.  Not relevant for setters. */
    1624             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1625             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1626             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1627             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1628             : };
    1629             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1630             : static_assert(0 < 1, "There is no slot for us");
    1631             : 
    1632             : static bool
    1633           0 : get_blockedTrackingNodeCount(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
    1634             : {
    1635           0 :   int32_t result(self->BlockedTrackingNodeCount());
    1636           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1637           0 :   args.rval().setInt32(int32_t(result));
    1638           0 :   return true;
    1639             : }
    1640             : 
    1641             : static const JSJitInfo blockedTrackingNodeCount_getterinfo = {
    1642             :   { (JSJitGetterOp)get_blockedTrackingNodeCount },
    1643             :   { prototypes::id::HTMLDocument },
    1644             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1645             :   JSJitInfo::Getter,
    1646             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    1647             :   JSVAL_TYPE_INT32,  /* returnType.  Not relevant for setters. */
    1648             :   true,  /* isInfallible. False in setters. */
    1649             :   true,  /* isMovable.  Not relevant for setters. */
    1650             :   true, /* isEliminatable.  Not relevant for setters. */
    1651             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1652             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1653             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1654             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1655             : };
    1656             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1657             : static_assert(0 < 1, "There is no slot for us");
    1658             : 
    1659             : static bool
    1660           0 : get_blockedTrackingNodes(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
    1661             : {
    1662           0 :   auto result(StrongOrRawPtr<nsINodeList>(self->BlockedTrackingNodes()));
    1663           0 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1664           0 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    1665           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1666           0 :     return false;
    1667             :   }
    1668           0 :   return true;
    1669             : }
    1670             : 
    1671             : static const JSJitInfo blockedTrackingNodes_getterinfo = {
    1672             :   { (JSJitGetterOp)get_blockedTrackingNodes },
    1673             :   { prototypes::id::HTMLDocument },
    1674             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1675             :   JSJitInfo::Getter,
    1676             :   JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    1677             :   JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
    1678             :   false,  /* isInfallible. False in setters. */
    1679             :   true,  /* isMovable.  Not relevant for setters. */
    1680             :   true, /* isEliminatable.  Not relevant for setters. */
    1681             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1682             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1683             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1684             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1685             : };
    1686             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1687             : static_assert(0 < 1, "There is no slot for us");
    1688             : 
    1689             : static bool
    1690           1 : get_location(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitGetterCallArgs args)
    1691             : {
    1692           2 :   auto result(StrongOrRawPtr<mozilla::dom::Location>(self->GetLocation()));
    1693           1 :   MOZ_ASSERT(!JS_IsExceptionPending(cx));
    1694           1 :   if (!result) {
    1695           0 :     args.rval().setNull();
    1696           0 :     return true;
    1697             :   }
    1698           1 :   if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    1699           0 :     MOZ_ASSERT(true || JS_IsExceptionPending(cx));
    1700           0 :     return false;
    1701             :   }
    1702           1 :   return true;
    1703             : }
    1704             : 
    1705             : static bool
    1706           0 : set_location(JSContext* cx, JS::Handle<JSObject*> obj, nsHTMLDocument* self, JSJitSetterCallArgs args)
    1707             : {
    1708           0 :   JS::Rooted<JS::Value> v(cx);
    1709           0 :   if (!JS_GetProperty(cx, obj, "location", &v)) {
    1710           0 :     return false;
    1711             :   }
    1712             : 
    1713           0 :   if (!v.isObject()) {
    1714           0 :     return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "HTMLDocument.location");
    1715             :   }
    1716             : 
    1717           0 :   JS::Rooted<JSObject*> targetObj(cx, &v.toObject());
    1718           0 :   return JS_SetProperty(cx, targetObj, "href", args[0]);
    1719             : }
    1720             : 
    1721             : static const JSJitInfo location_getterinfo = {
    1722             :   { (JSJitGetterOp)get_location },
    1723             :   { prototypes::id::HTMLDocument },
    1724             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1725             :   JSJitInfo::Getter,
    1726             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1727             :   JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
    1728             :   false,  /* isInfallible. False in setters. */
    1729             :   false,  /* isMovable.  Not relevant for setters. */
    1730             :   false, /* isEliminatable.  Not relevant for setters. */
    1731             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1732             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1733             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1734             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1735             : };
    1736             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1737             : static_assert(0 < 1, "There is no slot for us");
    1738             : static const JSJitInfo location_setterinfo = {
    1739             :   { (JSJitGetterOp)set_location },
    1740             :   { prototypes::id::HTMLDocument },
    1741             :   { PrototypeTraits<prototypes::id::HTMLDocument>::Depth },
    1742             :   JSJitInfo::Setter,
    1743             :   JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    1744             :   JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
    1745             :   false,  /* isInfallible. False in setters. */
    1746             :   false,  /* isMovable.  Not relevant for setters. */
    1747             :   false, /* isEliminatable.  Not relevant for setters. */
    1748             :   false, /* isAlwaysInSlot.  Only relevant for getters. */
    1749             :   false, /* isLazilyCachedInSlot.  Only relevant for getters. */
    1750             :   false,  /* isTypedMethod.  Only relevant for methods. */
    1751             :   0   /* Reserved slot index, if we're stored in a slot, else 0. */
    1752             : };
    1753             : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
    1754             : static_assert(0 < 1, "There is no slot for us");
    1755             : 
    1756             : static void
    1757           0 : _objectMoved(JSObject* obj, const JSObject* old)
    1758             : {
    1759           0 :   nsHTMLDocument* self = UnwrapPossiblyNotInitializedDOMObject<nsHTMLDocument>(obj);
    1760           0 :   if (self) {
    1761           0 :     UpdateWrapper(self, self, obj, old);
    1762             :   }
    1763           0 : }
    1764             : 
    1765             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    1766             : #if defined(__clang__)
    1767             : #pragma clang diagnostic push
    1768             : #pragma clang diagnostic ignored "-Wmissing-braces"
    1769             : #endif
    1770             : static const JSFunctionSpec sMethods_specs[] = {
    1771             :   JS_FNSPEC("getElementsByName", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&getElementsByName_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    1772             :   JS_FNSPEC("open", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&open_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    1773             :   JS_FNSPEC("close", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&close_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    1774             :   JS_FNSPEC("write", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&write_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    1775             :   JS_FNSPEC("writeln", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&writeln_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    1776             :   JS_FNSPEC("execCommand", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&execCommand_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    1777             :   JS_FNSPEC("queryCommandEnabled", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&queryCommandEnabled_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    1778             :   JS_FNSPEC("queryCommandIndeterm", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&queryCommandIndeterm_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    1779             :   JS_FNSPEC("queryCommandState", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&queryCommandState_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    1780             :   JS_FNSPEC("queryCommandSupported", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&queryCommandSupported_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    1781             :   JS_FNSPEC("queryCommandValue", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&queryCommandValue_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
    1782             :   JS_FNSPEC("clear", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&clear_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    1783             :   JS_FNSPEC("getSelection", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&getSelection_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    1784             :   JS_FNSPEC("captureEvents", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&captureEvents_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    1785             :   JS_FNSPEC("releaseEvents", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&releaseEvents_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
    1786             :   JS_FS_END
    1787             : };
    1788             : #if defined(__clang__)
    1789             : #pragma clang diagnostic pop
    1790             : #endif
    1791             : 
    1792             : 
    1793             : // Can't be const because the pref-enabled boolean needs to be writable
    1794             : static Prefable<const JSFunctionSpec> sMethods[] = {
    1795             :   { nullptr, &sMethods_specs[0] },
    1796             :   { nullptr, nullptr }
    1797             : };
    1798             : 
    1799             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    1800             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    1801             : static_assert(15 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    1802             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    1803             : 
    1804             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    1805             : #if defined(__clang__)
    1806             : #pragma clang diagnostic push
    1807             : #pragma clang diagnostic ignored "-Wmissing-braces"
    1808             : #endif
    1809             : static const JSPropertySpec sAttributes_specs[] = {
    1810             :   { "domain", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &domain_getterinfo, GenericBindingSetter, &domain_setterinfo },
    1811             :   { "cookie", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &cookie_getterinfo, GenericBindingSetter, &cookie_setterinfo },
    1812             :   { "body", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &body_getterinfo, GenericBindingSetter, &body_setterinfo },
    1813             :   { "head", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &head_getterinfo, nullptr, nullptr },
    1814             :   { "images", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &images_getterinfo, nullptr, nullptr },
    1815             :   { "embeds", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &embeds_getterinfo, nullptr, nullptr },
    1816             :   { "plugins", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &plugins_getterinfo, nullptr, nullptr },
    1817             :   { "links", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &links_getterinfo, nullptr, nullptr },
    1818             :   { "forms", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &forms_getterinfo, nullptr, nullptr },
    1819             :   { "scripts", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &scripts_getterinfo, nullptr, nullptr },
    1820             :   { "designMode", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &designMode_getterinfo, GenericBindingSetter, &designMode_setterinfo },
    1821             :   { "fgColor", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &fgColor_getterinfo, GenericBindingSetter, &fgColor_setterinfo },
    1822             :   { "linkColor", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &linkColor_getterinfo, GenericBindingSetter, &linkColor_setterinfo },
    1823             :   { "vlinkColor", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &vlinkColor_getterinfo, GenericBindingSetter, &vlinkColor_setterinfo },
    1824             :   { "alinkColor", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &alinkColor_getterinfo, GenericBindingSetter, &alinkColor_setterinfo },
    1825             :   { "bgColor", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &bgColor_getterinfo, GenericBindingSetter, &bgColor_setterinfo },
    1826             :   { "anchors", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &anchors_getterinfo, nullptr, nullptr },
    1827             :   { "applets", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &applets_getterinfo, nullptr, nullptr },
    1828             :   { "all", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &all_getterinfo, nullptr, nullptr },
    1829             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
    1830             : };
    1831             : #if defined(__clang__)
    1832             : #pragma clang diagnostic pop
    1833             : #endif
    1834             : 
    1835             : 
    1836             : // Can't be const because the pref-enabled boolean needs to be writable
    1837             : static Prefable<const JSPropertySpec> sAttributes[] = {
    1838             :   { nullptr, &sAttributes_specs[0] },
    1839             :   { nullptr, nullptr }
    1840             : };
    1841             : 
    1842             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    1843             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    1844             : static_assert(19 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    1845             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    1846             : 
    1847             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    1848             : #if defined(__clang__)
    1849             : #pragma clang diagnostic push
    1850             : #pragma clang diagnostic ignored "-Wmissing-braces"
    1851             : #endif
    1852             : static const JSPropertySpec sChromeAttributes_specs[] = {
    1853             :   { "blockedTrackingNodeCount", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &blockedTrackingNodeCount_getterinfo, nullptr, nullptr },
    1854             :   { "blockedTrackingNodes", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &blockedTrackingNodes_getterinfo, nullptr, nullptr },
    1855             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
    1856             : };
    1857             : #if defined(__clang__)
    1858             : #pragma clang diagnostic pop
    1859             : #endif
    1860             : 
    1861             : 
    1862             : // Can't be const because the pref-enabled boolean needs to be writable
    1863             : static Prefable<const JSPropertySpec> sChromeAttributes[] = {
    1864             :   { nullptr, &sChromeAttributes_specs[0] },
    1865             :   { nullptr, nullptr }
    1866             : };
    1867             : 
    1868             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    1869             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    1870             : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    1871             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    1872             : 
    1873             : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
    1874             : #if defined(__clang__)
    1875             : #pragma clang diagnostic push
    1876             : #pragma clang diagnostic ignored "-Wmissing-braces"
    1877             : #endif
    1878             : static const JSPropertySpec sUnforgeableAttributes_specs[] = {
    1879             :   { "location", JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericBindingGetter, &location_getterinfo, GenericBindingSetter, &location_setterinfo },
    1880             :   { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
    1881             : };
    1882             : #if defined(__clang__)
    1883             : #pragma clang diagnostic pop
    1884             : #endif
    1885             : 
    1886             : 
    1887             : // Can't be const because the pref-enabled boolean needs to be writable
    1888             : static Prefable<const JSPropertySpec> sUnforgeableAttributes[] = {
    1889             :   { nullptr, &sUnforgeableAttributes_specs[0] },
    1890             :   { nullptr, nullptr }
    1891             : };
    1892             : 
    1893             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    1894             :     "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
    1895             : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    1896             :     "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
    1897             : 
    1898             : 
    1899             : static uint16_t sNativeProperties_sortedPropertyIndices[35];
    1900             : static PropertyInfo sNativeProperties_propertyInfos[35];
    1901             : 
    1902             : static const NativePropertiesN<3> sNativeProperties = {
    1903             :   false, 0,
    1904             :   false, 0,
    1905             :   true,  0 /* sMethods */,
    1906             :   true,  1 /* sAttributes */,
    1907             :   false, 0,
    1908             :   true,  2 /* sUnforgeableAttributes */,
    1909             :   false, 0,
    1910             :   -1,
    1911             :   35,
    1912             :   sNativeProperties_sortedPropertyIndices,
    1913             :   {
    1914             :     { sMethods, &sNativeProperties_propertyInfos[0] },
    1915             :     { sAttributes, &sNativeProperties_propertyInfos[15] },
    1916             :     { sUnforgeableAttributes, &sNativeProperties_propertyInfos[34] }
    1917             :   }
    1918             : };
    1919             : static_assert(35 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
    1920             :     "We have a property info count that is oversized");
    1921             : 
    1922             : static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[2];
    1923             : static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[2];
    1924             : 
    1925             : static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
    1926             :   false, 0,
    1927             :   false, 0,
    1928             :   false, 0,
    1929             :   true,  0 /* sChromeAttributes */,
    1930             :   false, 0,
    1931             :   false, 0,
    1932             :   false, 0,
    1933             :   -1,
    1934             :   2,
    1935             :   sChromeOnlyNativeProperties_sortedPropertyIndices,
    1936             :   {
    1937             :     { sChromeAttributes, &sChromeOnlyNativeProperties_propertyInfos[0] }
    1938             :   }
    1939             : };
    1940             : static_assert(2 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
    1941             :     "We have a property info count that is oversized");
    1942             : 
    1943             : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
    1944             :   {
    1945             :     "Function",
    1946             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
    1947             :     &sBoringInterfaceObjectClassClassOps,
    1948             :     JS_NULL_CLASS_SPEC,
    1949             :     JS_NULL_CLASS_EXT,
    1950             :     &sInterfaceObjectClassObjectOps
    1951             :   },
    1952             :   eInterface,
    1953             :   true,
    1954             :   prototypes::id::HTMLDocument,
    1955             :   PrototypeTraits<prototypes::id::HTMLDocument>::Depth,
    1956             :   sNativePropertyHooks,
    1957             :   "function HTMLDocument() {\n    [native code]\n}",
    1958             :   DocumentBinding::GetConstructorObject
    1959             : };
    1960             : 
    1961             : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
    1962             :   {
    1963             :     "HTMLDocumentPrototype",
    1964             :     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE + 1 /* slot for the JSObject holding the unforgeable properties */),
    1965             :     JS_NULL_CLASS_OPS,
    1966             :     JS_NULL_CLASS_SPEC,
    1967             :     JS_NULL_CLASS_EXT,
    1968             :     JS_NULL_OBJECT_OPS
    1969             :   },
    1970             :   eInterfacePrototype,
    1971             :   false,
    1972             :   prototypes::id::HTMLDocument,
    1973             :   PrototypeTraits<prototypes::id::HTMLDocument>::Depth,
    1974             :   sNativePropertyHooks,
    1975             :   "[object HTMLDocumentPrototype]",
    1976             :   DocumentBinding::GetProtoObject
    1977             : };
    1978             : 
    1979             : JSObject*
    1980           8 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
    1981             : {
    1982           8 :   return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
    1983             : }
    1984             : 
    1985             : static_assert(IsBaseOf<nsISupports, nsHTMLDocument >::value,
    1986             :                   "We don't support non-nsISupports native classes for "
    1987             :                   "proxy-based bindings yet");
    1988             : 
    1989             : 
    1990             : class DOMProxyHandler : public ShadowingDOMProxyHandler
    1991             : {
    1992             : public:
    1993             :   explicit constexpr DOMProxyHandler()
    1994             :   {
    1995             :   }
    1996             : 
    1997             :   virtual bool
    1998             :   getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
    1999             : 
    2000             :   virtual bool
    2001             :   defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const override;
    2002             : 
    2003             :   using mozilla::dom::DOMProxyHandler::defineProperty;
    2004             : 
    2005             :   virtual bool
    2006             :   ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const override;
    2007             : 
    2008             :   virtual bool
    2009             :   hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const override;
    2010             : 
    2011             :   virtual bool
    2012             :   get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
    2013             : 
    2014             :   virtual const char*
    2015             :   className(JSContext* cx, JS::Handle<JSObject*> proxy) const override;
    2016             : 
    2017             :   virtual bool
    2018             :   finalizeInBackground(const JS::Value& priv) const override;
    2019             : 
    2020             :   virtual void
    2021             :   finalize(JSFreeOp* fop, JSObject* proxy) const override;
    2022             : 
    2023             :   static const DOMProxyHandler*
    2024             :   getInstance();
    2025             : 
    2026             :   virtual bool
    2027             :   delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const override;
    2028             : };
    2029             : 
    2030             : MOZ_ALWAYS_INLINE bool
    2031           6 : IsProxy(JSObject* obj)
    2032             : {
    2033           6 :   return js::IsProxy(obj) && js::GetProxyHandler(obj) == DOMProxyHandler::getInstance();
    2034             : }
    2035             : 
    2036             : MOZ_ALWAYS_INLINE nsHTMLDocument*
    2037           6 : UnwrapProxy(JSObject* obj)
    2038             : {
    2039           6 :   MOZ_ASSERT(js::IsProxy(obj));
    2040           6 :   if (js::GetProxyHandler(obj) != DOMProxyHandler::getInstance()) {
    2041           0 :     MOZ_ASSERT(xpc::WrapperFactory::IsXrayWrapper(obj));
    2042           0 :     obj = js::UncheckedUnwrap(obj);
    2043             :   }
    2044           6 :   MOZ_ASSERT(IsProxy(obj));
    2045           6 :   return static_cast<nsHTMLDocument*>(js::GetProxyReservedSlot(obj, DOM_OBJECT_SLOT).toPrivate());
    2046             : }
    2047             : 
    2048             : bool
    2049          53 : DOMProxyHandler::getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const
    2050             : {
    2051          53 :   bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
    2052         106 :   JS::Rooted<JSObject*> expando(cx);
    2053          53 :   if (!isXray && (expando = GetExpandoObject(proxy))) {
    2054           0 :     if (!JS_GetOwnPropertyDescriptorById(cx, expando, id, desc)) {
    2055           0 :       return false;
    2056             :     }
    2057           0 :     if (desc.object()) {
    2058             :       // Pretend the property lives on the wrapper.
    2059           0 :       desc.object().set(proxy);
    2060           0 :       return true;
    2061             :     }
    2062             :   }
    2063             : 
    2064          53 :   bool callNamedGetter = false;
    2065          53 :   if (!ignoreNamedProps) {
    2066          53 :     if (!isXray) {
    2067           0 :       callNamedGetter = true;
    2068             :     } else {
    2069             :       bool hasOnProto;
    2070          53 :       if (!HasPropertyOnPrototype(cx, proxy, id, &hasOnProto)) {
    2071           0 :         return false;
    2072             :       }
    2073          53 :       callNamedGetter = !hasOnProto;
    2074             :     }
    2075             :   }
    2076          53 :   if (callNamedGetter) {
    2077           0 :     binding_detail::FakeString name;
    2078             :     bool isSymbol;
    2079           0 :     if (!ConvertIdToString(cx, id, name, isSymbol)) {
    2080           0 :       return false;
    2081             :     }
    2082           0 :     if (!isSymbol) {
    2083           0 :       nsHTMLDocument* self = UnwrapProxy(proxy);
    2084           0 :       bool found = false;
    2085           0 :       binding_detail::FastErrorResult rv;
    2086           0 :       JS::Rooted<JSObject*> result(cx);
    2087           0 :       self->NamedGetter(cx, NonNullHelper(Constify(name)), found, &result, rv);
    2088           0 :       if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2089           0 :         return false;
    2090             :       }
    2091           0 :       MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2092             : 
    2093           0 :       if (found) {
    2094           0 :         JS::ExposeObjectToActiveJS(result);
    2095           0 :         desc.value().setObject(*result);
    2096           0 :         if (!MaybeWrapObjectValue(cx, desc.value())) {
    2097           0 :           return false;
    2098             :         }
    2099           0 :         FillPropertyDescriptor(desc, proxy, true, true);
    2100           0 :         return true;
    2101             :       }
    2102             :     }
    2103             :   }
    2104             : 
    2105          53 :   desc.object().set(nullptr);
    2106          53 :   return true;
    2107             : }
    2108             : 
    2109             : bool
    2110           0 : DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const
    2111             : {
    2112           0 :   bool found = false;
    2113           0 :   binding_detail::FakeString name;
    2114             :   bool isSymbol;
    2115           0 :   if (!ConvertIdToString(cx, id, name, isSymbol)) {
    2116           0 :     return false;
    2117             :   }
    2118           0 :   if (!isSymbol) {
    2119           0 :     nsHTMLDocument* self = UnwrapProxy(proxy);
    2120           0 :     binding_detail::FastErrorResult rv;
    2121           0 :     JS::Rooted<JSObject*> result(cx);
    2122           0 :     self->NamedGetter(cx, NonNullHelper(Constify(name)), found, &result, rv);
    2123           0 :     if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2124           0 :       return false;
    2125             :     }
    2126           0 :     MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2127             :     (void)result;
    2128             :   }
    2129             : 
    2130           0 :   if (found) {
    2131           0 :     *defined = true;
    2132           0 :     return opresult.failNoNamedSetter();
    2133             :   }
    2134           0 :   return mozilla::dom::DOMProxyHandler::defineProperty(cx, proxy, id, desc, opresult, defined);
    2135             : }
    2136             : 
    2137             : 
    2138             : bool
    2139           0 : DOMProxyHandler::ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const
    2140             : {
    2141           0 :   bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
    2142             : 
    2143           0 :   nsTArray<nsString> names;
    2144           0 :   UnwrapProxy(proxy)->GetSupportedNames(names);
    2145           0 :   if (!AppendNamedPropertyIds(cx, proxy, names, !isXray, props)) {
    2146           0 :     return false;
    2147             :   }
    2148             : 
    2149           0 :   JS::Rooted<JSObject*> expando(cx);
    2150           0 :   if (!isXray && (expando = DOMProxyHandler::GetExpandoObject(proxy)) &&
    2151           0 :       !js::GetPropertyKeys(cx, expando, flags, &props)) {
    2152           0 :     return false;
    2153             :   }
    2154             : 
    2155           0 :   return true;
    2156             : }
    2157             : 
    2158             : bool
    2159           0 : DOMProxyHandler::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const
    2160             : {
    2161           0 :   MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
    2162             :             "Should not have a XrayWrapper here");
    2163             : 
    2164             : 
    2165           0 :   JS::Rooted<JSObject*> expando(cx, GetExpandoObject(proxy));
    2166           0 :   if (expando) {
    2167           0 :     bool b = true;
    2168           0 :     bool ok = JS_HasPropertyById(cx, expando, id, &b);
    2169           0 :     *bp = !!b;
    2170           0 :     if (!ok || *bp) {
    2171           0 :       return ok;
    2172             :     }
    2173             :   }
    2174             : 
    2175           0 :   bool found = false;
    2176           0 :   binding_detail::FakeString name;
    2177             :   bool isSymbol;
    2178           0 :   if (!ConvertIdToString(cx, id, name, isSymbol)) {
    2179           0 :     return false;
    2180             :   }
    2181           0 :   if (!isSymbol) {
    2182           0 :     nsHTMLDocument* self = UnwrapProxy(proxy);
    2183           0 :     binding_detail::FastErrorResult rv;
    2184           0 :     JS::Rooted<JSObject*> result(cx);
    2185           0 :     self->NamedGetter(cx, NonNullHelper(Constify(name)), found, &result, rv);
    2186           0 :     if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2187           0 :       return false;
    2188             :     }
    2189           0 :     MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2190             :     (void)result;
    2191             :   }
    2192             : 
    2193           0 :   *bp = found;
    2194             : 
    2195           0 :   return true;
    2196             : }
    2197             : 
    2198             : bool
    2199           6 : DOMProxyHandler::get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const
    2200             : {
    2201           6 :   MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
    2202             :               "Should not have a XrayWrapper here");
    2203             : 
    2204             :   { // Scope for expando
    2205          12 :     JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
    2206           6 :     if (expando) {
    2207             :       bool hasProp;
    2208           6 :       if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
    2209           0 :         return false;
    2210             :       }
    2211             : 
    2212           6 :       if (hasProp) {
    2213             :         // Forward the get to the expando object, but our receiver is whatever our
    2214             :         // receiver is.
    2215           0 :         return JS_ForwardGetPropertyTo(cx, expando, id, receiver, vp);
    2216             :       }
    2217             :     }
    2218             :   }
    2219             : 
    2220          12 :   binding_detail::FakeString name;
    2221             :   bool isSymbol;
    2222           6 :   if (!ConvertIdToString(cx, id, name, isSymbol)) {
    2223           0 :     return false;
    2224             :   }
    2225           6 :   if (!isSymbol) {
    2226           6 :     nsHTMLDocument* self = UnwrapProxy(proxy);
    2227           6 :     bool found = false;
    2228          12 :     binding_detail::FastErrorResult rv;
    2229          12 :     JS::Rooted<JSObject*> result(cx);
    2230           6 :     self->NamedGetter(cx, NonNullHelper(Constify(name)), found, &result, rv);
    2231           6 :     if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2232           0 :       return false;
    2233             :     }
    2234           6 :     MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2235             : 
    2236           6 :     if (found) {
    2237           0 :       JS::ExposeObjectToActiveJS(result);
    2238           0 :       vp.setObject(*result);
    2239           0 :       if (!MaybeWrapObjectValue(cx, vp)) {
    2240           0 :         return false;
    2241             :       }
    2242           0 :       return true;
    2243             :     }
    2244             :   }
    2245             : 
    2246             :   bool foundOnPrototype;
    2247           6 :   if (!GetPropertyOnPrototype(cx, proxy, receiver, id, &foundOnPrototype, vp)) {
    2248           0 :     return false;
    2249             :   }
    2250             : 
    2251           6 :   if (foundOnPrototype) {
    2252           6 :     return true;
    2253             :   }
    2254             : 
    2255           0 :   vp.setUndefined();
    2256           0 :   return true;
    2257             : }
    2258             : 
    2259             : const char*
    2260           0 : DOMProxyHandler::className(JSContext* cx, JS::Handle<JSObject*> proxy) const
    2261             : {
    2262           0 :   return "HTMLDocument";
    2263             : }
    2264             : 
    2265             : bool
    2266           7 : DOMProxyHandler::finalizeInBackground(const JS::Value& priv) const
    2267             : {
    2268           7 :   return false;
    2269             : }
    2270             : 
    2271             : void
    2272           0 : DOMProxyHandler::finalize(JSFreeOp* fop, JSObject* proxy) const
    2273             : {
    2274           0 :   nsHTMLDocument* self = UnwrapPossiblyNotInitializedDOMObject<nsHTMLDocument>(proxy);
    2275           0 :   if (self) {
    2276             :     // Either our proxy created an expando object or not.  If it did,
    2277             :     // then we would have preserved ourselves, and hence if we're going
    2278             :     // away so is our C++ object and we should reset its expando value.
    2279             :     // It's possible that in this situation the C++ object's reflector
    2280             :     // pointer has been nulled out, but if not it's pointing to us.  If
    2281             :     // our proxy did _not_ create an expando object then it's possible
    2282             :     // that we're no longer the reflector for our C++ object (and
    2283             :     // incremental finalization is finally getting to us), and that in
    2284             :     // the meantime the new reflector has created an expando object.
    2285             :     // In that case we do NOT want to clear the expando pointer in the
    2286             :     // C++ object.
    2287             :     //
    2288             :     // It's important to do this before we ClearWrapper, of course.
    2289           0 :     JSObject* reflector = self->GetWrapperMaybeDead();
    2290           0 :     if (!reflector || reflector == proxy) {
    2291           0 :       self->mExpandoAndGeneration.expando = JS::UndefinedValue();
    2292             :     }
    2293           0 :     ClearWrapper(self, self, proxy);
    2294           0 :     AddForDeferredFinalization<nsHTMLDocument>(self);
    2295             :   }
    2296           0 : }
    2297             : 
    2298             : const DOMProxyHandler*
    2299          19 : DOMProxyHandler::getInstance()
    2300             : {
    2301             :   static const DOMProxyHandler instance;
    2302          19 :   return &instance;
    2303             : }
    2304             : 
    2305             : bool
    2306           0 : DOMProxyHandler::delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const
    2307             : {
    2308           0 :   MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
    2309             :             "Should not have a XrayWrapper here");
    2310             : 
    2311             :   // Try named delete only if the named property visibility
    2312             :   // algorithm says the property is visible.
    2313           0 :   bool tryNamedDelete = true;
    2314             :   { // Scope for expando
    2315           0 :     JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
    2316           0 :     if (expando) {
    2317             :       bool hasProp;
    2318           0 :       if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
    2319           0 :         return false;
    2320             :       }
    2321           0 :       tryNamedDelete = !hasProp;
    2322             :     }
    2323             :   }
    2324           0 :   if (tryNamedDelete) {
    2325           0 :     bool found = false;
    2326             :     bool deleteSucceeded;
    2327           0 :     binding_detail::FakeString name;
    2328             :     bool isSymbol;
    2329           0 :     if (!ConvertIdToString(cx, id, name, isSymbol)) {
    2330           0 :       return false;
    2331             :     }
    2332           0 :     if (!isSymbol) {
    2333           0 :       nsHTMLDocument* self = UnwrapProxy(proxy);
    2334           0 :       binding_detail::FastErrorResult rv;
    2335           0 :       JS::Rooted<JSObject*> result(cx);
    2336           0 :       self->NamedGetter(cx, NonNullHelper(Constify(name)), found, &result, rv);
    2337           0 :       if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
    2338           0 :         return false;
    2339             :       }
    2340           0 :       MOZ_ASSERT(!JS_IsExceptionPending(cx));
    2341             :       (void)result;
    2342             :     }
    2343           0 :     deleteSucceeded = !found;
    2344           0 :     if (found) {
    2345           0 :       return deleteSucceeded ? opresult.succeed() : opresult.failCantDelete();
    2346             :     }
    2347             :   }
    2348             : 
    2349           0 :   return dom::DOMProxyHandler::delete_(cx, proxy, id, opresult);
    2350             : }
    2351             : 
    2352             : static const js::ClassExtension sClassExtension = PROXY_MAKE_EXT(
    2353             :     _objectMoved
    2354             : );
    2355             : 
    2356             : static const DOMJSClass sClass = {
    2357             :   PROXY_CLASS_WITH_EXT("HTMLDocument",
    2358             :                        JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1),
    2359             :                        &sClassExtension),
    2360             :   { prototypes::id::EventTarget, prototypes::id::Node, prototypes::id::Document, prototypes::id::HTMLDocument, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
    2361             :   IsBaseOf<nsISupports, nsHTMLDocument >::value,
    2362             :   sNativePropertyHooks,
    2363             :   FindAssociatedGlobalForNative<nsHTMLDocument>::Get,
    2364             :   GetProtoObjectHandle,
    2365             :   GetCCParticipant<nsHTMLDocument>::Get()
    2366             : };
    2367             : 
    2368             : bool
    2369           7 : Wrap(JSContext* aCx, nsHTMLDocument* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
    2370             : {
    2371             :   MOZ_ASSERT(static_cast<nsHTMLDocument*>(aObject) ==
    2372             :              reinterpret_cast<nsHTMLDocument*>(aObject),
    2373             :              "Multiple inheritance for nsHTMLDocument is broken.");
    2374             :   MOZ_ASSERT(static_cast<nsIDocument*>(aObject) ==
    2375             :              reinterpret_cast<nsIDocument*>(aObject),
    2376             :              "Multiple inheritance for nsIDocument is broken.");
    2377             :   MOZ_ASSERT(static_cast<nsINode*>(aObject) ==
    2378             :              reinterpret_cast<nsINode*>(aObject),
    2379             :              "Multiple inheritance for nsINode is broken.");
    2380             :   MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
    2381             :              reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
    2382             :              "Multiple inheritance for mozilla::dom::EventTarget is broken.");
    2383           7 :   MOZ_ASSERT(ToSupportsIsCorrect(aObject));
    2384           7 :   MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
    2385           7 :   MOZ_ASSERT(!aCache->GetWrapper(),
    2386             :              "You should probably not be using Wrap() directly; use "
    2387             :              "GetOrCreateDOMReflector instead");
    2388             : 
    2389           7 :   MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
    2390             :              "nsISupports must be on our primary inheritance chain");
    2391             : 
    2392          14 :   JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
    2393           7 :   if (!global) {
    2394           0 :     return false;
    2395             :   }
    2396           7 :   MOZ_ASSERT(JS_IsGlobalObject(global));
    2397           7 :   MOZ_ASSERT(JS::ObjectIsNotGray(global));
    2398             : 
    2399             :   // That might have ended up wrapping us already, due to the wonders
    2400             :   // of XBL.  Check for that, and bail out as needed.
    2401           7 :   aReflector.set(aCache->GetWrapper());
    2402           7 :   if (aReflector) {
    2403             : #ifdef DEBUG
    2404           0 :     binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
    2405             : #endif // DEBUG
    2406           0 :     return true;
    2407             :   }
    2408             : 
    2409          14 :   JSAutoCompartment ac(aCx, global);
    2410           7 :   JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
    2411           7 :   if (!canonicalProto) {
    2412           0 :     return false;
    2413             :   }
    2414          14 :   JS::Rooted<JSObject*> proto(aCx);
    2415           7 :   if (aGivenProto) {
    2416           0 :     proto = aGivenProto;
    2417             :     // Unfortunately, while aGivenProto was in the compartment of aCx
    2418             :     // coming in, we changed compartments to that of "parent" so may need
    2419             :     // to wrap the proto here.
    2420           0 :     if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
    2421           0 :       if (!JS_WrapObject(aCx, &proto)) {
    2422           0 :         return false;
    2423             :       }
    2424             :     }
    2425             :   } else {
    2426           7 :     proto = canonicalProto;
    2427             :   }
    2428             : 
    2429          14 :   BindingJSObjectCreator<nsHTMLDocument> creator(aCx);
    2430          14 :   JS::Rooted<JS::Value> expandoValue(aCx, JS::PrivateValue(&aObject->mExpandoAndGeneration));
    2431          14 :   creator.CreateProxyObject(aCx, &sClass.mBase, DOMProxyHandler::getInstance(),
    2432           7 :                             proto, aObject, expandoValue, aReflector);
    2433           7 :   if (!aReflector) {
    2434           0 :     return false;
    2435             :   }
    2436             : 
    2437             : 
    2438           7 :   aCache->SetWrapper(aReflector);
    2439             : 
    2440             :   // Important: do unforgeable property setup after we have handed
    2441             :   // over ownership of the C++ object to obj as needed, so that if
    2442             :   // we fail and it ends up GCed it won't have problems in the
    2443             :   // finalizer trying to drop its ownership of the C++ object.
    2444             :   JS::Rooted<JSObject*> expando(aCx,
    2445          14 :     DOMProxyHandler::EnsureExpandoObject(aCx, aReflector));
    2446           7 :   if (!expando) {
    2447           0 :     aCache->ReleaseWrapper(aObject);
    2448           0 :     aCache->ClearWrapper();
    2449           0 :     return false;
    2450             :   }
    2451             :   JS::Rooted<JSObject*> unforgeableHolder(aCx,
    2452          14 :     &js::GetReservedSlot(canonicalProto, DOM_INTERFACE_PROTO_SLOTS_BASE).toObject());
    2453           7 :   if (!JS_InitializePropertiesFromCompatibleNativeObject(aCx, expando, unforgeableHolder)) {
    2454           0 :     aCache->ReleaseWrapper(aObject);
    2455           0 :     aCache->ClearWrapper();
    2456           0 :     return false;
    2457             :   }
    2458           7 :   creator.InitializationSucceeded();
    2459             : 
    2460           7 :   MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
    2461             :              aCache->GetWrapperPreserveColor() == aReflector);
    2462             :   // If proto != canonicalProto, we have to preserve our wrapper;
    2463             :   // otherwise we won't be able to properly recreate it later, since
    2464             :   // we won't know what proto to use.  Note that we don't check
    2465             :   // aGivenProto here, since it's entirely possible (and even
    2466             :   // somewhat common) to have a non-null aGivenProto which is the
    2467             :   // same as canonicalProto.
    2468           7 :   if (proto != canonicalProto) {
    2469           0 :     PreserveWrapper(aObject);
    2470             :   }
    2471             : 
    2472           7 :   return true;
    2473             : }
    2474             : 
    2475             : static bool
    2476          53 : ResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::MutableHandle<JS::PropertyDescriptor> desc)
    2477             : {
    2478          53 :   return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc);
    2479             : }
    2480             : 
    2481             : static bool
    2482           0 : EnumerateOwnProperties(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::AutoIdVector& props)
    2483             : {
    2484           0 :   return js::GetProxyHandler(obj)->ownPropertyKeys(cx, wrapper, props);
    2485             : }
    2486             : 
    2487             : const NativePropertyHooks sNativePropertyHooks[] = { {
    2488             :   ResolveOwnProperty,
    2489             :   EnumerateOwnProperties,
    2490             :   nullptr,
    2491             :   { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
    2492             :   prototypes::id::HTMLDocument,
    2493             :   constructors::id::HTMLDocument,
    2494             :   DocumentBinding::sNativePropertyHooks,
    2495             :   &DefaultXrayExpandoObjectClass
    2496             : } };
    2497             : 
    2498             : void
    2499           7 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
    2500             : {
    2501           7 :   JS::Handle<JSObject*> parentProto(DocumentBinding::GetProtoObjectHandle(aCx));
    2502           7 :   if (!parentProto) {
    2503           0 :     return;
    2504             :   }
    2505             : 
    2506           7 :   JS::Handle<JSObject*> constructorProto(DocumentBinding::GetConstructorObjectHandle(aCx));
    2507           7 :   if (!constructorProto) {
    2508           0 :     return;
    2509             :   }
    2510             : 
    2511             :   static bool sIdsInited = false;
    2512           7 :   if (!sIdsInited && NS_IsMainThread()) {
    2513           2 :     if (!InitIds(aCx, sNativeProperties.Upcast())) {
    2514           0 :       return;
    2515             :     }
    2516           2 :     if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
    2517           0 :       return;
    2518             :     }
    2519           2 :     sIdsInited = true;
    2520             :   }
    2521             : 
    2522           7 :   JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::HTMLDocument);
    2523           7 :   JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::HTMLDocument);
    2524          14 :   dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
    2525             :                               &sPrototypeClass.mBase, protoCache,
    2526             :                               constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
    2527             :                               interfaceCache,
    2528             :                               sNativeProperties.Upcast(),
    2529           7 :                               nsContentUtils::ThreadsafeIsSystemCaller(aCx) ? sChromeOnlyNativeProperties.Upcast() : nullptr,
    2530             :                               "HTMLDocument", aDefineOnGlobal,
    2531             :                               nullptr,
    2532           7 :                               false);
    2533             : 
    2534          14 :   JS::Rooted<JSObject*> unforgeableHolder(aCx);
    2535             :   {
    2536          14 :     JS::Rooted<JSObject*> holderProto(aCx, nullptr);
    2537           7 :     unforgeableHolder = JS_NewObjectWithoutMetadata(aCx, nullptr, holderProto);
    2538           7 :     if (!unforgeableHolder) {
    2539           0 :       *protoCache = nullptr;
    2540           0 :       if (interfaceCache) {
    2541           0 :         *interfaceCache = nullptr;
    2542             :       }
    2543           0 :       return;
    2544             :     }
    2545             :   }
    2546             : 
    2547           7 :   if (!DefineUnforgeableAttributes(aCx, unforgeableHolder, sUnforgeableAttributes)) {
    2548           0 :     *protoCache = nullptr;
    2549           0 :     if (interfaceCache) {
    2550           0 :       *interfaceCache = nullptr;
    2551             :     }
    2552           0 :     return;
    2553             :   }
    2554             : 
    2555           7 :   if (*protoCache) {
    2556           7 :     js::SetReservedSlot(*protoCache, DOM_INTERFACE_PROTO_SLOTS_BASE,
    2557          14 :                         JS::ObjectValue(*unforgeableHolder));
    2558             :   }
    2559             : }
    2560             : 
    2561             : JS::Handle<JSObject*>
    2562          15 : GetProtoObjectHandle(JSContext* aCx)
    2563             : {
    2564             :   /* Get the interface prototype object for this class.  This will create the
    2565             :      object as needed. */
    2566          15 :   bool aDefineOnGlobal = true;
    2567             : 
    2568             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    2569          15 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    2570          15 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    2571           0 :     return nullptr;
    2572             :   }
    2573             : 
    2574             :   /* Check to see whether the interface objects are already installed */
    2575          15 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    2576          15 :   if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::HTMLDocument)) {
    2577          14 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    2578           7 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    2579             :   }
    2580             : 
    2581             :   /*
    2582             :    * The object might _still_ be null, but that's OK.
    2583             :    *
    2584             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    2585             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    2586             :    * changed after they have been set.
    2587             :    *
    2588             :    * Calling address() avoids the read read barrier that does gray
    2589             :    * unmarking, but it's not possible for the object to be gray here.
    2590             :    */
    2591             : 
    2592          15 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::HTMLDocument);
    2593          15 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    2594          15 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    2595             : }
    2596             : 
    2597             : JSObject*
    2598           0 : GetProtoObject(JSContext* aCx)
    2599             : {
    2600           0 :   return GetProtoObjectHandle(aCx);
    2601             : }
    2602             : 
    2603             : JS::Handle<JSObject*>
    2604           8 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
    2605             : {
    2606             :   /* Get the interface object for this class.  This will create the object as
    2607             :      needed. */
    2608             : 
    2609             :   /* Make sure our global is sane.  Hopefully we can remove this sometime */
    2610           8 :   JSObject* global = JS::CurrentGlobalOrNull(aCx);
    2611           8 :   if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    2612           0 :     return nullptr;
    2613             :   }
    2614             : 
    2615             :   /* Check to see whether the interface objects are already installed */
    2616           8 :   ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
    2617           8 :   if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::HTMLDocument)) {
    2618           0 :     JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    2619           0 :     CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
    2620             :   }
    2621             : 
    2622             :   /*
    2623             :    * The object might _still_ be null, but that's OK.
    2624             :    *
    2625             :    * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
    2626             :    * traced by TraceProtoAndIfaceCache() and its contents are never
    2627             :    * changed after they have been set.
    2628             :    *
    2629             :    * Calling address() avoids the read read barrier that does gray
    2630             :    * unmarking, but it's not possible for the object to be gray here.
    2631             :    */
    2632             : 
    2633           8 :   const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::HTMLDocument);
    2634           8 :   MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
    2635           8 :   return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
    2636             : }
    2637             : 
    2638             : JSObject*
    2639           0 : GetConstructorObject(JSContext* aCx)
    2640             : {
    2641           0 :   return GetConstructorObjectHandle(aCx);
    2642             : }
    2643             : 
    2644             : } // namespace HTMLDocumentBinding
    2645             : 
    2646             : 
    2647             : 
    2648             : } // namespace dom
    2649             : } // namespace mozilla

Generated by: LCOV version 1.13