/* THIS FILE IS AUTOGENERATED FROM XMLHttpRequestEventTarget.webidl BY Codegen.py - DO NOT EDIT */

#include "EventHandlerBinding.h"
#include "EventTargetBinding.h"
#include "WrapperFactory.h"
#include "XMLHttpRequestEventTargetBinding.h"
#include "mozilla/OwningNonNull.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/DOMJSClass.h"
#include "mozilla/dom/NonRefcountedDOMObject.h"
#include "mozilla/dom/Nullable.h"
#include "mozilla/dom/XMLHttpRequestEventTarget.h"
#include "mozilla/dom/XrayExpandoClass.h"
#include "nsThreadUtils.h"
#include "xpcprivate.h"

namespace mozilla {
namespace dom {

namespace XMLHttpRequestEventTargetBinding {

static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventTargetBinding::NativeType>::value,
              "Can't inherit from an interface with a different ownership model.");

static bool
get_onloadstart(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLHttpRequestEventTarget* self, JSJitGetterCallArgs args)
{
  RefPtr<EventHandlerNonNull> result(self->GetOnloadstart());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (result) {
    args.rval().setObject(*GetCallbackFromCallbackObject(result));
    if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
      return false;
    }
    return true;
  } else {
    args.rval().setNull();
    return true;
  }
}

static bool
set_onloadstart(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLHttpRequestEventTarget* self, JSJitSetterCallArgs args)
{
  RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
  if (args[0].isObject()) {
      { // Scope for tempRoot
        JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
        arg0 = new binding_detail::FastEventHandlerNonNull(cx, tempRoot, mozilla::dom::GetIncumbentGlobal());
      }
  } else {
    arg0 = nullptr;
  }
  self->SetOnloadstart(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo onloadstart_getterinfo = {
  { (JSJitGetterOp)get_onloadstart },
  { prototypes::id::XMLHttpRequestEventTarget },
  { PrototypeTraits<prototypes::id::XMLHttpRequestEventTarget>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert(0 < 1, "There is no slot for us");
static const JSJitInfo onloadstart_setterinfo = {
  { (JSJitGetterOp)set_onloadstart },
  { prototypes::id::XMLHttpRequestEventTarget },
  { PrototypeTraits<prototypes::id::XMLHttpRequestEventTarget>::Depth },
  JSJitInfo::Setter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert(0 < 1, "There is no slot for us");

static bool
get_onprogress(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLHttpRequestEventTarget* self, JSJitGetterCallArgs args)
{
  RefPtr<EventHandlerNonNull> result(self->GetOnprogress());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (result) {
    args.rval().setObject(*GetCallbackFromCallbackObject(result));
    if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
      return false;
    }
    return true;
  } else {
    args.rval().setNull();
    return true;
  }
}

static bool
set_onprogress(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLHttpRequestEventTarget* self, JSJitSetterCallArgs args)
{
  RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
  if (args[0].isObject()) {
      { // Scope for tempRoot
        JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
        arg0 = new binding_detail::FastEventHandlerNonNull(cx, tempRoot, mozilla::dom::GetIncumbentGlobal());
      }
  } else {
    arg0 = nullptr;
  }
  self->SetOnprogress(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo onprogress_getterinfo = {
  { (JSJitGetterOp)get_onprogress },
  { prototypes::id::XMLHttpRequestEventTarget },
  { PrototypeTraits<prototypes::id::XMLHttpRequestEventTarget>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert(0 < 1, "There is no slot for us");
static const JSJitInfo onprogress_setterinfo = {
  { (JSJitGetterOp)set_onprogress },
  { prototypes::id::XMLHttpRequestEventTarget },
  { PrototypeTraits<prototypes::id::XMLHttpRequestEventTarget>::Depth },
  JSJitInfo::Setter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert(0 < 1, "There is no slot for us");

static bool
get_onabort(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLHttpRequestEventTarget* self, JSJitGetterCallArgs args)
{
  RefPtr<EventHandlerNonNull> result(self->GetOnabort());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (result) {
    args.rval().setObject(*GetCallbackFromCallbackObject(result));
    if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
      return false;
    }
    return true;
  } else {
    args.rval().setNull();
    return true;
  }
}

static bool
set_onabort(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLHttpRequestEventTarget* self, JSJitSetterCallArgs args)
{
  RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
  if (args[0].isObject()) {
      { // Scope for tempRoot
        JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
        arg0 = new binding_detail::FastEventHandlerNonNull(cx, tempRoot, mozilla::dom::GetIncumbentGlobal());
      }
  } else {
    arg0 = nullptr;
  }
  self->SetOnabort(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo onabort_getterinfo = {
  { (JSJitGetterOp)get_onabort },
  { prototypes::id::XMLHttpRequestEventTarget },
  { PrototypeTraits<prototypes::id::XMLHttpRequestEventTarget>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert(0 < 1, "There is no slot for us");
static const JSJitInfo onabort_setterinfo = {
  { (JSJitGetterOp)set_onabort },
  { prototypes::id::XMLHttpRequestEventTarget },
  { PrototypeTraits<prototypes::id::XMLHttpRequestEventTarget>::Depth },
  JSJitInfo::Setter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert(0 < 1, "There is no slot for us");

static bool
get_onerror(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLHttpRequestEventTarget* self, JSJitGetterCallArgs args)
{
  RefPtr<EventHandlerNonNull> result(self->GetOnerror());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (result) {
    args.rval().setObject(*GetCallbackFromCallbackObject(result));
    if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
      return false;
    }
    return true;
  } else {
    args.rval().setNull();
    return true;
  }
}

static bool
set_onerror(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLHttpRequestEventTarget* self, JSJitSetterCallArgs args)
{
  RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
  if (args[0].isObject()) {
      { // Scope for tempRoot
        JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
        arg0 = new binding_detail::FastEventHandlerNonNull(cx, tempRoot, mozilla::dom::GetIncumbentGlobal());
      }
  } else {
    arg0 = nullptr;
  }
  self->SetOnerror(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo onerror_getterinfo = {
  { (JSJitGetterOp)get_onerror },
  { prototypes::id::XMLHttpRequestEventTarget },
  { PrototypeTraits<prototypes::id::XMLHttpRequestEventTarget>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert(0 < 1, "There is no slot for us");
static const JSJitInfo onerror_setterinfo = {
  { (JSJitGetterOp)set_onerror },
  { prototypes::id::XMLHttpRequestEventTarget },
  { PrototypeTraits<prototypes::id::XMLHttpRequestEventTarget>::Depth },
  JSJitInfo::Setter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert(0 < 1, "There is no slot for us");

static bool
get_onload(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLHttpRequestEventTarget* self, JSJitGetterCallArgs args)
{
  RefPtr<EventHandlerNonNull> result(self->GetOnload());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (result) {
    args.rval().setObject(*GetCallbackFromCallbackObject(result));
    if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
      return false;
    }
    return true;
  } else {
    args.rval().setNull();
    return true;
  }
}

static bool
set_onload(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLHttpRequestEventTarget* self, JSJitSetterCallArgs args)
{
  RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
  if (args[0].isObject()) {
      { // Scope for tempRoot
        JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
        arg0 = new binding_detail::FastEventHandlerNonNull(cx, tempRoot, mozilla::dom::GetIncumbentGlobal());
      }
  } else {
    arg0 = nullptr;
  }
  self->SetOnload(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo onload_getterinfo = {
  { (JSJitGetterOp)get_onload },
  { prototypes::id::XMLHttpRequestEventTarget },
  { PrototypeTraits<prototypes::id::XMLHttpRequestEventTarget>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert(0 < 1, "There is no slot for us");
static const JSJitInfo onload_setterinfo = {
  { (JSJitGetterOp)set_onload },
  { prototypes::id::XMLHttpRequestEventTarget },
  { PrototypeTraits<prototypes::id::XMLHttpRequestEventTarget>::Depth },
  JSJitInfo::Setter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert(0 < 1, "There is no slot for us");

static bool
get_ontimeout(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLHttpRequestEventTarget* self, JSJitGetterCallArgs args)
{
  RefPtr<EventHandlerNonNull> result(self->GetOntimeout());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (result) {
    args.rval().setObject(*GetCallbackFromCallbackObject(result));
    if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
      return false;
    }
    return true;
  } else {
    args.rval().setNull();
    return true;
  }
}

static bool
set_ontimeout(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLHttpRequestEventTarget* self, JSJitSetterCallArgs args)
{
  RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
  if (args[0].isObject()) {
      { // Scope for tempRoot
        JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
        arg0 = new binding_detail::FastEventHandlerNonNull(cx, tempRoot, mozilla::dom::GetIncumbentGlobal());
      }
  } else {
    arg0 = nullptr;
  }
  self->SetOntimeout(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo ontimeout_getterinfo = {
  { (JSJitGetterOp)get_ontimeout },
  { prototypes::id::XMLHttpRequestEventTarget },
  { PrototypeTraits<prototypes::id::XMLHttpRequestEventTarget>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert(0 < 1, "There is no slot for us");
static const JSJitInfo ontimeout_setterinfo = {
  { (JSJitGetterOp)set_ontimeout },
  { prototypes::id::XMLHttpRequestEventTarget },
  { PrototypeTraits<prototypes::id::XMLHttpRequestEventTarget>::Depth },
  JSJitInfo::Setter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert(0 < 1, "There is no slot for us");

static bool
get_onloadend(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLHttpRequestEventTarget* self, JSJitGetterCallArgs args)
{
  RefPtr<EventHandlerNonNull> result(self->GetOnloadend());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (result) {
    args.rval().setObject(*GetCallbackFromCallbackObject(result));
    if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
      return false;
    }
    return true;
  } else {
    args.rval().setNull();
    return true;
  }
}

static bool
set_onloadend(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLHttpRequestEventTarget* self, JSJitSetterCallArgs args)
{
  RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
  if (args[0].isObject()) {
      { // Scope for tempRoot
        JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
        arg0 = new binding_detail::FastEventHandlerNonNull(cx, tempRoot, mozilla::dom::GetIncumbentGlobal());
      }
  } else {
    arg0 = nullptr;
  }
  self->SetOnloadend(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo onloadend_getterinfo = {
  { (JSJitGetterOp)get_onloadend },
  { prototypes::id::XMLHttpRequestEventTarget },
  { PrototypeTraits<prototypes::id::XMLHttpRequestEventTarget>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert(0 < 1, "There is no slot for us");
static const JSJitInfo onloadend_setterinfo = {
  { (JSJitGetterOp)set_onloadend },
  { prototypes::id::XMLHttpRequestEventTarget },
  { PrototypeTraits<prototypes::id::XMLHttpRequestEventTarget>::Depth },
  JSJitInfo::Setter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  false,  /* isMovable.  Not relevant for setters. */
  false, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert(0 < 1, "There is no slot for us");

static const JSPropertySpec sAttributes_specs[] = {
  { "onloadstart", JSPROP_SHARED | JSPROP_ENUMERATE, { { { { GenericBindingGetter, &onloadstart_getterinfo } }, { { GenericBindingSetter, &onloadstart_setterinfo } } } } },
  { "onprogress", JSPROP_SHARED | JSPROP_ENUMERATE, { { { { GenericBindingGetter, &onprogress_getterinfo } }, { { GenericBindingSetter, &onprogress_setterinfo } } } } },
  { "onabort", JSPROP_SHARED | JSPROP_ENUMERATE, { { { { GenericBindingGetter, &onabort_getterinfo } }, { { GenericBindingSetter, &onabort_setterinfo } } } } },
  { "onerror", JSPROP_SHARED | JSPROP_ENUMERATE, { { { { GenericBindingGetter, &onerror_getterinfo } }, { { GenericBindingSetter, &onerror_setterinfo } } } } },
  { "onload", JSPROP_SHARED | JSPROP_ENUMERATE, { { { { GenericBindingGetter, &onload_getterinfo } }, { { GenericBindingSetter, &onload_setterinfo } } } } },
  { "ontimeout", JSPROP_SHARED | JSPROP_ENUMERATE, { { { { GenericBindingGetter, &ontimeout_getterinfo } }, { { GenericBindingSetter, &ontimeout_setterinfo } } } } },
  { "onloadend", JSPROP_SHARED | JSPROP_ENUMERATE, { { { { GenericBindingGetter, &onloadend_getterinfo } }, { { GenericBindingSetter, &onloadend_setterinfo } } } } },
  JS_PS_END
};


// Can't be const because the pref-enabled boolean needs to be writable
static Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_specs[0] },
  { nullptr, nullptr }
};

static jsid sAttributes_ids[8];


static const NativePropertiesN<1> sNativeProperties = {
  -1,
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  {
    { sAttributes, sAttributes_ids, sAttributes_specs }
  }
};

static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
  {
    "Function",
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
    &sBoringInterfaceObjectClassClassOps,
    JS_NULL_CLASS_SPEC,
    JS_NULL_CLASS_EXT,
    &sInterfaceObjectClassObjectOps
  },
  eInterface,
  true,
  prototypes::id::XMLHttpRequestEventTarget,
  PrototypeTraits<prototypes::id::XMLHttpRequestEventTarget>::Depth,
  sNativePropertyHooks,
  "function XMLHttpRequestEventTarget() {\n    [native code]\n}",
  EventTargetBinding::GetConstructorObject
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "XMLHttpRequestEventTargetPrototype",
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
    JS_NULL_CLASS_OPS,
    JS_NULL_CLASS_SPEC,
    JS_NULL_CLASS_EXT,
    JS_NULL_OBJECT_OPS
  },
  eInterfacePrototype,
  false,
  prototypes::id::XMLHttpRequestEventTarget,
  PrototypeTraits<prototypes::id::XMLHttpRequestEventTarget>::Depth,
  sNativePropertyHooks,
  "[object XMLHttpRequestEventTargetPrototype]",
  EventTargetBinding::GetProtoObject
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  if (!NS_IsMainThread()) {
    const char* name = js::GetObjectClass(aObj)->name;
    if (strcmp(name, "DedicatedWorkerGlobalScope") && strcmp(name, "SharedWorkerGlobalScope")) {
      return false;
    }
  }

  return true;
}

JSObject*
DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
{
  return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
}

const NativePropertyHooks sNativePropertyHooks[] = { {
  nullptr,
  nullptr,
  nullptr,
  { sNativeProperties.Upcast(), nullptr },
  prototypes::id::XMLHttpRequestEventTarget,
  constructors::id::XMLHttpRequestEventTarget,
  EventTargetBinding::sNativePropertyHooks,
  &DefaultXrayExpandoObjectClass
} };

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
{
  JS::Handle<JSObject*> parentProto(EventTargetBinding::GetProtoObjectHandle(aCx));
  if (!parentProto) {
    return;
  }

  JS::Handle<JSObject*> constructorProto(EventTargetBinding::GetConstructorObjectHandle(aCx));
  if (!constructorProto) {
    return;
  }

  static bool sIdsInited = false;
  if (!sIdsInited && NS_IsMainThread()) {
    if (!InitIds(aCx, sAttributes, sAttributes_ids)) {
      return;
    }
    sIdsInited = true;
  }

  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::XMLHttpRequestEventTarget);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::XMLHttpRequestEventTarget);
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass.mBase, protoCache,
                              constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "XMLHttpRequestEventTarget", aDefineOnGlobal,
                              nullptr,
                              false);
}

JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  bool aDefineOnGlobal = true;

  /* Make sure our global is sane.  Hopefully we can remove this sometime */
  JSObject* global = JS::CurrentGlobalOrNull(aCx);
  if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    return nullptr;
  }

  /* Check to see whether the interface objects are already installed */
  ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
  if (!protoAndIfaceCache.EntrySlotIfExists(prototypes::id::XMLHttpRequestEventTarget)) {
    JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
  }

  /*
   * The object might _still_ be null, but that's OK.
   *
   * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
   * traced by TraceProtoAndIfaceCache() and its contents are never
   * changed after they have been set.
   *
   * Calling address() avoids the read read barrier that does gray
   * unmarking, but it's not possible for the object to be gray here.
   */

  const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::XMLHttpRequestEventTarget);
  MOZ_ASSERT_IF(entrySlot, !JS::ObjectIsMarkedGray(entrySlot));
  return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
}

JSObject*
GetProtoObject(JSContext* aCx)
{
  return GetProtoObjectHandle(aCx);
}

JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
{
  /* Get the interface object for this class.  This will create the object as
     needed. */

  /* Make sure our global is sane.  Hopefully we can remove this sometime */
  JSObject* global = JS::CurrentGlobalOrNull(aCx);
  if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
    return nullptr;
  }

  /* Check to see whether the interface objects are already installed */
  ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
  if (!protoAndIfaceCache.EntrySlotIfExists(constructors::id::XMLHttpRequestEventTarget)) {
    JS::Rooted<JSObject*> rootedGlobal(aCx, global);
    CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
  }

  /*
   * The object might _still_ be null, but that's OK.
   *
   * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
   * traced by TraceProtoAndIfaceCache() and its contents are never
   * changed after they have been set.
   *
   * Calling address() avoids the read read barrier that does gray
   * unmarking, but it's not possible for the object to be gray here.
   */

  const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::XMLHttpRequestEventTarget);
  MOZ_ASSERT_IF(entrySlot, !JS::ObjectIsMarkedGray(entrySlot));
  return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
}

JSObject*
GetConstructorObject(JSContext* aCx)
{
  return GetConstructorObjectHandle(aCx);
}

} // namespace XMLHttpRequestEventTargetBinding



} // namespace dom
} // namespace mozilla
