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

#include <type_traits>
#include "APZTestDataBinding.h"
#include "AtomList.h"
#include "MainThreadUtils.h"
#include "WrapperFactory.h"
#include "js/Array.h"
#include "js/CallAndConstruct.h"
#include "js/Exception.h"
#include "js/ForOfIterator.h"
#include "js/MapAndSet.h"
#include "js/Object.h"
#include "js/PropertyAndElement.h"
#include "js/PropertyDescriptor.h"
#include "js/experimental/JitInfo.h"
#include "mozilla/Atomics.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/OwningNonNull.h"
#include "mozilla/StaticPrefs_apz.h"
#include "mozilla/dom/BindingCallContext.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/DOMJSClass.h"
#include "mozilla/dom/NonRefcountedDOMObject.h"
#include "mozilla/dom/PrimitiveConversions.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/SimpleGlobalObject.h"
#include "mozilla/dom/XrayExpandoClass.h"

namespace mozilla::dom {

namespace binding_detail {}; // Just to make sure it's known as a namespace
using namespace mozilla::dom::binding_detail;



APZHitResult::APZHitResult()
{
  // Safe to pass a null context if we pass a null value
  Init();
}




bool
APZHitResult::InitIds(JSContext* cx, APZHitResultAtoms* atomsCache)
{
  MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->scrollId_id.init(cx, "scrollId") ||
      !atomsCache->screenY_id.init(cx, "screenY") ||
      !atomsCache->screenX_id.init(cx, "screenX") ||
      !atomsCache->layersId_id.init(cx, "layersId") ||
      !atomsCache->hitResult_id.init(cx, "hitResult")) {
    return false;
  }
  return true;
}

bool
APZHitResult::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
APZHitResult::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  APZHitResultAtoms* atomsCache = GetAtomCache<APZHitResultAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mHitResult.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      uint16_t const & currentValue = mHitResult.InternalValue();
      temp.setInt32(int32_t(currentValue));
      if (!JS_DefinePropertyById(cx, obj, atomsCache->hitResult_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mLayersId.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      uint64_t const & currentValue = mLayersId.InternalValue();
      temp.set(JS_NumberValue(double(currentValue)));
      if (!JS_DefinePropertyById(cx, obj, atomsCache->layersId_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mScreenX.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      float const & currentValue = mScreenX.InternalValue();
      temp.set(JS_NumberValue(double(currentValue)));
      if (!JS_DefinePropertyById(cx, obj, atomsCache->screenX_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mScreenY.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      float const & currentValue = mScreenY.InternalValue();
      temp.set(JS_NumberValue(double(currentValue)));
      if (!JS_DefinePropertyById(cx, obj, atomsCache->screenY_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mScrollId.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      uint64_t const & currentValue = mScrollId.InternalValue();
      temp.set(JS_NumberValue(double(currentValue)));
      if (!JS_DefinePropertyById(cx, obj, atomsCache->scrollId_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

void
APZHitResult::TraceDictionary(JSTracer* trc)
{
}

APZHitResult&
APZHitResult::operator=(const APZHitResult& aOther)
{
  DictionaryBase::operator=(aOther);
  mHitResult.Reset();
  if (aOther.mHitResult.WasPassed()) {
    mHitResult.Construct(aOther.mHitResult.Value());
  }
  mLayersId.Reset();
  if (aOther.mLayersId.WasPassed()) {
    mLayersId.Construct(aOther.mLayersId.Value());
  }
  mScreenX.Reset();
  if (aOther.mScreenX.WasPassed()) {
    mScreenX.Construct(aOther.mScreenX.Value());
  }
  mScreenY.Reset();
  if (aOther.mScreenY.WasPassed()) {
    mScreenY.Construct(aOther.mScreenY.Value());
  }
  mScrollId.Reset();
  if (aOther.mScrollId.WasPassed()) {
    mScrollId.Construct(aOther.mScrollId.Value());
  }
  return *this;
}



APZSampledResult::APZSampledResult()
{
  // Safe to pass a null context if we pass a null value
  Init();
}




bool
APZSampledResult::InitIds(JSContext* cx, APZSampledResultAtoms* atomsCache)
{
  MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->scrollOffsetY_id.init(cx, "scrollOffsetY") ||
      !atomsCache->scrollOffsetX_id.init(cx, "scrollOffsetX") ||
      !atomsCache->scrollId_id.init(cx, "scrollId") ||
      !atomsCache->sampledTimeStamp_id.init(cx, "sampledTimeStamp") ||
      !atomsCache->layersId_id.init(cx, "layersId")) {
    return false;
  }
  return true;
}

bool
APZSampledResult::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
APZSampledResult::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  APZSampledResultAtoms* atomsCache = GetAtomCache<APZSampledResultAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mLayersId.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      uint64_t const & currentValue = mLayersId.InternalValue();
      temp.set(JS_NumberValue(double(currentValue)));
      if (!JS_DefinePropertyById(cx, obj, atomsCache->layersId_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mSampledTimeStamp.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      double const & currentValue = mSampledTimeStamp.InternalValue();
      temp.set(JS_NumberValue(double(currentValue)));
      if (!JS_DefinePropertyById(cx, obj, atomsCache->sampledTimeStamp_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mScrollId.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      uint64_t const & currentValue = mScrollId.InternalValue();
      temp.set(JS_NumberValue(double(currentValue)));
      if (!JS_DefinePropertyById(cx, obj, atomsCache->scrollId_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mScrollOffsetX.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      float const & currentValue = mScrollOffsetX.InternalValue();
      temp.set(JS_NumberValue(double(currentValue)));
      if (!JS_DefinePropertyById(cx, obj, atomsCache->scrollOffsetX_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mScrollOffsetY.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      float const & currentValue = mScrollOffsetY.InternalValue();
      temp.set(JS_NumberValue(double(currentValue)));
      if (!JS_DefinePropertyById(cx, obj, atomsCache->scrollOffsetY_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

void
APZSampledResult::TraceDictionary(JSTracer* trc)
{
}

APZSampledResult&
APZSampledResult::operator=(const APZSampledResult& aOther)
{
  DictionaryBase::operator=(aOther);
  mLayersId.Reset();
  if (aOther.mLayersId.WasPassed()) {
    mLayersId.Construct(aOther.mLayersId.Value());
  }
  mSampledTimeStamp.Reset();
  if (aOther.mSampledTimeStamp.WasPassed()) {
    mSampledTimeStamp.Construct(aOther.mSampledTimeStamp.Value());
  }
  mScrollId.Reset();
  if (aOther.mScrollId.WasPassed()) {
    mScrollId.Construct(aOther.mScrollId.Value());
  }
  mScrollOffsetX.Reset();
  if (aOther.mScrollOffsetX.WasPassed()) {
    mScrollOffsetX.Construct(aOther.mScrollOffsetX.Value());
  }
  mScrollOffsetY.Reset();
  if (aOther.mScrollOffsetY.WasPassed()) {
    mScrollOffsetY.Construct(aOther.mScrollOffsetY.Value());
  }
  return *this;
}



AdditionalDataEntry::AdditionalDataEntry()
{
  // Safe to pass a null context if we pass a null value
  Init();
}




bool
AdditionalDataEntry::InitIds(JSContext* cx, AdditionalDataEntryAtoms* atomsCache)
{
  MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->value_id.init(cx, "value") ||
      !atomsCache->key_id.init(cx, "key")) {
    return false;
  }
  return true;
}

bool
AdditionalDataEntry::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
AdditionalDataEntry::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  AdditionalDataEntryAtoms* atomsCache = GetAtomCache<AdditionalDataEntryAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mKey.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      nsString const & currentValue = mKey.InternalValue();
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->key_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mValue.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      nsString const & currentValue = mValue.InternalValue();
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->value_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

void
AdditionalDataEntry::TraceDictionary(JSTracer* trc)
{
}

AdditionalDataEntry&
AdditionalDataEntry::operator=(const AdditionalDataEntry& aOther)
{
  DictionaryBase::operator=(aOther);
  mKey.Reset();
  if (aOther.mKey.WasPassed()) {
    mKey.Construct(aOther.mKey.Value());
  }
  mValue.Reset();
  if (aOther.mValue.WasPassed()) {
    mValue.Construct(aOther.mValue.Value());
  }
  return *this;
}



FrameUniformity::FrameUniformity()
{
  // Safe to pass a null context if we pass a null value
  Init();
}




bool
FrameUniformity::InitIds(JSContext* cx, FrameUniformityAtoms* atomsCache)
{
  MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->layerAddress_id.init(cx, "layerAddress") ||
      !atomsCache->frameUniformity_id.init(cx, "frameUniformity")) {
    return false;
  }
  return true;
}

bool
FrameUniformity::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
FrameUniformity::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  FrameUniformityAtoms* atomsCache = GetAtomCache<FrameUniformityAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mFrameUniformity.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      float const & currentValue = mFrameUniformity.InternalValue();
      temp.set(JS_NumberValue(double(currentValue)));
      if (!JS_DefinePropertyById(cx, obj, atomsCache->frameUniformity_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mLayerAddress.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      uint32_t const & currentValue = mLayerAddress.InternalValue();
      temp.setNumber(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->layerAddress_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

void
FrameUniformity::TraceDictionary(JSTracer* trc)
{
}

FrameUniformity&
FrameUniformity::operator=(const FrameUniformity& aOther)
{
  DictionaryBase::operator=(aOther);
  mFrameUniformity.Reset();
  if (aOther.mFrameUniformity.WasPassed()) {
    mFrameUniformity.Construct(aOther.mFrameUniformity.Value());
  }
  mLayerAddress.Reset();
  if (aOther.mLayerAddress.WasPassed()) {
    mLayerAddress.Construct(aOther.mLayerAddress.Value());
  }
  return *this;
}



ScrollFrameDataEntry::ScrollFrameDataEntry()
{
  // Safe to pass a null context if we pass a null value
  Init();
}




bool
ScrollFrameDataEntry::InitIds(JSContext* cx, ScrollFrameDataEntryAtoms* atomsCache)
{
  MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->value_id.init(cx, "value") ||
      !atomsCache->key_id.init(cx, "key")) {
    return false;
  }
  return true;
}

bool
ScrollFrameDataEntry::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
ScrollFrameDataEntry::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  ScrollFrameDataEntryAtoms* atomsCache = GetAtomCache<ScrollFrameDataEntryAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mKey.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      nsString const & currentValue = mKey.InternalValue();
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->key_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mValue.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      nsString const & currentValue = mValue.InternalValue();
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
        return false;
      }
      if (!JS_DefinePropertyById(cx, obj, atomsCache->value_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

void
ScrollFrameDataEntry::TraceDictionary(JSTracer* trc)
{
}

ScrollFrameDataEntry&
ScrollFrameDataEntry::operator=(const ScrollFrameDataEntry& aOther)
{
  DictionaryBase::operator=(aOther);
  mKey.Reset();
  if (aOther.mKey.WasPassed()) {
    mKey.Construct(aOther.mKey.Value());
  }
  mValue.Reset();
  if (aOther.mValue.WasPassed()) {
    mValue.Construct(aOther.mValue.Value());
  }
  return *this;
}



FrameUniformityResults::FrameUniformityResults()
{
  // Safe to pass a null context if we pass a null value
  Init();
}




bool
FrameUniformityResults::InitIds(JSContext* cx, FrameUniformityResultsAtoms* atomsCache)
{
  MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->layerUniformities_id.init(cx, "layerUniformities")) {
    return false;
  }
  return true;
}

bool
FrameUniformityResults::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
FrameUniformityResults::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  FrameUniformityResultsAtoms* atomsCache = GetAtomCache<FrameUniformityResultsAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mLayerUniformities.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      Sequence<FrameUniformity> const & currentValue = mLayerUniformities.InternalValue();

      uint32_t length = currentValue.Length();
      JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
      if (!returnArray) {
        return false;
      }
      // Scope for 'tmp'
      {
        JS::Rooted<JS::Value> tmp(cx);
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
          // Control block to let us common up the JS_DefineElement calls when there
          // are different ways to succeed at wrapping the object.
          do {
            if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
              return false;
            }
            break;
          } while (false);
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                                JSPROP_ENUMERATE)) {
            return false;
          }
        }
      }
      temp.setObject(*returnArray);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->layerUniformities_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

void
FrameUniformityResults::TraceDictionary(JSTracer* trc)
{
}

FrameUniformityResults&
FrameUniformityResults::operator=(const FrameUniformityResults& aOther)
{
  DictionaryBase::operator=(aOther);
  mLayerUniformities.Reset();
  if (aOther.mLayerUniformities.WasPassed()) {
    mLayerUniformities.Construct(aOther.mLayerUniformities.Value());
  }
  return *this;
}



ScrollFrameData::ScrollFrameData()
{
  // Safe to pass a null context if we pass a null value
  Init();
}




bool
ScrollFrameData::InitIds(JSContext* cx, ScrollFrameDataAtoms* atomsCache)
{
  MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->scrollId_id.init(cx, "scrollId") ||
      !atomsCache->entries_id.init(cx, "entries")) {
    return false;
  }
  return true;
}

bool
ScrollFrameData::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
ScrollFrameData::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  ScrollFrameDataAtoms* atomsCache = GetAtomCache<ScrollFrameDataAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mEntries.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      Sequence<ScrollFrameDataEntry> const & currentValue = mEntries.InternalValue();

      uint32_t length = currentValue.Length();
      JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
      if (!returnArray) {
        return false;
      }
      // Scope for 'tmp'
      {
        JS::Rooted<JS::Value> tmp(cx);
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
          // Control block to let us common up the JS_DefineElement calls when there
          // are different ways to succeed at wrapping the object.
          do {
            if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
              return false;
            }
            break;
          } while (false);
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                                JSPROP_ENUMERATE)) {
            return false;
          }
        }
      }
      temp.setObject(*returnArray);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->entries_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mScrollId.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      uint64_t const & currentValue = mScrollId.InternalValue();
      temp.set(JS_NumberValue(double(currentValue)));
      if (!JS_DefinePropertyById(cx, obj, atomsCache->scrollId_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

void
ScrollFrameData::TraceDictionary(JSTracer* trc)
{
}

ScrollFrameData&
ScrollFrameData::operator=(const ScrollFrameData& aOther)
{
  DictionaryBase::operator=(aOther);
  mEntries.Reset();
  if (aOther.mEntries.WasPassed()) {
    mEntries.Construct(aOther.mEntries.Value());
  }
  mScrollId.Reset();
  if (aOther.mScrollId.WasPassed()) {
    mScrollId.Construct(aOther.mScrollId.Value());
  }
  return *this;
}



APZBucket::APZBucket()
{
  // Safe to pass a null context if we pass a null value
  Init();
}




bool
APZBucket::InitIds(JSContext* cx, APZBucketAtoms* atomsCache)
{
  MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->sequenceNumber_id.init(cx, "sequenceNumber") ||
      !atomsCache->scrollFrames_id.init(cx, "scrollFrames")) {
    return false;
  }
  return true;
}

bool
APZBucket::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
APZBucket::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  APZBucketAtoms* atomsCache = GetAtomCache<APZBucketAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mScrollFrames.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      Sequence<ScrollFrameData> const & currentValue = mScrollFrames.InternalValue();

      uint32_t length = currentValue.Length();
      JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
      if (!returnArray) {
        return false;
      }
      // Scope for 'tmp'
      {
        JS::Rooted<JS::Value> tmp(cx);
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
          // Control block to let us common up the JS_DefineElement calls when there
          // are different ways to succeed at wrapping the object.
          do {
            if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
              return false;
            }
            break;
          } while (false);
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                                JSPROP_ENUMERATE)) {
            return false;
          }
        }
      }
      temp.setObject(*returnArray);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->scrollFrames_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mSequenceNumber.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      uint32_t const & currentValue = mSequenceNumber.InternalValue();
      temp.setNumber(currentValue);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->sequenceNumber_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

void
APZBucket::TraceDictionary(JSTracer* trc)
{
}

APZBucket&
APZBucket::operator=(const APZBucket& aOther)
{
  DictionaryBase::operator=(aOther);
  mScrollFrames.Reset();
  if (aOther.mScrollFrames.WasPassed()) {
    mScrollFrames.Construct(aOther.mScrollFrames.Value());
  }
  mSequenceNumber.Reset();
  if (aOther.mSequenceNumber.WasPassed()) {
    mSequenceNumber.Construct(aOther.mSequenceNumber.Value());
  }
  return *this;
}



APZTestData::APZTestData()
{
  // Safe to pass a null context if we pass a null value
  Init();
}




bool
APZTestData::InitIds(JSContext* cx, APZTestDataAtoms* atomsCache)
{
  MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->sampledResults_id.init(cx, "sampledResults") ||
      !atomsCache->repaintRequests_id.init(cx, "repaintRequests") ||
      !atomsCache->paints_id.init(cx, "paints") ||
      !atomsCache->hitResults_id.init(cx, "hitResults") ||
      !atomsCache->additionalData_id.init(cx, "additionalData")) {
    return false;
  }
  return true;
}

bool
APZTestData::Init(const char* sourceDescription, bool passedToJSImpl)
{
  return true;
}

bool
APZTestData::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  APZTestDataAtoms* atomsCache = GetAtomCache<APZTestDataAtoms>(cx);
  if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
      !InitIds(cx, atomsCache)) {
    return false;
  }

  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
  if (!obj) {
    return false;
  }
  rval.set(JS::ObjectValue(*obj));

  if (mAdditionalData.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      Sequence<AdditionalDataEntry> const & currentValue = mAdditionalData.InternalValue();

      uint32_t length = currentValue.Length();
      JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
      if (!returnArray) {
        return false;
      }
      // Scope for 'tmp'
      {
        JS::Rooted<JS::Value> tmp(cx);
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
          // Control block to let us common up the JS_DefineElement calls when there
          // are different ways to succeed at wrapping the object.
          do {
            if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
              return false;
            }
            break;
          } while (false);
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                                JSPROP_ENUMERATE)) {
            return false;
          }
        }
      }
      temp.setObject(*returnArray);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->additionalData_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mHitResults.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      Sequence<APZHitResult> const & currentValue = mHitResults.InternalValue();

      uint32_t length = currentValue.Length();
      JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
      if (!returnArray) {
        return false;
      }
      // Scope for 'tmp'
      {
        JS::Rooted<JS::Value> tmp(cx);
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
          // Control block to let us common up the JS_DefineElement calls when there
          // are different ways to succeed at wrapping the object.
          do {
            if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
              return false;
            }
            break;
          } while (false);
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                                JSPROP_ENUMERATE)) {
            return false;
          }
        }
      }
      temp.setObject(*returnArray);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->hitResults_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mPaints.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      Sequence<APZBucket> const & currentValue = mPaints.InternalValue();

      uint32_t length = currentValue.Length();
      JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
      if (!returnArray) {
        return false;
      }
      // Scope for 'tmp'
      {
        JS::Rooted<JS::Value> tmp(cx);
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
          // Control block to let us common up the JS_DefineElement calls when there
          // are different ways to succeed at wrapping the object.
          do {
            if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
              return false;
            }
            break;
          } while (false);
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                                JSPROP_ENUMERATE)) {
            return false;
          }
        }
      }
      temp.setObject(*returnArray);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->paints_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mRepaintRequests.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      Sequence<APZBucket> const & currentValue = mRepaintRequests.InternalValue();

      uint32_t length = currentValue.Length();
      JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
      if (!returnArray) {
        return false;
      }
      // Scope for 'tmp'
      {
        JS::Rooted<JS::Value> tmp(cx);
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
          // Control block to let us common up the JS_DefineElement calls when there
          // are different ways to succeed at wrapping the object.
          do {
            if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
              return false;
            }
            break;
          } while (false);
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                                JSPROP_ENUMERATE)) {
            return false;
          }
        }
      }
      temp.setObject(*returnArray);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->repaintRequests_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  if (mSampledResults.WasPassed()) {
    do {
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
      JS::Rooted<JS::Value> temp(cx);
      Sequence<APZSampledResult> const & currentValue = mSampledResults.InternalValue();

      uint32_t length = currentValue.Length();
      JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
      if (!returnArray) {
        return false;
      }
      // Scope for 'tmp'
      {
        JS::Rooted<JS::Value> tmp(cx);
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
          // Control block to let us common up the JS_DefineElement calls when there
          // are different ways to succeed at wrapping the object.
          do {
            if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
              return false;
            }
            break;
          } while (false);
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                                JSPROP_ENUMERATE)) {
            return false;
          }
        }
      }
      temp.setObject(*returnArray);
      if (!JS_DefinePropertyById(cx, obj, atomsCache->sampledResults_id, temp, JSPROP_ENUMERATE)) {
        return false;
      }
      break;
    } while(false);
  }

  return true;
}

void
APZTestData::TraceDictionary(JSTracer* trc)
{
}

APZTestData&
APZTestData::operator=(const APZTestData& aOther)
{
  DictionaryBase::operator=(aOther);
  mAdditionalData.Reset();
  if (aOther.mAdditionalData.WasPassed()) {
    mAdditionalData.Construct(aOther.mAdditionalData.Value());
  }
  mHitResults.Reset();
  if (aOther.mHitResults.WasPassed()) {
    mHitResults.Construct(aOther.mHitResults.Value());
  }
  mPaints.Reset();
  if (aOther.mPaints.WasPassed()) {
    mPaints.Construct(aOther.mPaints.Value());
  }
  mRepaintRequests.Reset();
  if (aOther.mRepaintRequests.WasPassed()) {
    mRepaintRequests.Construct(aOther.mRepaintRequests.Value());
  }
  mSampledResults.Reset();
  if (aOther.mSampledResults.WasPassed()) {
    mSampledResults.Construct(aOther.mSampledResults.Value());
  }
  return *this;
}


namespace APZHitResultFlags_Binding {

MOZ_GLOBINIT static const ConstantSpec sConstants_specs[] = {
  { "INVISIBLE", JS::Int32Value(0) },
  { "VISIBLE", JS::Int32Value(1) },
  { "IRREGULAR_AREA", JS::Int32Value(2) },
  { "APZ_AWARE_LISTENERS", JS::Int32Value(4) },
  { "INACTIVE_SCROLLFRAME", JS::Int32Value(8) },
  { "PAN_X_DISABLED", JS::Int32Value(16) },
  { "PAN_Y_DISABLED", JS::Int32Value(32) },
  { "PINCH_ZOOM_DISABLED", JS::Int32Value(64) },
  { "DOUBLE_TAP_ZOOM_DISABLED", JS::Int32Value(128) },
  { "SCROLLBAR", JS::Int32Value(256) },
  { "SCROLLBAR_THUMB", JS::Int32Value(512) },
  { "SCROLLBAR_VERTICAL", JS::Int32Value(1024) },
  { "REQUIRES_TARGET_CONFIRMATION", JS::Int32Value(2048) },
  { 0, JS::UndefinedValue() }
};


static const Prefable<const ConstantSpec> sConstants[] = {
  { nullptr, &sConstants_specs[0] },
  { nullptr, nullptr }
};

static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(13 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");


static uint16_t sNativeProperties_sortedPropertyIndices[13];
static PropertyInfo sNativeProperties_propertyInfos[13];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sConstants */,
  -1,
  13,
  sNativeProperties_sortedPropertyIndices,
  {
    { sConstants, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(13 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
    "We have a property info count that is oversized");

bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
  nullptr,
  { sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
  prototypes::id::_ID_Count,
  constructors::id::APZHitResultFlags,
  &DefaultXrayExpandoObjectClass
};

static const DOMIfaceAndProtoJSClass sNamespaceObjectClass = {
  {
    "APZHitResultFlags",
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS,
    JS_NULL_CLASS_OPS,
    JS_NULL_CLASS_SPEC,
    JS_NULL_CLASS_EXT,
    JS_NULL_OBJECT_OPS
  },
  eNamespace,
  prototypes::id::_ID_Count,
  0,
  &sNativePropertyHooks,
  // This isn't strictly following the spec (see
  // https://console.spec.whatwg.org/#ref-for-dfn-namespace-object),
  // but should be ok for Xrays.
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return StaticPrefs::apz_test_logging_enabled();
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmObjectPrototype(aCx));
  if (!constructorProto) {
    return;
  }

  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::APZHitResultFlags);
  dom::CreateNamespaceObject(aCx, aGlobal, constructorProto,
                             sNamespaceObjectClass,
                             interfaceCache,
                             sNativeProperties.Upcast(),
                             nullptr,
                             "APZHitResultFlags",
                             ShouldExpose<APZHitResultFlags_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal));
}

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

  return GetPerInterfaceObjectHandle(aCx, constructors::id::APZHitResultFlags,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace APZHitResultFlags_Binding



} // namespace mozilla::dom
