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

#include <type_traits>
#include "AtomList.h"
#include "BufferSourceBinding.h"
#include "DOMExceptionBinding.h"
#include "EventHandlerBinding.h"
#include "EventTargetBinding.h"
#include "MainThreadUtils.h"
#include "WebGPUBinding.h"
#include "WrapperFactory.h"
#include "XrayWrapper.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/Symbol.h"
#include "js/experimental/JitInfo.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "mozilla/Atomics.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/OwningNonNull.h"
#include "mozilla/ProfilerLabels.h"
#include "mozilla/dom/BindingCallContext.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/DOMJSClass.h"
#include "mozilla/dom/HTMLCanvasElement.h"
#include "mozilla/dom/HTMLImageElement.h"
#include "mozilla/dom/HTMLVideoElement.h"
#include "mozilla/dom/ImageBitmap.h"
#include "mozilla/dom/NonRefcountedDOMObject.h"
#include "mozilla/dom/Nullable.h"
#include "mozilla/dom/OffscreenCanvas.h"
#include "mozilla/dom/PrimitiveConversions.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/SimpleGlobalObject.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/dom/UnionTypes.h"
#include "mozilla/dom/VideoFrame.h"
#include "mozilla/dom/WebIDLPrefs.h"
#include "mozilla/dom/XrayExpandoClass.h"
#include "mozilla/webgpu/Adapter.h"
#include "mozilla/webgpu/BindGroup.h"
#include "mozilla/webgpu/BindGroupLayout.h"
#include "mozilla/webgpu/Buffer.h"
#include "mozilla/webgpu/CanvasContext.h"
#include "mozilla/webgpu/CommandBuffer.h"
#include "mozilla/webgpu/CommandEncoder.h"
#include "mozilla/webgpu/CompilationInfo.h"
#include "mozilla/webgpu/CompilationMessage.h"
#include "mozilla/webgpu/ComputePassEncoder.h"
#include "mozilla/webgpu/ComputePipeline.h"
#include "mozilla/webgpu/Device.h"
#include "mozilla/webgpu/DeviceLostInfo.h"
#include "mozilla/webgpu/Error.h"
#include "mozilla/webgpu/ExternalTexture.h"
#include "mozilla/webgpu/Instance.h"
#include "mozilla/webgpu/InternalError.h"
#include "mozilla/webgpu/OutOfMemoryError.h"
#include "mozilla/webgpu/PipelineError.h"
#include "mozilla/webgpu/PipelineLayout.h"
#include "mozilla/webgpu/QuerySet.h"
#include "mozilla/webgpu/Queue.h"
#include "mozilla/webgpu/RenderBundle.h"
#include "mozilla/webgpu/RenderBundleEncoder.h"
#include "mozilla/webgpu/RenderPassEncoder.h"
#include "mozilla/webgpu/RenderPipeline.h"
#include "mozilla/webgpu/Sampler.h"
#include "mozilla/webgpu/ShaderModule.h"
#include "mozilla/webgpu/SupportedFeatures.h"
#include "mozilla/webgpu/SupportedLimits.h"
#include "mozilla/webgpu/Texture.h"
#include "mozilla/webgpu/TextureView.h"
#include "mozilla/webgpu/ValidationError.h"
#include "nsContentUtils.h"
#include "nsRFPService.h"

namespace mozilla {

namespace dom {

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


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUPowerPreference>::Values[2];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUPowerPreference aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUPowerPreference>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUPowerPreference>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUPowerPreference>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUFeatureName>::Values[19];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUFeatureName aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUFeatureName>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUFeatureName>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUFeatureName>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUBufferMapState>::Values[3];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUBufferMapState aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUBufferMapState>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUBufferMapState>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUBufferMapState>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUTextureDimension>::Values[3];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUTextureDimension aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUTextureDimension>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUTextureDimension>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUTextureDimension>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUTextureViewDimension>::Values[6];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUTextureViewDimension aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUTextureViewDimension>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUTextureViewDimension>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUTextureViewDimension>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUTextureAspect>::Values[3];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUTextureAspect aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUTextureAspect>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUTextureAspect>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUTextureAspect>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUTextureFormat>::Values[95];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUTextureFormat aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUTextureFormat>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUTextureFormat>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUTextureFormat>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUAddressMode>::Values[3];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUAddressMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUAddressMode>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUAddressMode>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUAddressMode>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUFilterMode>::Values[2];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUFilterMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUFilterMode>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUFilterMode>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUFilterMode>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUMipmapFilterMode>::Values[2];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUMipmapFilterMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUMipmapFilterMode>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUMipmapFilterMode>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUMipmapFilterMode>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUCompareFunction>::Values[8];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUCompareFunction aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUCompareFunction>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUCompareFunction>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUCompareFunction>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUBufferBindingType>::Values[3];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUBufferBindingType aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUBufferBindingType>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUBufferBindingType>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUBufferBindingType>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUSamplerBindingType>::Values[3];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUSamplerBindingType aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUSamplerBindingType>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUSamplerBindingType>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUSamplerBindingType>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUTextureSampleType>::Values[5];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUTextureSampleType aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUTextureSampleType>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUTextureSampleType>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUTextureSampleType>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUStorageTextureAccess>::Values[3];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUStorageTextureAccess aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUStorageTextureAccess>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUStorageTextureAccess>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUStorageTextureAccess>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUCompilationMessageType>::Values[3];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUCompilationMessageType aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUCompilationMessageType>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUCompilationMessageType>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUCompilationMessageType>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUPipelineErrorReason>::Values[2];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUPipelineErrorReason aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUPipelineErrorReason>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUPipelineErrorReason>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUPipelineErrorReason>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUAutoLayoutMode>::Values[1];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUAutoLayoutMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUAutoLayoutMode>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUAutoLayoutMode>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUAutoLayoutMode>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUPrimitiveTopology>::Values[5];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUPrimitiveTopology aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUPrimitiveTopology>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUPrimitiveTopology>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUPrimitiveTopology>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUFrontFace>::Values[2];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUFrontFace aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUFrontFace>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUFrontFace>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUFrontFace>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUCullMode>::Values[3];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUCullMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUCullMode>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUCullMode>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUCullMode>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUBlendFactor>::Values[13];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUBlendFactor aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUBlendFactor>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUBlendFactor>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUBlendFactor>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUBlendOperation>::Values[5];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUBlendOperation aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUBlendOperation>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUBlendOperation>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUBlendOperation>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUStencilOperation>::Values[8];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUStencilOperation aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUStencilOperation>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUStencilOperation>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUStencilOperation>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUIndexFormat>::Values[2];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUIndexFormat aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUIndexFormat>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUIndexFormat>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUIndexFormat>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUVertexFormat>::Values[41];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUVertexFormat aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUVertexFormat>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUVertexFormat>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUVertexFormat>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUVertexStepMode>::Values[2];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUVertexStepMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUVertexStepMode>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUVertexStepMode>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUVertexStepMode>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPULoadOp>::Values[2];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPULoadOp aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPULoadOp>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPULoadOp>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPULoadOp>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUStoreOp>::Values[2];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUStoreOp aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUStoreOp>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUStoreOp>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUStoreOp>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUQueryType>::Values[2];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUQueryType aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUQueryType>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUQueryType>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUQueryType>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUCanvasAlphaMode>::Values[2];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUCanvasAlphaMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUCanvasAlphaMode>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUCanvasAlphaMode>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUCanvasAlphaMode>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUDeviceLostReason>::Values[2];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUDeviceLostReason aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUDeviceLostReason>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUDeviceLostReason>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUDeviceLostReason>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUErrorFilter>::Values[3];
} // namespace binding_detail

bool
ToJSValue(JSContext* aCx, GPUErrorFilter aArgument, JS::MutableHandle<JS::Value> aValue)
{
  MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUErrorFilter>::Values));
  JSString* resultStr =
    JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUErrorFilter>::Values[uint32_t(aArgument)].BeginReading(),
                      binding_detail::EnumStrings<GPUErrorFilter>::Values[uint32_t(aArgument)].Length());
  if (!resultStr) {
    return false;
  }
  aValue.setString(resultStr);
  return true;
}


void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningGPUPipelineLayoutOrGPUAutoLayoutMode& aUnion, const char* aName, uint32_t aFlags)
{
  if (aUnion.IsGPUPipelineLayout()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUPipelineLayout(), "mGPUPipelineLayout", aFlags);
  }
}


void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture& aUnion, const char* aName, uint32_t aFlags)
{
  if (aUnion.IsGPUSampler()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUSampler(), "mGPUSampler", aFlags);
  } else if (aUnion.IsGPUTexture()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUTexture(), "mGPUTexture", aFlags);
  } else if (aUnion.IsGPUTextureView()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUTextureView(), "mGPUTextureView", aFlags);
  } else if (aUnion.IsGPUBuffer()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUBuffer(), "mGPUBuffer", aFlags);
  } else if (aUnion.IsGPUBufferBinding()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUBufferBinding(), "mGPUBufferBinding", aFlags);
  } else if (aUnion.IsGPUExternalTexture()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUExternalTexture(), "mGPUExternalTexture", aFlags);
  }
}


void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningGPUTextureOrGPUTextureView& aUnion, const char* aName, uint32_t aFlags)
{
  if (aUnion.IsGPUTexture()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUTexture(), "mGPUTexture", aFlags);
  } else if (aUnion.IsGPUTextureView()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUTextureView(), "mGPUTextureView", aFlags);
  }
}


void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningHTMLVideoElementOrVideoFrame& aUnion, const char* aName, uint32_t aFlags)
{
  if (aUnion.IsHTMLVideoElement()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsHTMLVideoElement(), "mHTMLVideoElement", aFlags);
  } else if (aUnion.IsVideoFrame()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsVideoFrame(), "mVideoFrame", aFlags);
  }
}


void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas& aUnion, const char* aName, uint32_t aFlags)
{
  if (aUnion.IsImageBitmap()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsImageBitmap(), "mImageBitmap", aFlags);
  } else if (aUnion.IsHTMLImageElement()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsHTMLImageElement(), "mHTMLImageElement", aFlags);
  } else if (aUnion.IsHTMLCanvasElement()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsHTMLCanvasElement(), "mHTMLCanvasElement", aFlags);
  } else if (aUnion.IsOffscreenCanvas()) {
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsOffscreenCanvas(), "mOffscreenCanvas", aFlags);
  }
}


void
ImplCycleCollectionUnlink(OwningGPUPipelineLayoutOrGPUAutoLayoutMode& aUnion)
{
  aUnion.Uninit();
}


void
ImplCycleCollectionUnlink(OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture& aUnion)
{
  aUnion.Uninit();
}


void
ImplCycleCollectionUnlink(OwningGPUTextureOrGPUTextureView& aUnion)
{
  aUnion.Uninit();
}


void
ImplCycleCollectionUnlink(OwningHTMLVideoElementOrVideoFrame& aUnion)
{
  aUnion.Uninit();
}


void
ImplCycleCollectionUnlink(OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas& aUnion)
{
  aUnion.Uninit();
}



GPUBlendComponent::GPUBlendComponent()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->srcFactor_id.init(cx, "srcFactor") ||
      !atomsCache->operation_id.init(cx, "operation") ||
      !atomsCache->dstFactor_id.init(cx, "dstFactor")) {
    return false;
  }
  return true;
}

bool
GPUBlendComponent::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUBlendComponentAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUBlendComponentAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->dstFactor_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUBlendFactor>::Values,
                                                                         "GPUBlendFactor", "'dstFactor' member of GPUBlendComponent",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mDstFactor = static_cast<GPUBlendFactor>(index);
    }
  } else {
    mDstFactor = GPUBlendFactor::Zero;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->operation_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUBlendOperation>::Values,
                                                                         "GPUBlendOperation", "'operation' member of GPUBlendComponent",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mOperation = static_cast<GPUBlendOperation>(index);
    }
  } else {
    mOperation = GPUBlendOperation::Add;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->srcFactor_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUBlendFactor>::Values,
                                                                         "GPUBlendFactor", "'srcFactor' member of GPUBlendComponent",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mSrcFactor = static_cast<GPUBlendFactor>(index);
    }
  } else {
    mSrcFactor = GPUBlendFactor::One;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUBlendComponent::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUBlendComponent&
GPUBlendComponent::operator=(const GPUBlendComponent& aOther)
{
  DictionaryBase::operator=(aOther);
  mDstFactor = aOther.mDstFactor;
  mOperation = aOther.mOperation;
  mSrcFactor = aOther.mSrcFactor;
  return *this;
}



GPUBufferBinding::GPUBufferBinding()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->size_id.init(cx, "size") ||
      !atomsCache->offset_id.init(cx, "offset") ||
      !atomsCache->buffer_id.init(cx, "buffer")) {
    return false;
  }
  return true;
}

bool
GPUBufferBinding::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUBufferBindingAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUBufferBindingAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->buffer_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      static_assert(IsRefcounted<mozilla::webgpu::Buffer>::value, "We can only store refcounted classes.");
      {
        // Our JSContext should be in the right global to do unwrapping in.
        nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(temp.ptr(), mBuffer, cx);
        if (NS_FAILED(rv)) {
          cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'buffer' member of GPUBufferBinding", "GPUBuffer");
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'buffer' member of GPUBufferBinding");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'buffer' member of GPUBufferBinding");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->offset_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, temp.ref(), "'offset' member of GPUBufferBinding", &mOffset)) {
      return false;
    }
  } else {
    mOffset = 0ULL;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->size_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mSize.Construct();
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, temp.ref(), "'size' member of GPUBufferBinding", &(mSize.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }
  return true;
}

bool
GPUBufferBinding::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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



GPUBufferBinding&
GPUBufferBinding::operator=(const GPUBufferBinding& aOther)
{
  DictionaryBase::operator=(aOther);
  mBuffer = aOther.mBuffer;
  mOffset = aOther.mOffset;
  mSize.Reset();
  if (aOther.mSize.WasPassed()) {
    mSize.Construct(aOther.mSize.Value());
  }
  return *this;
}



GPUBufferBindingLayout::GPUBufferBindingLayout()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->type_id.init(cx, "type") ||
      !atomsCache->minBindingSize_id.init(cx, "minBindingSize") ||
      !atomsCache->hasDynamicOffset_id.init(cx, "hasDynamicOffset")) {
    return false;
  }
  return true;
}

bool
GPUBufferBindingLayout::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUBufferBindingLayoutAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUBufferBindingLayoutAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->hasDynamicOffset_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'hasDynamicOffset' member of GPUBufferBindingLayout", &mHasDynamicOffset)) {
      return false;
    }
  } else {
    mHasDynamicOffset = false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->minBindingSize_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, temp.ref(), "'minBindingSize' member of GPUBufferBindingLayout", &mMinBindingSize)) {
      return false;
    }
  } else {
    mMinBindingSize = 0ULL;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->type_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUBufferBindingType>::Values,
                                                                         "GPUBufferBindingType", "'type' member of GPUBufferBindingLayout",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mType = static_cast<GPUBufferBindingType>(index);
    }
  } else {
    mType = GPUBufferBindingType::Uniform;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUBufferBindingLayout::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUBufferBindingLayout&
GPUBufferBindingLayout::operator=(const GPUBufferBindingLayout& aOther)
{
  DictionaryBase::operator=(aOther);
  mHasDynamicOffset = aOther.mHasDynamicOffset;
  mMinBindingSize = aOther.mMinBindingSize;
  mType = aOther.mType;
  return *this;
}



GPUCanvasConfiguration::GPUCanvasConfiguration()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->viewFormats_id.init(cx, "viewFormats") ||
      !atomsCache->usage_id.init(cx, "usage") ||
      !atomsCache->format_id.init(cx, "format") ||
      !atomsCache->device_id.init(cx, "device") ||
      !atomsCache->alphaMode_id.init(cx, "alphaMode")) {
    return false;
  }
  return true;
}

bool
GPUCanvasConfiguration::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUCanvasConfigurationAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUCanvasConfigurationAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->alphaMode_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUCanvasAlphaMode>::Values,
                                                                         "GPUCanvasAlphaMode", "'alphaMode' member of GPUCanvasConfiguration",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mAlphaMode = static_cast<GPUCanvasAlphaMode>(index);
    }
  } else {
    mAlphaMode = GPUCanvasAlphaMode::Opaque;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->device_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      static_assert(IsRefcounted<mozilla::webgpu::Device>::value, "We can only store refcounted classes.");
      {
        // Our JSContext should be in the right global to do unwrapping in.
        nsresult rv = UnwrapObject<prototypes::id::GPUDevice, mozilla::webgpu::Device>(temp.ptr(), mDevice, cx);
        if (NS_FAILED(rv)) {
          cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'device' member of GPUCanvasConfiguration", "GPUDevice");
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'device' member of GPUCanvasConfiguration");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'device' member of GPUCanvasConfiguration");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->format_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUTextureFormat>::Values,
                                                                         "GPUTextureFormat", "'format' member of GPUCanvasConfiguration",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mFormat = static_cast<GPUTextureFormat>(index);
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'format' member of GPUCanvasConfiguration");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->usage_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'usage' member of GPUCanvasConfiguration", &mUsage)) {
      return false;
    }
  } else {
    mUsage = 16U;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->viewFormats_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'viewFormats' member of GPUCanvasConfiguration", "sequence");
        return false;
      }
      Sequence<GPUTextureFormat> &arr = mViewFormats;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        GPUTextureFormat* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        GPUTextureFormat& slot = *slotPtr;
        {
          int index;
          if (!binding_detail::FindEnumStringIndex<true>(cx, temp,
                                                                             binding_detail::EnumStrings<GPUTextureFormat>::Values,
                                                                             "GPUTextureFormat", "element of 'viewFormats' member of GPUCanvasConfiguration",
                                                                             &index)) {
            return false;
          }
          MOZ_ASSERT(index >= 0);
          slot = static_cast<GPUTextureFormat>(index);
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'viewFormats' member of GPUCanvasConfiguration", "sequence");
      return false;
    }
  } else {
    /* mViewFormats array is already empty; nothing to do */
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUCanvasConfiguration::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

bool
GPUCanvasConfiguration::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
  GPUCanvasConfigurationAtoms* atomsCache = GetAtomCache<GPUCanvasConfigurationAtoms>(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));

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    GPUCanvasAlphaMode const & currentValue = mAlphaMode;
    if (!ToJSValue(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->alphaMode_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    OwningNonNull<mozilla::webgpu::Device> const & currentValue = mDevice;
    if (!GetOrCreateDOMReflector(cx, currentValue, &temp)) {
      MOZ_ASSERT(JS_IsExceptionPending(cx));
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->device_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    GPUTextureFormat const & currentValue = mFormat;
    if (!ToJSValue(cx, currentValue, &temp)) {
      return false;
    }
    if (!JS_DefinePropertyById(cx, obj, atomsCache->format_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

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

  do {
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
    JS::Rooted<JS::Value> temp(cx);
    Sequence<GPUTextureFormat> const & currentValue = mViewFormats;

    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 (!ToJSValue(cx, currentValue[sequenceIdx0], &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->viewFormats_id, temp, JSPROP_ENUMERATE)) {
      return false;
    }
    break;
  } while(false);

  return true;
}

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



GPUCanvasConfiguration&
GPUCanvasConfiguration::operator=(const GPUCanvasConfiguration& aOther)
{
  DictionaryBase::operator=(aOther);
  mAlphaMode = aOther.mAlphaMode;
  mDevice = aOther.mDevice;
  mFormat = aOther.mFormat;
  mUsage = aOther.mUsage;
  mViewFormats = aOther.mViewFormats;
  return *this;
}



GPUColorDict::GPUColorDict()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->r_id.init(cx, "r") ||
      !atomsCache->g_id.init(cx, "g") ||
      !atomsCache->b_id.init(cx, "b") ||
      !atomsCache->a_id.init(cx, "a")) {
    return false;
  }
  return true;
}

bool
GPUColorDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUColorDictAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUColorDictAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->a_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), "'a' member of GPUColorDict", &mA)) {
      return false;
    } else if (!std::isfinite(mA)) {
      cx.ThrowErrorMessage<MSG_NOT_FINITE>("'a' member of GPUColorDict");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'a' member of GPUColorDict");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->b_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), "'b' member of GPUColorDict", &mB)) {
      return false;
    } else if (!std::isfinite(mB)) {
      cx.ThrowErrorMessage<MSG_NOT_FINITE>("'b' member of GPUColorDict");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'b' member of GPUColorDict");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->g_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), "'g' member of GPUColorDict", &mG)) {
      return false;
    } else if (!std::isfinite(mG)) {
      cx.ThrowErrorMessage<MSG_NOT_FINITE>("'g' member of GPUColorDict");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'g' member of GPUColorDict");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->r_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), "'r' member of GPUColorDict", &mR)) {
      return false;
    } else if (!std::isfinite(mR)) {
      cx.ThrowErrorMessage<MSG_NOT_FINITE>("'r' member of GPUColorDict");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'r' member of GPUColorDict");
  }
  return true;
}

bool
GPUColorDict::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUColorDict&
GPUColorDict::operator=(const GPUColorDict& aOther)
{
  DictionaryBase::operator=(aOther);
  mA = aOther.mA;
  mB = aOther.mB;
  mG = aOther.mG;
  mR = aOther.mR;
  return *this;
}



GPUComputePassTimestampWrites::GPUComputePassTimestampWrites()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->querySet_id.init(cx, "querySet") ||
      !atomsCache->endOfPassWriteIndex_id.init(cx, "endOfPassWriteIndex") ||
      !atomsCache->beginningOfPassWriteIndex_id.init(cx, "beginningOfPassWriteIndex")) {
    return false;
  }
  return true;
}

bool
GPUComputePassTimestampWrites::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUComputePassTimestampWritesAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUComputePassTimestampWritesAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->beginningOfPassWriteIndex_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mBeginningOfPassWriteIndex.Construct();
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'beginningOfPassWriteIndex' member of GPUComputePassTimestampWrites", &(mBeginningOfPassWriteIndex.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->endOfPassWriteIndex_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mEndOfPassWriteIndex.Construct();
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'endOfPassWriteIndex' member of GPUComputePassTimestampWrites", &(mEndOfPassWriteIndex.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->querySet_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      static_assert(IsRefcounted<mozilla::webgpu::QuerySet>::value, "We can only store refcounted classes.");
      {
        // Our JSContext should be in the right global to do unwrapping in.
        nsresult rv = UnwrapObject<prototypes::id::GPUQuerySet, mozilla::webgpu::QuerySet>(temp.ptr(), mQuerySet, cx);
        if (NS_FAILED(rv)) {
          cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'querySet' member of GPUComputePassTimestampWrites", "GPUQuerySet");
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'querySet' member of GPUComputePassTimestampWrites");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'querySet' member of GPUComputePassTimestampWrites");
  }
  return true;
}

bool
GPUComputePassTimestampWrites::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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



GPUComputePassTimestampWrites&
GPUComputePassTimestampWrites::operator=(const GPUComputePassTimestampWrites& aOther)
{
  DictionaryBase::operator=(aOther);
  mBeginningOfPassWriteIndex.Reset();
  if (aOther.mBeginningOfPassWriteIndex.WasPassed()) {
    mBeginningOfPassWriteIndex.Construct(aOther.mBeginningOfPassWriteIndex.Value());
  }
  mEndOfPassWriteIndex.Reset();
  if (aOther.mEndOfPassWriteIndex.WasPassed()) {
    mEndOfPassWriteIndex.Construct(aOther.mEndOfPassWriteIndex.Value());
  }
  mQuerySet = aOther.mQuerySet;
  return *this;
}



GPUExtent3DDict::GPUExtent3DDict()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->width_id.init(cx, "width") ||
      !atomsCache->height_id.init(cx, "height") ||
      !atomsCache->depthOrArrayLayers_id.init(cx, "depthOrArrayLayers")) {
    return false;
  }
  return true;
}

bool
GPUExtent3DDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUExtent3DDictAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUExtent3DDictAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->depthOrArrayLayers_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'depthOrArrayLayers' member of GPUExtent3DDict", &mDepthOrArrayLayers)) {
      return false;
    }
  } else {
    mDepthOrArrayLayers = 1U;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->height_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'height' member of GPUExtent3DDict", &mHeight)) {
      return false;
    }
  } else {
    mHeight = 1U;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->width_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'width' member of GPUExtent3DDict", &mWidth)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'width' member of GPUExtent3DDict");
  }
  return true;
}

bool
GPUExtent3DDict::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUExtent3DDict&
GPUExtent3DDict::operator=(const GPUExtent3DDict& aOther)
{
  DictionaryBase::operator=(aOther);
  mDepthOrArrayLayers = aOther.mDepthOrArrayLayers;
  mHeight = aOther.mHeight;
  mWidth = aOther.mWidth;
  return *this;
}



GPUExternalTextureBindingLayout::GPUExternalTextureBindingLayout()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




bool
GPUExternalTextureBindingLayout::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  return true;
}

bool
GPUExternalTextureBindingLayout::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUExternalTextureBindingLayout&
GPUExternalTextureBindingLayout::operator=(const GPUExternalTextureBindingLayout& aOther)
{
  DictionaryBase::operator=(aOther);
  return *this;
}



GPUMultisampleState::GPUMultisampleState()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->mask_id.init(cx, "mask") ||
      !atomsCache->count_id.init(cx, "count") ||
      !atomsCache->alphaToCoverageEnabled_id.init(cx, "alphaToCoverageEnabled")) {
    return false;
  }
  return true;
}

bool
GPUMultisampleState::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUMultisampleStateAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUMultisampleStateAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->alphaToCoverageEnabled_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'alphaToCoverageEnabled' member of GPUMultisampleState", &mAlphaToCoverageEnabled)) {
      return false;
    }
  } else {
    mAlphaToCoverageEnabled = false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->count_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'count' member of GPUMultisampleState", &mCount)) {
      return false;
    }
  } else {
    mCount = 1U;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->mask_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'mask' member of GPUMultisampleState", &mMask)) {
      return false;
    }
  } else {
    mMask = 4294967295U;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUMultisampleState::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUMultisampleState&
GPUMultisampleState::operator=(const GPUMultisampleState& aOther)
{
  DictionaryBase::operator=(aOther);
  mAlphaToCoverageEnabled = aOther.mAlphaToCoverageEnabled;
  mCount = aOther.mCount;
  mMask = aOther.mMask;
  return *this;
}



GPUObjectDescriptorBase::GPUObjectDescriptorBase()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

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

bool
GPUObjectDescriptorBase::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUObjectDescriptorBaseAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUObjectDescriptorBaseAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->label_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mLabel)) {
      return false;
    }
    if (!NormalizeUSVString(mLabel)) {
      JS_ReportOutOfMemory(cx);
      return false;
    }
  } else {
    mLabel.AssignLiteral(u"");
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUObjectDescriptorBase::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUObjectDescriptorBase&
GPUObjectDescriptorBase::operator=(const GPUObjectDescriptorBase& aOther)
{
  DictionaryBase::operator=(aOther);
  mLabel = aOther.mLabel;
  return *this;
}



GPUOrigin2DDict::GPUOrigin2DDict()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

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

bool
GPUOrigin2DDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUOrigin2DDictAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUOrigin2DDictAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->x_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'x' member of GPUOrigin2DDict", &mX)) {
      return false;
    }
  } else {
    mX = 0U;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->y_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'y' member of GPUOrigin2DDict", &mY)) {
      return false;
    }
  } else {
    mY = 0U;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUOrigin2DDict::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUOrigin2DDict&
GPUOrigin2DDict::operator=(const GPUOrigin2DDict& aOther)
{
  DictionaryBase::operator=(aOther);
  mX = aOther.mX;
  mY = aOther.mY;
  return *this;
}



GPUOrigin3DDict::GPUOrigin3DDict()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->z_id.init(cx, "z") ||
      !atomsCache->y_id.init(cx, "y") ||
      !atomsCache->x_id.init(cx, "x")) {
    return false;
  }
  return true;
}

bool
GPUOrigin3DDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUOrigin3DDictAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUOrigin3DDictAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->x_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'x' member of GPUOrigin3DDict", &mX)) {
      return false;
    }
  } else {
    mX = 0U;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->y_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'y' member of GPUOrigin3DDict", &mY)) {
      return false;
    }
  } else {
    mY = 0U;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->z_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'z' member of GPUOrigin3DDict", &mZ)) {
      return false;
    }
  } else {
    mZ = 0U;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUOrigin3DDict::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUOrigin3DDict&
GPUOrigin3DDict::operator=(const GPUOrigin3DDict& aOther)
{
  DictionaryBase::operator=(aOther);
  mX = aOther.mX;
  mY = aOther.mY;
  mZ = aOther.mZ;
  return *this;
}



GPUPipelineErrorInit::GPUPipelineErrorInit()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

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

bool
GPUPipelineErrorInit::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUPipelineErrorInitAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUPipelineErrorInitAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->reason_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUPipelineErrorReason>::Values,
                                                                         "GPUPipelineErrorReason", "'reason' member of GPUPipelineErrorInit",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mReason = static_cast<GPUPipelineErrorReason>(index);
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'reason' member of GPUPipelineErrorInit");
  }
  return true;
}

bool
GPUPipelineErrorInit::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUPipelineErrorInit&
GPUPipelineErrorInit::operator=(const GPUPipelineErrorInit& aOther)
{
  DictionaryBase::operator=(aOther);
  mReason = aOther.mReason;
  return *this;
}


bool
GPUPipelineLayoutOrGPUAutoLayoutMode::TrySetToGPUPipelineLayout(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    NonNull<mozilla::webgpu::PipelineLayout>& memberSlot = RawSetAsGPUPipelineLayout();
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUPipelineLayout, mozilla::webgpu::PipelineLayout>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyGPUPipelineLayout();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
GPUPipelineLayoutOrGPUAutoLayoutMode::TrySetToGPUPipelineLayout(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUPipelineLayout(cx, value, tryNext, passedToJSImpl);
}







bool
GPUPipelineLayoutOrGPUAutoLayoutMode::TrySetToGPUAutoLayoutMode(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    GPUAutoLayoutMode& memberSlot = RawSetAsGPUAutoLayoutMode();
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, value,
                                                                         binding_detail::EnumStrings<GPUAutoLayoutMode>::Values,
                                                                         "GPUAutoLayoutMode", "GPUAutoLayoutMode branch of (GPUPipelineLayout or GPUAutoLayoutMode)",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      memberSlot = static_cast<GPUAutoLayoutMode>(index);
    }
  }
  return true;
}

bool
GPUPipelineLayoutOrGPUAutoLayoutMode::TrySetToGPUAutoLayoutMode(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUAutoLayoutMode(cx, value, tryNext, passedToJSImpl);
}







bool
GPUPipelineLayoutOrGPUAutoLayoutMode::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToGPUPipelineLayout(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (!done) {
    do {
      done = (failed = !TrySetToGPUAutoLayoutMode(cx, value, tryNext)) || !tryNext;
      break;
    } while (false);
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "GPUPipelineLayout");
    return false;
  }
  return true;
}

bool
GPUPipelineLayoutOrGPUAutoLayoutMode::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}


bool
GPUPipelineLayoutOrGPUAutoLayoutMode::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
  switch (mType) {
    case eUninitialized: {
      return false;
    }
    case eGPUPipelineLayout: {
      if (!GetOrCreateDOMReflector(cx, mValue.mGPUPipelineLayout.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    case eGPUAutoLayoutMode: {
      if (!ToJSValue(cx, mValue.mGPUAutoLayoutMode.Value(), rval)) {
        return false;
      }
      return true;
    }
    default: {
      return false;
    }
  }
}



OwningGPUPipelineLayoutOrGPUAutoLayoutMode::OwningGPUPipelineLayoutOrGPUAutoLayoutMode(OwningGPUPipelineLayoutOrGPUAutoLayoutMode&& aOther)
  : mType(eUninitialized)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eGPUPipelineLayout: {
      mType = eGPUPipelineLayout;
      mValue.mGPUPipelineLayout.SetValue(std::move(aOther.mValue.mGPUPipelineLayout.Value()));
      break;
    }
    case eGPUAutoLayoutMode: {
      mType = eGPUAutoLayoutMode;
      mValue.mGPUAutoLayoutMode.SetValue(std::move(aOther.mValue.mGPUAutoLayoutMode.Value()));
      break;
    }
  }
}



bool
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::TrySetToGPUPipelineLayout(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    OwningNonNull<mozilla::webgpu::PipelineLayout>& memberSlot = RawSetAsGPUPipelineLayout();
    static_assert(IsRefcounted<mozilla::webgpu::PipelineLayout>::value, "We can only store refcounted classes.");
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUPipelineLayout, mozilla::webgpu::PipelineLayout>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyGPUPipelineLayout();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::TrySetToGPUPipelineLayout(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUPipelineLayout(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] OwningNonNull<mozilla::webgpu::PipelineLayout>&
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::RawSetAsGPUPipelineLayout()
{
  if (mType == eGPUPipelineLayout) {
    return mValue.mGPUPipelineLayout.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eGPUPipelineLayout;
  return mValue.mGPUPipelineLayout.SetValue();
}

[[nodiscard]] OwningNonNull<mozilla::webgpu::PipelineLayout>&
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::SetAsGPUPipelineLayout()
{
  if (mType == eGPUPipelineLayout) {
    return mValue.mGPUPipelineLayout.Value();
  }
  Uninit();
  mType = eGPUPipelineLayout;
  return mValue.mGPUPipelineLayout.SetValue();
}


void
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::DestroyGPUPipelineLayout()
{
  MOZ_RELEASE_ASSERT(IsGPUPipelineLayout(), "Wrong type!");
  mValue.mGPUPipelineLayout.Destroy();
  mType = eUninitialized;
}



bool
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::TrySetToGPUAutoLayoutMode(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    GPUAutoLayoutMode& memberSlot = RawSetAsGPUAutoLayoutMode();
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, value,
                                                                         binding_detail::EnumStrings<GPUAutoLayoutMode>::Values,
                                                                         "GPUAutoLayoutMode", "GPUAutoLayoutMode branch of (GPUPipelineLayout or GPUAutoLayoutMode)",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      memberSlot = static_cast<GPUAutoLayoutMode>(index);
    }
  }
  return true;
}

bool
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::TrySetToGPUAutoLayoutMode(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUAutoLayoutMode(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] GPUAutoLayoutMode&
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::RawSetAsGPUAutoLayoutMode()
{
  if (mType == eGPUAutoLayoutMode) {
    return mValue.mGPUAutoLayoutMode.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eGPUAutoLayoutMode;
  return mValue.mGPUAutoLayoutMode.SetValue();
}

[[nodiscard]] GPUAutoLayoutMode&
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::SetAsGPUAutoLayoutMode()
{
  if (mType == eGPUAutoLayoutMode) {
    return mValue.mGPUAutoLayoutMode.Value();
  }
  Uninit();
  mType = eGPUAutoLayoutMode;
  return mValue.mGPUAutoLayoutMode.SetValue();
}


void
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::DestroyGPUAutoLayoutMode()
{
  MOZ_RELEASE_ASSERT(IsGPUAutoLayoutMode(), "Wrong type!");
  mValue.mGPUAutoLayoutMode.Destroy();
  mType = eUninitialized;
}



bool
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToGPUPipelineLayout(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (!done) {
    do {
      done = (failed = !TrySetToGPUAutoLayoutMode(cx, value, tryNext)) || !tryNext;
      break;
    } while (false);
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "GPUPipelineLayout");
    return false;
  }
  return true;
}

bool
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}

void
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::Uninit()
{
  switch (mType) {
    case eUninitialized: {
      break;
    }
    case eGPUPipelineLayout: {
      DestroyGPUPipelineLayout();
      break;
    }
    case eGPUAutoLayoutMode: {
      DestroyGPUAutoLayoutMode();
      break;
    }
  }
}

bool
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
  switch (mType) {
    case eUninitialized: {
      return false;
    }
    case eGPUPipelineLayout: {
      if (!GetOrCreateDOMReflector(cx, mValue.mGPUPipelineLayout.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    case eGPUAutoLayoutMode: {
      if (!ToJSValue(cx, mValue.mGPUAutoLayoutMode.Value(), rval)) {
        return false;
      }
      return true;
    }
    default: {
      return false;
    }
  }
}

OwningGPUPipelineLayoutOrGPUAutoLayoutMode&
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::operator=(OwningGPUPipelineLayoutOrGPUAutoLayoutMode&& aOther)
{
  this->~OwningGPUPipelineLayoutOrGPUAutoLayoutMode();
  new (this) OwningGPUPipelineLayoutOrGPUAutoLayoutMode (std::move(aOther));
  return *this;
}


OwningGPUPipelineLayoutOrGPUAutoLayoutMode&
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::operator=(const OwningGPUPipelineLayoutOrGPUAutoLayoutMode& aOther)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eGPUPipelineLayout: {
      SetAsGPUPipelineLayout() = aOther.GetAsGPUPipelineLayout();
      break;
    }
    case eGPUAutoLayoutMode: {
      SetAsGPUAutoLayoutMode() = aOther.GetAsGPUAutoLayoutMode();
      break;
    }
  }
  return *this;
}



GPUPrimitiveState::GPUPrimitiveState()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->unclippedDepth_id.init(cx, "unclippedDepth") ||
      !atomsCache->topology_id.init(cx, "topology") ||
      !atomsCache->stripIndexFormat_id.init(cx, "stripIndexFormat") ||
      !atomsCache->frontFace_id.init(cx, "frontFace") ||
      !atomsCache->cullMode_id.init(cx, "cullMode")) {
    return false;
  }
  return true;
}

bool
GPUPrimitiveState::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUPrimitiveStateAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUPrimitiveStateAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->cullMode_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUCullMode>::Values,
                                                                         "GPUCullMode", "'cullMode' member of GPUPrimitiveState",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mCullMode = static_cast<GPUCullMode>(index);
    }
  } else {
    mCullMode = GPUCullMode::None;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->frontFace_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUFrontFace>::Values,
                                                                         "GPUFrontFace", "'frontFace' member of GPUPrimitiveState",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mFrontFace = static_cast<GPUFrontFace>(index);
    }
  } else {
    mFrontFace = GPUFrontFace::Ccw;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->stripIndexFormat_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mStripIndexFormat.Construct();
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUIndexFormat>::Values,
                                                                         "GPUIndexFormat", "'stripIndexFormat' member of GPUPrimitiveState",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      (mStripIndexFormat.Value()) = static_cast<GPUIndexFormat>(index);
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->topology_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUPrimitiveTopology>::Values,
                                                                         "GPUPrimitiveTopology", "'topology' member of GPUPrimitiveState",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mTopology = static_cast<GPUPrimitiveTopology>(index);
    }
  } else {
    mTopology = GPUPrimitiveTopology::Triangle_list;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->unclippedDepth_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'unclippedDepth' member of GPUPrimitiveState", &mUnclippedDepth)) {
      return false;
    }
  } else {
    mUnclippedDepth = false;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUPrimitiveState::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUPrimitiveState&
GPUPrimitiveState::operator=(const GPUPrimitiveState& aOther)
{
  DictionaryBase::operator=(aOther);
  mCullMode = aOther.mCullMode;
  mFrontFace = aOther.mFrontFace;
  mStripIndexFormat.Reset();
  if (aOther.mStripIndexFormat.WasPassed()) {
    mStripIndexFormat.Construct(aOther.mStripIndexFormat.Value());
  }
  mTopology = aOther.mTopology;
  mUnclippedDepth = aOther.mUnclippedDepth;
  return *this;
}



GPUProgrammableStage::GPUProgrammableStage()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}



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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->module_id.init(cx, "module") ||
      !atomsCache->entryPoint_id.init(cx, "entryPoint") ||
      !atomsCache->constants_id.init(cx, "constants")) {
    return false;
  }
  return true;
}

bool
GPUProgrammableStage::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUProgrammableStageAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUProgrammableStageAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->constants_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mConstants.Construct();
    if (temp.ref().isObject()) {
      auto& recordEntries = (mConstants.Value()).Entries();

      JS::Rooted<JSObject*> recordObj(cx, &temp.ref().toObject());
      JS::RootedVector<jsid> ids(cx);
      if (!js::GetPropertyKeys(cx, recordObj,
                               JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
        return false;
      }
      if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
        JS_ReportOutOfMemory(cx);
        return false;
      }
      JS::Rooted<JS::Value> propNameValue(cx);
      JS::Rooted<JS::Value> temp(cx);
      JS::Rooted<jsid> curId(cx);
      JS::Rooted<JS::Value> idVal(cx);
      // Use a hashset to keep track of ids seen, to avoid
      // introducing nasty O(N^2) behavior scanning for them all the
      // time.  Ideally we'd use a data structure with O(1) lookup
      // _and_ ordering for the MozMap, but we don't have one lying
      // around.
      nsTHashtable<nsStringHashKey> idsSeen;
      for (size_t i = 0; i < ids.length(); ++i) {
        curId = ids[i];

        JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
        if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
                                             &desc)) {
          return false;
        }

        if (desc.isNothing() || !desc->enumerable()) {
          continue;
        }

        idVal = js::IdToValue(curId);
        nsString propName;
        // This will just throw if idVal is a Symbol, like the spec says
        // to do.
        if (!ConvertJSValueToUSVString(cx, idVal, "key of 'constants' member of GPUProgrammableStage", propName)) {
          return false;
        }

        if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
          return false;
        }

        Record<nsString, double>::EntryType* entry;
        if (!idsSeen.EnsureInserted(propName)) {
          // Find the existing entry.
          auto idx = recordEntries.IndexOf(propName);
          MOZ_ASSERT(idx != recordEntries.NoIndex,
                     "Why is it not found?");
          // Now blow it away to make it look like it was just added
          // to the array, because it's not obvious that it's
          // safe to write to its already-initialized mValue via our
          // normal codegen conversions.  For example, the value
          // could be a union and this would change its type, but
          // codegen assumes we won't do that.
          entry = recordEntries.ReconstructElementAt(idx);
        } else {
          // Safe to do an infallible append here, because we did a
          // SetCapacity above to the right capacity.
          entry = recordEntries.AppendElement();
        }
        entry->mKey = propName;
        double& slot = entry->mValue;
        if (!ValueToPrimitive<double, eDefault>(cx, temp, "Value in 'constants' member of GPUProgrammableStage", &slot)) {
          return false;
        } else if (!std::isfinite(slot)) {
          cx.ThrowErrorMessage<MSG_NOT_FINITE>("Value in 'constants' member of GPUProgrammableStage");
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'constants' member of GPUProgrammableStage");
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->entryPoint_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mEntryPoint.Construct();
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mEntryPoint.Value()))) {
      return false;
    }
    if (!NormalizeUSVString((mEntryPoint.Value()))) {
      JS_ReportOutOfMemory(cx);
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->module_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      static_assert(IsRefcounted<mozilla::webgpu::ShaderModule>::value, "We can only store refcounted classes.");
      {
        // Our JSContext should be in the right global to do unwrapping in.
        nsresult rv = UnwrapObject<prototypes::id::GPUShaderModule, mozilla::webgpu::ShaderModule>(temp.ptr(), mModule, cx);
        if (NS_FAILED(rv)) {
          cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'module' member of GPUProgrammableStage", "GPUShaderModule");
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'module' member of GPUProgrammableStage");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'module' member of GPUProgrammableStage");
  }
  return true;
}

bool
GPUProgrammableStage::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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





GPURenderPassTimestampWrites::GPURenderPassTimestampWrites()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->querySet_id.init(cx, "querySet") ||
      !atomsCache->endOfPassWriteIndex_id.init(cx, "endOfPassWriteIndex") ||
      !atomsCache->beginningOfPassWriteIndex_id.init(cx, "beginningOfPassWriteIndex")) {
    return false;
  }
  return true;
}

bool
GPURenderPassTimestampWrites::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPURenderPassTimestampWritesAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPURenderPassTimestampWritesAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->beginningOfPassWriteIndex_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mBeginningOfPassWriteIndex.Construct();
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'beginningOfPassWriteIndex' member of GPURenderPassTimestampWrites", &(mBeginningOfPassWriteIndex.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->endOfPassWriteIndex_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mEndOfPassWriteIndex.Construct();
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'endOfPassWriteIndex' member of GPURenderPassTimestampWrites", &(mEndOfPassWriteIndex.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->querySet_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      static_assert(IsRefcounted<mozilla::webgpu::QuerySet>::value, "We can only store refcounted classes.");
      {
        // Our JSContext should be in the right global to do unwrapping in.
        nsresult rv = UnwrapObject<prototypes::id::GPUQuerySet, mozilla::webgpu::QuerySet>(temp.ptr(), mQuerySet, cx);
        if (NS_FAILED(rv)) {
          cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'querySet' member of GPURenderPassTimestampWrites", "GPUQuerySet");
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'querySet' member of GPURenderPassTimestampWrites");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'querySet' member of GPURenderPassTimestampWrites");
  }
  return true;
}

bool
GPURenderPassTimestampWrites::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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



GPURenderPassTimestampWrites&
GPURenderPassTimestampWrites::operator=(const GPURenderPassTimestampWrites& aOther)
{
  DictionaryBase::operator=(aOther);
  mBeginningOfPassWriteIndex.Reset();
  if (aOther.mBeginningOfPassWriteIndex.WasPassed()) {
    mBeginningOfPassWriteIndex.Construct(aOther.mBeginningOfPassWriteIndex.Value());
  }
  mEndOfPassWriteIndex.Reset();
  if (aOther.mEndOfPassWriteIndex.WasPassed()) {
    mEndOfPassWriteIndex.Construct(aOther.mEndOfPassWriteIndex.Value());
  }
  mQuerySet = aOther.mQuerySet;
  return *this;
}



GPURequestAdapterOptions::GPURequestAdapterOptions()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->xrCompatible_id.init(cx, "xrCompatible") ||
      !atomsCache->powerPreference_id.init(cx, "powerPreference") ||
      !atomsCache->forceFallbackAdapter_id.init(cx, "forceFallbackAdapter") ||
      !atomsCache->featureLevel_id.init(cx, "featureLevel")) {
    return false;
  }
  return true;
}

bool
GPURequestAdapterOptions::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPURequestAdapterOptionsAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPURequestAdapterOptionsAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->featureLevel_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mFeatureLevel)) {
      return false;
    }
  } else {
    mFeatureLevel.AssignLiteral(u"core");
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->forceFallbackAdapter_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'forceFallbackAdapter' member of GPURequestAdapterOptions", &mForceFallbackAdapter)) {
      return false;
    }
  } else {
    mForceFallbackAdapter = false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->powerPreference_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mPowerPreference.Construct();
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUPowerPreference>::Values,
                                                                         "GPUPowerPreference", "'powerPreference' member of GPURequestAdapterOptions",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      (mPowerPreference.Value()) = static_cast<GPUPowerPreference>(index);
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->xrCompatible_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'xrCompatible' member of GPURequestAdapterOptions", &mXrCompatible)) {
      return false;
    }
  } else {
    mXrCompatible = false;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPURequestAdapterOptions::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPURequestAdapterOptions&
GPURequestAdapterOptions::operator=(const GPURequestAdapterOptions& aOther)
{
  DictionaryBase::operator=(aOther);
  mFeatureLevel = aOther.mFeatureLevel;
  mForceFallbackAdapter = aOther.mForceFallbackAdapter;
  mPowerPreference.Reset();
  if (aOther.mPowerPreference.WasPassed()) {
    mPowerPreference.Construct(aOther.mPowerPreference.Value());
  }
  mXrCompatible = aOther.mXrCompatible;
  return *this;
}



GPUSamplerBindingLayout::GPUSamplerBindingLayout()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

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

bool
GPUSamplerBindingLayout::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUSamplerBindingLayoutAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUSamplerBindingLayoutAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->type_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUSamplerBindingType>::Values,
                                                                         "GPUSamplerBindingType", "'type' member of GPUSamplerBindingLayout",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mType = static_cast<GPUSamplerBindingType>(index);
    }
  } else {
    mType = GPUSamplerBindingType::Filtering;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUSamplerBindingLayout::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUSamplerBindingLayout&
GPUSamplerBindingLayout::operator=(const GPUSamplerBindingLayout& aOther)
{
  DictionaryBase::operator=(aOther);
  mType = aOther.mType;
  return *this;
}



GPUStencilFaceState::GPUStencilFaceState()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->passOp_id.init(cx, "passOp") ||
      !atomsCache->failOp_id.init(cx, "failOp") ||
      !atomsCache->depthFailOp_id.init(cx, "depthFailOp") ||
      !atomsCache->compare_id.init(cx, "compare")) {
    return false;
  }
  return true;
}

bool
GPUStencilFaceState::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUStencilFaceStateAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUStencilFaceStateAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->compare_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUCompareFunction>::Values,
                                                                         "GPUCompareFunction", "'compare' member of GPUStencilFaceState",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mCompare = static_cast<GPUCompareFunction>(index);
    }
  } else {
    mCompare = GPUCompareFunction::Always;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->depthFailOp_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUStencilOperation>::Values,
                                                                         "GPUStencilOperation", "'depthFailOp' member of GPUStencilFaceState",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mDepthFailOp = static_cast<GPUStencilOperation>(index);
    }
  } else {
    mDepthFailOp = GPUStencilOperation::Keep;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->failOp_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUStencilOperation>::Values,
                                                                         "GPUStencilOperation", "'failOp' member of GPUStencilFaceState",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mFailOp = static_cast<GPUStencilOperation>(index);
    }
  } else {
    mFailOp = GPUStencilOperation::Keep;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->passOp_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUStencilOperation>::Values,
                                                                         "GPUStencilOperation", "'passOp' member of GPUStencilFaceState",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mPassOp = static_cast<GPUStencilOperation>(index);
    }
  } else {
    mPassOp = GPUStencilOperation::Keep;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUStencilFaceState::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUStencilFaceState&
GPUStencilFaceState::operator=(const GPUStencilFaceState& aOther)
{
  DictionaryBase::operator=(aOther);
  mCompare = aOther.mCompare;
  mDepthFailOp = aOther.mDepthFailOp;
  mFailOp = aOther.mFailOp;
  mPassOp = aOther.mPassOp;
  return *this;
}



GPUStorageTextureBindingLayout::GPUStorageTextureBindingLayout()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->viewDimension_id.init(cx, "viewDimension") ||
      !atomsCache->format_id.init(cx, "format") ||
      !atomsCache->access_id.init(cx, "access")) {
    return false;
  }
  return true;
}

bool
GPUStorageTextureBindingLayout::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUStorageTextureBindingLayoutAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUStorageTextureBindingLayoutAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->access_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUStorageTextureAccess>::Values,
                                                                         "GPUStorageTextureAccess", "'access' member of GPUStorageTextureBindingLayout",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mAccess = static_cast<GPUStorageTextureAccess>(index);
    }
  } else {
    mAccess = GPUStorageTextureAccess::Write_only;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->format_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUTextureFormat>::Values,
                                                                         "GPUTextureFormat", "'format' member of GPUStorageTextureBindingLayout",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mFormat = static_cast<GPUTextureFormat>(index);
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'format' member of GPUStorageTextureBindingLayout");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->viewDimension_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUTextureViewDimension>::Values,
                                                                         "GPUTextureViewDimension", "'viewDimension' member of GPUStorageTextureBindingLayout",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mViewDimension = static_cast<GPUTextureViewDimension>(index);
    }
  } else {
    mViewDimension = GPUTextureViewDimension::_2d;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUStorageTextureBindingLayout::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUStorageTextureBindingLayout&
GPUStorageTextureBindingLayout::operator=(const GPUStorageTextureBindingLayout& aOther)
{
  DictionaryBase::operator=(aOther);
  mAccess = aOther.mAccess;
  mFormat = aOther.mFormat;
  mViewDimension = aOther.mViewDimension;
  return *this;
}



GPUTexelCopyBufferLayout::GPUTexelCopyBufferLayout()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->rowsPerImage_id.init(cx, "rowsPerImage") ||
      !atomsCache->offset_id.init(cx, "offset") ||
      !atomsCache->bytesPerRow_id.init(cx, "bytesPerRow")) {
    return false;
  }
  return true;
}

bool
GPUTexelCopyBufferLayout::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUTexelCopyBufferLayoutAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUTexelCopyBufferLayoutAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->bytesPerRow_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mBytesPerRow.Construct();
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'bytesPerRow' member of GPUTexelCopyBufferLayout", &(mBytesPerRow.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->offset_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, temp.ref(), "'offset' member of GPUTexelCopyBufferLayout", &mOffset)) {
      return false;
    }
  } else {
    mOffset = 0ULL;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->rowsPerImage_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mRowsPerImage.Construct();
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'rowsPerImage' member of GPUTexelCopyBufferLayout", &(mRowsPerImage.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }
  return true;
}

bool
GPUTexelCopyBufferLayout::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUTexelCopyBufferLayout&
GPUTexelCopyBufferLayout::operator=(const GPUTexelCopyBufferLayout& aOther)
{
  DictionaryBase::operator=(aOther);
  mBytesPerRow.Reset();
  if (aOther.mBytesPerRow.WasPassed()) {
    mBytesPerRow.Construct(aOther.mBytesPerRow.Value());
  }
  mOffset = aOther.mOffset;
  mRowsPerImage.Reset();
  if (aOther.mRowsPerImage.WasPassed()) {
    mRowsPerImage.Construct(aOther.mRowsPerImage.Value());
  }
  return *this;
}



GPUTextureBindingLayout::GPUTextureBindingLayout()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->viewDimension_id.init(cx, "viewDimension") ||
      !atomsCache->sampleType_id.init(cx, "sampleType") ||
      !atomsCache->multisampled_id.init(cx, "multisampled")) {
    return false;
  }
  return true;
}

bool
GPUTextureBindingLayout::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUTextureBindingLayoutAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUTextureBindingLayoutAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->multisampled_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'multisampled' member of GPUTextureBindingLayout", &mMultisampled)) {
      return false;
    }
  } else {
    mMultisampled = false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->sampleType_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUTextureSampleType>::Values,
                                                                         "GPUTextureSampleType", "'sampleType' member of GPUTextureBindingLayout",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mSampleType = static_cast<GPUTextureSampleType>(index);
    }
  } else {
    mSampleType = GPUTextureSampleType::Float;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->viewDimension_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUTextureViewDimension>::Values,
                                                                         "GPUTextureViewDimension", "'viewDimension' member of GPUTextureBindingLayout",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mViewDimension = static_cast<GPUTextureViewDimension>(index);
    }
  } else {
    mViewDimension = GPUTextureViewDimension::_2d;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUTextureBindingLayout::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUTextureBindingLayout&
GPUTextureBindingLayout::operator=(const GPUTextureBindingLayout& aOther)
{
  DictionaryBase::operator=(aOther);
  mMultisampled = aOther.mMultisampled;
  mSampleType = aOther.mSampleType;
  mViewDimension = aOther.mViewDimension;
  return *this;
}


bool
GPUTextureOrGPUTextureView::TrySetToGPUTexture(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    NonNull<mozilla::webgpu::Texture>& memberSlot = RawSetAsGPUTexture();
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUTexture, mozilla::webgpu::Texture>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyGPUTexture();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
GPUTextureOrGPUTextureView::TrySetToGPUTexture(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUTexture(cx, value, tryNext, passedToJSImpl);
}







bool
GPUTextureOrGPUTextureView::TrySetToGPUTextureView(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    NonNull<mozilla::webgpu::TextureView>& memberSlot = RawSetAsGPUTextureView();
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUTextureView, mozilla::webgpu::TextureView>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyGPUTextureView();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
GPUTextureOrGPUTextureView::TrySetToGPUTextureView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUTextureView(cx, value, tryNext, passedToJSImpl);
}







bool
GPUTextureOrGPUTextureView::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToGPUTexture(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToGPUTextureView(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "GPUTexture, GPUTextureView");
    return false;
  }
  return true;
}

bool
GPUTextureOrGPUTextureView::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}


bool
GPUTextureOrGPUTextureView::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
  switch (mType) {
    case eUninitialized: {
      return false;
    }
    case eGPUTexture: {
      if (!GetOrCreateDOMReflector(cx, mValue.mGPUTexture.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    case eGPUTextureView: {
      if (!GetOrCreateDOMReflector(cx, mValue.mGPUTextureView.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    default: {
      return false;
    }
  }
}



OwningGPUTextureOrGPUTextureView::OwningGPUTextureOrGPUTextureView(OwningGPUTextureOrGPUTextureView&& aOther)
  : mType(eUninitialized)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eGPUTexture: {
      mType = eGPUTexture;
      mValue.mGPUTexture.SetValue(std::move(aOther.mValue.mGPUTexture.Value()));
      break;
    }
    case eGPUTextureView: {
      mType = eGPUTextureView;
      mValue.mGPUTextureView.SetValue(std::move(aOther.mValue.mGPUTextureView.Value()));
      break;
    }
  }
}



bool
OwningGPUTextureOrGPUTextureView::TrySetToGPUTexture(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    OwningNonNull<mozilla::webgpu::Texture>& memberSlot = RawSetAsGPUTexture();
    static_assert(IsRefcounted<mozilla::webgpu::Texture>::value, "We can only store refcounted classes.");
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUTexture, mozilla::webgpu::Texture>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyGPUTexture();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
OwningGPUTextureOrGPUTextureView::TrySetToGPUTexture(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUTexture(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] OwningNonNull<mozilla::webgpu::Texture>&
OwningGPUTextureOrGPUTextureView::RawSetAsGPUTexture()
{
  if (mType == eGPUTexture) {
    return mValue.mGPUTexture.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eGPUTexture;
  return mValue.mGPUTexture.SetValue();
}

[[nodiscard]] OwningNonNull<mozilla::webgpu::Texture>&
OwningGPUTextureOrGPUTextureView::SetAsGPUTexture()
{
  if (mType == eGPUTexture) {
    return mValue.mGPUTexture.Value();
  }
  Uninit();
  mType = eGPUTexture;
  return mValue.mGPUTexture.SetValue();
}


void
OwningGPUTextureOrGPUTextureView::DestroyGPUTexture()
{
  MOZ_RELEASE_ASSERT(IsGPUTexture(), "Wrong type!");
  mValue.mGPUTexture.Destroy();
  mType = eUninitialized;
}



bool
OwningGPUTextureOrGPUTextureView::TrySetToGPUTextureView(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    OwningNonNull<mozilla::webgpu::TextureView>& memberSlot = RawSetAsGPUTextureView();
    static_assert(IsRefcounted<mozilla::webgpu::TextureView>::value, "We can only store refcounted classes.");
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUTextureView, mozilla::webgpu::TextureView>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyGPUTextureView();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
OwningGPUTextureOrGPUTextureView::TrySetToGPUTextureView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUTextureView(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] OwningNonNull<mozilla::webgpu::TextureView>&
OwningGPUTextureOrGPUTextureView::RawSetAsGPUTextureView()
{
  if (mType == eGPUTextureView) {
    return mValue.mGPUTextureView.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eGPUTextureView;
  return mValue.mGPUTextureView.SetValue();
}

[[nodiscard]] OwningNonNull<mozilla::webgpu::TextureView>&
OwningGPUTextureOrGPUTextureView::SetAsGPUTextureView()
{
  if (mType == eGPUTextureView) {
    return mValue.mGPUTextureView.Value();
  }
  Uninit();
  mType = eGPUTextureView;
  return mValue.mGPUTextureView.SetValue();
}


void
OwningGPUTextureOrGPUTextureView::DestroyGPUTextureView()
{
  MOZ_RELEASE_ASSERT(IsGPUTextureView(), "Wrong type!");
  mValue.mGPUTextureView.Destroy();
  mType = eUninitialized;
}



bool
OwningGPUTextureOrGPUTextureView::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToGPUTexture(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToGPUTextureView(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "GPUTexture, GPUTextureView");
    return false;
  }
  return true;
}

bool
OwningGPUTextureOrGPUTextureView::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}

void
OwningGPUTextureOrGPUTextureView::Uninit()
{
  switch (mType) {
    case eUninitialized: {
      break;
    }
    case eGPUTexture: {
      DestroyGPUTexture();
      break;
    }
    case eGPUTextureView: {
      DestroyGPUTextureView();
      break;
    }
  }
}

bool
OwningGPUTextureOrGPUTextureView::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
  switch (mType) {
    case eUninitialized: {
      return false;
    }
    case eGPUTexture: {
      if (!GetOrCreateDOMReflector(cx, mValue.mGPUTexture.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    case eGPUTextureView: {
      if (!GetOrCreateDOMReflector(cx, mValue.mGPUTextureView.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    default: {
      return false;
    }
  }
}

OwningGPUTextureOrGPUTextureView&
OwningGPUTextureOrGPUTextureView::operator=(OwningGPUTextureOrGPUTextureView&& aOther)
{
  this->~OwningGPUTextureOrGPUTextureView();
  new (this) OwningGPUTextureOrGPUTextureView (std::move(aOther));
  return *this;
}


OwningGPUTextureOrGPUTextureView&
OwningGPUTextureOrGPUTextureView::operator=(const OwningGPUTextureOrGPUTextureView& aOther)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eGPUTexture: {
      SetAsGPUTexture() = aOther.GetAsGPUTexture();
      break;
    }
    case eGPUTextureView: {
      SetAsGPUTextureView() = aOther.GetAsGPUTextureView();
      break;
    }
  }
  return *this;
}



GPUVertexAttribute::GPUVertexAttribute()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->shaderLocation_id.init(cx, "shaderLocation") ||
      !atomsCache->offset_id.init(cx, "offset") ||
      !atomsCache->format_id.init(cx, "format")) {
    return false;
  }
  return true;
}

bool
GPUVertexAttribute::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUVertexAttributeAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUVertexAttributeAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->format_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUVertexFormat>::Values,
                                                                         "GPUVertexFormat", "'format' member of GPUVertexAttribute",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mFormat = static_cast<GPUVertexFormat>(index);
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'format' member of GPUVertexAttribute");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->offset_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, temp.ref(), "'offset' member of GPUVertexAttribute", &mOffset)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'offset' member of GPUVertexAttribute");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->shaderLocation_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'shaderLocation' member of GPUVertexAttribute", &mShaderLocation)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'shaderLocation' member of GPUVertexAttribute");
  }
  return true;
}

bool
GPUVertexAttribute::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUVertexAttribute&
GPUVertexAttribute::operator=(const GPUVertexAttribute& aOther)
{
  DictionaryBase::operator=(aOther);
  mFormat = aOther.mFormat;
  mOffset = aOther.mOffset;
  mShaderLocation = aOther.mShaderLocation;
  return *this;
}


bool
HTMLVideoElementOrVideoFrame::TrySetToHTMLVideoElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    NonNull<mozilla::dom::HTMLVideoElement>& memberSlot = RawSetAsHTMLVideoElement();
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::HTMLVideoElement, mozilla::dom::HTMLVideoElement>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyHTMLVideoElement();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
HTMLVideoElementOrVideoFrame::TrySetToHTMLVideoElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToHTMLVideoElement(cx, value, tryNext, passedToJSImpl);
}







bool
HTMLVideoElementOrVideoFrame::TrySetToVideoFrame(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    NonNull<mozilla::dom::VideoFrame>& memberSlot = RawSetAsVideoFrame();
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::VideoFrame, mozilla::dom::VideoFrame>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyVideoFrame();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
HTMLVideoElementOrVideoFrame::TrySetToVideoFrame(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToVideoFrame(cx, value, tryNext, passedToJSImpl);
}







bool
HTMLVideoElementOrVideoFrame::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToHTMLVideoElement(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToVideoFrame(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "HTMLVideoElement, VideoFrame");
    return false;
  }
  return true;
}

bool
HTMLVideoElementOrVideoFrame::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}


bool
HTMLVideoElementOrVideoFrame::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
  switch (mType) {
    case eUninitialized: {
      return false;
    }
    case eHTMLVideoElement: {
      if (!GetOrCreateDOMReflector(cx, mValue.mHTMLVideoElement.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    case eVideoFrame: {
      if (!GetOrCreateDOMReflector(cx, mValue.mVideoFrame.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    default: {
      return false;
    }
  }
}



OwningHTMLVideoElementOrVideoFrame::OwningHTMLVideoElementOrVideoFrame(OwningHTMLVideoElementOrVideoFrame&& aOther)
  : mType(eUninitialized)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eHTMLVideoElement: {
      mType = eHTMLVideoElement;
      mValue.mHTMLVideoElement.SetValue(std::move(aOther.mValue.mHTMLVideoElement.Value()));
      break;
    }
    case eVideoFrame: {
      mType = eVideoFrame;
      mValue.mVideoFrame.SetValue(std::move(aOther.mValue.mVideoFrame.Value()));
      break;
    }
  }
}



bool
OwningHTMLVideoElementOrVideoFrame::TrySetToHTMLVideoElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    OwningNonNull<mozilla::dom::HTMLVideoElement>& memberSlot = RawSetAsHTMLVideoElement();
    static_assert(IsRefcounted<mozilla::dom::HTMLVideoElement>::value, "We can only store refcounted classes.");
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::HTMLVideoElement, mozilla::dom::HTMLVideoElement>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyHTMLVideoElement();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
OwningHTMLVideoElementOrVideoFrame::TrySetToHTMLVideoElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToHTMLVideoElement(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] OwningNonNull<mozilla::dom::HTMLVideoElement>&
OwningHTMLVideoElementOrVideoFrame::RawSetAsHTMLVideoElement()
{
  if (mType == eHTMLVideoElement) {
    return mValue.mHTMLVideoElement.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eHTMLVideoElement;
  return mValue.mHTMLVideoElement.SetValue();
}

[[nodiscard]] OwningNonNull<mozilla::dom::HTMLVideoElement>&
OwningHTMLVideoElementOrVideoFrame::SetAsHTMLVideoElement()
{
  if (mType == eHTMLVideoElement) {
    return mValue.mHTMLVideoElement.Value();
  }
  Uninit();
  mType = eHTMLVideoElement;
  return mValue.mHTMLVideoElement.SetValue();
}


void
OwningHTMLVideoElementOrVideoFrame::DestroyHTMLVideoElement()
{
  MOZ_RELEASE_ASSERT(IsHTMLVideoElement(), "Wrong type!");
  mValue.mHTMLVideoElement.Destroy();
  mType = eUninitialized;
}



bool
OwningHTMLVideoElementOrVideoFrame::TrySetToVideoFrame(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    OwningNonNull<mozilla::dom::VideoFrame>& memberSlot = RawSetAsVideoFrame();
    static_assert(IsRefcounted<mozilla::dom::VideoFrame>::value, "We can only store refcounted classes.");
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::VideoFrame, mozilla::dom::VideoFrame>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyVideoFrame();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
OwningHTMLVideoElementOrVideoFrame::TrySetToVideoFrame(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToVideoFrame(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] OwningNonNull<mozilla::dom::VideoFrame>&
OwningHTMLVideoElementOrVideoFrame::RawSetAsVideoFrame()
{
  if (mType == eVideoFrame) {
    return mValue.mVideoFrame.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eVideoFrame;
  return mValue.mVideoFrame.SetValue();
}

[[nodiscard]] OwningNonNull<mozilla::dom::VideoFrame>&
OwningHTMLVideoElementOrVideoFrame::SetAsVideoFrame()
{
  if (mType == eVideoFrame) {
    return mValue.mVideoFrame.Value();
  }
  Uninit();
  mType = eVideoFrame;
  return mValue.mVideoFrame.SetValue();
}


void
OwningHTMLVideoElementOrVideoFrame::DestroyVideoFrame()
{
  MOZ_RELEASE_ASSERT(IsVideoFrame(), "Wrong type!");
  mValue.mVideoFrame.Destroy();
  mType = eUninitialized;
}



bool
OwningHTMLVideoElementOrVideoFrame::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToHTMLVideoElement(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToVideoFrame(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "HTMLVideoElement, VideoFrame");
    return false;
  }
  return true;
}

bool
OwningHTMLVideoElementOrVideoFrame::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}

void
OwningHTMLVideoElementOrVideoFrame::Uninit()
{
  switch (mType) {
    case eUninitialized: {
      break;
    }
    case eHTMLVideoElement: {
      DestroyHTMLVideoElement();
      break;
    }
    case eVideoFrame: {
      DestroyVideoFrame();
      break;
    }
  }
}

bool
OwningHTMLVideoElementOrVideoFrame::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
  switch (mType) {
    case eUninitialized: {
      return false;
    }
    case eHTMLVideoElement: {
      if (!GetOrCreateDOMReflector(cx, mValue.mHTMLVideoElement.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    case eVideoFrame: {
      if (!GetOrCreateDOMReflector(cx, mValue.mVideoFrame.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    default: {
      return false;
    }
  }
}

OwningHTMLVideoElementOrVideoFrame&
OwningHTMLVideoElementOrVideoFrame::operator=(OwningHTMLVideoElementOrVideoFrame&& aOther)
{
  this->~OwningHTMLVideoElementOrVideoFrame();
  new (this) OwningHTMLVideoElementOrVideoFrame (std::move(aOther));
  return *this;
}


OwningHTMLVideoElementOrVideoFrame&
OwningHTMLVideoElementOrVideoFrame::operator=(const OwningHTMLVideoElementOrVideoFrame& aOther)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eHTMLVideoElement: {
      SetAsHTMLVideoElement() = aOther.GetAsHTMLVideoElement();
      break;
    }
    case eVideoFrame: {
      SetAsVideoFrame() = aOther.GetAsVideoFrame();
      break;
    }
  }
  return *this;
}


bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToImageBitmap(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    NonNull<mozilla::dom::ImageBitmap>& memberSlot = RawSetAsImageBitmap();
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::ImageBitmap, mozilla::dom::ImageBitmap>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyImageBitmap();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToImageBitmap(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToImageBitmap(cx, value, tryNext, passedToJSImpl);
}







bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLImageElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    NonNull<mozilla::dom::HTMLImageElement>& memberSlot = RawSetAsHTMLImageElement();
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::HTMLImageElement, mozilla::dom::HTMLImageElement>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyHTMLImageElement();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLImageElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToHTMLImageElement(cx, value, tryNext, passedToJSImpl);
}







bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLCanvasElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    NonNull<mozilla::dom::HTMLCanvasElement>& memberSlot = RawSetAsHTMLCanvasElement();
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::HTMLCanvasElement, mozilla::dom::HTMLCanvasElement>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyHTMLCanvasElement();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLCanvasElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToHTMLCanvasElement(cx, value, tryNext, passedToJSImpl);
}







bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToOffscreenCanvas(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    NonNull<mozilla::dom::OffscreenCanvas>& memberSlot = RawSetAsOffscreenCanvas();
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::OffscreenCanvas, mozilla::dom::OffscreenCanvas>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyOffscreenCanvas();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToOffscreenCanvas(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToOffscreenCanvas(cx, value, tryNext, passedToJSImpl);
}







bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToImageBitmap(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToHTMLImageElement(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToHTMLCanvasElement(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToOffscreenCanvas(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ImageBitmap, HTMLImageElement, HTMLCanvasElement, OffscreenCanvas");
    return false;
  }
  return true;
}

bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}


bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
  switch (mType) {
    case eUninitialized: {
      return false;
    }
    case eImageBitmap: {
      if (!GetOrCreateDOMReflector(cx, mValue.mImageBitmap.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    case eHTMLImageElement: {
      if (!GetOrCreateDOMReflector(cx, mValue.mHTMLImageElement.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    case eHTMLCanvasElement: {
      if (!GetOrCreateDOMReflector(cx, mValue.mHTMLCanvasElement.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    case eOffscreenCanvas: {
      if (!GetOrCreateDOMReflector(cx, mValue.mOffscreenCanvas.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    default: {
      return false;
    }
  }
}



OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas(OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas&& aOther)
  : mType(eUninitialized)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eImageBitmap: {
      mType = eImageBitmap;
      mValue.mImageBitmap.SetValue(std::move(aOther.mValue.mImageBitmap.Value()));
      break;
    }
    case eHTMLImageElement: {
      mType = eHTMLImageElement;
      mValue.mHTMLImageElement.SetValue(std::move(aOther.mValue.mHTMLImageElement.Value()));
      break;
    }
    case eHTMLCanvasElement: {
      mType = eHTMLCanvasElement;
      mValue.mHTMLCanvasElement.SetValue(std::move(aOther.mValue.mHTMLCanvasElement.Value()));
      break;
    }
    case eOffscreenCanvas: {
      mType = eOffscreenCanvas;
      mValue.mOffscreenCanvas.SetValue(std::move(aOther.mValue.mOffscreenCanvas.Value()));
      break;
    }
  }
}



bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToImageBitmap(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    OwningNonNull<mozilla::dom::ImageBitmap>& memberSlot = RawSetAsImageBitmap();
    static_assert(IsRefcounted<mozilla::dom::ImageBitmap>::value, "We can only store refcounted classes.");
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::ImageBitmap, mozilla::dom::ImageBitmap>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyImageBitmap();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToImageBitmap(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToImageBitmap(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] OwningNonNull<mozilla::dom::ImageBitmap>&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::RawSetAsImageBitmap()
{
  if (mType == eImageBitmap) {
    return mValue.mImageBitmap.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eImageBitmap;
  return mValue.mImageBitmap.SetValue();
}

[[nodiscard]] OwningNonNull<mozilla::dom::ImageBitmap>&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::SetAsImageBitmap()
{
  if (mType == eImageBitmap) {
    return mValue.mImageBitmap.Value();
  }
  Uninit();
  mType = eImageBitmap;
  return mValue.mImageBitmap.SetValue();
}


void
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::DestroyImageBitmap()
{
  MOZ_RELEASE_ASSERT(IsImageBitmap(), "Wrong type!");
  mValue.mImageBitmap.Destroy();
  mType = eUninitialized;
}



bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLImageElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    OwningNonNull<mozilla::dom::HTMLImageElement>& memberSlot = RawSetAsHTMLImageElement();
    static_assert(IsRefcounted<mozilla::dom::HTMLImageElement>::value, "We can only store refcounted classes.");
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::HTMLImageElement, mozilla::dom::HTMLImageElement>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyHTMLImageElement();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLImageElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToHTMLImageElement(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] OwningNonNull<mozilla::dom::HTMLImageElement>&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::RawSetAsHTMLImageElement()
{
  if (mType == eHTMLImageElement) {
    return mValue.mHTMLImageElement.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eHTMLImageElement;
  return mValue.mHTMLImageElement.SetValue();
}

[[nodiscard]] OwningNonNull<mozilla::dom::HTMLImageElement>&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::SetAsHTMLImageElement()
{
  if (mType == eHTMLImageElement) {
    return mValue.mHTMLImageElement.Value();
  }
  Uninit();
  mType = eHTMLImageElement;
  return mValue.mHTMLImageElement.SetValue();
}


void
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::DestroyHTMLImageElement()
{
  MOZ_RELEASE_ASSERT(IsHTMLImageElement(), "Wrong type!");
  mValue.mHTMLImageElement.Destroy();
  mType = eUninitialized;
}



bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLCanvasElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    OwningNonNull<mozilla::dom::HTMLCanvasElement>& memberSlot = RawSetAsHTMLCanvasElement();
    static_assert(IsRefcounted<mozilla::dom::HTMLCanvasElement>::value, "We can only store refcounted classes.");
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::HTMLCanvasElement, mozilla::dom::HTMLCanvasElement>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyHTMLCanvasElement();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLCanvasElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToHTMLCanvasElement(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] OwningNonNull<mozilla::dom::HTMLCanvasElement>&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::RawSetAsHTMLCanvasElement()
{
  if (mType == eHTMLCanvasElement) {
    return mValue.mHTMLCanvasElement.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eHTMLCanvasElement;
  return mValue.mHTMLCanvasElement.SetValue();
}

[[nodiscard]] OwningNonNull<mozilla::dom::HTMLCanvasElement>&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::SetAsHTMLCanvasElement()
{
  if (mType == eHTMLCanvasElement) {
    return mValue.mHTMLCanvasElement.Value();
  }
  Uninit();
  mType = eHTMLCanvasElement;
  return mValue.mHTMLCanvasElement.SetValue();
}


void
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::DestroyHTMLCanvasElement()
{
  MOZ_RELEASE_ASSERT(IsHTMLCanvasElement(), "Wrong type!");
  mValue.mHTMLCanvasElement.Destroy();
  mType = eUninitialized;
}



bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToOffscreenCanvas(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    OwningNonNull<mozilla::dom::OffscreenCanvas>& memberSlot = RawSetAsOffscreenCanvas();
    static_assert(IsRefcounted<mozilla::dom::OffscreenCanvas>::value, "We can only store refcounted classes.");
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::OffscreenCanvas, mozilla::dom::OffscreenCanvas>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyOffscreenCanvas();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToOffscreenCanvas(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToOffscreenCanvas(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] OwningNonNull<mozilla::dom::OffscreenCanvas>&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::RawSetAsOffscreenCanvas()
{
  if (mType == eOffscreenCanvas) {
    return mValue.mOffscreenCanvas.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eOffscreenCanvas;
  return mValue.mOffscreenCanvas.SetValue();
}

[[nodiscard]] OwningNonNull<mozilla::dom::OffscreenCanvas>&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::SetAsOffscreenCanvas()
{
  if (mType == eOffscreenCanvas) {
    return mValue.mOffscreenCanvas.Value();
  }
  Uninit();
  mType = eOffscreenCanvas;
  return mValue.mOffscreenCanvas.SetValue();
}


void
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::DestroyOffscreenCanvas()
{
  MOZ_RELEASE_ASSERT(IsOffscreenCanvas(), "Wrong type!");
  mValue.mOffscreenCanvas.Destroy();
  mType = eUninitialized;
}



bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToImageBitmap(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToHTMLImageElement(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToHTMLCanvasElement(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToOffscreenCanvas(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ImageBitmap, HTMLImageElement, HTMLCanvasElement, OffscreenCanvas");
    return false;
  }
  return true;
}

bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}

void
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::Uninit()
{
  switch (mType) {
    case eUninitialized: {
      break;
    }
    case eImageBitmap: {
      DestroyImageBitmap();
      break;
    }
    case eHTMLImageElement: {
      DestroyHTMLImageElement();
      break;
    }
    case eHTMLCanvasElement: {
      DestroyHTMLCanvasElement();
      break;
    }
    case eOffscreenCanvas: {
      DestroyOffscreenCanvas();
      break;
    }
  }
}

bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
  switch (mType) {
    case eUninitialized: {
      return false;
    }
    case eImageBitmap: {
      if (!GetOrCreateDOMReflector(cx, mValue.mImageBitmap.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    case eHTMLImageElement: {
      if (!GetOrCreateDOMReflector(cx, mValue.mHTMLImageElement.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    case eHTMLCanvasElement: {
      if (!GetOrCreateDOMReflector(cx, mValue.mHTMLCanvasElement.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    case eOffscreenCanvas: {
      if (!GetOrCreateDOMReflector(cx, mValue.mOffscreenCanvas.Value(), rval)) {
        MOZ_ASSERT(JS_IsExceptionPending(cx));
        return false;
      }
      return true;
    }
    default: {
      return false;
    }
  }
}

OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::operator=(OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas&& aOther)
{
  this->~OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas();
  new (this) OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas (std::move(aOther));
  return *this;
}


OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::operator=(const OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas& aOther)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eImageBitmap: {
      SetAsImageBitmap() = aOther.GetAsImageBitmap();
      break;
    }
    case eHTMLImageElement: {
      SetAsHTMLImageElement() = aOther.GetAsHTMLImageElement();
      break;
    }
    case eHTMLCanvasElement: {
      SetAsHTMLCanvasElement() = aOther.GetAsHTMLCanvasElement();
      break;
    }
    case eOffscreenCanvas: {
      SetAsOffscreenCanvas() = aOther.GetAsOffscreenCanvas();
      break;
    }
  }
  return *this;
}


bool
DoubleSequenceOrGPUColorDict::TrySetToDoubleSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    binding_detail::AutoSequence<double>& memberSlot = RawSetAsDoubleSequence();
    JS::ForOfIterator iter(cx);
    if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
      return false;
    }
    if (!iter.valueIsIterable()) {
      DestroyDoubleSequence();
      tryNext = true;
      return true;
    }
    binding_detail::AutoSequence<double> &arr = memberSlot;
    JS::Rooted<JS::Value> temp(cx);
    while (true) {
      bool done;
      if (!iter.next(&temp, &done)) {
        return false;
      }
      if (done) {
        break;
      }
      double* slotPtr = arr.AppendElement(mozilla::fallible);
      if (!slotPtr) {
        JS_ReportOutOfMemory(cx);
        return false;
      }
      double& slot = *slotPtr;
      if (!ValueToPrimitive<double, eDefault>(cx, temp, "Element of sequence<double> branch of (sequence<double> or GPUColorDict)", &slot)) {
        return false;
      } else if (!std::isfinite(slot)) {
        cx.ThrowErrorMessage<MSG_NOT_FINITE>("Element of sequence<double> branch of (sequence<double> or GPUColorDict)");
        return false;
      }
    }
  }
  return true;
}

bool
DoubleSequenceOrGPUColorDict::TrySetToDoubleSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToDoubleSequence(cx, value, tryNext, passedToJSImpl);
}







bool
DoubleSequenceOrGPUColorDict::TrySetToGPUColorDict(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    binding_detail::FastGPUColorDict& memberSlot = RawSetAsGPUColorDict();
    if (!IsConvertibleToDictionary(value)) {
      DestroyGPUColorDict();
      tryNext = true;
      return true;
    }
    if (!memberSlot.Init(cx, value, "GPUColorDict branch of (sequence<double> or GPUColorDict)", passedToJSImpl)) {
      return false;
    }
  }
  return true;
}

bool
DoubleSequenceOrGPUColorDict::TrySetToGPUColorDict(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUColorDict(cx, value, tryNext, passedToJSImpl);
}







bool
DoubleSequenceOrGPUColorDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToDoubleSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (!done) {
    done = (failed = !TrySetToGPUColorDict(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<double>, GPUColorDict");
    return false;
  }
  return true;
}

bool
DoubleSequenceOrGPUColorDict::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}




OwningDoubleSequenceOrGPUColorDict::OwningDoubleSequenceOrGPUColorDict(OwningDoubleSequenceOrGPUColorDict&& aOther)
  : mType(eUninitialized)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eDoubleSequence: {
      mType = eDoubleSequence;
      mValue.mDoubleSequence.SetValue(std::move(aOther.mValue.mDoubleSequence.Value()));
      break;
    }
    case eGPUColorDict: {
      mType = eGPUColorDict;
      mValue.mGPUColorDict.SetValue(std::move(aOther.mValue.mGPUColorDict.Value()));
      break;
    }
  }
}



bool
OwningDoubleSequenceOrGPUColorDict::TrySetToDoubleSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    Sequence<double>& memberSlot = RawSetAsDoubleSequence();
    JS::ForOfIterator iter(cx);
    if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
      return false;
    }
    if (!iter.valueIsIterable()) {
      DestroyDoubleSequence();
      tryNext = true;
      return true;
    }
    Sequence<double> &arr = memberSlot;
    JS::Rooted<JS::Value> temp(cx);
    while (true) {
      bool done;
      if (!iter.next(&temp, &done)) {
        return false;
      }
      if (done) {
        break;
      }
      double* slotPtr = arr.AppendElement(mozilla::fallible);
      if (!slotPtr) {
        JS_ReportOutOfMemory(cx);
        return false;
      }
      double& slot = *slotPtr;
      if (!ValueToPrimitive<double, eDefault>(cx, temp, "Element of sequence<double> branch of (sequence<double> or GPUColorDict)", &slot)) {
        return false;
      } else if (!std::isfinite(slot)) {
        cx.ThrowErrorMessage<MSG_NOT_FINITE>("Element of sequence<double> branch of (sequence<double> or GPUColorDict)");
        return false;
      }
    }
  }
  return true;
}

bool
OwningDoubleSequenceOrGPUColorDict::TrySetToDoubleSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToDoubleSequence(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] Sequence<double>&
OwningDoubleSequenceOrGPUColorDict::RawSetAsDoubleSequence()
{
  if (mType == eDoubleSequence) {
    return mValue.mDoubleSequence.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eDoubleSequence;
  return mValue.mDoubleSequence.SetValue();
}

[[nodiscard]] Sequence<double>&
OwningDoubleSequenceOrGPUColorDict::SetAsDoubleSequence()
{
  if (mType == eDoubleSequence) {
    return mValue.mDoubleSequence.Value();
  }
  Uninit();
  mType = eDoubleSequence;
  return mValue.mDoubleSequence.SetValue();
}


void
OwningDoubleSequenceOrGPUColorDict::DestroyDoubleSequence()
{
  MOZ_RELEASE_ASSERT(IsDoubleSequence(), "Wrong type!");
  mValue.mDoubleSequence.Destroy();
  mType = eUninitialized;
}



bool
OwningDoubleSequenceOrGPUColorDict::TrySetToGPUColorDict(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    GPUColorDict& memberSlot = RawSetAsGPUColorDict();
    if (!IsConvertibleToDictionary(value)) {
      DestroyGPUColorDict();
      tryNext = true;
      return true;
    }
    if (!memberSlot.Init(cx, value, "GPUColorDict branch of (sequence<double> or GPUColorDict)", passedToJSImpl)) {
      return false;
    }
  }
  return true;
}

bool
OwningDoubleSequenceOrGPUColorDict::TrySetToGPUColorDict(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUColorDict(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] GPUColorDict&
OwningDoubleSequenceOrGPUColorDict::RawSetAsGPUColorDict()
{
  if (mType == eGPUColorDict) {
    return mValue.mGPUColorDict.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eGPUColorDict;
  return mValue.mGPUColorDict.SetValue();
}

[[nodiscard]] GPUColorDict&
OwningDoubleSequenceOrGPUColorDict::SetAsGPUColorDict()
{
  if (mType == eGPUColorDict) {
    return mValue.mGPUColorDict.Value();
  }
  Uninit();
  mType = eGPUColorDict;
  return mValue.mGPUColorDict.SetValue();
}


void
OwningDoubleSequenceOrGPUColorDict::DestroyGPUColorDict()
{
  MOZ_RELEASE_ASSERT(IsGPUColorDict(), "Wrong type!");
  mValue.mGPUColorDict.Destroy();
  mType = eUninitialized;
}



bool
OwningDoubleSequenceOrGPUColorDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToDoubleSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (!done) {
    done = (failed = !TrySetToGPUColorDict(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<double>, GPUColorDict");
    return false;
  }
  return true;
}

bool
OwningDoubleSequenceOrGPUColorDict::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}

void
OwningDoubleSequenceOrGPUColorDict::Uninit()
{
  switch (mType) {
    case eUninitialized: {
      break;
    }
    case eDoubleSequence: {
      DestroyDoubleSequence();
      break;
    }
    case eGPUColorDict: {
      DestroyGPUColorDict();
      break;
    }
  }
}

OwningDoubleSequenceOrGPUColorDict&
OwningDoubleSequenceOrGPUColorDict::operator=(OwningDoubleSequenceOrGPUColorDict&& aOther)
{
  this->~OwningDoubleSequenceOrGPUColorDict();
  new (this) OwningDoubleSequenceOrGPUColorDict (std::move(aOther));
  return *this;
}


OwningDoubleSequenceOrGPUColorDict&
OwningDoubleSequenceOrGPUColorDict::operator=(const OwningDoubleSequenceOrGPUColorDict& aOther)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eDoubleSequence: {
      SetAsDoubleSequence() = aOther.GetAsDoubleSequence();
      break;
    }
    case eGPUColorDict: {
      SetAsGPUColorDict() = aOther.GetAsGPUColorDict();
      break;
    }
  }
  return *this;
}



GPUBindGroupLayoutEntry::GPUBindGroupLayoutEntry()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->visibility_id.init(cx, "visibility") ||
      !atomsCache->texture_id.init(cx, "texture") ||
      !atomsCache->storageTexture_id.init(cx, "storageTexture") ||
      !atomsCache->sampler_id.init(cx, "sampler") ||
      !atomsCache->externalTexture_id.init(cx, "externalTexture") ||
      !atomsCache->buffer_id.init(cx, "buffer") ||
      !atomsCache->binding_id.init(cx, "binding")) {
    return false;
  }
  return true;
}

bool
GPUBindGroupLayoutEntry::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUBindGroupLayoutEntryAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUBindGroupLayoutEntryAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->binding_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'binding' member of GPUBindGroupLayoutEntry", &mBinding)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'binding' member of GPUBindGroupLayoutEntry");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->buffer_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mBuffer.Construct();
    if (!(mBuffer.Value()).Init(cx, temp.ref(), "'buffer' member of GPUBindGroupLayoutEntry", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->externalTexture_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mExternalTexture.Construct();
    if (!(mExternalTexture.Value()).Init(cx, temp.ref(), "'externalTexture' member of GPUBindGroupLayoutEntry", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->sampler_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mSampler.Construct();
    if (!(mSampler.Value()).Init(cx, temp.ref(), "'sampler' member of GPUBindGroupLayoutEntry", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->storageTexture_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mStorageTexture.Construct();
    if (!(mStorageTexture.Value()).Init(cx, temp.ref(), "'storageTexture' member of GPUBindGroupLayoutEntry", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->texture_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mTexture.Construct();
    if (!(mTexture.Value()).Init(cx, temp.ref(), "'texture' member of GPUBindGroupLayoutEntry", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->visibility_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'visibility' member of GPUBindGroupLayoutEntry", &mVisibility)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'visibility' member of GPUBindGroupLayoutEntry");
  }
  return true;
}

bool
GPUBindGroupLayoutEntry::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUBindGroupLayoutEntry&
GPUBindGroupLayoutEntry::operator=(const GPUBindGroupLayoutEntry& aOther)
{
  DictionaryBase::operator=(aOther);
  mBinding = aOther.mBinding;
  mBuffer.Reset();
  if (aOther.mBuffer.WasPassed()) {
    mBuffer.Construct(aOther.mBuffer.Value());
  }
  mExternalTexture.Reset();
  if (aOther.mExternalTexture.WasPassed()) {
    mExternalTexture.Construct(aOther.mExternalTexture.Value());
  }
  mSampler.Reset();
  if (aOther.mSampler.WasPassed()) {
    mSampler.Construct(aOther.mSampler.Value());
  }
  mStorageTexture.Reset();
  if (aOther.mStorageTexture.WasPassed()) {
    mStorageTexture.Construct(aOther.mStorageTexture.Value());
  }
  mTexture.Reset();
  if (aOther.mTexture.WasPassed()) {
    mTexture.Construct(aOther.mTexture.Value());
  }
  mVisibility = aOther.mVisibility;
  return *this;
}



GPUBlendState::GPUBlendState()
  : mAlpha(FastDictionaryInitializer()),
    mColor(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

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

bool
GPUBlendState::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUBlendStateAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUBlendStateAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->alpha_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mAlpha.Init(cx, temp.ref(), "'alpha' member of GPUBlendState", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'alpha' member of GPUBlendState");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->color_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mColor.Init(cx, temp.ref(), "'color' member of GPUBlendState", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'color' member of GPUBlendState");
  }
  return true;
}

bool
GPUBlendState::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUBlendState&
GPUBlendState::operator=(const GPUBlendState& aOther)
{
  DictionaryBase::operator=(aOther);
  mAlpha = aOther.mAlpha;
  mColor = aOther.mColor;
  return *this;
}



GPUBufferDescriptor::GPUBufferDescriptor()
  : GPUObjectDescriptorBase(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->usage_id.init(cx, "usage") ||
      !atomsCache->size_id.init(cx, "size") ||
      !atomsCache->mappedAtCreation_id.init(cx, "mappedAtCreation")) {
    return false;
  }
  return true;
}

bool
GPUBufferDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUBufferDescriptorAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUBufferDescriptorAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->mappedAtCreation_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'mappedAtCreation' member of GPUBufferDescriptor", &mMappedAtCreation)) {
      return false;
    }
  } else {
    mMappedAtCreation = false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->size_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, temp.ref(), "'size' member of GPUBufferDescriptor", &mSize)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'size' member of GPUBufferDescriptor");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->usage_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'usage' member of GPUBufferDescriptor", &mUsage)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'usage' member of GPUBufferDescriptor");
  }
  return true;
}

bool
GPUBufferDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUBufferDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}

GPUBufferDescriptor&
GPUBufferDescriptor::operator=(const GPUBufferDescriptor& aOther)
{
  GPUObjectDescriptorBase::operator=(aOther);
  mMappedAtCreation = aOther.mMappedAtCreation;
  mSize = aOther.mSize;
  mUsage = aOther.mUsage;
  return *this;
}



GPUCommandBufferDescriptor::GPUCommandBufferDescriptor()
  : GPUObjectDescriptorBase(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




bool
GPUCommandBufferDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  return true;
}

bool
GPUCommandBufferDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUCommandBufferDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}

GPUCommandBufferDescriptor&
GPUCommandBufferDescriptor::operator=(const GPUCommandBufferDescriptor& aOther)
{
  GPUObjectDescriptorBase::operator=(aOther);
  return *this;
}



GPUCommandEncoderDescriptor::GPUCommandEncoderDescriptor()
  : GPUObjectDescriptorBase(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




bool
GPUCommandEncoderDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  return true;
}

bool
GPUCommandEncoderDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUCommandEncoderDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}

GPUCommandEncoderDescriptor&
GPUCommandEncoderDescriptor::operator=(const GPUCommandEncoderDescriptor& aOther)
{
  GPUObjectDescriptorBase::operator=(aOther);
  return *this;
}



GPUComputePassDescriptor::GPUComputePassDescriptor()
  : GPUObjectDescriptorBase(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

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

bool
GPUComputePassDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUComputePassDescriptorAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUComputePassDescriptorAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->timestampWrites_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mTimestampWrites.Construct();
    if (!(mTimestampWrites.Value()).Init(cx, temp.ref(), "'timestampWrites' member of GPUComputePassDescriptor", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }
  return true;
}

bool
GPUComputePassDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUComputePassDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}



GPUComputePassDescriptor&
GPUComputePassDescriptor::operator=(const GPUComputePassDescriptor& aOther)
{
  GPUObjectDescriptorBase::operator=(aOther);
  mTimestampWrites.Reset();
  if (aOther.mTimestampWrites.WasPassed()) {
    mTimestampWrites.Construct(aOther.mTimestampWrites.Value());
  }
  return *this;
}



GPUDepthStencilState::GPUDepthStencilState()
  : mStencilBack(FastDictionaryInitializer()),
    mStencilFront(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->stencilWriteMask_id.init(cx, "stencilWriteMask") ||
      !atomsCache->stencilReadMask_id.init(cx, "stencilReadMask") ||
      !atomsCache->stencilFront_id.init(cx, "stencilFront") ||
      !atomsCache->stencilBack_id.init(cx, "stencilBack") ||
      !atomsCache->format_id.init(cx, "format") ||
      !atomsCache->depthWriteEnabled_id.init(cx, "depthWriteEnabled") ||
      !atomsCache->depthCompare_id.init(cx, "depthCompare") ||
      !atomsCache->depthBiasSlopeScale_id.init(cx, "depthBiasSlopeScale") ||
      !atomsCache->depthBiasClamp_id.init(cx, "depthBiasClamp") ||
      !atomsCache->depthBias_id.init(cx, "depthBias")) {
    return false;
  }
  return true;
}

bool
GPUDepthStencilState::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUDepthStencilStateAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUDepthStencilStateAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->depthBias_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<int32_t, eEnforceRange>(cx, temp.ref(), "'depthBias' member of GPUDepthStencilState", &mDepthBias)) {
      return false;
    }
  } else {
    mDepthBias = 0;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->depthBiasClamp_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<float, eDefault>(cx, temp.ref(), "'depthBiasClamp' member of GPUDepthStencilState", &mDepthBiasClamp)) {
      return false;
    } else if (!std::isfinite(mDepthBiasClamp)) {
      cx.ThrowErrorMessage<MSG_NOT_FINITE>("'depthBiasClamp' member of GPUDepthStencilState");
      return false;
    }
  } else {
    mDepthBiasClamp = 0.0F;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->depthBiasSlopeScale_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<float, eDefault>(cx, temp.ref(), "'depthBiasSlopeScale' member of GPUDepthStencilState", &mDepthBiasSlopeScale)) {
      return false;
    } else if (!std::isfinite(mDepthBiasSlopeScale)) {
      cx.ThrowErrorMessage<MSG_NOT_FINITE>("'depthBiasSlopeScale' member of GPUDepthStencilState");
      return false;
    }
  } else {
    mDepthBiasSlopeScale = 0.0F;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->depthCompare_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUCompareFunction>::Values,
                                                                         "GPUCompareFunction", "'depthCompare' member of GPUDepthStencilState",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mDepthCompare = static_cast<GPUCompareFunction>(index);
    }
  } else {
    mDepthCompare = GPUCompareFunction::Always;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->depthWriteEnabled_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'depthWriteEnabled' member of GPUDepthStencilState", &mDepthWriteEnabled)) {
      return false;
    }
  } else {
    mDepthWriteEnabled = false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->format_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUTextureFormat>::Values,
                                                                         "GPUTextureFormat", "'format' member of GPUDepthStencilState",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mFormat = static_cast<GPUTextureFormat>(index);
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'format' member of GPUDepthStencilState");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->stencilBack_id, temp.ptr())) {
      return false;
    }
  }
  if (!mStencilBack.Init(cx, (!isNull && !temp->isUndefined()) ? temp.ref() : JS::NullHandleValue, "'stencilBack' member of GPUDepthStencilState", passedToJSImpl)) {
    return false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->stencilFront_id, temp.ptr())) {
      return false;
    }
  }
  if (!mStencilFront.Init(cx, (!isNull && !temp->isUndefined()) ? temp.ref() : JS::NullHandleValue, "'stencilFront' member of GPUDepthStencilState", passedToJSImpl)) {
    return false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->stencilReadMask_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'stencilReadMask' member of GPUDepthStencilState", &mStencilReadMask)) {
      return false;
    }
  } else {
    mStencilReadMask = 4294967295U;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->stencilWriteMask_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'stencilWriteMask' member of GPUDepthStencilState", &mStencilWriteMask)) {
      return false;
    }
  } else {
    mStencilWriteMask = 4294967295U;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUDepthStencilState::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUDepthStencilState&
GPUDepthStencilState::operator=(const GPUDepthStencilState& aOther)
{
  DictionaryBase::operator=(aOther);
  mDepthBias = aOther.mDepthBias;
  mDepthBiasClamp = aOther.mDepthBiasClamp;
  mDepthBiasSlopeScale = aOther.mDepthBiasSlopeScale;
  mDepthCompare = aOther.mDepthCompare;
  mDepthWriteEnabled = aOther.mDepthWriteEnabled;
  mFormat = aOther.mFormat;
  mStencilBack = aOther.mStencilBack;
  mStencilFront = aOther.mStencilFront;
  mStencilReadMask = aOther.mStencilReadMask;
  mStencilWriteMask = aOther.mStencilWriteMask;
  return *this;
}



GPUExternalTextureDescriptor::GPUExternalTextureDescriptor()
  : GPUObjectDescriptorBase(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

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

bool
GPUExternalTextureDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUExternalTextureDescriptorAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUExternalTextureDescriptorAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->colorSpace_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<PredefinedColorSpace>::Values,
                                                                         "PredefinedColorSpace", "'colorSpace' member of GPUExternalTextureDescriptor",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mColorSpace = static_cast<PredefinedColorSpace>(index);
    }
  } else {
    mColorSpace = PredefinedColorSpace::Srgb;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->source_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mSource.Init(cx, temp.ref(), "'source' member of GPUExternalTextureDescriptor", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'source' member of GPUExternalTextureDescriptor");
  }
  return true;
}

bool
GPUExternalTextureDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUExternalTextureDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}



GPUExternalTextureDescriptor&
GPUExternalTextureDescriptor::operator=(const GPUExternalTextureDescriptor& aOther)
{
  GPUObjectDescriptorBase::operator=(aOther);
  mColorSpace = aOther.mColorSpace;
  mSource = aOther.mSource;
  return *this;
}



GPUPipelineDescriptorBase::GPUPipelineDescriptorBase()
  : GPUObjectDescriptorBase(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

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

bool
GPUPipelineDescriptorBase::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUPipelineDescriptorBaseAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUPipelineDescriptorBaseAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->layout_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mLayout.Init(cx, temp.ref(), "'layout' member of GPUPipelineDescriptorBase", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'layout' member of GPUPipelineDescriptorBase");
  }
  return true;
}

bool
GPUPipelineDescriptorBase::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUPipelineDescriptorBase::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}



GPUPipelineDescriptorBase&
GPUPipelineDescriptorBase::operator=(const GPUPipelineDescriptorBase& aOther)
{
  GPUObjectDescriptorBase::operator=(aOther);
  mLayout = aOther.mLayout;
  return *this;
}



GPUPipelineLayoutDescriptor::GPUPipelineLayoutDescriptor()
  : GPUObjectDescriptorBase(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

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

bool
GPUPipelineLayoutDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUPipelineLayoutDescriptorAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUPipelineLayoutDescriptorAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->bindGroupLayouts_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'bindGroupLayouts' member of GPUPipelineLayoutDescriptor", "sequence");
        return false;
      }
      Sequence<OwningNonNull<mozilla::webgpu::BindGroupLayout>> &arr = mBindGroupLayouts;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        OwningNonNull<mozilla::webgpu::BindGroupLayout>* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        OwningNonNull<mozilla::webgpu::BindGroupLayout>& slot = *slotPtr;
        if (temp.isObject()) {
          static_assert(IsRefcounted<mozilla::webgpu::BindGroupLayout>::value, "We can only store refcounted classes.");
          {
            // Our JSContext should be in the right global to do unwrapping in.
            nsresult rv = UnwrapObject<prototypes::id::GPUBindGroupLayout, mozilla::webgpu::BindGroupLayout>(&temp, slot, cx);
            if (NS_FAILED(rv)) {
              cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Element of 'bindGroupLayouts' member of GPUPipelineLayoutDescriptor", "GPUBindGroupLayout");
              return false;
            }
          }
        } else {
          cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of 'bindGroupLayouts' member of GPUPipelineLayoutDescriptor");
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'bindGroupLayouts' member of GPUPipelineLayoutDescriptor", "sequence");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'bindGroupLayouts' member of GPUPipelineLayoutDescriptor");
  }
  return true;
}

bool
GPUPipelineLayoutDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUPipelineLayoutDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}



GPUPipelineLayoutDescriptor&
GPUPipelineLayoutDescriptor::operator=(const GPUPipelineLayoutDescriptor& aOther)
{
  GPUObjectDescriptorBase::operator=(aOther);
  mBindGroupLayouts = aOther.mBindGroupLayouts;
  return *this;
}



GPUQuerySetDescriptor::GPUQuerySetDescriptor()
  : GPUObjectDescriptorBase(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

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

bool
GPUQuerySetDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUQuerySetDescriptorAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUQuerySetDescriptorAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->count_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'count' member of GPUQuerySetDescriptor", &mCount)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'count' member of GPUQuerySetDescriptor");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->type_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUQueryType>::Values,
                                                                         "GPUQueryType", "'type' member of GPUQuerySetDescriptor",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mType = static_cast<GPUQueryType>(index);
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'type' member of GPUQuerySetDescriptor");
  }
  return true;
}

bool
GPUQuerySetDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUQuerySetDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}

GPUQuerySetDescriptor&
GPUQuerySetDescriptor::operator=(const GPUQuerySetDescriptor& aOther)
{
  GPUObjectDescriptorBase::operator=(aOther);
  mCount = aOther.mCount;
  mType = aOther.mType;
  return *this;
}



GPUQueueDescriptor::GPUQueueDescriptor()
  : GPUObjectDescriptorBase(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




bool
GPUQueueDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  return true;
}

bool
GPUQueueDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUQueueDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}

GPUQueueDescriptor&
GPUQueueDescriptor::operator=(const GPUQueueDescriptor& aOther)
{
  GPUObjectDescriptorBase::operator=(aOther);
  return *this;
}



GPURenderBundleDescriptor::GPURenderBundleDescriptor()
  : GPUObjectDescriptorBase(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




bool
GPURenderBundleDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  return true;
}

bool
GPURenderBundleDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPURenderBundleDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}

GPURenderBundleDescriptor&
GPURenderBundleDescriptor::operator=(const GPURenderBundleDescriptor& aOther)
{
  GPUObjectDescriptorBase::operator=(aOther);
  return *this;
}



GPURenderPassDepthStencilAttachment::GPURenderPassDepthStencilAttachment()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->view_id.init(cx, "view") ||
      !atomsCache->stencilStoreOp_id.init(cx, "stencilStoreOp") ||
      !atomsCache->stencilReadOnly_id.init(cx, "stencilReadOnly") ||
      !atomsCache->stencilLoadOp_id.init(cx, "stencilLoadOp") ||
      !atomsCache->stencilClearValue_id.init(cx, "stencilClearValue") ||
      !atomsCache->depthStoreOp_id.init(cx, "depthStoreOp") ||
      !atomsCache->depthReadOnly_id.init(cx, "depthReadOnly") ||
      !atomsCache->depthLoadOp_id.init(cx, "depthLoadOp") ||
      !atomsCache->depthClearValue_id.init(cx, "depthClearValue")) {
    return false;
  }
  return true;
}

bool
GPURenderPassDepthStencilAttachment::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPURenderPassDepthStencilAttachmentAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPURenderPassDepthStencilAttachmentAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->depthClearValue_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mDepthClearValue.Construct();
    if (!ValueToPrimitive<float, eDefault>(cx, temp.ref(), "'depthClearValue' member of GPURenderPassDepthStencilAttachment", &(mDepthClearValue.Value()))) {
      return false;
    } else if (!std::isfinite((mDepthClearValue.Value()))) {
      cx.ThrowErrorMessage<MSG_NOT_FINITE>("'depthClearValue' member of GPURenderPassDepthStencilAttachment");
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->depthLoadOp_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mDepthLoadOp.Construct();
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPULoadOp>::Values,
                                                                         "GPULoadOp", "'depthLoadOp' member of GPURenderPassDepthStencilAttachment",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      (mDepthLoadOp.Value()) = static_cast<GPULoadOp>(index);
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->depthReadOnly_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'depthReadOnly' member of GPURenderPassDepthStencilAttachment", &mDepthReadOnly)) {
      return false;
    }
  } else {
    mDepthReadOnly = false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->depthStoreOp_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mDepthStoreOp.Construct();
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUStoreOp>::Values,
                                                                         "GPUStoreOp", "'depthStoreOp' member of GPURenderPassDepthStencilAttachment",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      (mDepthStoreOp.Value()) = static_cast<GPUStoreOp>(index);
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->stencilClearValue_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'stencilClearValue' member of GPURenderPassDepthStencilAttachment", &mStencilClearValue)) {
      return false;
    }
  } else {
    mStencilClearValue = 0U;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->stencilLoadOp_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mStencilLoadOp.Construct();
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPULoadOp>::Values,
                                                                         "GPULoadOp", "'stencilLoadOp' member of GPURenderPassDepthStencilAttachment",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      (mStencilLoadOp.Value()) = static_cast<GPULoadOp>(index);
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->stencilReadOnly_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'stencilReadOnly' member of GPURenderPassDepthStencilAttachment", &mStencilReadOnly)) {
      return false;
    }
  } else {
    mStencilReadOnly = false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->stencilStoreOp_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mStencilStoreOp.Construct();
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUStoreOp>::Values,
                                                                         "GPUStoreOp", "'stencilStoreOp' member of GPURenderPassDepthStencilAttachment",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      (mStencilStoreOp.Value()) = static_cast<GPUStoreOp>(index);
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->view_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mView.Init(cx, temp.ref(), "'view' member of GPURenderPassDepthStencilAttachment", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'view' member of GPURenderPassDepthStencilAttachment");
  }
  return true;
}

bool
GPURenderPassDepthStencilAttachment::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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



GPURenderPassDepthStencilAttachment&
GPURenderPassDepthStencilAttachment::operator=(const GPURenderPassDepthStencilAttachment& aOther)
{
  DictionaryBase::operator=(aOther);
  mDepthClearValue.Reset();
  if (aOther.mDepthClearValue.WasPassed()) {
    mDepthClearValue.Construct(aOther.mDepthClearValue.Value());
  }
  mDepthLoadOp.Reset();
  if (aOther.mDepthLoadOp.WasPassed()) {
    mDepthLoadOp.Construct(aOther.mDepthLoadOp.Value());
  }
  mDepthReadOnly = aOther.mDepthReadOnly;
  mDepthStoreOp.Reset();
  if (aOther.mDepthStoreOp.WasPassed()) {
    mDepthStoreOp.Construct(aOther.mDepthStoreOp.Value());
  }
  mStencilClearValue = aOther.mStencilClearValue;
  mStencilLoadOp.Reset();
  if (aOther.mStencilLoadOp.WasPassed()) {
    mStencilLoadOp.Construct(aOther.mStencilLoadOp.Value());
  }
  mStencilReadOnly = aOther.mStencilReadOnly;
  mStencilStoreOp.Reset();
  if (aOther.mStencilStoreOp.WasPassed()) {
    mStencilStoreOp.Construct(aOther.mStencilStoreOp.Value());
  }
  mView = aOther.mView;
  return *this;
}



GPURenderPassLayout::GPURenderPassLayout()
  : GPUObjectDescriptorBase(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->sampleCount_id.init(cx, "sampleCount") ||
      !atomsCache->depthStencilFormat_id.init(cx, "depthStencilFormat") ||
      !atomsCache->colorFormats_id.init(cx, "colorFormats")) {
    return false;
  }
  return true;
}

bool
GPURenderPassLayout::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPURenderPassLayoutAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPURenderPassLayoutAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->colorFormats_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'colorFormats' member of GPURenderPassLayout", "sequence");
        return false;
      }
      Sequence<GPUTextureFormat> &arr = mColorFormats;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        GPUTextureFormat* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        GPUTextureFormat& slot = *slotPtr;
        {
          int index;
          if (!binding_detail::FindEnumStringIndex<true>(cx, temp,
                                                                             binding_detail::EnumStrings<GPUTextureFormat>::Values,
                                                                             "GPUTextureFormat", "element of 'colorFormats' member of GPURenderPassLayout",
                                                                             &index)) {
            return false;
          }
          MOZ_ASSERT(index >= 0);
          slot = static_cast<GPUTextureFormat>(index);
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'colorFormats' member of GPURenderPassLayout", "sequence");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'colorFormats' member of GPURenderPassLayout");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->depthStencilFormat_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mDepthStencilFormat.Construct();
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUTextureFormat>::Values,
                                                                         "GPUTextureFormat", "'depthStencilFormat' member of GPURenderPassLayout",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      (mDepthStencilFormat.Value()) = static_cast<GPUTextureFormat>(index);
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->sampleCount_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'sampleCount' member of GPURenderPassLayout", &mSampleCount)) {
      return false;
    }
  } else {
    mSampleCount = 1U;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPURenderPassLayout::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPURenderPassLayout::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}

GPURenderPassLayout&
GPURenderPassLayout::operator=(const GPURenderPassLayout& aOther)
{
  GPUObjectDescriptorBase::operator=(aOther);
  mColorFormats = aOther.mColorFormats;
  mDepthStencilFormat.Reset();
  if (aOther.mDepthStencilFormat.WasPassed()) {
    mDepthStencilFormat.Construct(aOther.mDepthStencilFormat.Value());
  }
  mSampleCount = aOther.mSampleCount;
  return *this;
}



GPUSamplerDescriptor::GPUSamplerDescriptor()
  : GPUObjectDescriptorBase(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->mipmapFilter_id.init(cx, "mipmapFilter") ||
      !atomsCache->minFilter_id.init(cx, "minFilter") ||
      !atomsCache->maxAnisotropy_id.init(cx, "maxAnisotropy") ||
      !atomsCache->magFilter_id.init(cx, "magFilter") ||
      !atomsCache->lodMinClamp_id.init(cx, "lodMinClamp") ||
      !atomsCache->lodMaxClamp_id.init(cx, "lodMaxClamp") ||
      !atomsCache->compare_id.init(cx, "compare") ||
      !atomsCache->addressModeW_id.init(cx, "addressModeW") ||
      !atomsCache->addressModeV_id.init(cx, "addressModeV") ||
      !atomsCache->addressModeU_id.init(cx, "addressModeU")) {
    return false;
  }
  return true;
}

bool
GPUSamplerDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUSamplerDescriptorAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUSamplerDescriptorAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->addressModeU_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUAddressMode>::Values,
                                                                         "GPUAddressMode", "'addressModeU' member of GPUSamplerDescriptor",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mAddressModeU = static_cast<GPUAddressMode>(index);
    }
  } else {
    mAddressModeU = GPUAddressMode::Clamp_to_edge;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->addressModeV_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUAddressMode>::Values,
                                                                         "GPUAddressMode", "'addressModeV' member of GPUSamplerDescriptor",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mAddressModeV = static_cast<GPUAddressMode>(index);
    }
  } else {
    mAddressModeV = GPUAddressMode::Clamp_to_edge;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->addressModeW_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUAddressMode>::Values,
                                                                         "GPUAddressMode", "'addressModeW' member of GPUSamplerDescriptor",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mAddressModeW = static_cast<GPUAddressMode>(index);
    }
  } else {
    mAddressModeW = GPUAddressMode::Clamp_to_edge;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->compare_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mCompare.Construct();
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUCompareFunction>::Values,
                                                                         "GPUCompareFunction", "'compare' member of GPUSamplerDescriptor",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      (mCompare.Value()) = static_cast<GPUCompareFunction>(index);
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->lodMaxClamp_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<float, eDefault>(cx, temp.ref(), "'lodMaxClamp' member of GPUSamplerDescriptor", &mLodMaxClamp)) {
      return false;
    } else if (!std::isfinite(mLodMaxClamp)) {
      cx.ThrowErrorMessage<MSG_NOT_FINITE>("'lodMaxClamp' member of GPUSamplerDescriptor");
      return false;
    }
  } else {
    mLodMaxClamp = 32.0F;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->lodMinClamp_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<float, eDefault>(cx, temp.ref(), "'lodMinClamp' member of GPUSamplerDescriptor", &mLodMinClamp)) {
      return false;
    } else if (!std::isfinite(mLodMinClamp)) {
      cx.ThrowErrorMessage<MSG_NOT_FINITE>("'lodMinClamp' member of GPUSamplerDescriptor");
      return false;
    }
  } else {
    mLodMinClamp = 0.0F;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->magFilter_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUFilterMode>::Values,
                                                                         "GPUFilterMode", "'magFilter' member of GPUSamplerDescriptor",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mMagFilter = static_cast<GPUFilterMode>(index);
    }
  } else {
    mMagFilter = GPUFilterMode::Nearest;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->maxAnisotropy_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint16_t, eClamp>(cx, temp.ref(), "'maxAnisotropy' member of GPUSamplerDescriptor", &mMaxAnisotropy)) {
      return false;
    }
  } else {
    mMaxAnisotropy = 1;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->minFilter_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUFilterMode>::Values,
                                                                         "GPUFilterMode", "'minFilter' member of GPUSamplerDescriptor",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mMinFilter = static_cast<GPUFilterMode>(index);
    }
  } else {
    mMinFilter = GPUFilterMode::Nearest;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->mipmapFilter_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUMipmapFilterMode>::Values,
                                                                         "GPUMipmapFilterMode", "'mipmapFilter' member of GPUSamplerDescriptor",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mMipmapFilter = static_cast<GPUMipmapFilterMode>(index);
    }
  } else {
    mMipmapFilter = GPUMipmapFilterMode::Nearest;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUSamplerDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUSamplerDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}

GPUSamplerDescriptor&
GPUSamplerDescriptor::operator=(const GPUSamplerDescriptor& aOther)
{
  GPUObjectDescriptorBase::operator=(aOther);
  mAddressModeU = aOther.mAddressModeU;
  mAddressModeV = aOther.mAddressModeV;
  mAddressModeW = aOther.mAddressModeW;
  mCompare.Reset();
  if (aOther.mCompare.WasPassed()) {
    mCompare.Construct(aOther.mCompare.Value());
  }
  mLodMaxClamp = aOther.mLodMaxClamp;
  mLodMinClamp = aOther.mLodMinClamp;
  mMagFilter = aOther.mMagFilter;
  mMaxAnisotropy = aOther.mMaxAnisotropy;
  mMinFilter = aOther.mMinFilter;
  mMipmapFilter = aOther.mMipmapFilter;
  return *this;
}


bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUSampler(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    NonNull<mozilla::webgpu::Sampler>& memberSlot = RawSetAsGPUSampler();
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUSampler, mozilla::webgpu::Sampler>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyGPUSampler();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUSampler(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUSampler(cx, value, tryNext, passedToJSImpl);
}







bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUTexture(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    NonNull<mozilla::webgpu::Texture>& memberSlot = RawSetAsGPUTexture();
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUTexture, mozilla::webgpu::Texture>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyGPUTexture();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUTexture(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUTexture(cx, value, tryNext, passedToJSImpl);
}







bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUTextureView(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    NonNull<mozilla::webgpu::TextureView>& memberSlot = RawSetAsGPUTextureView();
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUTextureView, mozilla::webgpu::TextureView>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyGPUTextureView();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUTextureView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUTextureView(cx, value, tryNext, passedToJSImpl);
}







bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUBuffer(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    NonNull<mozilla::webgpu::Buffer>& memberSlot = RawSetAsGPUBuffer();
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyGPUBuffer();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUBuffer(cx, value, tryNext, passedToJSImpl);
}







bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUBufferBinding(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    binding_detail::FastGPUBufferBinding& memberSlot = RawSetAsGPUBufferBinding();
    if (!IsConvertibleToDictionary(value)) {
      DestroyGPUBufferBinding();
      tryNext = true;
      return true;
    }
    if (!memberSlot.Init(cx, value, "GPUBufferBinding branch of (GPUSampler or GPUTexture or GPUTextureView or GPUBuffer or GPUBufferBinding or GPUExternalTexture)", passedToJSImpl)) {
      return false;
    }
  }
  return true;
}

bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUBufferBinding(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUBufferBinding(cx, value, tryNext, passedToJSImpl);
}







bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUExternalTexture(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    NonNull<mozilla::webgpu::ExternalTexture>& memberSlot = RawSetAsGPUExternalTexture();
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUExternalTexture, mozilla::webgpu::ExternalTexture>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyGPUExternalTexture();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUExternalTexture(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUExternalTexture(cx, value, tryNext, passedToJSImpl);
}







bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToGPUSampler(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToGPUTexture(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToGPUTextureView(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToGPUBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToGPUExternalTexture(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (!done) {
    done = (failed = !TrySetToGPUBufferBinding(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "GPUSampler, GPUTexture, GPUTextureView, GPUBuffer, GPUExternalTexture, GPUBufferBinding");
    return false;
  }
  return true;
}

bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}




OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture(OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture&& aOther)
  : mType(eUninitialized)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eGPUSampler: {
      mType = eGPUSampler;
      mValue.mGPUSampler.SetValue(std::move(aOther.mValue.mGPUSampler.Value()));
      break;
    }
    case eGPUTexture: {
      mType = eGPUTexture;
      mValue.mGPUTexture.SetValue(std::move(aOther.mValue.mGPUTexture.Value()));
      break;
    }
    case eGPUTextureView: {
      mType = eGPUTextureView;
      mValue.mGPUTextureView.SetValue(std::move(aOther.mValue.mGPUTextureView.Value()));
      break;
    }
    case eGPUBuffer: {
      mType = eGPUBuffer;
      mValue.mGPUBuffer.SetValue(std::move(aOther.mValue.mGPUBuffer.Value()));
      break;
    }
    case eGPUBufferBinding: {
      mType = eGPUBufferBinding;
      mValue.mGPUBufferBinding.SetValue(std::move(aOther.mValue.mGPUBufferBinding.Value()));
      break;
    }
    case eGPUExternalTexture: {
      mType = eGPUExternalTexture;
      mValue.mGPUExternalTexture.SetValue(std::move(aOther.mValue.mGPUExternalTexture.Value()));
      break;
    }
  }
}



bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUSampler(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    OwningNonNull<mozilla::webgpu::Sampler>& memberSlot = RawSetAsGPUSampler();
    static_assert(IsRefcounted<mozilla::webgpu::Sampler>::value, "We can only store refcounted classes.");
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUSampler, mozilla::webgpu::Sampler>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyGPUSampler();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUSampler(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUSampler(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] OwningNonNull<mozilla::webgpu::Sampler>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::RawSetAsGPUSampler()
{
  if (mType == eGPUSampler) {
    return mValue.mGPUSampler.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eGPUSampler;
  return mValue.mGPUSampler.SetValue();
}

[[nodiscard]] OwningNonNull<mozilla::webgpu::Sampler>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::SetAsGPUSampler()
{
  if (mType == eGPUSampler) {
    return mValue.mGPUSampler.Value();
  }
  Uninit();
  mType = eGPUSampler;
  return mValue.mGPUSampler.SetValue();
}


void
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::DestroyGPUSampler()
{
  MOZ_RELEASE_ASSERT(IsGPUSampler(), "Wrong type!");
  mValue.mGPUSampler.Destroy();
  mType = eUninitialized;
}



bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUTexture(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    OwningNonNull<mozilla::webgpu::Texture>& memberSlot = RawSetAsGPUTexture();
    static_assert(IsRefcounted<mozilla::webgpu::Texture>::value, "We can only store refcounted classes.");
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUTexture, mozilla::webgpu::Texture>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyGPUTexture();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUTexture(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUTexture(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] OwningNonNull<mozilla::webgpu::Texture>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::RawSetAsGPUTexture()
{
  if (mType == eGPUTexture) {
    return mValue.mGPUTexture.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eGPUTexture;
  return mValue.mGPUTexture.SetValue();
}

[[nodiscard]] OwningNonNull<mozilla::webgpu::Texture>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::SetAsGPUTexture()
{
  if (mType == eGPUTexture) {
    return mValue.mGPUTexture.Value();
  }
  Uninit();
  mType = eGPUTexture;
  return mValue.mGPUTexture.SetValue();
}


void
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::DestroyGPUTexture()
{
  MOZ_RELEASE_ASSERT(IsGPUTexture(), "Wrong type!");
  mValue.mGPUTexture.Destroy();
  mType = eUninitialized;
}



bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUTextureView(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    OwningNonNull<mozilla::webgpu::TextureView>& memberSlot = RawSetAsGPUTextureView();
    static_assert(IsRefcounted<mozilla::webgpu::TextureView>::value, "We can only store refcounted classes.");
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUTextureView, mozilla::webgpu::TextureView>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyGPUTextureView();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUTextureView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUTextureView(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] OwningNonNull<mozilla::webgpu::TextureView>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::RawSetAsGPUTextureView()
{
  if (mType == eGPUTextureView) {
    return mValue.mGPUTextureView.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eGPUTextureView;
  return mValue.mGPUTextureView.SetValue();
}

[[nodiscard]] OwningNonNull<mozilla::webgpu::TextureView>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::SetAsGPUTextureView()
{
  if (mType == eGPUTextureView) {
    return mValue.mGPUTextureView.Value();
  }
  Uninit();
  mType = eGPUTextureView;
  return mValue.mGPUTextureView.SetValue();
}


void
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::DestroyGPUTextureView()
{
  MOZ_RELEASE_ASSERT(IsGPUTextureView(), "Wrong type!");
  mValue.mGPUTextureView.Destroy();
  mType = eUninitialized;
}



bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUBuffer(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    OwningNonNull<mozilla::webgpu::Buffer>& memberSlot = RawSetAsGPUBuffer();
    static_assert(IsRefcounted<mozilla::webgpu::Buffer>::value, "We can only store refcounted classes.");
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyGPUBuffer();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUBuffer(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] OwningNonNull<mozilla::webgpu::Buffer>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::RawSetAsGPUBuffer()
{
  if (mType == eGPUBuffer) {
    return mValue.mGPUBuffer.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eGPUBuffer;
  return mValue.mGPUBuffer.SetValue();
}

[[nodiscard]] OwningNonNull<mozilla::webgpu::Buffer>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::SetAsGPUBuffer()
{
  if (mType == eGPUBuffer) {
    return mValue.mGPUBuffer.Value();
  }
  Uninit();
  mType = eGPUBuffer;
  return mValue.mGPUBuffer.SetValue();
}


void
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::DestroyGPUBuffer()
{
  MOZ_RELEASE_ASSERT(IsGPUBuffer(), "Wrong type!");
  mValue.mGPUBuffer.Destroy();
  mType = eUninitialized;
}



bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUBufferBinding(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    GPUBufferBinding& memberSlot = RawSetAsGPUBufferBinding();
    if (!IsConvertibleToDictionary(value)) {
      DestroyGPUBufferBinding();
      tryNext = true;
      return true;
    }
    if (!memberSlot.Init(cx, value, "GPUBufferBinding branch of (GPUSampler or GPUTexture or GPUTextureView or GPUBuffer or GPUBufferBinding or GPUExternalTexture)", passedToJSImpl)) {
      return false;
    }
  }
  return true;
}

bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUBufferBinding(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUBufferBinding(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] GPUBufferBinding&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::RawSetAsGPUBufferBinding()
{
  if (mType == eGPUBufferBinding) {
    return mValue.mGPUBufferBinding.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eGPUBufferBinding;
  return mValue.mGPUBufferBinding.SetValue();
}

[[nodiscard]] GPUBufferBinding&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::SetAsGPUBufferBinding()
{
  if (mType == eGPUBufferBinding) {
    return mValue.mGPUBufferBinding.Value();
  }
  Uninit();
  mType = eGPUBufferBinding;
  return mValue.mGPUBufferBinding.SetValue();
}


void
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::DestroyGPUBufferBinding()
{
  MOZ_RELEASE_ASSERT(IsGPUBufferBinding(), "Wrong type!");
  mValue.mGPUBufferBinding.Destroy();
  mType = eUninitialized;
}



bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUExternalTexture(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    OwningNonNull<mozilla::webgpu::ExternalTexture>& memberSlot = RawSetAsGPUExternalTexture();
    static_assert(IsRefcounted<mozilla::webgpu::ExternalTexture>::value, "We can only store refcounted classes.");
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUExternalTexture, mozilla::webgpu::ExternalTexture>(value, memberSlot, cx);
      if (NS_FAILED(rv)) {
        DestroyGPUExternalTexture();
        tryNext = true;
        return true;
      }
    }
  }
  return true;
}

bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUExternalTexture(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUExternalTexture(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] OwningNonNull<mozilla::webgpu::ExternalTexture>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::RawSetAsGPUExternalTexture()
{
  if (mType == eGPUExternalTexture) {
    return mValue.mGPUExternalTexture.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eGPUExternalTexture;
  return mValue.mGPUExternalTexture.SetValue();
}

[[nodiscard]] OwningNonNull<mozilla::webgpu::ExternalTexture>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::SetAsGPUExternalTexture()
{
  if (mType == eGPUExternalTexture) {
    return mValue.mGPUExternalTexture.Value();
  }
  Uninit();
  mType = eGPUExternalTexture;
  return mValue.mGPUExternalTexture.SetValue();
}


void
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::DestroyGPUExternalTexture()
{
  MOZ_RELEASE_ASSERT(IsGPUExternalTexture(), "Wrong type!");
  mValue.mGPUExternalTexture.Destroy();
  mType = eUninitialized;
}



bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToGPUSampler(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToGPUTexture(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToGPUTextureView(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToGPUBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
           (failed = !TrySetToGPUExternalTexture(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (!done) {
    done = (failed = !TrySetToGPUBufferBinding(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "GPUSampler, GPUTexture, GPUTextureView, GPUBuffer, GPUExternalTexture, GPUBufferBinding");
    return false;
  }
  return true;
}

bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}

void
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::Uninit()
{
  switch (mType) {
    case eUninitialized: {
      break;
    }
    case eGPUSampler: {
      DestroyGPUSampler();
      break;
    }
    case eGPUTexture: {
      DestroyGPUTexture();
      break;
    }
    case eGPUTextureView: {
      DestroyGPUTextureView();
      break;
    }
    case eGPUBuffer: {
      DestroyGPUBuffer();
      break;
    }
    case eGPUBufferBinding: {
      DestroyGPUBufferBinding();
      break;
    }
    case eGPUExternalTexture: {
      DestroyGPUExternalTexture();
      break;
    }
  }
}

OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::operator=(OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture&& aOther)
{
  this->~OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture();
  new (this) OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture (std::move(aOther));
  return *this;
}


OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::operator=(const OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture& aOther)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eGPUSampler: {
      SetAsGPUSampler() = aOther.GetAsGPUSampler();
      break;
    }
    case eGPUTexture: {
      SetAsGPUTexture() = aOther.GetAsGPUTexture();
      break;
    }
    case eGPUTextureView: {
      SetAsGPUTextureView() = aOther.GetAsGPUTextureView();
      break;
    }
    case eGPUBuffer: {
      SetAsGPUBuffer() = aOther.GetAsGPUBuffer();
      break;
    }
    case eGPUBufferBinding: {
      SetAsGPUBufferBinding() = aOther.GetAsGPUBufferBinding();
      break;
    }
    case eGPUExternalTexture: {
      SetAsGPUExternalTexture() = aOther.GetAsGPUExternalTexture();
      break;
    }
  }
  return *this;
}



GPUShaderModuleCompilationHint::GPUShaderModuleCompilationHint()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

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

bool
GPUShaderModuleCompilationHint::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUShaderModuleCompilationHintAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUShaderModuleCompilationHintAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->entryPoint_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mEntryPoint)) {
      return false;
    }
    if (!NormalizeUSVString(mEntryPoint)) {
      JS_ReportOutOfMemory(cx);
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'entryPoint' member of GPUShaderModuleCompilationHint");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->layout_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mLayout.Construct();
    if (!(mLayout.Value()).Init(cx, temp.ref(), "'layout' member of GPUShaderModuleCompilationHint", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }
  return true;
}

bool
GPUShaderModuleCompilationHint::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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



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



GPUTexelCopyBufferInfo::GPUTexelCopyBufferInfo()
  : GPUTexelCopyBufferLayout(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

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

bool
GPUTexelCopyBufferInfo::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUTexelCopyBufferInfoAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUTexelCopyBufferInfoAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUTexelCopyBufferLayout::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->buffer_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      static_assert(IsRefcounted<mozilla::webgpu::Buffer>::value, "We can only store refcounted classes.");
      {
        // Our JSContext should be in the right global to do unwrapping in.
        nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(temp.ptr(), mBuffer, cx);
        if (NS_FAILED(rv)) {
          cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'buffer' member of GPUTexelCopyBufferInfo", "GPUBuffer");
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'buffer' member of GPUTexelCopyBufferInfo");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'buffer' member of GPUTexelCopyBufferInfo");
  }
  return true;
}

bool
GPUTexelCopyBufferInfo::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUTexelCopyBufferInfo::TraceDictionary(JSTracer* trc)
{
  GPUTexelCopyBufferLayout::TraceDictionary(trc);
}



GPUTexelCopyBufferInfo&
GPUTexelCopyBufferInfo::operator=(const GPUTexelCopyBufferInfo& aOther)
{
  GPUTexelCopyBufferLayout::operator=(aOther);
  mBuffer = aOther.mBuffer;
  return *this;
}



GPUTextureViewDescriptor::GPUTextureViewDescriptor()
  : GPUObjectDescriptorBase(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->mipLevelCount_id.init(cx, "mipLevelCount") ||
      !atomsCache->format_id.init(cx, "format") ||
      !atomsCache->dimension_id.init(cx, "dimension") ||
      !atomsCache->baseMipLevel_id.init(cx, "baseMipLevel") ||
      !atomsCache->baseArrayLayer_id.init(cx, "baseArrayLayer") ||
      !atomsCache->aspect_id.init(cx, "aspect") ||
      !atomsCache->arrayLayerCount_id.init(cx, "arrayLayerCount")) {
    return false;
  }
  return true;
}

bool
GPUTextureViewDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUTextureViewDescriptorAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUTextureViewDescriptorAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->arrayLayerCount_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mArrayLayerCount.Construct();
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'arrayLayerCount' member of GPUTextureViewDescriptor", &(mArrayLayerCount.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->aspect_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUTextureAspect>::Values,
                                                                         "GPUTextureAspect", "'aspect' member of GPUTextureViewDescriptor",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mAspect = static_cast<GPUTextureAspect>(index);
    }
  } else {
    mAspect = GPUTextureAspect::All;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->baseArrayLayer_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'baseArrayLayer' member of GPUTextureViewDescriptor", &mBaseArrayLayer)) {
      return false;
    }
  } else {
    mBaseArrayLayer = 0U;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->baseMipLevel_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'baseMipLevel' member of GPUTextureViewDescriptor", &mBaseMipLevel)) {
      return false;
    }
  } else {
    mBaseMipLevel = 0U;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->dimension_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mDimension.Construct();
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUTextureViewDimension>::Values,
                                                                         "GPUTextureViewDimension", "'dimension' member of GPUTextureViewDescriptor",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      (mDimension.Value()) = static_cast<GPUTextureViewDimension>(index);
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->format_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mFormat.Construct();
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUTextureFormat>::Values,
                                                                         "GPUTextureFormat", "'format' member of GPUTextureViewDescriptor",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      (mFormat.Value()) = static_cast<GPUTextureFormat>(index);
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->mipLevelCount_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mMipLevelCount.Construct();
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'mipLevelCount' member of GPUTextureViewDescriptor", &(mMipLevelCount.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }
  return true;
}

bool
GPUTextureViewDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUTextureViewDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}

GPUTextureViewDescriptor&
GPUTextureViewDescriptor::operator=(const GPUTextureViewDescriptor& aOther)
{
  GPUObjectDescriptorBase::operator=(aOther);
  mArrayLayerCount.Reset();
  if (aOther.mArrayLayerCount.WasPassed()) {
    mArrayLayerCount.Construct(aOther.mArrayLayerCount.Value());
  }
  mAspect = aOther.mAspect;
  mBaseArrayLayer = aOther.mBaseArrayLayer;
  mBaseMipLevel = aOther.mBaseMipLevel;
  mDimension.Reset();
  if (aOther.mDimension.WasPassed()) {
    mDimension.Construct(aOther.mDimension.Value());
  }
  mFormat.Reset();
  if (aOther.mFormat.WasPassed()) {
    mFormat.Construct(aOther.mFormat.Value());
  }
  mMipLevelCount.Reset();
  if (aOther.mMipLevelCount.WasPassed()) {
    mMipLevelCount.Construct(aOther.mMipLevelCount.Value());
  }
  return *this;
}



GPUVertexBufferLayout::GPUVertexBufferLayout()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->stepMode_id.init(cx, "stepMode") ||
      !atomsCache->attributes_id.init(cx, "attributes") ||
      !atomsCache->arrayStride_id.init(cx, "arrayStride")) {
    return false;
  }
  return true;
}

bool
GPUVertexBufferLayout::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUVertexBufferLayoutAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUVertexBufferLayoutAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->arrayStride_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, temp.ref(), "'arrayStride' member of GPUVertexBufferLayout", &mArrayStride)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'arrayStride' member of GPUVertexBufferLayout");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->attributes_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'attributes' member of GPUVertexBufferLayout", "sequence");
        return false;
      }
      Sequence<GPUVertexAttribute> &arr = mAttributes;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        GPUVertexAttribute* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        GPUVertexAttribute& slot = *slotPtr;
        if (!slot.Init(cx, temp, "Element of 'attributes' member of GPUVertexBufferLayout", passedToJSImpl)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'attributes' member of GPUVertexBufferLayout", "sequence");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'attributes' member of GPUVertexBufferLayout");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->stepMode_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUVertexStepMode>::Values,
                                                                         "GPUVertexStepMode", "'stepMode' member of GPUVertexBufferLayout",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mStepMode = static_cast<GPUVertexStepMode>(index);
    }
  } else {
    mStepMode = GPUVertexStepMode::Vertex;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUVertexBufferLayout::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUVertexBufferLayout&
GPUVertexBufferLayout::operator=(const GPUVertexBufferLayout& aOther)
{
  DictionaryBase::operator=(aOther);
  mArrayStride = aOther.mArrayStride;
  mAttributes = aOther.mAttributes;
  mStepMode = aOther.mStepMode;
  return *this;
}


bool
RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::TrySetToRangeEnforcedUnsignedLongSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    binding_detail::AutoSequence<uint32_t>& memberSlot = RawSetAsRangeEnforcedUnsignedLongSequence();
    JS::ForOfIterator iter(cx);
    if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
      return false;
    }
    if (!iter.valueIsIterable()) {
      DestroyRangeEnforcedUnsignedLongSequence();
      tryNext = true;
      return true;
    }
    binding_detail::AutoSequence<uint32_t> &arr = memberSlot;
    JS::Rooted<JS::Value> temp(cx);
    while (true) {
      bool done;
      if (!iter.next(&temp, &done)) {
        return false;
      }
      if (done) {
        break;
      }
      uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
      if (!slotPtr) {
        JS_ReportOutOfMemory(cx);
        return false;
      }
      uint32_t& slot = *slotPtr;
      if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp, "Element of sequence<unsigned long> branch of (sequence<unsigned long> or GPUExtent3DDict)", &slot)) {
        return false;
      }
    }
  }
  return true;
}

bool
RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::TrySetToRangeEnforcedUnsignedLongSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl);
}







bool
RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::TrySetToGPUExtent3DDict(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    binding_detail::FastGPUExtent3DDict& memberSlot = RawSetAsGPUExtent3DDict();
    if (!IsConvertibleToDictionary(value)) {
      DestroyGPUExtent3DDict();
      tryNext = true;
      return true;
    }
    if (!memberSlot.Init(cx, value, "GPUExtent3DDict branch of (sequence<unsigned long> or GPUExtent3DDict)", passedToJSImpl)) {
      return false;
    }
  }
  return true;
}

bool
RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::TrySetToGPUExtent3DDict(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUExtent3DDict(cx, value, tryNext, passedToJSImpl);
}







bool
RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (!done) {
    done = (failed = !TrySetToGPUExtent3DDict(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<unsigned long>, GPUExtent3DDict");
    return false;
  }
  return true;
}

bool
RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}




OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict(OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict&& aOther)
  : mType(eUninitialized)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eRangeEnforcedUnsignedLongSequence: {
      mType = eRangeEnforcedUnsignedLongSequence;
      mValue.mRangeEnforcedUnsignedLongSequence.SetValue(std::move(aOther.mValue.mRangeEnforcedUnsignedLongSequence.Value()));
      break;
    }
    case eGPUExtent3DDict: {
      mType = eGPUExtent3DDict;
      mValue.mGPUExtent3DDict.SetValue(std::move(aOther.mValue.mGPUExtent3DDict.Value()));
      break;
    }
  }
}



bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::TrySetToRangeEnforcedUnsignedLongSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    Sequence<uint32_t>& memberSlot = RawSetAsRangeEnforcedUnsignedLongSequence();
    JS::ForOfIterator iter(cx);
    if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
      return false;
    }
    if (!iter.valueIsIterable()) {
      DestroyRangeEnforcedUnsignedLongSequence();
      tryNext = true;
      return true;
    }
    Sequence<uint32_t> &arr = memberSlot;
    JS::Rooted<JS::Value> temp(cx);
    while (true) {
      bool done;
      if (!iter.next(&temp, &done)) {
        return false;
      }
      if (done) {
        break;
      }
      uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
      if (!slotPtr) {
        JS_ReportOutOfMemory(cx);
        return false;
      }
      uint32_t& slot = *slotPtr;
      if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp, "Element of sequence<unsigned long> branch of (sequence<unsigned long> or GPUExtent3DDict)", &slot)) {
        return false;
      }
    }
  }
  return true;
}

bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::TrySetToRangeEnforcedUnsignedLongSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] Sequence<uint32_t>&
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::RawSetAsRangeEnforcedUnsignedLongSequence()
{
  if (mType == eRangeEnforcedUnsignedLongSequence) {
    return mValue.mRangeEnforcedUnsignedLongSequence.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eRangeEnforcedUnsignedLongSequence;
  return mValue.mRangeEnforcedUnsignedLongSequence.SetValue();
}

[[nodiscard]] Sequence<uint32_t>&
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::SetAsRangeEnforcedUnsignedLongSequence()
{
  if (mType == eRangeEnforcedUnsignedLongSequence) {
    return mValue.mRangeEnforcedUnsignedLongSequence.Value();
  }
  Uninit();
  mType = eRangeEnforcedUnsignedLongSequence;
  return mValue.mRangeEnforcedUnsignedLongSequence.SetValue();
}


void
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::DestroyRangeEnforcedUnsignedLongSequence()
{
  MOZ_RELEASE_ASSERT(IsRangeEnforcedUnsignedLongSequence(), "Wrong type!");
  mValue.mRangeEnforcedUnsignedLongSequence.Destroy();
  mType = eUninitialized;
}



bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::TrySetToGPUExtent3DDict(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    GPUExtent3DDict& memberSlot = RawSetAsGPUExtent3DDict();
    if (!IsConvertibleToDictionary(value)) {
      DestroyGPUExtent3DDict();
      tryNext = true;
      return true;
    }
    if (!memberSlot.Init(cx, value, "GPUExtent3DDict branch of (sequence<unsigned long> or GPUExtent3DDict)", passedToJSImpl)) {
      return false;
    }
  }
  return true;
}

bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::TrySetToGPUExtent3DDict(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUExtent3DDict(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] GPUExtent3DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::RawSetAsGPUExtent3DDict()
{
  if (mType == eGPUExtent3DDict) {
    return mValue.mGPUExtent3DDict.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eGPUExtent3DDict;
  return mValue.mGPUExtent3DDict.SetValue();
}

[[nodiscard]] GPUExtent3DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::SetAsGPUExtent3DDict()
{
  if (mType == eGPUExtent3DDict) {
    return mValue.mGPUExtent3DDict.Value();
  }
  Uninit();
  mType = eGPUExtent3DDict;
  return mValue.mGPUExtent3DDict.SetValue();
}


void
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::DestroyGPUExtent3DDict()
{
  MOZ_RELEASE_ASSERT(IsGPUExtent3DDict(), "Wrong type!");
  mValue.mGPUExtent3DDict.Destroy();
  mType = eUninitialized;
}



bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (!done) {
    done = (failed = !TrySetToGPUExtent3DDict(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<unsigned long>, GPUExtent3DDict");
    return false;
  }
  return true;
}

bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}

void
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::Uninit()
{
  switch (mType) {
    case eUninitialized: {
      break;
    }
    case eRangeEnforcedUnsignedLongSequence: {
      DestroyRangeEnforcedUnsignedLongSequence();
      break;
    }
    case eGPUExtent3DDict: {
      DestroyGPUExtent3DDict();
      break;
    }
  }
}

OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::operator=(OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict&& aOther)
{
  this->~OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict();
  new (this) OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict (std::move(aOther));
  return *this;
}


OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::operator=(const OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict& aOther)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eRangeEnforcedUnsignedLongSequence: {
      SetAsRangeEnforcedUnsignedLongSequence() = aOther.GetAsRangeEnforcedUnsignedLongSequence();
      break;
    }
    case eGPUExtent3DDict: {
      SetAsGPUExtent3DDict() = aOther.GetAsGPUExtent3DDict();
      break;
    }
  }
  return *this;
}


bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::TrySetToRangeEnforcedUnsignedLongSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    binding_detail::AutoSequence<uint32_t>& memberSlot = RawSetAsRangeEnforcedUnsignedLongSequence();
    JS::ForOfIterator iter(cx);
    if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
      return false;
    }
    if (!iter.valueIsIterable()) {
      DestroyRangeEnforcedUnsignedLongSequence();
      tryNext = true;
      return true;
    }
    binding_detail::AutoSequence<uint32_t> &arr = memberSlot;
    JS::Rooted<JS::Value> temp(cx);
    while (true) {
      bool done;
      if (!iter.next(&temp, &done)) {
        return false;
      }
      if (done) {
        break;
      }
      uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
      if (!slotPtr) {
        JS_ReportOutOfMemory(cx);
        return false;
      }
      uint32_t& slot = *slotPtr;
      if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp, "Element of sequence<unsigned long> branch of (sequence<unsigned long> or GPUOrigin2DDict)", &slot)) {
        return false;
      }
    }
  }
  return true;
}

bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::TrySetToRangeEnforcedUnsignedLongSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl);
}







bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::TrySetToGPUOrigin2DDict(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    binding_detail::FastGPUOrigin2DDict& memberSlot = RawSetAsGPUOrigin2DDict();
    if (!IsConvertibleToDictionary(value)) {
      DestroyGPUOrigin2DDict();
      tryNext = true;
      return true;
    }
    if (!memberSlot.Init(cx, value, "GPUOrigin2DDict branch of (sequence<unsigned long> or GPUOrigin2DDict)", passedToJSImpl)) {
      return false;
    }
  }
  return true;
}

bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::TrySetToGPUOrigin2DDict(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUOrigin2DDict(cx, value, tryNext, passedToJSImpl);
}







bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (!done) {
    done = (failed = !TrySetToGPUOrigin2DDict(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<unsigned long>, GPUOrigin2DDict");
    return false;
  }
  return true;
}

bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}




OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict(OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict&& aOther)
  : mType(eUninitialized)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eRangeEnforcedUnsignedLongSequence: {
      mType = eRangeEnforcedUnsignedLongSequence;
      mValue.mRangeEnforcedUnsignedLongSequence.SetValue(std::move(aOther.mValue.mRangeEnforcedUnsignedLongSequence.Value()));
      break;
    }
    case eGPUOrigin2DDict: {
      mType = eGPUOrigin2DDict;
      mValue.mGPUOrigin2DDict.SetValue(std::move(aOther.mValue.mGPUOrigin2DDict.Value()));
      break;
    }
  }
}



bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::TrySetToRangeEnforcedUnsignedLongSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    Sequence<uint32_t>& memberSlot = RawSetAsRangeEnforcedUnsignedLongSequence();
    JS::ForOfIterator iter(cx);
    if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
      return false;
    }
    if (!iter.valueIsIterable()) {
      DestroyRangeEnforcedUnsignedLongSequence();
      tryNext = true;
      return true;
    }
    Sequence<uint32_t> &arr = memberSlot;
    JS::Rooted<JS::Value> temp(cx);
    while (true) {
      bool done;
      if (!iter.next(&temp, &done)) {
        return false;
      }
      if (done) {
        break;
      }
      uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
      if (!slotPtr) {
        JS_ReportOutOfMemory(cx);
        return false;
      }
      uint32_t& slot = *slotPtr;
      if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp, "Element of sequence<unsigned long> branch of (sequence<unsigned long> or GPUOrigin2DDict)", &slot)) {
        return false;
      }
    }
  }
  return true;
}

bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::TrySetToRangeEnforcedUnsignedLongSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] Sequence<uint32_t>&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::RawSetAsRangeEnforcedUnsignedLongSequence()
{
  if (mType == eRangeEnforcedUnsignedLongSequence) {
    return mValue.mRangeEnforcedUnsignedLongSequence.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eRangeEnforcedUnsignedLongSequence;
  return mValue.mRangeEnforcedUnsignedLongSequence.SetValue();
}

[[nodiscard]] Sequence<uint32_t>&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::SetAsRangeEnforcedUnsignedLongSequence()
{
  if (mType == eRangeEnforcedUnsignedLongSequence) {
    return mValue.mRangeEnforcedUnsignedLongSequence.Value();
  }
  Uninit();
  mType = eRangeEnforcedUnsignedLongSequence;
  return mValue.mRangeEnforcedUnsignedLongSequence.SetValue();
}


void
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::DestroyRangeEnforcedUnsignedLongSequence()
{
  MOZ_RELEASE_ASSERT(IsRangeEnforcedUnsignedLongSequence(), "Wrong type!");
  mValue.mRangeEnforcedUnsignedLongSequence.Destroy();
  mType = eUninitialized;
}



bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::TrySetToGPUOrigin2DDict(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    GPUOrigin2DDict& memberSlot = RawSetAsGPUOrigin2DDict();
    if (!IsConvertibleToDictionary(value)) {
      DestroyGPUOrigin2DDict();
      tryNext = true;
      return true;
    }
    if (!memberSlot.Init(cx, value, "GPUOrigin2DDict branch of (sequence<unsigned long> or GPUOrigin2DDict)", passedToJSImpl)) {
      return false;
    }
  }
  return true;
}

bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::TrySetToGPUOrigin2DDict(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUOrigin2DDict(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] GPUOrigin2DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::RawSetAsGPUOrigin2DDict()
{
  if (mType == eGPUOrigin2DDict) {
    return mValue.mGPUOrigin2DDict.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eGPUOrigin2DDict;
  return mValue.mGPUOrigin2DDict.SetValue();
}

[[nodiscard]] GPUOrigin2DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::SetAsGPUOrigin2DDict()
{
  if (mType == eGPUOrigin2DDict) {
    return mValue.mGPUOrigin2DDict.Value();
  }
  Uninit();
  mType = eGPUOrigin2DDict;
  return mValue.mGPUOrigin2DDict.SetValue();
}


void
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::DestroyGPUOrigin2DDict()
{
  MOZ_RELEASE_ASSERT(IsGPUOrigin2DDict(), "Wrong type!");
  mValue.mGPUOrigin2DDict.Destroy();
  mType = eUninitialized;
}



bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (!done) {
    done = (failed = !TrySetToGPUOrigin2DDict(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<unsigned long>, GPUOrigin2DDict");
    return false;
  }
  return true;
}

bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}

void
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::Uninit()
{
  switch (mType) {
    case eUninitialized: {
      break;
    }
    case eRangeEnforcedUnsignedLongSequence: {
      DestroyRangeEnforcedUnsignedLongSequence();
      break;
    }
    case eGPUOrigin2DDict: {
      DestroyGPUOrigin2DDict();
      break;
    }
  }
}

OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::operator=(OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict&& aOther)
{
  this->~OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict();
  new (this) OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict (std::move(aOther));
  return *this;
}


OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::operator=(const OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict& aOther)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eRangeEnforcedUnsignedLongSequence: {
      SetAsRangeEnforcedUnsignedLongSequence() = aOther.GetAsRangeEnforcedUnsignedLongSequence();
      break;
    }
    case eGPUOrigin2DDict: {
      SetAsGPUOrigin2DDict() = aOther.GetAsGPUOrigin2DDict();
      break;
    }
  }
  return *this;
}


bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::TrySetToRangeEnforcedUnsignedLongSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    binding_detail::AutoSequence<uint32_t>& memberSlot = RawSetAsRangeEnforcedUnsignedLongSequence();
    JS::ForOfIterator iter(cx);
    if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
      return false;
    }
    if (!iter.valueIsIterable()) {
      DestroyRangeEnforcedUnsignedLongSequence();
      tryNext = true;
      return true;
    }
    binding_detail::AutoSequence<uint32_t> &arr = memberSlot;
    JS::Rooted<JS::Value> temp(cx);
    while (true) {
      bool done;
      if (!iter.next(&temp, &done)) {
        return false;
      }
      if (done) {
        break;
      }
      uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
      if (!slotPtr) {
        JS_ReportOutOfMemory(cx);
        return false;
      }
      uint32_t& slot = *slotPtr;
      if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp, "Element of sequence<unsigned long> branch of (sequence<unsigned long> or GPUOrigin3DDict)", &slot)) {
        return false;
      }
    }
  }
  return true;
}

bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::TrySetToRangeEnforcedUnsignedLongSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl);
}







bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::TrySetToGPUOrigin3DDict(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    binding_detail::FastGPUOrigin3DDict& memberSlot = RawSetAsGPUOrigin3DDict();
    if (!IsConvertibleToDictionary(value)) {
      DestroyGPUOrigin3DDict();
      tryNext = true;
      return true;
    }
    if (!memberSlot.Init(cx, value, "GPUOrigin3DDict branch of (sequence<unsigned long> or GPUOrigin3DDict)", passedToJSImpl)) {
      return false;
    }
  }
  return true;
}

bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::TrySetToGPUOrigin3DDict(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUOrigin3DDict(cx, value, tryNext, passedToJSImpl);
}







bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (!done) {
    done = (failed = !TrySetToGPUOrigin3DDict(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<unsigned long>, GPUOrigin3DDict");
    return false;
  }
  return true;
}

bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}




OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict(OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict&& aOther)
  : mType(eUninitialized)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eRangeEnforcedUnsignedLongSequence: {
      mType = eRangeEnforcedUnsignedLongSequence;
      mValue.mRangeEnforcedUnsignedLongSequence.SetValue(std::move(aOther.mValue.mRangeEnforcedUnsignedLongSequence.Value()));
      break;
    }
    case eGPUOrigin3DDict: {
      mType = eGPUOrigin3DDict;
      mValue.mGPUOrigin3DDict.SetValue(std::move(aOther.mValue.mGPUOrigin3DDict.Value()));
      break;
    }
  }
}



bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::TrySetToRangeEnforcedUnsignedLongSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    Sequence<uint32_t>& memberSlot = RawSetAsRangeEnforcedUnsignedLongSequence();
    JS::ForOfIterator iter(cx);
    if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
      return false;
    }
    if (!iter.valueIsIterable()) {
      DestroyRangeEnforcedUnsignedLongSequence();
      tryNext = true;
      return true;
    }
    Sequence<uint32_t> &arr = memberSlot;
    JS::Rooted<JS::Value> temp(cx);
    while (true) {
      bool done;
      if (!iter.next(&temp, &done)) {
        return false;
      }
      if (done) {
        break;
      }
      uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
      if (!slotPtr) {
        JS_ReportOutOfMemory(cx);
        return false;
      }
      uint32_t& slot = *slotPtr;
      if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp, "Element of sequence<unsigned long> branch of (sequence<unsigned long> or GPUOrigin3DDict)", &slot)) {
        return false;
      }
    }
  }
  return true;
}

bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::TrySetToRangeEnforcedUnsignedLongSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] Sequence<uint32_t>&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::RawSetAsRangeEnforcedUnsignedLongSequence()
{
  if (mType == eRangeEnforcedUnsignedLongSequence) {
    return mValue.mRangeEnforcedUnsignedLongSequence.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eRangeEnforcedUnsignedLongSequence;
  return mValue.mRangeEnforcedUnsignedLongSequence.SetValue();
}

[[nodiscard]] Sequence<uint32_t>&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::SetAsRangeEnforcedUnsignedLongSequence()
{
  if (mType == eRangeEnforcedUnsignedLongSequence) {
    return mValue.mRangeEnforcedUnsignedLongSequence.Value();
  }
  Uninit();
  mType = eRangeEnforcedUnsignedLongSequence;
  return mValue.mRangeEnforcedUnsignedLongSequence.SetValue();
}


void
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::DestroyRangeEnforcedUnsignedLongSequence()
{
  MOZ_RELEASE_ASSERT(IsRangeEnforcedUnsignedLongSequence(), "Wrong type!");
  mValue.mRangeEnforcedUnsignedLongSequence.Destroy();
  mType = eUninitialized;
}



bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::TrySetToGPUOrigin3DDict(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  tryNext = false;
  { // scope for memberSlot
    GPUOrigin3DDict& memberSlot = RawSetAsGPUOrigin3DDict();
    if (!IsConvertibleToDictionary(value)) {
      DestroyGPUOrigin3DDict();
      tryNext = true;
      return true;
    }
    if (!memberSlot.Init(cx, value, "GPUOrigin3DDict branch of (sequence<unsigned long> or GPUOrigin3DDict)", passedToJSImpl)) {
      return false;
    }
  }
  return true;
}

bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::TrySetToGPUOrigin3DDict(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return TrySetToGPUOrigin3DDict(cx, value, tryNext, passedToJSImpl);
}

[[nodiscard]] GPUOrigin3DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::RawSetAsGPUOrigin3DDict()
{
  if (mType == eGPUOrigin3DDict) {
    return mValue.mGPUOrigin3DDict.Value();
  }
  MOZ_ASSERT(mType == eUninitialized);
  mType = eGPUOrigin3DDict;
  return mValue.mGPUOrigin3DDict.SetValue();
}

[[nodiscard]] GPUOrigin3DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::SetAsGPUOrigin3DDict()
{
  if (mType == eGPUOrigin3DDict) {
    return mValue.mGPUOrigin3DDict.Value();
  }
  Uninit();
  mType = eGPUOrigin3DDict;
  return mValue.mGPUOrigin3DDict.SetValue();
}


void
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::DestroyGPUOrigin3DDict()
{
  MOZ_RELEASE_ASSERT(IsGPUOrigin3DDict(), "Wrong type!");
  mValue.mGPUOrigin3DDict.Destroy();
  mType = eUninitialized;
}



bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  MOZ_ASSERT(mType == eUninitialized);

  bool done = false, failed = false, tryNext;
  if (value.isObject()) {
    done = (failed = !TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (!done) {
    done = (failed = !TrySetToGPUOrigin3DDict(cx, value, tryNext, passedToJSImpl)) || !tryNext;
  }
  if (failed) {
    return false;
  }
  if (!done) {
    cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<unsigned long>, GPUOrigin3DDict");
    return false;
  }
  return true;
}

bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, value, sourceDescription, passedToJSImpl);
}

void
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::Uninit()
{
  switch (mType) {
    case eUninitialized: {
      break;
    }
    case eRangeEnforcedUnsignedLongSequence: {
      DestroyRangeEnforcedUnsignedLongSequence();
      break;
    }
    case eGPUOrigin3DDict: {
      DestroyGPUOrigin3DDict();
      break;
    }
  }
}

OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::operator=(OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict&& aOther)
{
  this->~OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict();
  new (this) OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict (std::move(aOther));
  return *this;
}


OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::operator=(const OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict& aOther)
{
  switch (aOther.mType) {
    case eUninitialized: {
      MOZ_ASSERT(mType == eUninitialized,
                 "We need to destroy ourselves?");
      break;
    }
    case eRangeEnforcedUnsignedLongSequence: {
      SetAsRangeEnforcedUnsignedLongSequence() = aOther.GetAsRangeEnforcedUnsignedLongSequence();
      break;
    }
    case eGPUOrigin3DDict: {
      SetAsGPUOrigin3DDict() = aOther.GetAsGPUOrigin3DDict();
      break;
    }
  }
  return *this;
}



GPUBindGroupEntry::GPUBindGroupEntry()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

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

bool
GPUBindGroupEntry::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUBindGroupEntryAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUBindGroupEntryAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->binding_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'binding' member of GPUBindGroupEntry", &mBinding)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'binding' member of GPUBindGroupEntry");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->resource_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mResource.Init(cx, temp.ref(), "'resource' member of GPUBindGroupEntry", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'resource' member of GPUBindGroupEntry");
  }
  return true;
}

bool
GPUBindGroupEntry::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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



GPUBindGroupEntry&
GPUBindGroupEntry::operator=(const GPUBindGroupEntry& aOther)
{
  DictionaryBase::operator=(aOther);
  mBinding = aOther.mBinding;
  mResource = aOther.mResource;
  return *this;
}



GPUBindGroupLayoutDescriptor::GPUBindGroupLayoutDescriptor()
  : GPUObjectDescriptorBase(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

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

bool
GPUBindGroupLayoutDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUBindGroupLayoutDescriptorAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUBindGroupLayoutDescriptorAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->entries_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'entries' member of GPUBindGroupLayoutDescriptor", "sequence");
        return false;
      }
      Sequence<GPUBindGroupLayoutEntry> &arr = mEntries;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        GPUBindGroupLayoutEntry* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        GPUBindGroupLayoutEntry& slot = *slotPtr;
        if (!slot.Init(cx, temp, "Element of 'entries' member of GPUBindGroupLayoutDescriptor", passedToJSImpl)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'entries' member of GPUBindGroupLayoutDescriptor", "sequence");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'entries' member of GPUBindGroupLayoutDescriptor");
  }
  return true;
}

bool
GPUBindGroupLayoutDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUBindGroupLayoutDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}

GPUBindGroupLayoutDescriptor&
GPUBindGroupLayoutDescriptor::operator=(const GPUBindGroupLayoutDescriptor& aOther)
{
  GPUObjectDescriptorBase::operator=(aOther);
  mEntries = aOther.mEntries;
  return *this;
}



GPUColorTargetState::GPUColorTargetState()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->writeMask_id.init(cx, "writeMask") ||
      !atomsCache->format_id.init(cx, "format") ||
      !atomsCache->blend_id.init(cx, "blend")) {
    return false;
  }
  return true;
}

bool
GPUColorTargetState::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUColorTargetStateAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUColorTargetStateAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->blend_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mBlend.Construct();
    if (!(mBlend.Value()).Init(cx, temp.ref(), "'blend' member of GPUColorTargetState", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->format_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUTextureFormat>::Values,
                                                                         "GPUTextureFormat", "'format' member of GPUColorTargetState",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mFormat = static_cast<GPUTextureFormat>(index);
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'format' member of GPUColorTargetState");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->writeMask_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'writeMask' member of GPUColorTargetState", &mWriteMask)) {
      return false;
    }
  } else {
    mWriteMask = 15U;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUColorTargetState::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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

GPUColorTargetState&
GPUColorTargetState::operator=(const GPUColorTargetState& aOther)
{
  DictionaryBase::operator=(aOther);
  mBlend.Reset();
  if (aOther.mBlend.WasPassed()) {
    mBlend.Construct(aOther.mBlend.Value());
  }
  mFormat = aOther.mFormat;
  mWriteMask = aOther.mWriteMask;
  return *this;
}



GPUComputePipelineDescriptor::GPUComputePipelineDescriptor()
  : GPUPipelineDescriptorBase(FastDictionaryInitializer()),
    mCompute(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}



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

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

bool
GPUComputePipelineDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUComputePipelineDescriptorAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUComputePipelineDescriptorAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUPipelineDescriptorBase::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->compute_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mCompute.Init(cx, temp.ref(), "'compute' member of GPUComputePipelineDescriptor", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'compute' member of GPUComputePipelineDescriptor");
  }
  return true;
}

bool
GPUComputePipelineDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUComputePipelineDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUPipelineDescriptorBase::TraceDictionary(trc);
}





GPUCopyExternalImageSourceInfo::GPUCopyExternalImageSourceInfo()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->source_id.init(cx, "source") ||
      !atomsCache->origin_id.init(cx, "origin") ||
      !atomsCache->flipY_id.init(cx, "flipY")) {
    return false;
  }
  return true;
}

bool
GPUCopyExternalImageSourceInfo::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUCopyExternalImageSourceInfoAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUCopyExternalImageSourceInfoAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->flipY_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'flipY' member of GPUCopyExternalImageSourceInfo", &mFlipY)) {
      return false;
    }
  } else {
    mFlipY = false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->origin_id, temp.ptr())) {
      return false;
    }
  }
  mOrigin.Uninit();
  if (!(!isNull && !temp->isUndefined())) {
    if (!mOrigin.RawSetAsGPUOrigin2DDict().Init(cx, JS::NullHandleValue, "Member of (sequence<unsigned long> or GPUOrigin2DDict)")) {
      return false;
    }
  } else {
    if (!mOrigin.Init(cx, temp.ref(), "'origin' member of GPUCopyExternalImageSourceInfo", passedToJSImpl)) {
      return false;
    }
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->source_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mSource.Init(cx, temp.ref(), "'source' member of GPUCopyExternalImageSourceInfo", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'source' member of GPUCopyExternalImageSourceInfo");
  }
  return true;
}

bool
GPUCopyExternalImageSourceInfo::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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



GPUCopyExternalImageSourceInfo&
GPUCopyExternalImageSourceInfo::operator=(const GPUCopyExternalImageSourceInfo& aOther)
{
  DictionaryBase::operator=(aOther);
  mFlipY = aOther.mFlipY;
  mOrigin = aOther.mOrigin;
  mSource = aOther.mSource;
  return *this;
}



GPUDeviceDescriptor::GPUDeviceDescriptor()
  : GPUObjectDescriptorBase(FastDictionaryInitializer()),
    mDefaultQueue(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}



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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->requiredLimits_id.init(cx, "requiredLimits") ||
      !atomsCache->requiredFeatures_id.init(cx, "requiredFeatures") ||
      !atomsCache->defaultQueue_id.init(cx, "defaultQueue")) {
    return false;
  }
  return true;
}

bool
GPUDeviceDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUDeviceDescriptorAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUDeviceDescriptorAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->defaultQueue_id, temp.ptr())) {
      return false;
    }
  }
  if (!mDefaultQueue.Init(cx, (!isNull && !temp->isUndefined()) ? temp.ref() : JS::NullHandleValue, "'defaultQueue' member of GPUDeviceDescriptor", passedToJSImpl)) {
    return false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->requiredFeatures_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'requiredFeatures' member of GPUDeviceDescriptor", "sequence");
        return false;
      }
      Sequence<GPUFeatureName> &arr = mRequiredFeatures;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        GPUFeatureName* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        GPUFeatureName& slot = *slotPtr;
        {
          int index;
          if (!binding_detail::FindEnumStringIndex<true>(cx, temp,
                                                                             binding_detail::EnumStrings<GPUFeatureName>::Values,
                                                                             "GPUFeatureName", "element of 'requiredFeatures' member of GPUDeviceDescriptor",
                                                                             &index)) {
            return false;
          }
          MOZ_ASSERT(index >= 0);
          slot = static_cast<GPUFeatureName>(index);
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'requiredFeatures' member of GPUDeviceDescriptor", "sequence");
      return false;
    }
  } else {
    /* mRequiredFeatures array is already empty; nothing to do */
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->requiredLimits_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mRequiredLimits.Construct();
    if (temp.ref().isObject()) {
      auto& recordEntries = (mRequiredLimits.Value()).Entries();

      JS::Rooted<JSObject*> recordObj(cx, &temp.ref().toObject());
      JS::RootedVector<jsid> ids(cx);
      if (!js::GetPropertyKeys(cx, recordObj,
                               JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
        return false;
      }
      if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
        JS_ReportOutOfMemory(cx);
        return false;
      }
      JS::Rooted<JS::Value> propNameValue(cx);
      JS::Rooted<JS::Value> temp(cx);
      JS::Rooted<jsid> curId(cx);
      JS::Rooted<JS::Value> idVal(cx);
      // Use a hashset to keep track of ids seen, to avoid
      // introducing nasty O(N^2) behavior scanning for them all the
      // time.  Ideally we'd use a data structure with O(1) lookup
      // _and_ ordering for the MozMap, but we don't have one lying
      // around.
      nsTHashtable<nsStringHashKey> idsSeen;
      for (size_t i = 0; i < ids.length(); ++i) {
        curId = ids[i];

        JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
        if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
                                             &desc)) {
          return false;
        }

        if (desc.isNothing() || !desc->enumerable()) {
          continue;
        }

        idVal = js::IdToValue(curId);
        nsString propName;
        // This will just throw if idVal is a Symbol, like the spec says
        // to do.
        if (!ConvertJSValueToString(cx, idVal, "key of 'requiredLimits' member of GPUDeviceDescriptor", propName)) {
          return false;
        }

        if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
          return false;
        }

        Record<nsString, uint64_t>::EntryType* entry;
        if (!idsSeen.EnsureInserted(propName)) {
          // Find the existing entry.
          auto idx = recordEntries.IndexOf(propName);
          MOZ_ASSERT(idx != recordEntries.NoIndex,
                     "Why is it not found?");
          // Now blow it away to make it look like it was just added
          // to the array, because it's not obvious that it's
          // safe to write to its already-initialized mValue via our
          // normal codegen conversions.  For example, the value
          // could be a union and this would change its type, but
          // codegen assumes we won't do that.
          entry = recordEntries.ReconstructElementAt(idx);
        } else {
          // Safe to do an infallible append here, because we did a
          // SetCapacity above to the right capacity.
          entry = recordEntries.AppendElement();
        }
        entry->mKey = propName;
        uint64_t& slot = entry->mValue;
        if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, temp, "Value in 'requiredLimits' member of GPUDeviceDescriptor", &slot)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'requiredLimits' member of GPUDeviceDescriptor");
      return false;
    }
    mIsAnyMemberPresent = true;
  }
  return true;
}

bool
GPUDeviceDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUDeviceDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}



GPURenderBundleEncoderDescriptor::GPURenderBundleEncoderDescriptor()
  : GPURenderPassLayout(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

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

bool
GPURenderBundleEncoderDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPURenderBundleEncoderDescriptorAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPURenderBundleEncoderDescriptorAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPURenderPassLayout::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->depthReadOnly_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'depthReadOnly' member of GPURenderBundleEncoderDescriptor", &mDepthReadOnly)) {
      return false;
    }
  } else {
    mDepthReadOnly = false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->stencilReadOnly_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'stencilReadOnly' member of GPURenderBundleEncoderDescriptor", &mStencilReadOnly)) {
      return false;
    }
  } else {
    mStencilReadOnly = false;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPURenderBundleEncoderDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPURenderBundleEncoderDescriptor::TraceDictionary(JSTracer* trc)
{
  GPURenderPassLayout::TraceDictionary(trc);
}

GPURenderBundleEncoderDescriptor&
GPURenderBundleEncoderDescriptor::operator=(const GPURenderBundleEncoderDescriptor& aOther)
{
  GPURenderPassLayout::operator=(aOther);
  mDepthReadOnly = aOther.mDepthReadOnly;
  mStencilReadOnly = aOther.mStencilReadOnly;
  return *this;
}



GPURenderPassColorAttachment::GPURenderPassColorAttachment()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->view_id.init(cx, "view") ||
      !atomsCache->storeOp_id.init(cx, "storeOp") ||
      !atomsCache->resolveTarget_id.init(cx, "resolveTarget") ||
      !atomsCache->loadOp_id.init(cx, "loadOp") ||
      !atomsCache->depthSlice_id.init(cx, "depthSlice") ||
      !atomsCache->clearValue_id.init(cx, "clearValue")) {
    return false;
  }
  return true;
}

bool
GPURenderPassColorAttachment::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPURenderPassColorAttachmentAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPURenderPassColorAttachmentAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->clearValue_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mClearValue.Construct();
    if (!(mClearValue.Value()).Init(cx, temp.ref(), "'clearValue' member of GPURenderPassColorAttachment", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->depthSlice_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mDepthSlice.Construct();
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'depthSlice' member of GPURenderPassColorAttachment", &(mDepthSlice.Value()))) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->loadOp_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPULoadOp>::Values,
                                                                         "GPULoadOp", "'loadOp' member of GPURenderPassColorAttachment",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mLoadOp = static_cast<GPULoadOp>(index);
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'loadOp' member of GPURenderPassColorAttachment");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->resolveTarget_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mResolveTarget.Construct();
    if (!(mResolveTarget.Value()).Init(cx, temp.ref(), "'resolveTarget' member of GPURenderPassColorAttachment", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->storeOp_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUStoreOp>::Values,
                                                                         "GPUStoreOp", "'storeOp' member of GPURenderPassColorAttachment",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mStoreOp = static_cast<GPUStoreOp>(index);
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'storeOp' member of GPURenderPassColorAttachment");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->view_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mView.Init(cx, temp.ref(), "'view' member of GPURenderPassColorAttachment", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'view' member of GPURenderPassColorAttachment");
  }
  return true;
}

bool
GPURenderPassColorAttachment::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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



GPURenderPassColorAttachment&
GPURenderPassColorAttachment::operator=(const GPURenderPassColorAttachment& aOther)
{
  DictionaryBase::operator=(aOther);
  mClearValue.Reset();
  if (aOther.mClearValue.WasPassed()) {
    mClearValue.Construct(aOther.mClearValue.Value());
  }
  mDepthSlice.Reset();
  if (aOther.mDepthSlice.WasPassed()) {
    mDepthSlice.Construct(aOther.mDepthSlice.Value());
  }
  mLoadOp = aOther.mLoadOp;
  mResolveTarget.Reset();
  if (aOther.mResolveTarget.WasPassed()) {
    mResolveTarget.Construct(aOther.mResolveTarget.Value());
  }
  mStoreOp = aOther.mStoreOp;
  mView = aOther.mView;
  return *this;
}



GPUShaderModuleDescriptor::GPUShaderModuleDescriptor()
  : GPUObjectDescriptorBase(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

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

bool
GPUShaderModuleDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUShaderModuleDescriptorAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUShaderModuleDescriptorAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->code_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mCode)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'code' member of GPUShaderModuleDescriptor");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->compilationHints_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'compilationHints' member of GPUShaderModuleDescriptor", "sequence");
        return false;
      }
      Sequence<GPUShaderModuleCompilationHint> &arr = mCompilationHints;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        GPUShaderModuleCompilationHint* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        GPUShaderModuleCompilationHint& slot = *slotPtr;
        if (!slot.Init(cx, temp, "Element of 'compilationHints' member of GPUShaderModuleDescriptor", passedToJSImpl)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'compilationHints' member of GPUShaderModuleDescriptor", "sequence");
      return false;
    }
  } else {
    /* mCompilationHints array is already empty; nothing to do */
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUShaderModuleDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUShaderModuleDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}



GPUShaderModuleDescriptor&
GPUShaderModuleDescriptor::operator=(const GPUShaderModuleDescriptor& aOther)
{
  GPUObjectDescriptorBase::operator=(aOther);
  mCode = aOther.mCode;
  mCompilationHints = aOther.mCompilationHints;
  return *this;
}



GPUTexelCopyTextureInfo::GPUTexelCopyTextureInfo()
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->texture_id.init(cx, "texture") ||
      !atomsCache->origin_id.init(cx, "origin") ||
      !atomsCache->mipLevel_id.init(cx, "mipLevel") ||
      !atomsCache->aspect_id.init(cx, "aspect")) {
    return false;
  }
  return true;
}

bool
GPUTexelCopyTextureInfo::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUTexelCopyTextureInfoAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUTexelCopyTextureInfoAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  if (!IsConvertibleToDictionary(val)) {
    return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->aspect_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUTextureAspect>::Values,
                                                                         "GPUTextureAspect", "'aspect' member of GPUTexelCopyTextureInfo",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mAspect = static_cast<GPUTextureAspect>(index);
    }
  } else {
    mAspect = GPUTextureAspect::All;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->mipLevel_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'mipLevel' member of GPUTexelCopyTextureInfo", &mMipLevel)) {
      return false;
    }
  } else {
    mMipLevel = 0U;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->origin_id, temp.ptr())) {
      return false;
    }
  }
  mOrigin.Uninit();
  if (!(!isNull && !temp->isUndefined())) {
    if (!mOrigin.RawSetAsGPUOrigin3DDict().Init(cx, JS::NullHandleValue, "Member of (sequence<unsigned long> or GPUOrigin3DDict)")) {
      return false;
    }
  } else {
    if (!mOrigin.Init(cx, temp.ref(), "'origin' member of GPUTexelCopyTextureInfo", passedToJSImpl)) {
      return false;
    }
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->texture_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      static_assert(IsRefcounted<mozilla::webgpu::Texture>::value, "We can only store refcounted classes.");
      {
        // Our JSContext should be in the right global to do unwrapping in.
        nsresult rv = UnwrapObject<prototypes::id::GPUTexture, mozilla::webgpu::Texture>(temp.ptr(), mTexture, cx);
        if (NS_FAILED(rv)) {
          cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'texture' member of GPUTexelCopyTextureInfo", "GPUTexture");
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'texture' member of GPUTexelCopyTextureInfo");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'texture' member of GPUTexelCopyTextureInfo");
  }
  return true;
}

bool
GPUTexelCopyTextureInfo::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

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



GPUTexelCopyTextureInfo&
GPUTexelCopyTextureInfo::operator=(const GPUTexelCopyTextureInfo& aOther)
{
  DictionaryBase::operator=(aOther);
  mAspect = aOther.mAspect;
  mMipLevel = aOther.mMipLevel;
  mOrigin = aOther.mOrigin;
  mTexture = aOther.mTexture;
  return *this;
}



GPUTextureDescriptor::GPUTextureDescriptor()
  : GPUObjectDescriptorBase(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->viewFormats_id.init(cx, "viewFormats") ||
      !atomsCache->usage_id.init(cx, "usage") ||
      !atomsCache->size_id.init(cx, "size") ||
      !atomsCache->sampleCount_id.init(cx, "sampleCount") ||
      !atomsCache->mipLevelCount_id.init(cx, "mipLevelCount") ||
      !atomsCache->format_id.init(cx, "format") ||
      !atomsCache->dimension_id.init(cx, "dimension")) {
    return false;
  }
  return true;
}

bool
GPUTextureDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUTextureDescriptorAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUTextureDescriptorAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->dimension_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUTextureDimension>::Values,
                                                                         "GPUTextureDimension", "'dimension' member of GPUTextureDescriptor",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mDimension = static_cast<GPUTextureDimension>(index);
    }
  } else {
    mDimension = GPUTextureDimension::_2d;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->format_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    {
      int index;
      if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
                                                                         binding_detail::EnumStrings<GPUTextureFormat>::Values,
                                                                         "GPUTextureFormat", "'format' member of GPUTextureDescriptor",
                                                                         &index)) {
        return false;
      }
      MOZ_ASSERT(index >= 0);
      mFormat = static_cast<GPUTextureFormat>(index);
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'format' member of GPUTextureDescriptor");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->mipLevelCount_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'mipLevelCount' member of GPUTextureDescriptor", &mMipLevelCount)) {
      return false;
    }
  } else {
    mMipLevelCount = 1U;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->sampleCount_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'sampleCount' member of GPUTextureDescriptor", &mSampleCount)) {
      return false;
    }
  } else {
    mSampleCount = 1U;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->size_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mSize.Init(cx, temp.ref(), "'size' member of GPUTextureDescriptor", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'size' member of GPUTextureDescriptor");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->usage_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'usage' member of GPUTextureDescriptor", &mUsage)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'usage' member of GPUTextureDescriptor");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->viewFormats_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'viewFormats' member of GPUTextureDescriptor", "sequence");
        return false;
      }
      Sequence<GPUTextureFormat> &arr = mViewFormats;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        GPUTextureFormat* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        GPUTextureFormat& slot = *slotPtr;
        {
          int index;
          if (!binding_detail::FindEnumStringIndex<true>(cx, temp,
                                                                             binding_detail::EnumStrings<GPUTextureFormat>::Values,
                                                                             "GPUTextureFormat", "element of 'viewFormats' member of GPUTextureDescriptor",
                                                                             &index)) {
            return false;
          }
          MOZ_ASSERT(index >= 0);
          slot = static_cast<GPUTextureFormat>(index);
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'viewFormats' member of GPUTextureDescriptor", "sequence");
      return false;
    }
  } else {
    /* mViewFormats array is already empty; nothing to do */
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUTextureDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUTextureDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}

GPUTextureDescriptor&
GPUTextureDescriptor::operator=(const GPUTextureDescriptor& aOther)
{
  GPUObjectDescriptorBase::operator=(aOther);
  mDimension = aOther.mDimension;
  mFormat = aOther.mFormat;
  mMipLevelCount = aOther.mMipLevelCount;
  mSampleCount = aOther.mSampleCount;
  mSize = aOther.mSize;
  mUsage = aOther.mUsage;
  mViewFormats = aOther.mViewFormats;
  return *this;
}



GPUVertexState::GPUVertexState()
  : GPUProgrammableStage(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}



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

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

bool
GPUVertexState::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUVertexStateAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUVertexStateAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUProgrammableStage::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->buffers_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'buffers' member of GPUVertexState", "sequence");
        return false;
      }
      Sequence<Nullable<GPUVertexBufferLayout>> &arr = mBuffers;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        Nullable<GPUVertexBufferLayout>* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        Nullable<GPUVertexBufferLayout>& slot = *slotPtr;
        if (temp.isNullOrUndefined()) {
          slot.SetNull();
        } else {
          if (!slot.SetValue().Init(cx, temp, "Element of 'buffers' member of GPUVertexState", passedToJSImpl)) {
            return false;
          }
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'buffers' member of GPUVertexState", "sequence");
      return false;
    }
  } else {
    /* mBuffers array is already empty; nothing to do */
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUVertexState::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUVertexState::TraceDictionary(JSTracer* trc)
{
  GPUProgrammableStage::TraceDictionary(trc);
}





GPUBindGroupDescriptor::GPUBindGroupDescriptor()
  : GPUObjectDescriptorBase(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

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

bool
GPUBindGroupDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUBindGroupDescriptorAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUBindGroupDescriptorAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->entries_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'entries' member of GPUBindGroupDescriptor", "sequence");
        return false;
      }
      Sequence<GPUBindGroupEntry> &arr = mEntries;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        GPUBindGroupEntry* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        GPUBindGroupEntry& slot = *slotPtr;
        if (!slot.Init(cx, temp, "Element of 'entries' member of GPUBindGroupDescriptor", passedToJSImpl)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'entries' member of GPUBindGroupDescriptor", "sequence");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'entries' member of GPUBindGroupDescriptor");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->layout_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      static_assert(IsRefcounted<mozilla::webgpu::BindGroupLayout>::value, "We can only store refcounted classes.");
      {
        // Our JSContext should be in the right global to do unwrapping in.
        nsresult rv = UnwrapObject<prototypes::id::GPUBindGroupLayout, mozilla::webgpu::BindGroupLayout>(temp.ptr(), mLayout, cx);
        if (NS_FAILED(rv)) {
          cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'layout' member of GPUBindGroupDescriptor", "GPUBindGroupLayout");
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'layout' member of GPUBindGroupDescriptor");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'layout' member of GPUBindGroupDescriptor");
  }
  return true;
}

bool
GPUBindGroupDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUBindGroupDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}



GPUBindGroupDescriptor&
GPUBindGroupDescriptor::operator=(const GPUBindGroupDescriptor& aOther)
{
  GPUObjectDescriptorBase::operator=(aOther);
  mEntries = aOther.mEntries;
  mLayout = aOther.mLayout;
  return *this;
}



GPUCopyExternalImageDestInfo::GPUCopyExternalImageDestInfo()
  : GPUTexelCopyTextureInfo(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

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

bool
GPUCopyExternalImageDestInfo::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUCopyExternalImageDestInfoAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUCopyExternalImageDestInfoAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUTexelCopyTextureInfo::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->premultipliedAlpha_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'premultipliedAlpha' member of GPUCopyExternalImageDestInfo", &mPremultipliedAlpha)) {
      return false;
    }
  } else {
    mPremultipliedAlpha = false;
  }
  mIsAnyMemberPresent = true;
  return true;
}

bool
GPUCopyExternalImageDestInfo::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUCopyExternalImageDestInfo::TraceDictionary(JSTracer* trc)
{
  GPUTexelCopyTextureInfo::TraceDictionary(trc);
}



GPUCopyExternalImageDestInfo&
GPUCopyExternalImageDestInfo::operator=(const GPUCopyExternalImageDestInfo& aOther)
{
  GPUTexelCopyTextureInfo::operator=(aOther);
  mPremultipliedAlpha = aOther.mPremultipliedAlpha;
  return *this;
}



GPUFragmentState::GPUFragmentState()
  : GPUProgrammableStage(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}



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

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

bool
GPUFragmentState::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPUFragmentStateAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPUFragmentStateAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUProgrammableStage::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->targets_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'targets' member of GPUFragmentState", "sequence");
        return false;
      }
      Sequence<GPUColorTargetState> &arr = mTargets;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        GPUColorTargetState* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        GPUColorTargetState& slot = *slotPtr;
        if (!slot.Init(cx, temp, "Element of 'targets' member of GPUFragmentState", passedToJSImpl)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'targets' member of GPUFragmentState", "sequence");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'targets' member of GPUFragmentState");
  }
  return true;
}

bool
GPUFragmentState::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPUFragmentState::TraceDictionary(JSTracer* trc)
{
  GPUProgrammableStage::TraceDictionary(trc);
}





GPURenderPassDescriptor::GPURenderPassDescriptor()
  : GPUObjectDescriptorBase(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}




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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->timestampWrites_id.init(cx, "timestampWrites") ||
      !atomsCache->occlusionQuerySet_id.init(cx, "occlusionQuerySet") ||
      !atomsCache->depthStencilAttachment_id.init(cx, "depthStencilAttachment") ||
      !atomsCache->colorAttachments_id.init(cx, "colorAttachments")) {
    return false;
  }
  return true;
}

bool
GPURenderPassDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPURenderPassDescriptorAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPURenderPassDescriptorAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUObjectDescriptorBase::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->colorAttachments_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (temp.ref().isObject()) {
      JS::ForOfIterator iter(cx);
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
        return false;
      }
      if (!iter.valueIsIterable()) {
        cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'colorAttachments' member of GPURenderPassDescriptor", "sequence");
        return false;
      }
      Sequence<GPURenderPassColorAttachment> &arr = mColorAttachments;
      JS::Rooted<JS::Value> temp(cx);
      while (true) {
        bool done;
        if (!iter.next(&temp, &done)) {
          return false;
        }
        if (done) {
          break;
        }
        GPURenderPassColorAttachment* slotPtr = arr.AppendElement(mozilla::fallible);
        if (!slotPtr) {
          JS_ReportOutOfMemory(cx);
          return false;
        }
        GPURenderPassColorAttachment& slot = *slotPtr;
        if (!slot.Init(cx, temp, "Element of 'colorAttachments' member of GPURenderPassDescriptor", passedToJSImpl)) {
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'colorAttachments' member of GPURenderPassDescriptor", "sequence");
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'colorAttachments' member of GPURenderPassDescriptor");
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->depthStencilAttachment_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mDepthStencilAttachment.Construct();
    if (!(mDepthStencilAttachment.Value()).Init(cx, temp.ref(), "'depthStencilAttachment' member of GPURenderPassDescriptor", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->occlusionQuerySet_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mOcclusionQuerySet.Construct();
    if (temp.ref().isObject()) {
      static_assert(IsRefcounted<mozilla::webgpu::QuerySet>::value, "We can only store refcounted classes.");
      {
        // Our JSContext should be in the right global to do unwrapping in.
        nsresult rv = UnwrapObject<prototypes::id::GPUQuerySet, mozilla::webgpu::QuerySet>(temp.ptr(), (mOcclusionQuerySet.Value()), cx);
        if (NS_FAILED(rv)) {
          cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'occlusionQuerySet' member of GPURenderPassDescriptor", "GPUQuerySet");
          return false;
        }
      }
    } else {
      cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'occlusionQuerySet' member of GPURenderPassDescriptor");
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->timestampWrites_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mTimestampWrites.Construct();
    if (!(mTimestampWrites.Value()).Init(cx, temp.ref(), "'timestampWrites' member of GPURenderPassDescriptor", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }
  return true;
}

bool
GPURenderPassDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPURenderPassDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUObjectDescriptorBase::TraceDictionary(trc);
}



GPURenderPassDescriptor&
GPURenderPassDescriptor::operator=(const GPURenderPassDescriptor& aOther)
{
  GPUObjectDescriptorBase::operator=(aOther);
  mColorAttachments = aOther.mColorAttachments;
  mDepthStencilAttachment.Reset();
  if (aOther.mDepthStencilAttachment.WasPassed()) {
    mDepthStencilAttachment.Construct(aOther.mDepthStencilAttachment.Value());
  }
  mOcclusionQuerySet.Reset();
  if (aOther.mOcclusionQuerySet.WasPassed()) {
    mOcclusionQuerySet.Construct(aOther.mOcclusionQuerySet.Value());
  }
  mTimestampWrites.Reset();
  if (aOther.mTimestampWrites.WasPassed()) {
    mTimestampWrites.Construct(aOther.mTimestampWrites.Value());
  }
  return *this;
}



GPURenderPipelineDescriptor::GPURenderPipelineDescriptor()
  : GPUPipelineDescriptorBase(FastDictionaryInitializer()),
    mMultisample(FastDictionaryInitializer()),
    mPrimitive(FastDictionaryInitializer()),
    mVertex(FastDictionaryInitializer())
{
  // Safe to pass a null context if we pass a null value
  Init(nullptr, JS::NullHandleValue);
}



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

  // Initialize these in reverse order so that any failure leaves the first one
  // uninitialized.
  if (!atomsCache->vertex_id.init(cx, "vertex") ||
      !atomsCache->primitive_id.init(cx, "primitive") ||
      !atomsCache->multisample_id.init(cx, "multisample") ||
      !atomsCache->fragment_id.init(cx, "fragment") ||
      !atomsCache->depthStencil_id.init(cx, "depthStencil")) {
    return false;
  }
  return true;
}

bool
GPURenderPipelineDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // Passing a null JSContext is OK only if we're initing from null,
  // Since in that case we will not have to do any property gets
  // Also evaluate isNullOrUndefined in order to avoid false-positive
  // checkers by static analysis tools
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
  GPURenderPipelineDescriptorAtoms* atomsCache = nullptr;
  if (cx) {
    atomsCache = GetAtomCache<GPURenderPipelineDescriptorAtoms>(cx);
    if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
        !InitIds(cx, atomsCache)) {
      return false;
    }
  }

  // Per spec, we init the parent's members first
  if (!GPUPipelineDescriptorBase::Init(cx, val)) {
    return false;
  }

  bool isNull = val.isNullOrUndefined();
  // We only need these if !isNull, in which case we have |cx|.
  Maybe<JS::Rooted<JSObject *> > object;
  Maybe<JS::Rooted<JS::Value> > temp;
  if (!isNull) {
    MOZ_ASSERT(cx);
    object.emplace(cx, &val.toObject());
    temp.emplace(cx);
  }
  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->depthStencil_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mDepthStencil.Construct();
    if (!(mDepthStencil.Value()).Init(cx, temp.ref(), "'depthStencil' member of GPURenderPipelineDescriptor", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->fragment_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    mFragment.Construct();
    if (!(mFragment.Value()).Init(cx, temp.ref(), "'fragment' member of GPURenderPipelineDescriptor", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  }

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->multisample_id, temp.ptr())) {
      return false;
    }
  }
  if (!mMultisample.Init(cx, (!isNull && !temp->isUndefined()) ? temp.ref() : JS::NullHandleValue, "'multisample' member of GPURenderPipelineDescriptor", passedToJSImpl)) {
    return false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->primitive_id, temp.ptr())) {
      return false;
    }
  }
  if (!mPrimitive.Init(cx, (!isNull && !temp->isUndefined()) ? temp.ref() : JS::NullHandleValue, "'primitive' member of GPURenderPipelineDescriptor", passedToJSImpl)) {
    return false;
  }
  mIsAnyMemberPresent = true;

  if (!isNull) {
    if (!JS_GetPropertyById(cx, *object, atomsCache->vertex_id, temp.ptr())) {
      return false;
    }
  }
  if (!isNull && !temp->isUndefined()) {
    if (!mVertex.Init(cx, temp.ref(), "'vertex' member of GPURenderPipelineDescriptor", passedToJSImpl)) {
      return false;
    }
    mIsAnyMemberPresent = true;
  } else if (cx) {
    // Don't error out if we have no cx.  In that
    // situation the caller is default-constructing us and we'll
    // just assume they know what they're doing.
    return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'vertex' member of GPURenderPipelineDescriptor");
  }
  return true;
}

bool
GPURenderPipelineDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
  // We don't want to use sourceDescription for our context here;
  // that's not really what it's formatted for.
  BindingCallContext cx(cx_, nullptr);
  return Init(cx, val, sourceDescription, passedToJSImpl);
}

void
GPURenderPipelineDescriptor::TraceDictionary(JSTracer* trc)
{
  GPUPipelineDescriptorBase::TraceDictionary(trc);
}




namespace GPU_Binding {

MOZ_CAN_RUN_SCRIPT static bool
requestAdapter(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPU.requestAdapter");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPU", "requestAdapter", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Instance*>(void_self);
  binding_detail::FastGPURequestAdapterOptions arg0;
  if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
    return false;
  }
  FastErrorResult rv;
  auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->RequestAdapter(Constify(arg0), rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPU.requestAdapter"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
requestAdapter_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  bool ok = requestAdapter(cx, obj, void_self, args);
  if (ok) {
    return true;
  }
  return ConvertExceptionToPromise(cx, args.rval());
}

static const JSJitInfo requestAdapter_methodinfo = {
  { (JSJitGetterOp)requestAdapter_promiseWrapper },
  { prototypes::id::GPU },
  { PrototypeTraits<prototypes::id::GPU>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
getPreferredCanvasFormat(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPU", "getPreferredCanvasFormat", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Instance*>(void_self);
  GPUTextureFormat result(MOZ_KnownLive(self)->GetPreferredCanvasFormat());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo getPreferredCanvasFormat_methodinfo = {
  { (JSJitGetterOp)getPreferredCanvasFormat },
  { prototypes::id::GPU },
  { PrototypeTraits<prototypes::id::GPU>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_wgslLanguageFeatures(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPU", "wgslLanguageFeatures", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Instance*>(void_self);
  auto result(StrongOrRawPtr<mozilla::webgpu::WGSLLanguageFeatures>(MOZ_KnownLive(self)->WgslLanguageFeatures()));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo wgslLanguageFeatures_getterinfo = {
  { get_wgslLanguageFeatures },
  { prototypes::id::GPU },
  { PrototypeTraits<prototypes::id::GPU>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  true,  /* isMovable.  Not relevant for setters. */
  true, /* 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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::Instance* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Instance>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::Instance>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("requestAdapter", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&requestAdapter_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("getPreferredCanvasFormat", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getPreferredCanvasFormat_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};

static const PrefableDisablers sMethods_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSFunctionSpec> sMethods[] = {
  { &sMethods_disablers0, &sMethods_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(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("wgslLanguageFeatures", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &wgslLanguageFeatures_getterinfo, nullptr, nullptr),
  JS_PS_END
};

static const PrefableDisablers sAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSPropertySpec> sAttributes[] = {
  { &sAttributes_disablers0, &sAttributes_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(1 <= 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[3];
static PropertyInfo sNativeProperties_propertyInfos[3];

static const NativePropertiesN<2> sNativeProperties = {
  false, 0,
  false, 0,
  true,  0 /* sMethods */,
  true,  1 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  3,
  sNativeProperties_sortedPropertyIndices,
  {
    { sMethods, &sNativeProperties_propertyInfos[0] },
    { sAttributes, &sNativeProperties_propertyInfos[2] }
  }
};
static_assert(3 < 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::GPU,
  constructors::id::GPU,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPU>::Depth,
  prototypes::id::GPU,
  true,
  0,
  "GPU",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUPrototype",
    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,
  prototypes::id::GPU,
  PrototypeTraits<prototypes::id::GPU>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPU",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::Instance>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPU, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::Instance>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::Instance>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::Instance>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::Instance>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::Instance* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::Instance>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::Instance*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::Instance> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPU);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPU);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPU",
                              ShouldExpose<GPU_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPU,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPU,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPU_Binding



namespace GPUAdapter_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_features(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapter", "features", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Adapter*>(void_self);
  auto result(StrongOrRawPtr<mozilla::webgpu::SupportedFeatures>(MOZ_KnownLive(self)->Features()));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo features_getterinfo = {
  { get_features },
  { prototypes::id::GPUAdapter },
  { PrototypeTraits<prototypes::id::GPUAdapter>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  true,  /* isMovable.  Not relevant for setters. */
  true, /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_limits(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapter", "limits", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Adapter*>(void_self);
  auto result(StrongOrRawPtr<mozilla::webgpu::SupportedLimits>(MOZ_KnownLive(self)->Limits()));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo limits_getterinfo = {
  { get_limits },
  { prototypes::id::GPUAdapter },
  { PrototypeTraits<prototypes::id::GPUAdapter>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  true,  /* isMovable.  Not relevant for setters. */
  true, /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_info(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapter", "info", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Adapter*>(void_self);
  auto result(StrongOrRawPtr<mozilla::webgpu::AdapterInfo>(MOZ_KnownLive(self)->Info()));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo info_getterinfo = {
  { get_info },
  { prototypes::id::GPUAdapter },
  { PrototypeTraits<prototypes::id::GPUAdapter>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  true,  /* isMovable.  Not relevant for setters. */
  true, /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
requestDevice(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUAdapter.requestDevice");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapter", "requestDevice", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Adapter*>(void_self);
  binding_detail::FastGPUDeviceDescriptor arg0;
  if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
    return false;
  }
  FastErrorResult rv;
  auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->RequestDevice(Constify(arg0), rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUAdapter.requestDevice"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
requestDevice_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  bool ok = requestDevice(cx, obj, void_self, args);
  if (ok) {
    return true;
  }
  return ConvertExceptionToPromise(cx, args.rval());
}

static const JSJitInfo requestDevice_methodinfo = {
  { (JSJitGetterOp)requestDevice_promiseWrapper },
  { prototypes::id::GPUAdapter },
  { PrototypeTraits<prototypes::id::GPUAdapter>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_missingFeatures(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapter", "missingFeatures", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Adapter*>(void_self);
  uint64_t result(MOZ_KnownLive(self)->MissingFeatures());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().set(JS_NumberValue(double(result)));
  return true;
}

static const JSJitInfo missingFeatures_getterinfo = {
  { get_missingFeatures },
  { prototypes::id::GPUAdapter },
  { PrototypeTraits<prototypes::id::GPUAdapter>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::Adapter* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Adapter>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::Adapter>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("requestDevice", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&requestDevice_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};

static const PrefableDisablers sMethods_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSFunctionSpec> sMethods[] = {
  { &sMethods_disablers0, &sMethods_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(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("features", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &features_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("limits", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &limits_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("info", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &info_getterinfo, nullptr, nullptr),
  JS_PS_END,
  JSPropertySpec::nativeAccessors("missingFeatures", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &missingFeatures_getterinfo, nullptr, nullptr),
  JS_PS_END
};

static const PrefableDisablers sAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const PrefableDisablers sAttributes_disablers4 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), &nsRFPService::IsSystemPrincipalOrAboutFingerprintingProtection
};

static const Prefable<const JSPropertySpec> sAttributes[] = {
  { &sAttributes_disablers0, &sAttributes_specs[0] },
  { &sAttributes_disablers4, &sAttributes_specs[4] },
  { nullptr, nullptr }
};

static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(3 <= 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[5];
static PropertyInfo sNativeProperties_propertyInfos[5];

static const NativePropertiesN<2> sNativeProperties = {
  false, 0,
  false, 0,
  true,  0 /* sMethods */,
  true,  1 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  5,
  sNativeProperties_sortedPropertyIndices,
  {
    { sMethods, &sNativeProperties_propertyInfos[0] },
    { sAttributes, &sNativeProperties_propertyInfos[1] }
  }
};
static_assert(5 < 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::GPUAdapter,
  constructors::id::GPUAdapter,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUAdapter>::Depth,
  prototypes::id::GPUAdapter,
  true,
  0,
  "GPUAdapter",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUAdapterPrototype",
    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,
  prototypes::id::GPUAdapter,
  PrototypeTraits<prototypes::id::GPUAdapter>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUAdapter",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::Adapter>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUAdapter, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::Adapter>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::Adapter>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::Adapter>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::Adapter>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::Adapter* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::Adapter>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::Adapter*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::Adapter> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUAdapter);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUAdapter);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUAdapter",
                              ShouldExpose<GPUAdapter_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUAdapter,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUAdapter,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUAdapter_Binding



namespace GPUAdapterInfo_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_vendor(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapterInfo", "vendor", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetVendor(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetVendor(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo vendor_getterinfo = {
  { get_vendor },
  { prototypes::id::GPUAdapterInfo },
  { PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_architecture(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapterInfo", "architecture", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetArchitecture(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetArchitecture(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo architecture_getterinfo = {
  { get_architecture },
  { prototypes::id::GPUAdapterInfo },
  { PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_device(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapterInfo", "device", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetDevice(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetDevice(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo device_getterinfo = {
  { get_device },
  { prototypes::id::GPUAdapterInfo },
  { PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_description(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapterInfo", "description", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetDescription(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetDescription(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo description_getterinfo = {
  { get_description },
  { prototypes::id::GPUAdapterInfo },
  { PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_subgroupMinSize(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapterInfo", "subgroupMinSize", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->SubgroupMinSize());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo subgroupMinSize_getterinfo = {
  { get_subgroupMinSize },
  { prototypes::id::GPUAdapterInfo },
  { PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_subgroupMaxSize(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapterInfo", "subgroupMaxSize", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->SubgroupMaxSize());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo subgroupMaxSize_getterinfo = {
  { get_subgroupMaxSize },
  { prototypes::id::GPUAdapterInfo },
  { PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_isFallbackAdapter(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapterInfo", "isFallbackAdapter", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
  bool result(MOZ_KnownLive(self)->IsFallbackAdapter());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setBoolean(result);
  return true;
}

static const JSJitInfo isFallbackAdapter_getterinfo = {
  { get_isFallbackAdapter },
  { prototypes::id::GPUAdapterInfo },
  { PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_wgpuName(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapterInfo", "wgpuName", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetWgpuName(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetWgpuName(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo wgpuName_getterinfo = {
  { get_wgpuName },
  { prototypes::id::GPUAdapterInfo },
  { PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_wgpuVendor(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapterInfo", "wgpuVendor", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->WgpuVendor());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo wgpuVendor_getterinfo = {
  { get_wgpuVendor },
  { prototypes::id::GPUAdapterInfo },
  { PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_wgpuDevice(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapterInfo", "wgpuDevice", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->WgpuDevice());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo wgpuDevice_getterinfo = {
  { get_wgpuDevice },
  { prototypes::id::GPUAdapterInfo },
  { PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_wgpuDeviceType(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapterInfo", "wgpuDeviceType", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetWgpuDeviceType(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetWgpuDeviceType(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo wgpuDeviceType_getterinfo = {
  { get_wgpuDeviceType },
  { prototypes::id::GPUAdapterInfo },
  { PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_wgpuDriver(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapterInfo", "wgpuDriver", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetWgpuDriver(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetWgpuDriver(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo wgpuDriver_getterinfo = {
  { get_wgpuDriver },
  { prototypes::id::GPUAdapterInfo },
  { PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_wgpuDriverInfo(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapterInfo", "wgpuDriverInfo", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetWgpuDriverInfo(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetWgpuDriverInfo(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo wgpuDriverInfo_getterinfo = {
  { get_wgpuDriverInfo },
  { prototypes::id::GPUAdapterInfo },
  { PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_wgpuBackend(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUAdapterInfo", "wgpuBackend", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetWgpuBackend(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetWgpuBackend(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo wgpuBackend_getterinfo = {
  { get_wgpuBackend },
  { prototypes::id::GPUAdapterInfo },
  { PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::AdapterInfo* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::AdapterInfo>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::AdapterInfo>(self);
  }
}

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("vendor", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &vendor_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("architecture", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &architecture_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("device", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &device_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("description", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &description_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("subgroupMinSize", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &subgroupMinSize_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("subgroupMaxSize", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &subgroupMaxSize_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("isFallbackAdapter", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &isFallbackAdapter_getterinfo, nullptr, nullptr),
  JS_PS_END
};

static const PrefableDisablers sAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSPropertySpec> sAttributes[] = {
  { &sAttributes_disablers0, &sAttributes_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(7 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");

MOZ_GLOBINIT static const JSPropertySpec sChromeAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("wgpuName", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &wgpuName_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("wgpuVendor", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &wgpuVendor_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("wgpuDevice", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &wgpuDevice_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("wgpuDeviceType", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &wgpuDeviceType_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("wgpuDriver", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &wgpuDriver_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("wgpuDriverInfo", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &wgpuDriverInfo_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("wgpuBackend", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &wgpuBackend_getterinfo, nullptr, nullptr),
  JS_PS_END
};

static const PrefableDisablers sChromeAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSPropertySpec> sChromeAttributes[] = {
  { &sChromeAttributes_disablers0, &sChromeAttributes_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(7 <= 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[7];
static PropertyInfo sNativeProperties_propertyInfos[7];

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

static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[7];
static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[7];

static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sChromeAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  7,
  sChromeOnlyNativeProperties_sortedPropertyIndices,
  {
    { sChromeAttributes, &sChromeOnlyNativeProperties_propertyInfos[0] }
  }
};
static_assert(7 < 1ull << (CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount)),
    "We have a property info count that is oversized");

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

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth,
  prototypes::id::GPUAdapterInfo,
  true,
  0,
  "GPUAdapterInfo",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUAdapterInfoPrototype",
    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,
  prototypes::id::GPUAdapterInfo,
  PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUAdapterInfo",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::AdapterInfo>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUAdapterInfo, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::AdapterInfo>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::AdapterInfo>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::AdapterInfo>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::AdapterInfo>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::AdapterInfo* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::AdapterInfo>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::AdapterInfo*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::AdapterInfo> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUAdapterInfo);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUAdapterInfo);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              sChromeOnlyNativeProperties.Upcast(),
                              "GPUAdapterInfo",
                              ShouldExpose<GPUAdapterInfo_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUAdapterInfo,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUAdapterInfo,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUAdapterInfo_Binding



namespace GPUBindGroup_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUBindGroup", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::BindGroup*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUBindGroup", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::BindGroup*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPUBindGroup },
  { PrototypeTraits<prototypes::id::GPUBindGroup>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPUBindGroup },
  { PrototypeTraits<prototypes::id::GPUBindGroup>::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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::BindGroup* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::BindGroup>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::BindGroup>(self);
  }
}

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};


static const Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_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(1 <= 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[1];
static PropertyInfo sNativeProperties_propertyInfos[1];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  1,
  sNativeProperties_sortedPropertyIndices,
  {
    { sAttributes, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(1 < 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::GPUBindGroup,
  constructors::id::GPUBindGroup,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUBindGroup>::Depth,
  prototypes::id::GPUBindGroup,
  true,
  0,
  "GPUBindGroup",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUBindGroupPrototype",
    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,
  prototypes::id::GPUBindGroup,
  PrototypeTraits<prototypes::id::GPUBindGroup>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUBindGroup",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::BindGroup>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUBindGroup, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::BindGroup>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::BindGroup>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::BindGroup>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::BindGroup>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::BindGroup* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::BindGroup>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::BindGroup*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::BindGroup> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUBindGroup);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUBindGroup);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUBindGroup",
                              ShouldExpose<GPUBindGroup_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUBindGroup,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUBindGroup,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUBindGroup_Binding



namespace GPUBindGroupLayout_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUBindGroupLayout", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::BindGroupLayout*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUBindGroupLayout", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::BindGroupLayout*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPUBindGroupLayout },
  { PrototypeTraits<prototypes::id::GPUBindGroupLayout>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPUBindGroupLayout },
  { PrototypeTraits<prototypes::id::GPUBindGroupLayout>::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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::BindGroupLayout* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::BindGroupLayout>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::BindGroupLayout>(self);
  }
}

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};


static const Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_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(1 <= 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[1];
static PropertyInfo sNativeProperties_propertyInfos[1];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  1,
  sNativeProperties_sortedPropertyIndices,
  {
    { sAttributes, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(1 < 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::GPUBindGroupLayout,
  constructors::id::GPUBindGroupLayout,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUBindGroupLayout>::Depth,
  prototypes::id::GPUBindGroupLayout,
  true,
  0,
  "GPUBindGroupLayout",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUBindGroupLayoutPrototype",
    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,
  prototypes::id::GPUBindGroupLayout,
  PrototypeTraits<prototypes::id::GPUBindGroupLayout>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUBindGroupLayout",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::BindGroupLayout>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUBindGroupLayout, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::BindGroupLayout>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::BindGroupLayout>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::BindGroupLayout>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::BindGroupLayout>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::BindGroupLayout* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::BindGroupLayout>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::BindGroupLayout*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::BindGroupLayout> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUBindGroupLayout);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUBindGroupLayout);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUBindGroupLayout",
                              ShouldExpose<GPUBindGroupLayout_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUBindGroupLayout,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUBindGroupLayout,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUBindGroupLayout_Binding



namespace GPUBuffer_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_size(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUBuffer", "size", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Buffer*>(void_self);
  uint64_t result(MOZ_KnownLive(self)->Size());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().set(JS_NumberValue(double(result)));
  return true;
}

static const JSJitInfo size_getterinfo = {
  { get_size },
  { prototypes::id::GPUBuffer },
  { PrototypeTraits<prototypes::id::GPUBuffer>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_usage(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUBuffer", "usage", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Buffer*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->Usage());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo usage_getterinfo = {
  { get_usage },
  { prototypes::id::GPUBuffer },
  { PrototypeTraits<prototypes::id::GPUBuffer>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_mapState(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUBuffer", "mapState", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Buffer*>(void_self);
  GPUBufferMapState result(MOZ_KnownLive(self)->MapState());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo mapState_getterinfo = {
  { get_mapState },
  { prototypes::id::GPUBuffer },
  { PrototypeTraits<prototypes::id::GPUBuffer>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
mapAsync(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUBuffer.mapAsync");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUBuffer", "mapAsync", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Buffer*>(void_self);
  if (!args.requireAtLeast(cx, "GPUBuffer.mapAsync", 1)) {
    return false;
  }
  uint32_t arg0;
  if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
    return false;
  }
  uint64_t arg1;
  if (args.hasDefined(1)) {
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
      return false;
    }
  } else {
    arg1 = 0ULL;
  }
  Optional<uint64_t> arg2;
  if (args.hasDefined(2)) {
    arg2.Construct();
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2.Value())) {
      return false;
    }
  }
  FastErrorResult rv;
  auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->MapAsync(arg0, arg1, Constify(arg2), rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUBuffer.mapAsync"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
mapAsync_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  bool ok = mapAsync(cx, obj, void_self, args);
  if (ok) {
    return true;
  }
  return ConvertExceptionToPromise(cx, args.rval());
}

static const JSJitInfo mapAsync_methodinfo = {
  { (JSJitGetterOp)mapAsync_promiseWrapper },
  { prototypes::id::GPUBuffer },
  { PrototypeTraits<prototypes::id::GPUBuffer>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
getMappedRange(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUBuffer.getMappedRange");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUBuffer", "getMappedRange", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Buffer*>(void_self);
  uint64_t arg0;
  if (args.hasDefined(0)) {
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
      return false;
    }
  } else {
    arg0 = 0ULL;
  }
  Optional<uint64_t> arg1;
  if (args.hasDefined(1)) {
    arg1.Construct();
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1.Value())) {
      return false;
    }
  }
  FastErrorResult rv;
  JS::Rooted<JSObject*> result(cx);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetMappedRange(cx, arg0, Constify(arg1), &result, rv))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetMappedRange(cx, arg0, Constify(arg1), &result, rv);
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUBuffer.getMappedRange"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  JS::ExposeObjectToActiveJS(result);
  args.rval().setObject(*result);
  if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo getMappedRange_methodinfo = {
  { (JSJitGetterOp)getMappedRange },
  { prototypes::id::GPUBuffer },
  { PrototypeTraits<prototypes::id::GPUBuffer>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
unmap(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUBuffer", "unmap", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Buffer*>(void_self);
  FastErrorResult rv;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Unmap(cx, rv))>, "Should be returning void here");
  MOZ_KnownLive(self)->Unmap(cx, rv);
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUBuffer.unmap"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo unmap_methodinfo = {
  { (JSJitGetterOp)unmap },
  { prototypes::id::GPUBuffer },
  { PrototypeTraits<prototypes::id::GPUBuffer>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
destroy(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUBuffer", "destroy", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Buffer*>(void_self);
  FastErrorResult rv;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Destroy(cx, rv))>, "Should be returning void here");
  MOZ_KnownLive(self)->Destroy(cx, rv);
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUBuffer.destroy"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo destroy_methodinfo = {
  { (JSJitGetterOp)destroy },
  { prototypes::id::GPUBuffer },
  { PrototypeTraits<prototypes::id::GPUBuffer>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUBuffer", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Buffer*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUBuffer", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Buffer*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPUBuffer },
  { PrototypeTraits<prototypes::id::GPUBuffer>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPUBuffer },
  { PrototypeTraits<prototypes::id::GPUBuffer>::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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::Buffer* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Buffer>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::Buffer>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("mapAsync", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&mapAsync_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("getMappedRange", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getMappedRange_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("unmap", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&unmap_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("destroy", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&destroy_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};

static const PrefableDisablers sMethods_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSFunctionSpec> sMethods[] = {
  { &sMethods_disablers0, &sMethods_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(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("size", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &size_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("usage", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &usage_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("mapState", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &mapState_getterinfo, nullptr, nullptr),
  JS_PS_END,
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};

static const PrefableDisablers sAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSPropertySpec> sAttributes[] = {
  { &sAttributes_disablers0, &sAttributes_specs[0] },
  { nullptr, &sAttributes_specs[4] },
  { nullptr, nullptr }
};

static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(3 <= 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[8];
static PropertyInfo sNativeProperties_propertyInfos[8];

static const NativePropertiesN<2> sNativeProperties = {
  false, 0,
  false, 0,
  true,  0 /* sMethods */,
  true,  1 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  8,
  sNativeProperties_sortedPropertyIndices,
  {
    { sMethods, &sNativeProperties_propertyInfos[0] },
    { sAttributes, &sNativeProperties_propertyInfos[4] }
  }
};
static_assert(8 < 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::GPUBuffer,
  constructors::id::GPUBuffer,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUBuffer>::Depth,
  prototypes::id::GPUBuffer,
  true,
  0,
  "GPUBuffer",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUBufferPrototype",
    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,
  prototypes::id::GPUBuffer,
  PrototypeTraits<prototypes::id::GPUBuffer>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUBuffer",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::Buffer>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUBuffer, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::Buffer>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::Buffer>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::Buffer>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::Buffer>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::Buffer* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::Buffer>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::Buffer*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::Buffer> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUBuffer);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUBuffer);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUBuffer",
                              ShouldExpose<GPUBuffer_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUBuffer,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUBuffer,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUBuffer_Binding



namespace GPUBufferUsage_Binding {

MOZ_GLOBINIT static const ConstantSpec sConstants_specs[] = {
  { "MAP_READ", JS::NumberValue(1U) },
  { "MAP_WRITE", JS::NumberValue(2U) },
  { "COPY_SRC", JS::NumberValue(4U) },
  { "COPY_DST", JS::NumberValue(8U) },
  { "INDEX", JS::NumberValue(16U) },
  { "VERTEX", JS::NumberValue(32U) },
  { "UNIFORM", JS::NumberValue(64U) },
  { "STORAGE", JS::NumberValue(128U) },
  { "INDIRECT", JS::NumberValue(256U) },
  { "QUERY_RESOLVE", JS::NumberValue(512U) },
  { 0, JS::UndefinedValue() }
};

static const PrefableDisablers sConstants_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const ConstantSpec> sConstants[] = {
  { &sConstants_disablers0, &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(10 <= 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[10];
static PropertyInfo sNativeProperties_propertyInfos[10];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sConstants */,
  -1,
  10,
  sNativeProperties_sortedPropertyIndices,
  {
    { sConstants, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(10 < 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::GPUBufferUsage,
  &DefaultXrayExpandoObjectClass
};

static const DOMIfaceAndProtoJSClass sNamespaceObjectClass = {
  {
    "GPUBufferUsage",
    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 mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

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::GPUBufferUsage);
  dom::CreateNamespaceObject(aCx, aGlobal, constructorProto,
                             sNamespaceObjectClass,
                             interfaceCache,
                             sNativeProperties.Upcast(),
                             nullptr,
                             "GPUBufferUsage",
                             ShouldExpose<GPUBufferUsage_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::GPUBufferUsage,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUBufferUsage_Binding



namespace GPUCanvasContext_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_canvas(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCanvasContext", "canvas", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CanvasContext*>(void_self);
  OwningHTMLCanvasElementOrOffscreenCanvas result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetCanvas(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetCanvas(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!result.ToJSVal(cx, obj, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo canvas_getterinfo = {
  { get_canvas },
  { prototypes::id::GPUCanvasContext },
  { PrototypeTraits<prototypes::id::GPUCanvasContext>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
configure(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUCanvasContext.configure");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCanvasContext", "configure", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CanvasContext*>(void_self);
  if (!args.requireAtLeast(cx, "GPUCanvasContext.configure", 1)) {
    return false;
  }
  binding_detail::FastGPUCanvasConfiguration arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  FastErrorResult rv;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Configure(Constify(arg0), rv))>, "Should be returning void here");
  MOZ_KnownLive(self)->Configure(Constify(arg0), rv);
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUCanvasContext.configure"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo configure_methodinfo = {
  { (JSJitGetterOp)configure },
  { prototypes::id::GPUCanvasContext },
  { PrototypeTraits<prototypes::id::GPUCanvasContext>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
unconfigure(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCanvasContext", "unconfigure", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CanvasContext*>(void_self);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Unconfigure())>, "Should be returning void here");
  MOZ_KnownLive(self)->Unconfigure();
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo unconfigure_methodinfo = {
  { (JSJitGetterOp)unconfigure },
  { prototypes::id::GPUCanvasContext },
  { PrototypeTraits<prototypes::id::GPUCanvasContext>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
getConfiguration(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCanvasContext", "getConfiguration", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CanvasContext*>(void_self);
  Nullable<GPUCanvasConfiguration> result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetConfiguration(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetConfiguration(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (result.IsNull()) {
    args.rval().setNull();
    return true;
  }
  if (!result.Value().ToObjectInternal(cx, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo getConfiguration_methodinfo = {
  { (JSJitGetterOp)getConfiguration },
  { prototypes::id::GPUCanvasContext },
  { PrototypeTraits<prototypes::id::GPUCanvasContext>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
getCurrentTexture(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCanvasContext", "getCurrentTexture", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CanvasContext*>(void_self);
  FastErrorResult rv;
  auto result(StrongOrRawPtr<mozilla::webgpu::Texture>(MOZ_KnownLive(self)->GetCurrentTexture(rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUCanvasContext.getCurrentTexture"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo getCurrentTexture_methodinfo = {
  { (JSJitGetterOp)getCurrentTexture },
  { prototypes::id::GPUCanvasContext },
  { PrototypeTraits<prototypes::id::GPUCanvasContext>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::CanvasContext* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CanvasContext>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::CanvasContext>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("configure", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&configure_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("unconfigure", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&unconfigure_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("getConfiguration", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getConfiguration_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("getCurrentTexture", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getCurrentTexture_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};

static const PrefableDisablers sMethods_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSFunctionSpec> sMethods[] = {
  { &sMethods_disablers0, &sMethods_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(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("canvas", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &canvas_getterinfo, nullptr, nullptr),
  JS_PS_END
};

static const PrefableDisablers sAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSPropertySpec> sAttributes[] = {
  { &sAttributes_disablers0, &sAttributes_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(1 <= 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[5];
static PropertyInfo sNativeProperties_propertyInfos[5];

static const NativePropertiesN<2> sNativeProperties = {
  false, 0,
  false, 0,
  true,  0 /* sMethods */,
  true,  1 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  5,
  sNativeProperties_sortedPropertyIndices,
  {
    { sMethods, &sNativeProperties_propertyInfos[0] },
    { sAttributes, &sNativeProperties_propertyInfos[4] }
  }
};
static_assert(5 < 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::GPUCanvasContext,
  constructors::id::GPUCanvasContext,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUCanvasContext>::Depth,
  prototypes::id::GPUCanvasContext,
  true,
  0,
  "GPUCanvasContext",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUCanvasContextPrototype",
    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,
  prototypes::id::GPUCanvasContext,
  PrototypeTraits<prototypes::id::GPUCanvasContext>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUCanvasContext",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::CanvasContext>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUCanvasContext, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::CanvasContext>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::CanvasContext>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::CanvasContext>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::CanvasContext>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::CanvasContext* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::CanvasContext>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::CanvasContext*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::CanvasContext> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUCanvasContext);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUCanvasContext);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUCanvasContext",
                              ShouldExpose<GPUCanvasContext_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUCanvasContext,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUCanvasContext,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUCanvasContext_Binding



namespace GPUColorWrite_Binding {

MOZ_GLOBINIT static const ConstantSpec sConstants_specs[] = {
  { "RED", JS::NumberValue(1U) },
  { "GREEN", JS::NumberValue(2U) },
  { "BLUE", JS::NumberValue(4U) },
  { "ALPHA", JS::NumberValue(8U) },
  { "ALL", JS::NumberValue(15U) },
  { 0, JS::UndefinedValue() }
};

static const PrefableDisablers sConstants_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const ConstantSpec> sConstants[] = {
  { &sConstants_disablers0, &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(5 <= 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[5];
static PropertyInfo sNativeProperties_propertyInfos[5];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sConstants */,
  -1,
  5,
  sNativeProperties_sortedPropertyIndices,
  {
    { sConstants, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(5 < 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::GPUColorWrite,
  &DefaultXrayExpandoObjectClass
};

static const DOMIfaceAndProtoJSClass sNamespaceObjectClass = {
  {
    "GPUColorWrite",
    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 mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

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::GPUColorWrite);
  dom::CreateNamespaceObject(aCx, aGlobal, constructorProto,
                             sNamespaceObjectClass,
                             interfaceCache,
                             sNativeProperties.Upcast(),
                             nullptr,
                             "GPUColorWrite",
                             ShouldExpose<GPUColorWrite_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::GPUColorWrite,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUColorWrite_Binding



namespace GPUCommandBuffer_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCommandBuffer", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CommandBuffer*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCommandBuffer", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CommandBuffer*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPUCommandBuffer },
  { PrototypeTraits<prototypes::id::GPUCommandBuffer>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPUCommandBuffer },
  { PrototypeTraits<prototypes::id::GPUCommandBuffer>::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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::CommandBuffer* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CommandBuffer>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::CommandBuffer>(self);
  }
}

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};


static const Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_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(1 <= 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[1];
static PropertyInfo sNativeProperties_propertyInfos[1];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  1,
  sNativeProperties_sortedPropertyIndices,
  {
    { sAttributes, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(1 < 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::GPUCommandBuffer,
  constructors::id::GPUCommandBuffer,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUCommandBuffer>::Depth,
  prototypes::id::GPUCommandBuffer,
  true,
  0,
  "GPUCommandBuffer",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUCommandBufferPrototype",
    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,
  prototypes::id::GPUCommandBuffer,
  PrototypeTraits<prototypes::id::GPUCommandBuffer>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUCommandBuffer",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::CommandBuffer>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUCommandBuffer, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::CommandBuffer>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::CommandBuffer>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::CommandBuffer>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::CommandBuffer>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::CommandBuffer* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::CommandBuffer>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::CommandBuffer*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::CommandBuffer> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUCommandBuffer);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUCommandBuffer);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUCommandBuffer",
                              ShouldExpose<GPUCommandBuffer_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUCommandBuffer,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUCommandBuffer,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUCommandBuffer_Binding



namespace GPUCommandEncoder_Binding {

MOZ_CAN_RUN_SCRIPT static bool
beginRenderPass(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUCommandEncoder.beginRenderPass");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCommandEncoder", "beginRenderPass", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPUCommandEncoder.beginRenderPass", 1)) {
    return false;
  }
  binding_detail::FastGPURenderPassDescriptor arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  auto result(StrongOrRawPtr<mozilla::webgpu::RenderPassEncoder>(MOZ_KnownLive(self)->BeginRenderPass(Constify(arg0))));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo beginRenderPass_methodinfo = {
  { (JSJitGetterOp)beginRenderPass },
  { prototypes::id::GPUCommandEncoder },
  { PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
beginComputePass(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUCommandEncoder.beginComputePass");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCommandEncoder", "beginComputePass", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
  binding_detail::FastGPUComputePassDescriptor arg0;
  if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
    return false;
  }
  auto result(StrongOrRawPtr<mozilla::webgpu::ComputePassEncoder>(MOZ_KnownLive(self)->BeginComputePass(Constify(arg0))));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo beginComputePass_methodinfo = {
  { (JSJitGetterOp)beginComputePass },
  { prototypes::id::GPUCommandEncoder },
  { PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
copyBufferToBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUCommandEncoder.copyBufferToBuffer");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCommandEncoder", "copyBufferToBuffer", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
  unsigned argcount = std::min(args.length(), 5u);
  switch (argcount) {
    case 2: {
      [[fallthrough]];
    }
    case 3: {
      NonNull<mozilla::webgpu::Buffer> arg0;
      if (args[0].isObject()) {
        {
          // Our JSContext should be in the right global to do unwrapping in.
          nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
          if (NS_FAILED(rv)) {
            cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
            return false;
          }
        }
      } else {
        cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
        return false;
      }
      NonNull<mozilla::webgpu::Buffer> arg1;
      if (args[1].isObject()) {
        {
          // Our JSContext should be in the right global to do unwrapping in.
          nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[1], arg1, cx);
          if (NS_FAILED(rv)) {
            cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "GPUBuffer");
            return false;
          }
        }
      } else {
        cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
        return false;
      }
      Optional<uint64_t> arg2;
      if (args.hasDefined(2)) {
        arg2.Construct();
        if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2.Value())) {
          return false;
        }
      }
      // NOTE: This assert does NOT call the function.
      static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->CopyBufferToBuffer(MOZ_KnownLive(NonNullHelper(arg0)), MOZ_KnownLive(NonNullHelper(arg1)), Constify(arg2)))>, "Should be returning void here");
      MOZ_KnownLive(self)->CopyBufferToBuffer(MOZ_KnownLive(NonNullHelper(arg0)), MOZ_KnownLive(NonNullHelper(arg1)), Constify(arg2));
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
      args.rval().setUndefined();
      return true;
      break;
    }
    case 4: {
      [[fallthrough]];
    }
    case 5: {
      NonNull<mozilla::webgpu::Buffer> arg0;
      if (args[0].isObject()) {
        {
          // Our JSContext should be in the right global to do unwrapping in.
          nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
          if (NS_FAILED(rv)) {
            cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
            return false;
          }
        }
      } else {
        cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
        return false;
      }
      uint64_t arg1;
      if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
        return false;
      }
      NonNull<mozilla::webgpu::Buffer> arg2;
      if (args[2].isObject()) {
        {
          // Our JSContext should be in the right global to do unwrapping in.
          nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[2], arg2, cx);
          if (NS_FAILED(rv)) {
            cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 3", "GPUBuffer");
            return false;
          }
        }
      } else {
        cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 3");
        return false;
      }
      uint64_t arg3;
      if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
        return false;
      }
      Optional<uint64_t> arg4;
      if (args.hasDefined(4)) {
        arg4.Construct();
        if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[4], "Argument 5", &arg4.Value())) {
          return false;
        }
      }
      // NOTE: This assert does NOT call the function.
      static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->CopyBufferToBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, MOZ_KnownLive(NonNullHelper(arg2)), arg3, Constify(arg4)))>, "Should be returning void here");
      MOZ_KnownLive(self)->CopyBufferToBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, MOZ_KnownLive(NonNullHelper(arg2)), arg3, Constify(arg4));
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
      args.rval().setUndefined();
      return true;
      break;
    }
    default: {
      // Using nsPrintfCString here would require including that
      // header.  Let's not worry about it.
      nsAutoCString argCountStr;
      argCountStr.AppendPrintf("%u", args.length());
      return cx.ThrowErrorMessage<MSG_INVALID_OVERLOAD_ARGCOUNT>(argCountStr.get());
    }
  }
  MOZ_CRASH("We have an always-returning default case");
  return false;
}

static const JSJitInfo copyBufferToBuffer_methodinfo = {
  { (JSJitGetterOp)copyBufferToBuffer },
  { prototypes::id::GPUCommandEncoder },
  { PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
copyBufferToTexture(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUCommandEncoder.copyBufferToTexture");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCommandEncoder", "copyBufferToTexture", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPUCommandEncoder.copyBufferToTexture", 3)) {
    return false;
  }
  binding_detail::FastGPUTexelCopyBufferInfo arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  binding_detail::FastGPUTexelCopyTextureInfo arg1;
  if (!arg1.Init(cx, args[1], "Argument 2", false)) {
    return false;
  }
  RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict arg2;
  if (!arg2.Init(cx, args[2], "Argument 3", false)) {
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->CopyBufferToTexture(Constify(arg0), Constify(arg1), Constify(arg2)))>, "Should be returning void here");
  MOZ_KnownLive(self)->CopyBufferToTexture(Constify(arg0), Constify(arg1), Constify(arg2));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo copyBufferToTexture_methodinfo = {
  { (JSJitGetterOp)copyBufferToTexture },
  { prototypes::id::GPUCommandEncoder },
  { PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
copyTextureToBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUCommandEncoder.copyTextureToBuffer");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCommandEncoder", "copyTextureToBuffer", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPUCommandEncoder.copyTextureToBuffer", 3)) {
    return false;
  }
  binding_detail::FastGPUTexelCopyTextureInfo arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  binding_detail::FastGPUTexelCopyBufferInfo arg1;
  if (!arg1.Init(cx, args[1], "Argument 2", false)) {
    return false;
  }
  RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict arg2;
  if (!arg2.Init(cx, args[2], "Argument 3", false)) {
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->CopyTextureToBuffer(Constify(arg0), Constify(arg1), Constify(arg2)))>, "Should be returning void here");
  MOZ_KnownLive(self)->CopyTextureToBuffer(Constify(arg0), Constify(arg1), Constify(arg2));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo copyTextureToBuffer_methodinfo = {
  { (JSJitGetterOp)copyTextureToBuffer },
  { prototypes::id::GPUCommandEncoder },
  { PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
copyTextureToTexture(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUCommandEncoder.copyTextureToTexture");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCommandEncoder", "copyTextureToTexture", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPUCommandEncoder.copyTextureToTexture", 3)) {
    return false;
  }
  binding_detail::FastGPUTexelCopyTextureInfo arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  binding_detail::FastGPUTexelCopyTextureInfo arg1;
  if (!arg1.Init(cx, args[1], "Argument 2", false)) {
    return false;
  }
  RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict arg2;
  if (!arg2.Init(cx, args[2], "Argument 3", false)) {
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->CopyTextureToTexture(Constify(arg0), Constify(arg1), Constify(arg2)))>, "Should be returning void here");
  MOZ_KnownLive(self)->CopyTextureToTexture(Constify(arg0), Constify(arg1), Constify(arg2));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo copyTextureToTexture_methodinfo = {
  { (JSJitGetterOp)copyTextureToTexture },
  { prototypes::id::GPUCommandEncoder },
  { PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
clearBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUCommandEncoder.clearBuffer");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCommandEncoder", "clearBuffer", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPUCommandEncoder.clearBuffer", 1)) {
    return false;
  }
  NonNull<mozilla::webgpu::Buffer> arg0;
  if (args[0].isObject()) {
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
      if (NS_FAILED(rv)) {
        cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
        return false;
      }
    }
  } else {
    cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
    return false;
  }
  uint64_t arg1;
  if (args.hasDefined(1)) {
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
      return false;
    }
  } else {
    arg1 = 0ULL;
  }
  Optional<uint64_t> arg2;
  if (args.hasDefined(2)) {
    arg2.Construct();
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2.Value())) {
      return false;
    }
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->ClearBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, Constify(arg2)))>, "Should be returning void here");
  MOZ_KnownLive(self)->ClearBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, Constify(arg2));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo clearBuffer_methodinfo = {
  { (JSJitGetterOp)clearBuffer },
  { prototypes::id::GPUCommandEncoder },
  { PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
resolveQuerySet(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUCommandEncoder.resolveQuerySet");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCommandEncoder", "resolveQuerySet", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPUCommandEncoder.resolveQuerySet", 5)) {
    return false;
  }
  NonNull<mozilla::webgpu::QuerySet> arg0;
  if (args[0].isObject()) {
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUQuerySet, mozilla::webgpu::QuerySet>(args[0], arg0, cx);
      if (NS_FAILED(rv)) {
        cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUQuerySet");
        return false;
      }
    }
  } else {
    cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
    return false;
  }
  uint32_t arg1;
  if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
    return false;
  }
  uint32_t arg2;
  if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
    return false;
  }
  NonNull<mozilla::webgpu::Buffer> arg3;
  if (args[3].isObject()) {
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[3], arg3, cx);
      if (NS_FAILED(rv)) {
        cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 4", "GPUBuffer");
        return false;
      }
    }
  } else {
    cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 4");
    return false;
  }
  uint64_t arg4;
  if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[4], "Argument 5", &arg4)) {
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->ResolveQuerySet(MOZ_KnownLive(NonNullHelper(arg0)), arg1, arg2, MOZ_KnownLive(NonNullHelper(arg3)), arg4))>, "Should be returning void here");
  MOZ_KnownLive(self)->ResolveQuerySet(MOZ_KnownLive(NonNullHelper(arg0)), arg1, arg2, MOZ_KnownLive(NonNullHelper(arg3)), arg4);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo resolveQuerySet_methodinfo = {
  { (JSJitGetterOp)resolveQuerySet },
  { prototypes::id::GPUCommandEncoder },
  { PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
finish(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUCommandEncoder.finish");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCommandEncoder", "finish", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
  binding_detail::FastGPUCommandBufferDescriptor arg0;
  if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
    return false;
  }
  auto result(StrongOrRawPtr<mozilla::webgpu::CommandBuffer>(MOZ_KnownLive(self)->Finish(Constify(arg0))));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo finish_methodinfo = {
  { (JSJitGetterOp)finish },
  { prototypes::id::GPUCommandEncoder },
  { PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
pushDebugGroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCommandEncoder", "pushDebugGroup", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPUCommandEncoder.pushDebugGroup", 1)) {
    return false;
  }
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->PushDebugGroup(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->PushDebugGroup(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo pushDebugGroup_methodinfo = {
  { (JSJitGetterOp)pushDebugGroup },
  { prototypes::id::GPUCommandEncoder },
  { PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
popDebugGroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCommandEncoder", "popDebugGroup", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->PopDebugGroup())>, "Should be returning void here");
  MOZ_KnownLive(self)->PopDebugGroup();
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo popDebugGroup_methodinfo = {
  { (JSJitGetterOp)popDebugGroup },
  { prototypes::id::GPUCommandEncoder },
  { PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
insertDebugMarker(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCommandEncoder", "insertDebugMarker", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPUCommandEncoder.insertDebugMarker", 1)) {
    return false;
  }
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->InsertDebugMarker(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->InsertDebugMarker(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo insertDebugMarker_methodinfo = {
  { (JSJitGetterOp)insertDebugMarker },
  { prototypes::id::GPUCommandEncoder },
  { PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCommandEncoder", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCommandEncoder", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPUCommandEncoder },
  { PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPUCommandEncoder },
  { PrototypeTraits<prototypes::id::GPUCommandEncoder>::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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::CommandEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CommandEncoder>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::CommandEncoder>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("beginRenderPass", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&beginRenderPass_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("beginComputePass", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&beginComputePass_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("copyBufferToBuffer", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&copyBufferToBuffer_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("copyBufferToTexture", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&copyBufferToTexture_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("copyTextureToBuffer", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&copyTextureToBuffer_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("copyTextureToTexture", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&copyTextureToTexture_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("clearBuffer", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&clearBuffer_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("resolveQuerySet", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&resolveQuerySet_methodinfo), 5, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("finish", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&finish_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FS_END,
  JS_FNSPEC("pushDebugGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&pushDebugGroup_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("popDebugGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&popDebugGroup_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("insertDebugMarker", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&insertDebugMarker_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};

static const PrefableDisablers sMethods_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSFunctionSpec> sMethods[] = {
  { &sMethods_disablers0, &sMethods_specs[0] },
  { nullptr, &sMethods_specs[10] },
  { nullptr, nullptr }
};

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

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};


static const Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_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(1 <= 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<2> sNativeProperties = {
  false, 0,
  false, 0,
  true,  0 /* sMethods */,
  true,  1 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  13,
  sNativeProperties_sortedPropertyIndices,
  {
    { sMethods, &sNativeProperties_propertyInfos[0] },
    { sAttributes, &sNativeProperties_propertyInfos[12] }
  }
};
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::GPUCommandEncoder,
  constructors::id::GPUCommandEncoder,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth,
  prototypes::id::GPUCommandEncoder,
  true,
  0,
  "GPUCommandEncoder",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUCommandEncoderPrototype",
    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,
  prototypes::id::GPUCommandEncoder,
  PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUCommandEncoder",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::CommandEncoder>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUCommandEncoder, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::CommandEncoder>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::CommandEncoder>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::CommandEncoder>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::CommandEncoder>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::CommandEncoder* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::CommandEncoder>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::CommandEncoder*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::CommandEncoder> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUCommandEncoder);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUCommandEncoder);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUCommandEncoder",
                              ShouldExpose<GPUCommandEncoder_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUCommandEncoder,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUCommandEncoder,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUCommandEncoder_Binding



namespace GPUCompilationInfo_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_messages(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCompilationInfo", "messages", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CompilationInfo*>(void_self);
  // Have to either root across the getter call or reget after.
  bool isXray;
  JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
  if (!slotStorage) {
    return false;
  }
  const size_t slotIndex = isXray ? (DOM_EXPANDO_RESERVED_SLOTS + 0) : (DOM_INSTANCE_RESERVED_SLOTS + 0);
  MOZ_ASSERT(slotIndex < JSCLASS_RESERVED_SLOTS(JS::GetClass(slotStorage)));
  {
    // Scope for cachedVal
    JS::Value cachedVal = JS::GetReservedSlot(slotStorage, slotIndex);
    if (!cachedVal.isUndefined()) {
      args.rval().set(cachedVal);
      // The cached value is in the compartment of slotStorage,
      // so wrap into the caller compartment as needed.
      return MaybeWrapNonDOMObjectValue(cx, args.rval());
    }
  }

  nsTArray<StrongPtrForMember<mozilla::webgpu::CompilationMessage>> result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetMessages(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetMessages(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  {
    JS::Rooted<JSObject*> conversionScope(cx, isXray ? JS::CurrentGlobalOrNull(cx) : slotStorage);
    JSAutoRealm ar(cx, conversionScope);
    do { // block we break out of when done wrapping

      uint32_t length = result.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 (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) {
              MOZ_ASSERT(JS_IsExceptionPending(cx));
              return false;
            }
            break;
          } while (false);
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
                                JSPROP_ENUMERATE)) {
            return false;
          }
        }
      }
      args.rval().setObject(*returnArray);
      break;
    } while (false);
    JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
    if (!JS_FreezeObject(cx, rvalObj)) {
      return false;
    }
  }
  { // And now store things in the realm of our slotStorage.
    JSAutoRealm ar(cx, slotStorage);
    // Make a copy so that we don't do unnecessary wrapping on args.rval().
    JS::Rooted<JS::Value> storedVal(cx, args.rval());
    if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
      return false;
    }
    JS::SetReservedSlot(slotStorage, slotIndex, storedVal);
    if (!isXray) {
      // In the Xray case we don't need to do this, because getting the
      // expando object already preserved our wrapper.
      PreserveWrapper(self);
    }
  }
  // And now make sure args.rval() is in the caller realm.
  return MaybeWrapNonDOMObjectValue(cx, args.rval());
}

static const JSJitInfo messages_getterinfo = {
  { get_messages },
  { prototypes::id::GPUCompilationInfo },
  { PrototypeTraits<prototypes::id::GPUCompilationInfo>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  true,  /* isMovable.  Not relevant for setters. */
  true, /* isEliminatable.  Not relevant for setters. */
  false, /* isAlwaysInSlot.  Only relevant for getters. */
  true, /* isLazilyCachedInSlot.  Only relevant for getters. */
  false,  /* isTypedMethod.  Only relevant for methods. */
  (DOM_INSTANCE_RESERVED_SLOTS + 0)   /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 2, "There is no slot for us");

static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::CompilationInfo* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CompilationInfo>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::CompilationInfo>(self);
  }
}

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("messages", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &messages_getterinfo, nullptr, nullptr),
  JS_PS_END
};

static const PrefableDisablers sAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSPropertySpec> sAttributes[] = {
  { &sAttributes_disablers0, &sAttributes_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(1 <= 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[1];
static PropertyInfo sNativeProperties_propertyInfos[1];

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

// This may allocate too many slots, because we only really need
// slots for our non-interface-typed members that we cache.  But
// allocating slots only for those would make the slot index
// computations much more complicated, so let's do this the simple
// way for now.
DEFINE_XRAY_EXPANDO_CLASS_WITH_OPS(static, sXrayExpandoObjectClass, 1,
                                   &xpc::XrayExpandoObjectClassOps);

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

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUCompilationInfo>::Depth,
  prototypes::id::GPUCompilationInfo,
  true,
  0,
  "GPUCompilationInfo",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUCompilationInfoPrototype",
    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,
  prototypes::id::GPUCompilationInfo,
  PrototypeTraits<prototypes::id::GPUCompilationInfo>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUCompilationInfo",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::CompilationInfo>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUCompilationInfo, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::CompilationInfo>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::CompilationInfo>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::CompilationInfo>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::CompilationInfo>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(2 >= 2,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::CompilationInfo* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::CompilationInfo>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::CompilationInfo*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::CompilationInfo> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
ClearCachedMessagesValue(mozilla::webgpu::CompilationInfo* aObject)
{
  JSObject* obj;
  obj = aObject->GetWrapper();
  if (!obj) {
    return;
  }
  JS::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), JS::UndefinedValue());
  ClearXrayExpandoSlots(RootingCx(), obj, (DOM_EXPANDO_RESERVED_SLOTS + 0));
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUCompilationInfo);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUCompilationInfo);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUCompilationInfo",
                              ShouldExpose<GPUCompilationInfo_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUCompilationInfo,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUCompilationInfo,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUCompilationInfo_Binding



namespace GPUCompilationMessage_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_message(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCompilationMessage", "message", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CompilationMessage*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetMessage(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetMessage(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo message_getterinfo = {
  { get_message },
  { prototypes::id::GPUCompilationMessage },
  { PrototypeTraits<prototypes::id::GPUCompilationMessage>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_type(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCompilationMessage", "type", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CompilationMessage*>(void_self);
  GPUCompilationMessageType result(MOZ_KnownLive(self)->Type());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo type_getterinfo = {
  { get_type },
  { prototypes::id::GPUCompilationMessage },
  { PrototypeTraits<prototypes::id::GPUCompilationMessage>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_lineNum(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCompilationMessage", "lineNum", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CompilationMessage*>(void_self);
  uint64_t result(MOZ_KnownLive(self)->LineNum());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().set(JS_NumberValue(double(result)));
  return true;
}

static const JSJitInfo lineNum_getterinfo = {
  { get_lineNum },
  { prototypes::id::GPUCompilationMessage },
  { PrototypeTraits<prototypes::id::GPUCompilationMessage>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_linePos(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCompilationMessage", "linePos", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CompilationMessage*>(void_self);
  uint64_t result(MOZ_KnownLive(self)->LinePos());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().set(JS_NumberValue(double(result)));
  return true;
}

static const JSJitInfo linePos_getterinfo = {
  { get_linePos },
  { prototypes::id::GPUCompilationMessage },
  { PrototypeTraits<prototypes::id::GPUCompilationMessage>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_offset(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCompilationMessage", "offset", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CompilationMessage*>(void_self);
  uint64_t result(MOZ_KnownLive(self)->Offset());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().set(JS_NumberValue(double(result)));
  return true;
}

static const JSJitInfo offset_getterinfo = {
  { get_offset },
  { prototypes::id::GPUCompilationMessage },
  { PrototypeTraits<prototypes::id::GPUCompilationMessage>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_length(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUCompilationMessage", "length", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::CompilationMessage*>(void_self);
  uint64_t result(MOZ_KnownLive(self)->Length());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().set(JS_NumberValue(double(result)));
  return true;
}

static const JSJitInfo length_getterinfo = {
  { get_length },
  { prototypes::id::GPUCompilationMessage },
  { PrototypeTraits<prototypes::id::GPUCompilationMessage>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::CompilationMessage* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CompilationMessage>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::CompilationMessage>(self);
  }
}

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("message", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &message_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("type", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &type_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("lineNum", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &lineNum_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("linePos", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &linePos_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("offset", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &offset_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("length", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &length_getterinfo, nullptr, nullptr),
  JS_PS_END
};

static const PrefableDisablers sAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSPropertySpec> sAttributes[] = {
  { &sAttributes_disablers0, &sAttributes_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(6 <= 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[6];
static PropertyInfo sNativeProperties_propertyInfos[6];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  6,
  sNativeProperties_sortedPropertyIndices,
  {
    { sAttributes, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(6 < 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::GPUCompilationMessage,
  constructors::id::GPUCompilationMessage,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUCompilationMessage>::Depth,
  prototypes::id::GPUCompilationMessage,
  true,
  0,
  "GPUCompilationMessage",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUCompilationMessagePrototype",
    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,
  prototypes::id::GPUCompilationMessage,
  PrototypeTraits<prototypes::id::GPUCompilationMessage>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUCompilationMessage",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::CompilationMessage>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUCompilationMessage, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::CompilationMessage>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::CompilationMessage>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::CompilationMessage>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::CompilationMessage>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::CompilationMessage* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::CompilationMessage>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::CompilationMessage*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::CompilationMessage> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUCompilationMessage);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUCompilationMessage);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUCompilationMessage",
                              ShouldExpose<GPUCompilationMessage_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUCompilationMessage,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUCompilationMessage,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUCompilationMessage_Binding



namespace GPUComputePassEncoder_Binding {

MOZ_CAN_RUN_SCRIPT static bool
setPipeline(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUComputePassEncoder.setPipeline");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUComputePassEncoder", "setPipeline", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPUComputePassEncoder.setPipeline", 1)) {
    return false;
  }
  NonNull<mozilla::webgpu::ComputePipeline> arg0;
  if (args[0].isObject()) {
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUComputePipeline, mozilla::webgpu::ComputePipeline>(args[0], arg0, cx);
      if (NS_FAILED(rv)) {
        cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUComputePipeline");
        return false;
      }
    }
  } else {
    cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetPipeline(MOZ_KnownLive(NonNullHelper(arg0))))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetPipeline(MOZ_KnownLive(NonNullHelper(arg0)));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo setPipeline_methodinfo = {
  { (JSJitGetterOp)setPipeline },
  { prototypes::id::GPUComputePassEncoder },
  { PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
dispatchWorkgroups(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUComputePassEncoder.dispatchWorkgroups");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUComputePassEncoder", "dispatchWorkgroups", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPUComputePassEncoder.dispatchWorkgroups", 1)) {
    return false;
  }
  uint32_t arg0;
  if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
    return false;
  }
  uint32_t arg1;
  if (args.hasDefined(1)) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
      return false;
    }
  } else {
    arg1 = 1U;
  }
  uint32_t arg2;
  if (args.hasDefined(2)) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
      return false;
    }
  } else {
    arg2 = 1U;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->DispatchWorkgroups(arg0, arg1, arg2))>, "Should be returning void here");
  MOZ_KnownLive(self)->DispatchWorkgroups(arg0, arg1, arg2);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo dispatchWorkgroups_methodinfo = {
  { (JSJitGetterOp)dispatchWorkgroups },
  { prototypes::id::GPUComputePassEncoder },
  { PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
dispatchWorkgroupsIndirect(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUComputePassEncoder.dispatchWorkgroupsIndirect");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUComputePassEncoder", "dispatchWorkgroupsIndirect", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPUComputePassEncoder.dispatchWorkgroupsIndirect", 2)) {
    return false;
  }
  NonNull<mozilla::webgpu::Buffer> arg0;
  if (args[0].isObject()) {
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
      if (NS_FAILED(rv)) {
        cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
        return false;
      }
    }
  } else {
    cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
    return false;
  }
  uint64_t arg1;
  if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->DispatchWorkgroupsIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1))>, "Should be returning void here");
  MOZ_KnownLive(self)->DispatchWorkgroupsIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo dispatchWorkgroupsIndirect_methodinfo = {
  { (JSJitGetterOp)dispatchWorkgroupsIndirect },
  { prototypes::id::GPUComputePassEncoder },
  { PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
end(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUComputePassEncoder", "end", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->End())>, "Should be returning void here");
  MOZ_KnownLive(self)->End();
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo end_methodinfo = {
  { (JSJitGetterOp)end },
  { prototypes::id::GPUComputePassEncoder },
  { PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
setBindGroup(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUComputePassEncoder.setBindGroup");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUComputePassEncoder", "setBindGroup", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
  unsigned argcount = std::min(args.length(), 5u);
  switch (argcount) {
    case 2: {
      [[fallthrough]];
    }
    case 3: {
      uint32_t arg0;
      if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
        return false;
      }
      mozilla::webgpu::BindGroup* arg1;
      if (args[1].isObject()) {
        {
          // Our JSContext should be in the right global to do unwrapping in.
          nsresult rv = UnwrapObject<prototypes::id::GPUBindGroup, mozilla::webgpu::BindGroup>(args[1], arg1, cx);
          if (NS_FAILED(rv)) {
            cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "GPUBindGroup");
            return false;
          }
        }
      } else if (args[1].isNullOrUndefined()) {
        arg1 = nullptr;
      } else {
        cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
        return false;
      }
      binding_detail::AutoSequence<uint32_t> arg2;
      if (args.hasDefined(2)) {
        if (args[2].isObject()) {
          JS::ForOfIterator iter(cx);
          if (!iter.init(args[2], JS::ForOfIterator::AllowNonIterable)) {
            return false;
          }
          if (!iter.valueIsIterable()) {
            cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 3", "sequence");
            return false;
          }
          binding_detail::AutoSequence<uint32_t> &arr = arg2;
          JS::Rooted<JS::Value> temp(cx);
          while (true) {
            bool done;
            if (!iter.next(&temp, &done)) {
              return false;
            }
            if (done) {
              break;
            }
            uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
            if (!slotPtr) {
              JS_ReportOutOfMemory(cx);
              return false;
            }
            uint32_t& slot = *slotPtr;
            if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp, "Element of argument 3", &slot)) {
              return false;
            }
          }
        } else {
          cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 3", "sequence");
          return false;
        }
      } else {
        /* arg2 array is already empty; nothing to do */
      }
      FastErrorResult rv;
      // NOTE: This assert does NOT call the function.
      static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), rv))>, "Should be returning void here");
      MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), rv);
      if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUComputePassEncoder.setBindGroup"))) {
        return false;
      }
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
      args.rval().setUndefined();
      return true;
      break;
    }
    case 5: {
      uint32_t arg0;
      if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
        return false;
      }
      mozilla::webgpu::BindGroup* arg1;
      if (args[1].isObject()) {
        {
          // Our JSContext should be in the right global to do unwrapping in.
          nsresult rv = UnwrapObject<prototypes::id::GPUBindGroup, mozilla::webgpu::BindGroup>(args[1], arg1, cx);
          if (NS_FAILED(rv)) {
            cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "GPUBindGroup");
            return false;
          }
        }
      } else if (args[1].isNullOrUndefined()) {
        arg1 = nullptr;
      } else {
        cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
        return false;
      }
      RootedSpiderMonkeyInterface<Uint32Array> arg2(cx);
      if (args[2].isObject()) {
        if (!arg2.Init(&args[2].toObject())) {
          cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 3", "Uint32Array");
          return false;
        }
        if (JS::IsLargeArrayBufferView(arg2.Obj())) {
          cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("Argument 3");
          return false;
        }
        if (JS::IsResizableArrayBufferView(arg2.Obj())) {
          cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("Argument 3");
          return false;
        }
        if (JS::IsImmutableArrayBufferView(arg2.Obj())) {
          cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_IMMUTABLE>("Argument 3");
          return false;
        }
      } else {
        cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 3");
        return false;
      }
      uint64_t arg3;
      if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
        return false;
      }
      uint32_t arg4;
      if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[4], "Argument 5", &arg4)) {
        return false;
      }
      FastErrorResult rv;
      // NOTE: This assert does NOT call the function.
      static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), arg3, arg4, rv))>, "Should be returning void here");
      MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), arg3, arg4, rv);
      if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUComputePassEncoder.setBindGroup"))) {
        return false;
      }
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
      args.rval().setUndefined();
      return true;
      break;
    }
    default: {
      // Using nsPrintfCString here would require including that
      // header.  Let's not worry about it.
      nsAutoCString argCountStr;
      argCountStr.AppendPrintf("%u", args.length());
      return cx.ThrowErrorMessage<MSG_INVALID_OVERLOAD_ARGCOUNT>(argCountStr.get());
    }
  }
  MOZ_CRASH("We have an always-returning default case");
  return false;
}

static const JSJitInfo setBindGroup_methodinfo = {
  { (JSJitGetterOp)setBindGroup },
  { prototypes::id::GPUComputePassEncoder },
  { PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
pushDebugGroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUComputePassEncoder", "pushDebugGroup", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPUComputePassEncoder.pushDebugGroup", 1)) {
    return false;
  }
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->PushDebugGroup(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->PushDebugGroup(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo pushDebugGroup_methodinfo = {
  { (JSJitGetterOp)pushDebugGroup },
  { prototypes::id::GPUComputePassEncoder },
  { PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
popDebugGroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUComputePassEncoder", "popDebugGroup", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->PopDebugGroup())>, "Should be returning void here");
  MOZ_KnownLive(self)->PopDebugGroup();
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo popDebugGroup_methodinfo = {
  { (JSJitGetterOp)popDebugGroup },
  { prototypes::id::GPUComputePassEncoder },
  { PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
insertDebugMarker(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUComputePassEncoder", "insertDebugMarker", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPUComputePassEncoder.insertDebugMarker", 1)) {
    return false;
  }
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->InsertDebugMarker(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->InsertDebugMarker(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo insertDebugMarker_methodinfo = {
  { (JSJitGetterOp)insertDebugMarker },
  { prototypes::id::GPUComputePassEncoder },
  { PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUComputePassEncoder", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUComputePassEncoder", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPUComputePassEncoder },
  { PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPUComputePassEncoder },
  { PrototypeTraits<prototypes::id::GPUComputePassEncoder>::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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::ComputePassEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ComputePassEncoder>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::ComputePassEncoder>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("setPipeline", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setPipeline_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("dispatchWorkgroups", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&dispatchWorkgroups_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("dispatchWorkgroupsIndirect", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&dispatchWorkgroupsIndirect_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("end", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&end_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FS_END,
  JS_FNSPEC("setBindGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setBindGroup_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("pushDebugGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&pushDebugGroup_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("popDebugGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&popDebugGroup_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("insertDebugMarker", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&insertDebugMarker_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};

static const PrefableDisablers sMethods_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSFunctionSpec> sMethods[] = {
  { &sMethods_disablers0, &sMethods_specs[0] },
  { nullptr, &sMethods_specs[5] },
  { nullptr, nullptr }
};

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

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};


static const Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_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(1 <= 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[9];
static PropertyInfo sNativeProperties_propertyInfos[9];

static const NativePropertiesN<2> sNativeProperties = {
  false, 0,
  false, 0,
  true,  0 /* sMethods */,
  true,  1 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  9,
  sNativeProperties_sortedPropertyIndices,
  {
    { sMethods, &sNativeProperties_propertyInfos[0] },
    { sAttributes, &sNativeProperties_propertyInfos[8] }
  }
};
static_assert(9 < 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::GPUComputePassEncoder,
  constructors::id::GPUComputePassEncoder,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth,
  prototypes::id::GPUComputePassEncoder,
  true,
  0,
  "GPUComputePassEncoder",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUComputePassEncoderPrototype",
    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,
  prototypes::id::GPUComputePassEncoder,
  PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUComputePassEncoder",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::ComputePassEncoder>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUComputePassEncoder, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::ComputePassEncoder>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::ComputePassEncoder>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::ComputePassEncoder>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::ComputePassEncoder>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::ComputePassEncoder* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::ComputePassEncoder>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::ComputePassEncoder*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::ComputePassEncoder> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUComputePassEncoder);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUComputePassEncoder);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUComputePassEncoder",
                              ShouldExpose<GPUComputePassEncoder_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUComputePassEncoder,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUComputePassEncoder,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUComputePassEncoder_Binding



namespace GPUComputePipeline_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUComputePipeline", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::ComputePipeline*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUComputePipeline", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::ComputePipeline*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPUComputePipeline },
  { PrototypeTraits<prototypes::id::GPUComputePipeline>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPUComputePipeline },
  { PrototypeTraits<prototypes::id::GPUComputePipeline>::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. */
};

MOZ_CAN_RUN_SCRIPT static bool
getBindGroupLayout(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUComputePipeline", "getBindGroupLayout", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::ComputePipeline*>(void_self);
  if (!args.requireAtLeast(cx, "GPUComputePipeline.getBindGroupLayout", 1)) {
    return false;
  }
  uint32_t arg0;
  if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[0], "Argument 1", &arg0)) {
    return false;
  }
  auto result(StrongOrRawPtr<mozilla::webgpu::BindGroupLayout>(MOZ_KnownLive(self)->GetBindGroupLayout(arg0)));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo getBindGroupLayout_methodinfo = {
  { (JSJitGetterOp)getBindGroupLayout },
  { prototypes::id::GPUComputePipeline },
  { PrototypeTraits<prototypes::id::GPUComputePipeline>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::ComputePipeline* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ComputePipeline>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::ComputePipeline>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("getBindGroupLayout", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getBindGroupLayout_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};


static const Prefable<const JSFunctionSpec> sMethods[] = {
  { nullptr, &sMethods_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(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};


static const Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_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(1 <= 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[2];
static PropertyInfo sNativeProperties_propertyInfos[2];

static const NativePropertiesN<2> sNativeProperties = {
  false, 0,
  false, 0,
  true,  0 /* sMethods */,
  true,  1 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  2,
  sNativeProperties_sortedPropertyIndices,
  {
    { sMethods, &sNativeProperties_propertyInfos[0] },
    { sAttributes, &sNativeProperties_propertyInfos[1] }
  }
};
static_assert(2 < 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::GPUComputePipeline,
  constructors::id::GPUComputePipeline,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUComputePipeline>::Depth,
  prototypes::id::GPUComputePipeline,
  true,
  0,
  "GPUComputePipeline",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUComputePipelinePrototype",
    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,
  prototypes::id::GPUComputePipeline,
  PrototypeTraits<prototypes::id::GPUComputePipeline>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUComputePipeline",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::ComputePipeline>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUComputePipeline, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::ComputePipeline>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::ComputePipeline>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::ComputePipeline>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::ComputePipeline>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::ComputePipeline* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::ComputePipeline>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::ComputePipeline*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::ComputePipeline> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUComputePipeline);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUComputePipeline);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUComputePipeline",
                              ShouldExpose<GPUComputePipeline_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUComputePipeline,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUComputePipeline,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUComputePipeline_Binding



namespace GPUDevice_Binding {

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

MOZ_CAN_RUN_SCRIPT static bool
get_features(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "features", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  auto result(StrongOrRawPtr<mozilla::webgpu::SupportedFeatures>(MOZ_KnownLive(self)->Features()));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo features_getterinfo = {
  { get_features },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  true,  /* isMovable.  Not relevant for setters. */
  true, /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_limits(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "limits", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  auto result(StrongOrRawPtr<mozilla::webgpu::SupportedLimits>(MOZ_KnownLive(self)->Limits()));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo limits_getterinfo = {
  { get_limits },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  true,  /* isMovable.  Not relevant for setters. */
  true, /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_adapterInfo(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "adapterInfo", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  auto result(StrongOrRawPtr<mozilla::webgpu::AdapterInfo>(MOZ_KnownLive(self)->GetAdapterInfo()));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo adapterInfo_getterinfo = {
  { get_adapterInfo },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  true,  /* isMovable.  Not relevant for setters. */
  true, /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_queue(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "queue", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  auto result(StrongOrRawPtr<mozilla::webgpu::Queue>(MOZ_KnownLive(self)->GetQueue()));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo queue_getterinfo = {
  { get_queue },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
  false,  /* isInfallible. False in setters. */
  true,  /* isMovable.  Not relevant for setters. */
  true, /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
destroy(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "destroy", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Destroy())>, "Should be returning void here");
  MOZ_KnownLive(self)->Destroy();
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo destroy_methodinfo = {
  { (JSJitGetterOp)destroy },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
createBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUDevice.createBuffer");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "createBuffer", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  if (!args.requireAtLeast(cx, "GPUDevice.createBuffer", 1)) {
    return false;
  }
  binding_detail::FastGPUBufferDescriptor arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  FastErrorResult rv;
  auto result(StrongOrRawPtr<mozilla::webgpu::Buffer>(MOZ_KnownLive(self)->CreateBuffer(Constify(arg0), rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUDevice.createBuffer"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo createBuffer_methodinfo = {
  { (JSJitGetterOp)createBuffer },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
createTexture(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUDevice.createTexture");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "createTexture", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  if (!args.requireAtLeast(cx, "GPUDevice.createTexture", 1)) {
    return false;
  }
  binding_detail::FastGPUTextureDescriptor arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  auto result(StrongOrRawPtr<mozilla::webgpu::Texture>(MOZ_KnownLive(self)->CreateTexture(Constify(arg0))));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo createTexture_methodinfo = {
  { (JSJitGetterOp)createTexture },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
importExternalTexture(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUDevice.importExternalTexture");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "importExternalTexture", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  if (!args.requireAtLeast(cx, "GPUDevice.importExternalTexture", 1)) {
    return false;
  }
  binding_detail::FastGPUExternalTextureDescriptor arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  FastErrorResult rv;
  auto result(StrongOrRawPtr<mozilla::webgpu::ExternalTexture>(MOZ_KnownLive(self)->ImportExternalTexture(Constify(arg0), rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUDevice.importExternalTexture"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo importExternalTexture_methodinfo = {
  { (JSJitGetterOp)importExternalTexture },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
createSampler(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUDevice.createSampler");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "createSampler", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  binding_detail::FastGPUSamplerDescriptor arg0;
  if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
    return false;
  }
  auto result(StrongOrRawPtr<mozilla::webgpu::Sampler>(MOZ_KnownLive(self)->CreateSampler(Constify(arg0))));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo createSampler_methodinfo = {
  { (JSJitGetterOp)createSampler },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
createBindGroupLayout(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUDevice.createBindGroupLayout");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "createBindGroupLayout", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  if (!args.requireAtLeast(cx, "GPUDevice.createBindGroupLayout", 1)) {
    return false;
  }
  binding_detail::FastGPUBindGroupLayoutDescriptor arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  auto result(StrongOrRawPtr<mozilla::webgpu::BindGroupLayout>(MOZ_KnownLive(self)->CreateBindGroupLayout(Constify(arg0))));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo createBindGroupLayout_methodinfo = {
  { (JSJitGetterOp)createBindGroupLayout },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
createPipelineLayout(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUDevice.createPipelineLayout");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "createPipelineLayout", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  if (!args.requireAtLeast(cx, "GPUDevice.createPipelineLayout", 1)) {
    return false;
  }
  binding_detail::FastGPUPipelineLayoutDescriptor arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  auto result(StrongOrRawPtr<mozilla::webgpu::PipelineLayout>(MOZ_KnownLive(self)->CreatePipelineLayout(Constify(arg0))));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo createPipelineLayout_methodinfo = {
  { (JSJitGetterOp)createPipelineLayout },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
createBindGroup(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUDevice.createBindGroup");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "createBindGroup", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  if (!args.requireAtLeast(cx, "GPUDevice.createBindGroup", 1)) {
    return false;
  }
  binding_detail::FastGPUBindGroupDescriptor arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  auto result(StrongOrRawPtr<mozilla::webgpu::BindGroup>(MOZ_KnownLive(self)->CreateBindGroup(Constify(arg0))));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo createBindGroup_methodinfo = {
  { (JSJitGetterOp)createBindGroup },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
createShaderModule(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUDevice.createShaderModule");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "createShaderModule", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  if (!args.requireAtLeast(cx, "GPUDevice.createShaderModule", 1)) {
    return false;
  }
  binding_detail::FastGPUShaderModuleDescriptor arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  FastErrorResult rv;
  auto result(StrongOrRawPtr<mozilla::webgpu::ShaderModule>(MOZ_KnownLive(self)->CreateShaderModule(Constify(arg0), rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUDevice.createShaderModule"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo createShaderModule_methodinfo = {
  { (JSJitGetterOp)createShaderModule },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
createComputePipeline(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUDevice.createComputePipeline");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "createComputePipeline", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  if (!args.requireAtLeast(cx, "GPUDevice.createComputePipeline", 1)) {
    return false;
  }
  binding_detail::FastGPUComputePipelineDescriptor arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  auto result(StrongOrRawPtr<mozilla::webgpu::ComputePipeline>(MOZ_KnownLive(self)->CreateComputePipeline(Constify(arg0))));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo createComputePipeline_methodinfo = {
  { (JSJitGetterOp)createComputePipeline },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
createRenderPipeline(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUDevice.createRenderPipeline");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "createRenderPipeline", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  if (!args.requireAtLeast(cx, "GPUDevice.createRenderPipeline", 1)) {
    return false;
  }
  binding_detail::FastGPURenderPipelineDescriptor arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  auto result(StrongOrRawPtr<mozilla::webgpu::RenderPipeline>(MOZ_KnownLive(self)->CreateRenderPipeline(Constify(arg0))));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo createRenderPipeline_methodinfo = {
  { (JSJitGetterOp)createRenderPipeline },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
createComputePipelineAsync(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUDevice.createComputePipelineAsync");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "createComputePipelineAsync", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  if (!args.requireAtLeast(cx, "GPUDevice.createComputePipelineAsync", 1)) {
    return false;
  }
  binding_detail::FastGPUComputePipelineDescriptor arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  FastErrorResult rv;
  auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->CreateComputePipelineAsync(Constify(arg0), rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUDevice.createComputePipelineAsync"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
createComputePipelineAsync_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  bool ok = createComputePipelineAsync(cx, obj, void_self, args);
  if (ok) {
    return true;
  }
  return ConvertExceptionToPromise(cx, args.rval());
}

static const JSJitInfo createComputePipelineAsync_methodinfo = {
  { (JSJitGetterOp)createComputePipelineAsync_promiseWrapper },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
createRenderPipelineAsync(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUDevice.createRenderPipelineAsync");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "createRenderPipelineAsync", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  if (!args.requireAtLeast(cx, "GPUDevice.createRenderPipelineAsync", 1)) {
    return false;
  }
  binding_detail::FastGPURenderPipelineDescriptor arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  FastErrorResult rv;
  auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->CreateRenderPipelineAsync(Constify(arg0), rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUDevice.createRenderPipelineAsync"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
createRenderPipelineAsync_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  bool ok = createRenderPipelineAsync(cx, obj, void_self, args);
  if (ok) {
    return true;
  }
  return ConvertExceptionToPromise(cx, args.rval());
}

static const JSJitInfo createRenderPipelineAsync_methodinfo = {
  { (JSJitGetterOp)createRenderPipelineAsync_promiseWrapper },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
createCommandEncoder(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUDevice.createCommandEncoder");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "createCommandEncoder", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  binding_detail::FastGPUCommandEncoderDescriptor arg0;
  if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
    return false;
  }
  auto result(StrongOrRawPtr<mozilla::webgpu::CommandEncoder>(MOZ_KnownLive(self)->CreateCommandEncoder(Constify(arg0))));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo createCommandEncoder_methodinfo = {
  { (JSJitGetterOp)createCommandEncoder },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
createRenderBundleEncoder(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUDevice.createRenderBundleEncoder");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "createRenderBundleEncoder", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  if (!args.requireAtLeast(cx, "GPUDevice.createRenderBundleEncoder", 1)) {
    return false;
  }
  binding_detail::FastGPURenderBundleEncoderDescriptor arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  auto result(StrongOrRawPtr<mozilla::webgpu::RenderBundleEncoder>(MOZ_KnownLive(self)->CreateRenderBundleEncoder(Constify(arg0))));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo createRenderBundleEncoder_methodinfo = {
  { (JSJitGetterOp)createRenderBundleEncoder },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
createQuerySet(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUDevice.createQuerySet");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "createQuerySet", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  if (!args.requireAtLeast(cx, "GPUDevice.createQuerySet", 1)) {
    return false;
  }
  binding_detail::FastGPUQuerySetDescriptor arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  FastErrorResult rv;
  auto result(StrongOrRawPtr<mozilla::webgpu::QuerySet>(MOZ_KnownLive(self)->CreateQuerySet(Constify(arg0), rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUDevice.createQuerySet"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo createQuerySet_methodinfo = {
  { (JSJitGetterOp)createQuerySet },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_lost(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "lost", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  FastErrorResult rv;
  auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->GetLost(rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUDevice.lost getter"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
get_lost_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  bool ok = get_lost(cx, obj, void_self, args);
  if (ok) {
    return true;
  }
  return ConvertExceptionToPromise(cx, args.rval());
}

static const JSJitInfo lost_getterinfo = {
  { get_lost_promiseWrapper },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
pushErrorScope(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUDevice.pushErrorScope");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "pushErrorScope", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  if (!args.requireAtLeast(cx, "GPUDevice.pushErrorScope", 1)) {
    return false;
  }
  GPUErrorFilter arg0;
  {
    int index;
    if (!binding_detail::FindEnumStringIndex<true>(cx, args[0],
                                                                       binding_detail::EnumStrings<GPUErrorFilter>::Values,
                                                                       "GPUErrorFilter", "argument 1",
                                                                       &index)) {
      return false;
    }
    MOZ_ASSERT(index >= 0);
    arg0 = static_cast<GPUErrorFilter>(index);
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->PushErrorScope(arg0))>, "Should be returning void here");
  MOZ_KnownLive(self)->PushErrorScope(arg0);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo pushErrorScope_methodinfo = {
  { (JSJitGetterOp)pushErrorScope },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
popErrorScope(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "popErrorScope", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  FastErrorResult rv;
  auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->PopErrorScope(rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUDevice.popErrorScope"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
popErrorScope_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  bool ok = popErrorScope(cx, obj, void_self, args);
  if (ok) {
    return true;
  }
  return ConvertExceptionToPromise(cx, args.rval());
}

static const JSJitInfo popErrorScope_methodinfo = {
  { (JSJitGetterOp)popErrorScope_promiseWrapper },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_onuncapturederror(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "onuncapturederror", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  RefPtr<EventHandlerNonNull> result(MOZ_KnownLive(self)->GetOnuncapturederror());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (result) {
    args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
    if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
      return false;
    }
    return true;
  } else {
    args.rval().setNull();
    return true;
  }
}

MOZ_CAN_RUN_SCRIPT static bool
set_onuncapturederror(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "onuncapturederror", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
  if (args[0].isObject()) {
    { // scope for tempRoot and tempGlobalRoot if needed
      arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
    }
  } else {
    arg0 = nullptr;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetOnuncapturederror(MOZ_KnownLive(Constify(arg0))))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetOnuncapturederror(MOZ_KnownLive(Constify(arg0)));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo onuncapturederror_getterinfo = {
  { get_onuncapturederror },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::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 const JSJitInfo onuncapturederror_setterinfo = {
  { (JSJitGetterOp)set_onuncapturederror },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDevice", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPUDevice },
  { PrototypeTraits<prototypes::id::GPUDevice>::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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::Device* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Device>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::Device>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("destroy", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&destroy_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("createBuffer", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createBuffer_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("createTexture", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createTexture_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FS_END,
  JS_FNSPEC("importExternalTexture", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&importExternalTexture_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FS_END,
  JS_FNSPEC("createSampler", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createSampler_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("createBindGroupLayout", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createBindGroupLayout_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("createPipelineLayout", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createPipelineLayout_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("createBindGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createBindGroup_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("createShaderModule", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createShaderModule_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("createComputePipeline", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createComputePipeline_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("createRenderPipeline", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createRenderPipeline_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("createComputePipelineAsync", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&createComputePipelineAsync_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("createRenderPipelineAsync", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&createRenderPipelineAsync_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("createCommandEncoder", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createCommandEncoder_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("createRenderBundleEncoder", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createRenderBundleEncoder_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("createQuerySet", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createQuerySet_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("pushErrorScope", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&pushErrorScope_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("popErrorScope", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&popErrorScope_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};

static const PrefableDisablers sMethods_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const PrefableDisablers sMethods_disablers4 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), &mozilla::webgpu::Instance::ExternalTexturePrefEnabled
};

static const PrefableDisablers sMethods_disablers6 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSFunctionSpec> sMethods[] = {
  { &sMethods_disablers0, &sMethods_specs[0] },
  { &sMethods_disablers4, &sMethods_specs[4] },
  { &sMethods_disablers6, &sMethods_specs[6] },
  { nullptr, nullptr }
};

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

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("features", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &features_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("limits", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &limits_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("adapterInfo", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &adapterInfo_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("queue", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &queue_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("lost", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ConvertExceptionsToPromises>, &lost_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("onuncapturederror", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &onuncapturederror_getterinfo, GenericSetter<NormalThisPolicy>, &onuncapturederror_setterinfo),
  JS_PS_END,
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};

static const PrefableDisablers sAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSPropertySpec> sAttributes[] = {
  { &sAttributes_disablers0, &sAttributes_specs[0] },
  { nullptr, &sAttributes_specs[7] },
  { nullptr, nullptr }
};

static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(6 <= 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[25];
static PropertyInfo sNativeProperties_propertyInfos[25];

static const NativePropertiesN<2> sNativeProperties = {
  false, 0,
  false, 0,
  true,  0 /* sMethods */,
  true,  1 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  25,
  sNativeProperties_sortedPropertyIndices,
  {
    { sMethods, &sNativeProperties_propertyInfos[0] },
    { sAttributes, &sNativeProperties_propertyInfos[18] }
  }
};
static_assert(25 < 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::GPUDevice,
  constructors::id::GPUDevice,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  EventTarget_Binding::GetConstructorObjectHandle,
  PrototypeTraits<prototypes::id::GPUDevice>::Depth,
  prototypes::id::GPUDevice,
  true,
  0,
  "GPUDevice",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUDevicePrototype",
    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,
  prototypes::id::GPUDevice,
  PrototypeTraits<prototypes::id::GPUDevice>::Depth,
  &sNativePropertyHooks,
  EventTarget_Binding::GetProtoObject
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUDevice",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::Device>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::EventTarget, prototypes::id::GPUDevice, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::Device>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::Device>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::Device>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::Device>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::Device* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::Device>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::Device*>);
  MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
             reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
             "Multiple inheritance for mozilla::dom::EventTarget is broken.");
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::Device> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUDevice);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUDevice);

  JS::Handle<JSObject*> parentProto(EventTarget_Binding::GetProtoObjectHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUDevice",
                              ShouldExpose<GPUDevice_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUDevice,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUDevice,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUDevice_Binding



namespace GPUDeviceLostInfo_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_reason(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDeviceLostInfo", "reason", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::DeviceLostInfo*>(void_self);
  GPUDeviceLostReason result(MOZ_KnownLive(self)->Reason());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo reason_getterinfo = {
  { get_reason },
  { prototypes::id::GPUDeviceLostInfo },
  { PrototypeTraits<prototypes::id::GPUDeviceLostInfo>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_message(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUDeviceLostInfo", "message", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::DeviceLostInfo*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetMessage(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetMessage(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo message_getterinfo = {
  { get_message },
  { prototypes::id::GPUDeviceLostInfo },
  { PrototypeTraits<prototypes::id::GPUDeviceLostInfo>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::DeviceLostInfo* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::DeviceLostInfo>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::DeviceLostInfo>(self);
  }
}

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("reason", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &reason_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("message", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &message_getterinfo, nullptr, nullptr),
  JS_PS_END
};

static const PrefableDisablers sAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSPropertySpec> sAttributes[] = {
  { &sAttributes_disablers0, &sAttributes_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(2 <= 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[2];
static PropertyInfo sNativeProperties_propertyInfos[2];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  2,
  sNativeProperties_sortedPropertyIndices,
  {
    { sAttributes, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(2 < 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::GPUDeviceLostInfo,
  constructors::id::GPUDeviceLostInfo,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUDeviceLostInfo>::Depth,
  prototypes::id::GPUDeviceLostInfo,
  true,
  0,
  "GPUDeviceLostInfo",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUDeviceLostInfoPrototype",
    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,
  prototypes::id::GPUDeviceLostInfo,
  PrototypeTraits<prototypes::id::GPUDeviceLostInfo>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUDeviceLostInfo",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::DeviceLostInfo>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUDeviceLostInfo, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::DeviceLostInfo>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::DeviceLostInfo>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::DeviceLostInfo>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::DeviceLostInfo>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::DeviceLostInfo* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::DeviceLostInfo>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::DeviceLostInfo*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::DeviceLostInfo> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUDeviceLostInfo);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUDeviceLostInfo);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUDeviceLostInfo",
                              ShouldExpose<GPUDeviceLostInfo_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUDeviceLostInfo,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUDeviceLostInfo,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUDeviceLostInfo_Binding



namespace GPUError_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_message(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUError", "message", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Error*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetMessage(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetMessage(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo message_getterinfo = {
  { get_message },
  { prototypes::id::GPUError },
  { PrototypeTraits<prototypes::id::GPUError>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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. */
};

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("message", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &message_getterinfo, nullptr, nullptr),
  JS_PS_END
};

static const PrefableDisablers sAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSPropertySpec> sAttributes[] = {
  { &sAttributes_disablers0, &sAttributes_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(1 <= 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[1];
static PropertyInfo sNativeProperties_propertyInfos[1];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  1,
  sNativeProperties_sortedPropertyIndices,
  {
    { sAttributes, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(1 < 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::GPUError,
  constructors::id::GPUError,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUError>::Depth,
  prototypes::id::GPUError,
  true,
  0,
  "GPUError",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUErrorPrototype",
    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,
  prototypes::id::GPUError,
  PrototypeTraits<prototypes::id::GPUError>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUError);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUError);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUError",
                              ShouldExpose<GPUError_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUError,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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

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::GPUError,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUError_Binding



namespace GPUExternalTexture_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUExternalTexture", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::ExternalTexture*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUExternalTexture", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::ExternalTexture*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPUExternalTexture },
  { PrototypeTraits<prototypes::id::GPUExternalTexture>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPUExternalTexture },
  { PrototypeTraits<prototypes::id::GPUExternalTexture>::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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::ExternalTexture* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ExternalTexture>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::ExternalTexture>(self);
  }
}

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};


static const Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_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(1 <= 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[1];
static PropertyInfo sNativeProperties_propertyInfos[1];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  1,
  sNativeProperties_sortedPropertyIndices,
  {
    { sAttributes, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(1 < 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::GPUExternalTexture,
  constructors::id::GPUExternalTexture,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUExternalTexture>::Depth,
  prototypes::id::GPUExternalTexture,
  true,
  0,
  "GPUExternalTexture",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUExternalTexturePrototype",
    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,
  prototypes::id::GPUExternalTexture,
  PrototypeTraits<prototypes::id::GPUExternalTexture>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUExternalTexture",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::ExternalTexture>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUExternalTexture, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::ExternalTexture>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::ExternalTexture>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::ExternalTexture>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::ExternalTexture>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::ExternalTexture* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::ExternalTexture>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::ExternalTexture*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::ExternalTexture> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUExternalTexture);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUExternalTexture);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUExternalTexture",
                              ShouldExpose<GPUExternalTexture_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUExternalTexture,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUExternalTexture,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUExternalTexture_Binding



namespace GPUInternalError_Binding {

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

static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::InternalError* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::InternalError>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::InternalError>(self);
  }
}

bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
  nullptr,
  { nullptr, nullptr, &sNativePropertiesInited },
  prototypes::id::GPUInternalError,
  constructors::id::GPUInternalError,
  &DefaultXrayExpandoObjectClass
};

static bool
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUInternalError", "constructor", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  JS::Rooted<JSObject*> obj(cx, &args.callee());
  if (!args.isConstructing()) {
    return ThrowConstructorWithoutNew(cx, "GPUInternalError");
  }

  JS::Rooted<JSObject*> desiredProto(cx);
  if (!GetDesiredProto(cx, args,
                       prototypes::id::GPUInternalError,
                       CreateInterfaceObjects,
                       &desiredProto)) {
    return false;
  }

  if (!args.requireAtLeast(cx, "GPUInternalError constructor", 1)) {
    return false;
  }
  GlobalObject global(cx, obj);
  if (global.Failed()) {
    return false;
  }

  bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  Maybe<JSAutoRealm> ar;
  if (objIsXray) {
    // Since our object is an Xray, we can just CheckedUnwrapStatic:
    // we know Xrays have no dynamic unwrap behavior.
    obj = js::CheckedUnwrapStatic(obj);
    if (!obj) {
      return false;
    }
    ar.emplace(cx, obj);
    if (!JS_WrapObject(cx, &desiredProto)) {
      return false;
    }
  }
  FastErrorResult rv;
  auto result(StrongOrRawPtr<mozilla::webgpu::InternalError>(mozilla::webgpu::InternalError::Constructor(global, NonNullHelper(Constify(arg0)), rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUInternalError constructor"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  static_assert(!std::is_pointer_v<decltype(result)>,
                "NewObject implies that we need to keep the object alive with a strong reference.");
  if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { _constructor, &sNativePropertyHooks },
  GPUError_Binding::GetConstructorObjectHandle,
  PrototypeTraits<prototypes::id::GPUInternalError>::Depth,
  prototypes::id::GPUInternalError,
  true,
  1,
  "GPUInternalError",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUInternalErrorPrototype",
    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,
  prototypes::id::GPUInternalError,
  PrototypeTraits<prototypes::id::GPUInternalError>::Depth,
  &sNativePropertyHooks,
  GPUError_Binding::GetProtoObject
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUInternalError",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::InternalError>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUError, prototypes::id::GPUInternalError, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::InternalError>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::InternalError>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::InternalError>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::InternalError>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::InternalError* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::InternalError>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::InternalError*>);
  MOZ_ASSERT(static_cast<mozilla::webgpu::Error*>(aObject) ==
             reinterpret_cast<mozilla::webgpu::Error*>(aObject),
             "Multiple inheritance for mozilla::webgpu::Error is broken.");
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::InternalError> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUInternalError);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUInternalError);

  JS::Handle<JSObject*> parentProto(GPUError_Binding::GetProtoObjectHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 1, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              nullptr,
                              nullptr,
                              "GPUInternalError",
                              ShouldExpose<GPUInternalError_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUInternalError,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUInternalError,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUInternalError_Binding



namespace GPUMapMode_Binding {

MOZ_GLOBINIT static const ConstantSpec sConstants_specs[] = {
  { "READ", JS::NumberValue(1U) },
  { "WRITE", JS::NumberValue(2U) },
  { 0, JS::UndefinedValue() }
};

static const PrefableDisablers sConstants_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const ConstantSpec> sConstants[] = {
  { &sConstants_disablers0, &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(2 <= 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[2];
static PropertyInfo sNativeProperties_propertyInfos[2];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sConstants */,
  -1,
  2,
  sNativeProperties_sortedPropertyIndices,
  {
    { sConstants, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(2 < 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::GPUMapMode,
  &DefaultXrayExpandoObjectClass
};

static const DOMIfaceAndProtoJSClass sNamespaceObjectClass = {
  {
    "GPUMapMode",
    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 mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

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::GPUMapMode);
  dom::CreateNamespaceObject(aCx, aGlobal, constructorProto,
                             sNamespaceObjectClass,
                             interfaceCache,
                             sNativeProperties.Upcast(),
                             nullptr,
                             "GPUMapMode",
                             ShouldExpose<GPUMapMode_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::GPUMapMode,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUMapMode_Binding



namespace GPUOutOfMemoryError_Binding {

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

static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::OutOfMemoryError* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::OutOfMemoryError>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::OutOfMemoryError>(self);
  }
}

bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
  nullptr,
  { nullptr, nullptr, &sNativePropertiesInited },
  prototypes::id::GPUOutOfMemoryError,
  constructors::id::GPUOutOfMemoryError,
  &DefaultXrayExpandoObjectClass
};

static bool
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUOutOfMemoryError", "constructor", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  JS::Rooted<JSObject*> obj(cx, &args.callee());
  if (!args.isConstructing()) {
    return ThrowConstructorWithoutNew(cx, "GPUOutOfMemoryError");
  }

  JS::Rooted<JSObject*> desiredProto(cx);
  if (!GetDesiredProto(cx, args,
                       prototypes::id::GPUOutOfMemoryError,
                       CreateInterfaceObjects,
                       &desiredProto)) {
    return false;
  }

  if (!args.requireAtLeast(cx, "GPUOutOfMemoryError constructor", 1)) {
    return false;
  }
  GlobalObject global(cx, obj);
  if (global.Failed()) {
    return false;
  }

  bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  Maybe<JSAutoRealm> ar;
  if (objIsXray) {
    // Since our object is an Xray, we can just CheckedUnwrapStatic:
    // we know Xrays have no dynamic unwrap behavior.
    obj = js::CheckedUnwrapStatic(obj);
    if (!obj) {
      return false;
    }
    ar.emplace(cx, obj);
    if (!JS_WrapObject(cx, &desiredProto)) {
      return false;
    }
  }
  FastErrorResult rv;
  auto result(StrongOrRawPtr<mozilla::webgpu::OutOfMemoryError>(mozilla::webgpu::OutOfMemoryError::Constructor(global, NonNullHelper(Constify(arg0)), rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUOutOfMemoryError constructor"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  static_assert(!std::is_pointer_v<decltype(result)>,
                "NewObject implies that we need to keep the object alive with a strong reference.");
  if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { _constructor, &sNativePropertyHooks },
  GPUError_Binding::GetConstructorObjectHandle,
  PrototypeTraits<prototypes::id::GPUOutOfMemoryError>::Depth,
  prototypes::id::GPUOutOfMemoryError,
  true,
  1,
  "GPUOutOfMemoryError",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUOutOfMemoryErrorPrototype",
    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,
  prototypes::id::GPUOutOfMemoryError,
  PrototypeTraits<prototypes::id::GPUOutOfMemoryError>::Depth,
  &sNativePropertyHooks,
  GPUError_Binding::GetProtoObject
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUOutOfMemoryError",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::OutOfMemoryError>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUError, prototypes::id::GPUOutOfMemoryError, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::OutOfMemoryError>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::OutOfMemoryError>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::OutOfMemoryError>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::OutOfMemoryError>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::OutOfMemoryError* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::OutOfMemoryError>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::OutOfMemoryError*>);
  MOZ_ASSERT(static_cast<mozilla::webgpu::Error*>(aObject) ==
             reinterpret_cast<mozilla::webgpu::Error*>(aObject),
             "Multiple inheritance for mozilla::webgpu::Error is broken.");
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::OutOfMemoryError> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUOutOfMemoryError);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUOutOfMemoryError);

  JS::Handle<JSObject*> parentProto(GPUError_Binding::GetProtoObjectHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 1, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              nullptr,
                              nullptr,
                              "GPUOutOfMemoryError",
                              ShouldExpose<GPUOutOfMemoryError_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUOutOfMemoryError,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUOutOfMemoryError,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUOutOfMemoryError_Binding



namespace GPUPipelineError_Binding {

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

MOZ_CAN_RUN_SCRIPT static bool
get_reason(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUPipelineError", "reason", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::PipelineError*>(void_self);
  GPUPipelineErrorReason result(MOZ_KnownLive(self)->Reason());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo reason_getterinfo = {
  { get_reason },
  { prototypes::id::GPUPipelineError },
  { PrototypeTraits<prototypes::id::GPUPipelineError>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::PipelineError* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::PipelineError>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::PipelineError>(self);
  }
}

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("reason", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &reason_getterinfo, nullptr, nullptr),
  JS_PS_END
};

static const PrefableDisablers sAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSPropertySpec> sAttributes[] = {
  { &sAttributes_disablers0, &sAttributes_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(1 <= 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[1];
static PropertyInfo sNativeProperties_propertyInfos[1];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  1,
  sNativeProperties_sortedPropertyIndices,
  {
    { sAttributes, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(1 < 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::GPUPipelineError,
  constructors::id::GPUPipelineError,
  &DefaultXrayExpandoObjectClass
};

static bool
_constructor(JSContext* cx_, unsigned argc, JS::Value* vp)
{
  BindingCallContext cx(cx_, "GPUPipelineError constructor");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUPipelineError", "constructor", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  JS::Rooted<JSObject*> obj(cx, &args.callee());
  if (!args.isConstructing()) {
    return ThrowConstructorWithoutNew(cx, "GPUPipelineError");
  }

  JS::Rooted<JSObject*> desiredProto(cx);
  if (!GetDesiredProto(cx, args,
                       prototypes::id::GPUPipelineError,
                       CreateInterfaceObjects,
                       &desiredProto)) {
    return false;
  }

  if (!args.requireAtLeast(cx, "GPUPipelineError constructor", 2)) {
    return false;
  }
  GlobalObject global(cx, obj);
  if (global.Failed()) {
    return false;
  }

  bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
  binding_detail::FakeString<char16_t> arg0;
  if (args.hasDefined(0)) {
    if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
      return false;
    }
  } else {
    arg0.AssignLiteral(u"");
  }
  binding_detail::FastGPUPipelineErrorInit arg1;
  if (!arg1.Init(cx, args[1], "Argument 2", false)) {
    return false;
  }
  Maybe<JSAutoRealm> ar;
  if (objIsXray) {
    // Since our object is an Xray, we can just CheckedUnwrapStatic:
    // we know Xrays have no dynamic unwrap behavior.
    obj = js::CheckedUnwrapStatic(obj);
    if (!obj) {
      return false;
    }
    ar.emplace(cx, obj);
    if (!JS_WrapObject(cx, &desiredProto)) {
      return false;
    }
  }
  auto result(StrongOrRawPtr<mozilla::webgpu::PipelineError>(mozilla::webgpu::PipelineError::Constructor(global, NonNullHelper(Constify(arg0)), Constify(arg1))));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  static_assert(!std::is_pointer_v<decltype(result)>,
                "NewObject implies that we need to keep the object alive with a strong reference.");
  if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { _constructor, &sNativePropertyHooks },
  DOMException_Binding::GetConstructorObjectHandle,
  PrototypeTraits<prototypes::id::GPUPipelineError>::Depth,
  prototypes::id::GPUPipelineError,
  true,
  2,
  "GPUPipelineError",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUPipelineErrorPrototype",
    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,
  prototypes::id::GPUPipelineError,
  PrototypeTraits<prototypes::id::GPUPipelineError>::Depth,
  &sNativePropertyHooks,
  DOMException_Binding::GetProtoObject
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUPipelineError",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::PipelineError>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::DOMException, prototypes::id::GPUPipelineError, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::PipelineError>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::PipelineError>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::PipelineError>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::PipelineError>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::PipelineError* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::PipelineError>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::PipelineError*>);
  MOZ_ASSERT(static_cast<mozilla::dom::DOMException*>(aObject) ==
             reinterpret_cast<mozilla::dom::DOMException*>(aObject),
             "Multiple inheritance for mozilla::dom::DOMException is broken.");
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::PipelineError> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUPipelineError);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUPipelineError);

  JS::Handle<JSObject*> parentProto(DOMException_Binding::GetProtoObjectHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 2, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUPipelineError",
                              ShouldExpose<GPUPipelineError_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUPipelineError,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUPipelineError,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUPipelineError_Binding



namespace GPUPipelineLayout_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUPipelineLayout", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::PipelineLayout*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUPipelineLayout", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::PipelineLayout*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPUPipelineLayout },
  { PrototypeTraits<prototypes::id::GPUPipelineLayout>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPUPipelineLayout },
  { PrototypeTraits<prototypes::id::GPUPipelineLayout>::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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::PipelineLayout* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::PipelineLayout>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::PipelineLayout>(self);
  }
}

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};


static const Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_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(1 <= 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[1];
static PropertyInfo sNativeProperties_propertyInfos[1];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  1,
  sNativeProperties_sortedPropertyIndices,
  {
    { sAttributes, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(1 < 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::GPUPipelineLayout,
  constructors::id::GPUPipelineLayout,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUPipelineLayout>::Depth,
  prototypes::id::GPUPipelineLayout,
  true,
  0,
  "GPUPipelineLayout",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUPipelineLayoutPrototype",
    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,
  prototypes::id::GPUPipelineLayout,
  PrototypeTraits<prototypes::id::GPUPipelineLayout>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUPipelineLayout",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::PipelineLayout>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUPipelineLayout, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::PipelineLayout>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::PipelineLayout>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::PipelineLayout>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::PipelineLayout>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::PipelineLayout* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::PipelineLayout>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::PipelineLayout*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::PipelineLayout> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUPipelineLayout);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUPipelineLayout);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUPipelineLayout",
                              ShouldExpose<GPUPipelineLayout_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUPipelineLayout,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUPipelineLayout,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUPipelineLayout_Binding



namespace GPUQuerySet_Binding {

MOZ_CAN_RUN_SCRIPT static bool
destroy(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUQuerySet", "destroy", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::QuerySet*>(void_self);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Destroy())>, "Should be returning void here");
  MOZ_KnownLive(self)->Destroy();
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo destroy_methodinfo = {
  { (JSJitGetterOp)destroy },
  { prototypes::id::GPUQuerySet },
  { PrototypeTraits<prototypes::id::GPUQuerySet>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_type(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUQuerySet", "type", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::QuerySet*>(void_self);
  GPUQueryType result(MOZ_KnownLive(self)->Type());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo type_getterinfo = {
  { get_type },
  { prototypes::id::GPUQuerySet },
  { PrototypeTraits<prototypes::id::GPUQuerySet>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_count(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUQuerySet", "count", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::QuerySet*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->Count());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo count_getterinfo = {
  { get_count },
  { prototypes::id::GPUQuerySet },
  { PrototypeTraits<prototypes::id::GPUQuerySet>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUQuerySet", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::QuerySet*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUQuerySet", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::QuerySet*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPUQuerySet },
  { PrototypeTraits<prototypes::id::GPUQuerySet>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPUQuerySet },
  { PrototypeTraits<prototypes::id::GPUQuerySet>::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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::QuerySet* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::QuerySet>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::QuerySet>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("destroy", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&destroy_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};

static const PrefableDisablers sMethods_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSFunctionSpec> sMethods[] = {
  { &sMethods_disablers0, &sMethods_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(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("type", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &type_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("count", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &count_getterinfo, nullptr, nullptr),
  JS_PS_END,
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};

static const PrefableDisablers sAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSPropertySpec> sAttributes[] = {
  { &sAttributes_disablers0, &sAttributes_specs[0] },
  { nullptr, &sAttributes_specs[3] },
  { nullptr, nullptr }
};

static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(2 <= 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[4];
static PropertyInfo sNativeProperties_propertyInfos[4];

static const NativePropertiesN<2> sNativeProperties = {
  false, 0,
  false, 0,
  true,  0 /* sMethods */,
  true,  1 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  4,
  sNativeProperties_sortedPropertyIndices,
  {
    { sMethods, &sNativeProperties_propertyInfos[0] },
    { sAttributes, &sNativeProperties_propertyInfos[1] }
  }
};
static_assert(4 < 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::GPUQuerySet,
  constructors::id::GPUQuerySet,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUQuerySet>::Depth,
  prototypes::id::GPUQuerySet,
  true,
  0,
  "GPUQuerySet",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUQuerySetPrototype",
    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,
  prototypes::id::GPUQuerySet,
  PrototypeTraits<prototypes::id::GPUQuerySet>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUQuerySet",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::QuerySet>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUQuerySet, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::QuerySet>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::QuerySet>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::QuerySet>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::QuerySet>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::QuerySet* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::QuerySet>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::QuerySet*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::QuerySet> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUQuerySet);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUQuerySet);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUQuerySet",
                              ShouldExpose<GPUQuerySet_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUQuerySet,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUQuerySet,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUQuerySet_Binding



namespace GPUQueue_Binding {

MOZ_CAN_RUN_SCRIPT static bool
submit(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUQueue.submit");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUQueue", "submit", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Queue*>(void_self);
  if (!args.requireAtLeast(cx, "GPUQueue.submit", 1)) {
    return false;
  }
  binding_detail::AutoSequence<OwningNonNull<mozilla::webgpu::CommandBuffer>> arg0;
  if (args[0].isObject()) {
    JS::ForOfIterator iter(cx);
    if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) {
      return false;
    }
    if (!iter.valueIsIterable()) {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 1", "sequence");
      return false;
    }
    binding_detail::AutoSequence<OwningNonNull<mozilla::webgpu::CommandBuffer>> &arr = arg0;
    JS::Rooted<JS::Value> temp(cx);
    while (true) {
      bool done;
      if (!iter.next(&temp, &done)) {
        return false;
      }
      if (done) {
        break;
      }
      OwningNonNull<mozilla::webgpu::CommandBuffer>* slotPtr = arr.AppendElement(mozilla::fallible);
      if (!slotPtr) {
        JS_ReportOutOfMemory(cx);
        return false;
      }
      OwningNonNull<mozilla::webgpu::CommandBuffer>& slot = *slotPtr;
      if (temp.isObject()) {
        static_assert(IsRefcounted<mozilla::webgpu::CommandBuffer>::value, "We can only store refcounted classes.");
        {
          // Our JSContext should be in the right global to do unwrapping in.
          nsresult rv = UnwrapObject<prototypes::id::GPUCommandBuffer, mozilla::webgpu::CommandBuffer>(&temp, slot, cx);
          if (NS_FAILED(rv)) {
            cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Element of argument 1", "GPUCommandBuffer");
            return false;
          }
        }
      } else {
        cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of argument 1");
        return false;
      }
    }
  } else {
    cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 1", "sequence");
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Submit(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->Submit(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo submit_methodinfo = {
  { (JSJitGetterOp)submit },
  { prototypes::id::GPUQueue },
  { PrototypeTraits<prototypes::id::GPUQueue>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
onSubmittedWorkDone(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUQueue", "onSubmittedWorkDone", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Queue*>(void_self);
  FastErrorResult rv;
  auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->OnSubmittedWorkDone(rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUQueue.onSubmittedWorkDone"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
onSubmittedWorkDone_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  bool ok = onSubmittedWorkDone(cx, obj, void_self, args);
  if (ok) {
    return true;
  }
  return ConvertExceptionToPromise(cx, args.rval());
}

static const JSJitInfo onSubmittedWorkDone_methodinfo = {
  { (JSJitGetterOp)onSubmittedWorkDone_promiseWrapper },
  { prototypes::id::GPUQueue },
  { PrototypeTraits<prototypes::id::GPUQueue>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
writeBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUQueue.writeBuffer");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUQueue", "writeBuffer", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Queue*>(void_self);
  if (!args.requireAtLeast(cx, "GPUQueue.writeBuffer", 3)) {
    return false;
  }
  NonNull<mozilla::webgpu::Buffer> arg0;
  if (args[0].isObject()) {
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
      if (NS_FAILED(rv)) {
        cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
        return false;
      }
    }
  } else {
    cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
    return false;
  }
  uint64_t arg1;
  if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
    return false;
  }
  MaybeSharedArrayBufferOrMaybeSharedArrayBufferView arg2;
  if (!arg2.Init(cx, args[2], "Argument 3", false)) {
    return false;
  }
  uint64_t arg3;
  if (args.hasDefined(3)) {
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
      return false;
    }
  } else {
    arg3 = 0ULL;
  }
  Optional<uint64_t> arg4;
  if (args.hasDefined(4)) {
    arg4.Construct();
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[4], "Argument 5", &arg4.Value())) {
      return false;
    }
  }
  FastErrorResult rv;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->WriteBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, Constify(arg2), arg3, Constify(arg4), rv))>, "Should be returning void here");
  MOZ_KnownLive(self)->WriteBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, Constify(arg2), arg3, Constify(arg4), rv);
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUQueue.writeBuffer"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo writeBuffer_methodinfo = {
  { (JSJitGetterOp)writeBuffer },
  { prototypes::id::GPUQueue },
  { PrototypeTraits<prototypes::id::GPUQueue>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
writeTexture(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUQueue.writeTexture");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUQueue", "writeTexture", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Queue*>(void_self);
  if (!args.requireAtLeast(cx, "GPUQueue.writeTexture", 4)) {
    return false;
  }
  binding_detail::FastGPUTexelCopyTextureInfo arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  MaybeSharedArrayBufferOrMaybeSharedArrayBufferView arg1;
  if (!arg1.Init(cx, args[1], "Argument 2", false)) {
    return false;
  }
  binding_detail::FastGPUTexelCopyBufferLayout arg2;
  if (!arg2.Init(cx, args[2], "Argument 3", false)) {
    return false;
  }
  RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict arg3;
  if (!arg3.Init(cx, args[3], "Argument 4", false)) {
    return false;
  }
  FastErrorResult rv;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->WriteTexture(Constify(arg0), Constify(arg1), Constify(arg2), Constify(arg3), rv))>, "Should be returning void here");
  MOZ_KnownLive(self)->WriteTexture(Constify(arg0), Constify(arg1), Constify(arg2), Constify(arg3), rv);
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUQueue.writeTexture"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo writeTexture_methodinfo = {
  { (JSJitGetterOp)writeTexture },
  { prototypes::id::GPUQueue },
  { PrototypeTraits<prototypes::id::GPUQueue>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
copyExternalImageToTexture(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUQueue.copyExternalImageToTexture");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUQueue", "copyExternalImageToTexture", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Queue*>(void_self);
  if (!args.requireAtLeast(cx, "GPUQueue.copyExternalImageToTexture", 3)) {
    return false;
  }
  binding_detail::FastGPUCopyExternalImageSourceInfo arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  binding_detail::FastGPUCopyExternalImageDestInfo arg1;
  if (!arg1.Init(cx, args[1], "Argument 2", false)) {
    return false;
  }
  RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict arg2;
  if (!arg2.Init(cx, args[2], "Argument 3", false)) {
    return false;
  }
  FastErrorResult rv;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->CopyExternalImageToTexture(Constify(arg0), Constify(arg1), Constify(arg2), rv))>, "Should be returning void here");
  MOZ_KnownLive(self)->CopyExternalImageToTexture(Constify(arg0), Constify(arg1), Constify(arg2), rv);
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUQueue.copyExternalImageToTexture"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo copyExternalImageToTexture_methodinfo = {
  { (JSJitGetterOp)copyExternalImageToTexture },
  { prototypes::id::GPUQueue },
  { PrototypeTraits<prototypes::id::GPUQueue>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUQueue", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Queue*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUQueue", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Queue*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPUQueue },
  { PrototypeTraits<prototypes::id::GPUQueue>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPUQueue },
  { PrototypeTraits<prototypes::id::GPUQueue>::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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::Queue* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Queue>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::Queue>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("submit", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&submit_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("onSubmittedWorkDone", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&onSubmittedWorkDone_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("writeBuffer", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&writeBuffer_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("writeTexture", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&writeTexture_methodinfo), 4, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("copyExternalImageToTexture", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&copyExternalImageToTexture_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};

static const PrefableDisablers sMethods_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSFunctionSpec> sMethods[] = {
  { &sMethods_disablers0, &sMethods_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(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};


static const Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_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(1 <= 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[6];
static PropertyInfo sNativeProperties_propertyInfos[6];

static const NativePropertiesN<2> sNativeProperties = {
  false, 0,
  false, 0,
  true,  0 /* sMethods */,
  true,  1 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  6,
  sNativeProperties_sortedPropertyIndices,
  {
    { sMethods, &sNativeProperties_propertyInfos[0] },
    { sAttributes, &sNativeProperties_propertyInfos[5] }
  }
};
static_assert(6 < 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::GPUQueue,
  constructors::id::GPUQueue,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUQueue>::Depth,
  prototypes::id::GPUQueue,
  true,
  0,
  "GPUQueue",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUQueuePrototype",
    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,
  prototypes::id::GPUQueue,
  PrototypeTraits<prototypes::id::GPUQueue>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUQueue",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::Queue>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUQueue, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::Queue>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::Queue>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::Queue>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::Queue>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::Queue* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::Queue>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::Queue*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::Queue> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUQueue);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUQueue);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUQueue",
                              ShouldExpose<GPUQueue_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUQueue,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUQueue,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUQueue_Binding



namespace GPURenderBundle_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderBundle", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderBundle*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderBundle", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderBundle*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPURenderBundle },
  { PrototypeTraits<prototypes::id::GPURenderBundle>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPURenderBundle },
  { PrototypeTraits<prototypes::id::GPURenderBundle>::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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::RenderBundle* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderBundle>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::RenderBundle>(self);
  }
}

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};


static const Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_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(1 <= 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[1];
static PropertyInfo sNativeProperties_propertyInfos[1];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  1,
  sNativeProperties_sortedPropertyIndices,
  {
    { sAttributes, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(1 < 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::GPURenderBundle,
  constructors::id::GPURenderBundle,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPURenderBundle>::Depth,
  prototypes::id::GPURenderBundle,
  true,
  0,
  "GPURenderBundle",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPURenderBundlePrototype",
    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,
  prototypes::id::GPURenderBundle,
  PrototypeTraits<prototypes::id::GPURenderBundle>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPURenderBundle",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::RenderBundle>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPURenderBundle, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::RenderBundle>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::RenderBundle>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::RenderBundle>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::RenderBundle>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::RenderBundle* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::RenderBundle>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::RenderBundle*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::RenderBundle> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPURenderBundle);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPURenderBundle);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPURenderBundle",
                              ShouldExpose<GPURenderBundle_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPURenderBundle,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPURenderBundle,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPURenderBundle_Binding



namespace GPURenderBundleEncoder_Binding {

MOZ_CAN_RUN_SCRIPT static bool
finish(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderBundleEncoder.finish");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderBundleEncoder", "finish", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
  binding_detail::FastGPURenderBundleDescriptor arg0;
  if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
    return false;
  }
  auto result(StrongOrRawPtr<mozilla::webgpu::RenderBundle>(MOZ_KnownLive(self)->Finish(Constify(arg0))));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo finish_methodinfo = {
  { (JSJitGetterOp)finish },
  { prototypes::id::GPURenderBundleEncoder },
  { PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
setBindGroup(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderBundleEncoder.setBindGroup");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderBundleEncoder", "setBindGroup", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
  unsigned argcount = std::min(args.length(), 5u);
  switch (argcount) {
    case 2: {
      [[fallthrough]];
    }
    case 3: {
      uint32_t arg0;
      if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
        return false;
      }
      mozilla::webgpu::BindGroup* arg1;
      if (args[1].isObject()) {
        {
          // Our JSContext should be in the right global to do unwrapping in.
          nsresult rv = UnwrapObject<prototypes::id::GPUBindGroup, mozilla::webgpu::BindGroup>(args[1], arg1, cx);
          if (NS_FAILED(rv)) {
            cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "GPUBindGroup");
            return false;
          }
        }
      } else if (args[1].isNullOrUndefined()) {
        arg1 = nullptr;
      } else {
        cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
        return false;
      }
      binding_detail::AutoSequence<uint32_t> arg2;
      if (args.hasDefined(2)) {
        if (args[2].isObject()) {
          JS::ForOfIterator iter(cx);
          if (!iter.init(args[2], JS::ForOfIterator::AllowNonIterable)) {
            return false;
          }
          if (!iter.valueIsIterable()) {
            cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 3", "sequence");
            return false;
          }
          binding_detail::AutoSequence<uint32_t> &arr = arg2;
          JS::Rooted<JS::Value> temp(cx);
          while (true) {
            bool done;
            if (!iter.next(&temp, &done)) {
              return false;
            }
            if (done) {
              break;
            }
            uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
            if (!slotPtr) {
              JS_ReportOutOfMemory(cx);
              return false;
            }
            uint32_t& slot = *slotPtr;
            if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp, "Element of argument 3", &slot)) {
              return false;
            }
          }
        } else {
          cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 3", "sequence");
          return false;
        }
      } else {
        /* arg2 array is already empty; nothing to do */
      }
      FastErrorResult rv;
      // NOTE: This assert does NOT call the function.
      static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), rv))>, "Should be returning void here");
      MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), rv);
      if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPURenderBundleEncoder.setBindGroup"))) {
        return false;
      }
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
      args.rval().setUndefined();
      return true;
      break;
    }
    case 5: {
      uint32_t arg0;
      if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
        return false;
      }
      mozilla::webgpu::BindGroup* arg1;
      if (args[1].isObject()) {
        {
          // Our JSContext should be in the right global to do unwrapping in.
          nsresult rv = UnwrapObject<prototypes::id::GPUBindGroup, mozilla::webgpu::BindGroup>(args[1], arg1, cx);
          if (NS_FAILED(rv)) {
            cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "GPUBindGroup");
            return false;
          }
        }
      } else if (args[1].isNullOrUndefined()) {
        arg1 = nullptr;
      } else {
        cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
        return false;
      }
      RootedSpiderMonkeyInterface<Uint32Array> arg2(cx);
      if (args[2].isObject()) {
        if (!arg2.Init(&args[2].toObject())) {
          cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 3", "Uint32Array");
          return false;
        }
        if (JS::IsLargeArrayBufferView(arg2.Obj())) {
          cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("Argument 3");
          return false;
        }
        if (JS::IsResizableArrayBufferView(arg2.Obj())) {
          cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("Argument 3");
          return false;
        }
        if (JS::IsImmutableArrayBufferView(arg2.Obj())) {
          cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_IMMUTABLE>("Argument 3");
          return false;
        }
      } else {
        cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 3");
        return false;
      }
      uint64_t arg3;
      if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
        return false;
      }
      uint32_t arg4;
      if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[4], "Argument 5", &arg4)) {
        return false;
      }
      FastErrorResult rv;
      // NOTE: This assert does NOT call the function.
      static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), arg3, arg4, rv))>, "Should be returning void here");
      MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), arg3, arg4, rv);
      if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPURenderBundleEncoder.setBindGroup"))) {
        return false;
      }
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
      args.rval().setUndefined();
      return true;
      break;
    }
    default: {
      // Using nsPrintfCString here would require including that
      // header.  Let's not worry about it.
      nsAutoCString argCountStr;
      argCountStr.AppendPrintf("%u", args.length());
      return cx.ThrowErrorMessage<MSG_INVALID_OVERLOAD_ARGCOUNT>(argCountStr.get());
    }
  }
  MOZ_CRASH("We have an always-returning default case");
  return false;
}

static const JSJitInfo setBindGroup_methodinfo = {
  { (JSJitGetterOp)setBindGroup },
  { prototypes::id::GPURenderBundleEncoder },
  { PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
pushDebugGroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderBundleEncoder", "pushDebugGroup", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.pushDebugGroup", 1)) {
    return false;
  }
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->PushDebugGroup(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->PushDebugGroup(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo pushDebugGroup_methodinfo = {
  { (JSJitGetterOp)pushDebugGroup },
  { prototypes::id::GPURenderBundleEncoder },
  { PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
popDebugGroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderBundleEncoder", "popDebugGroup", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->PopDebugGroup())>, "Should be returning void here");
  MOZ_KnownLive(self)->PopDebugGroup();
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo popDebugGroup_methodinfo = {
  { (JSJitGetterOp)popDebugGroup },
  { prototypes::id::GPURenderBundleEncoder },
  { PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
insertDebugMarker(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderBundleEncoder", "insertDebugMarker", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.insertDebugMarker", 1)) {
    return false;
  }
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->InsertDebugMarker(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->InsertDebugMarker(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo insertDebugMarker_methodinfo = {
  { (JSJitGetterOp)insertDebugMarker },
  { prototypes::id::GPURenderBundleEncoder },
  { PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderBundleEncoder", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderBundleEncoder", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPURenderBundleEncoder },
  { PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPURenderBundleEncoder },
  { PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::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. */
};

MOZ_CAN_RUN_SCRIPT static bool
setPipeline(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderBundleEncoder.setPipeline");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderBundleEncoder", "setPipeline", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.setPipeline", 1)) {
    return false;
  }
  NonNull<mozilla::webgpu::RenderPipeline> arg0;
  if (args[0].isObject()) {
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPURenderPipeline, mozilla::webgpu::RenderPipeline>(args[0], arg0, cx);
      if (NS_FAILED(rv)) {
        cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPURenderPipeline");
        return false;
      }
    }
  } else {
    cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetPipeline(MOZ_KnownLive(NonNullHelper(arg0))))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetPipeline(MOZ_KnownLive(NonNullHelper(arg0)));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo setPipeline_methodinfo = {
  { (JSJitGetterOp)setPipeline },
  { prototypes::id::GPURenderBundleEncoder },
  { PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
setIndexBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderBundleEncoder.setIndexBuffer");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderBundleEncoder", "setIndexBuffer", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.setIndexBuffer", 2)) {
    return false;
  }
  NonNull<mozilla::webgpu::Buffer> arg0;
  if (args[0].isObject()) {
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
      if (NS_FAILED(rv)) {
        cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
        return false;
      }
    }
  } else {
    cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
    return false;
  }
  GPUIndexFormat arg1;
  {
    int index;
    if (!binding_detail::FindEnumStringIndex<true>(cx, args[1],
                                                                       binding_detail::EnumStrings<GPUIndexFormat>::Values,
                                                                       "GPUIndexFormat", "argument 2",
                                                                       &index)) {
      return false;
    }
    MOZ_ASSERT(index >= 0);
    arg1 = static_cast<GPUIndexFormat>(index);
  }
  uint64_t arg2;
  if (args.hasDefined(2)) {
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
      return false;
    }
  } else {
    arg2 = 0ULL;
  }
  Optional<uint64_t> arg3;
  if (args.hasDefined(3)) {
    arg3.Construct();
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3.Value())) {
      return false;
    }
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetIndexBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, arg2, Constify(arg3)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetIndexBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, arg2, Constify(arg3));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo setIndexBuffer_methodinfo = {
  { (JSJitGetterOp)setIndexBuffer },
  { prototypes::id::GPURenderBundleEncoder },
  { PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
setVertexBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderBundleEncoder.setVertexBuffer");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderBundleEncoder", "setVertexBuffer", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.setVertexBuffer", 2)) {
    return false;
  }
  uint32_t arg0;
  if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
    return false;
  }
  NonNull<mozilla::webgpu::Buffer> arg1;
  if (args[1].isObject()) {
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[1], arg1, cx);
      if (NS_FAILED(rv)) {
        cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "GPUBuffer");
        return false;
      }
    }
  } else {
    cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
    return false;
  }
  uint64_t arg2;
  if (args.hasDefined(2)) {
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
      return false;
    }
  } else {
    arg2 = 0ULL;
  }
  Optional<uint64_t> arg3;
  if (args.hasDefined(3)) {
    arg3.Construct();
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3.Value())) {
      return false;
    }
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetVertexBuffer(arg0, MOZ_KnownLive(NonNullHelper(arg1)), arg2, Constify(arg3)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetVertexBuffer(arg0, MOZ_KnownLive(NonNullHelper(arg1)), arg2, Constify(arg3));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo setVertexBuffer_methodinfo = {
  { (JSJitGetterOp)setVertexBuffer },
  { prototypes::id::GPURenderBundleEncoder },
  { PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
draw(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderBundleEncoder.draw");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderBundleEncoder", "draw", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.draw", 1)) {
    return false;
  }
  uint32_t arg0;
  if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
    return false;
  }
  uint32_t arg1;
  if (args.hasDefined(1)) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
      return false;
    }
  } else {
    arg1 = 1U;
  }
  uint32_t arg2;
  if (args.hasDefined(2)) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
      return false;
    }
  } else {
    arg2 = 0U;
  }
  uint32_t arg3;
  if (args.hasDefined(3)) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
      return false;
    }
  } else {
    arg3 = 0U;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Draw(arg0, arg1, arg2, arg3))>, "Should be returning void here");
  MOZ_KnownLive(self)->Draw(arg0, arg1, arg2, arg3);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo draw_methodinfo = {
  { (JSJitGetterOp)draw },
  { prototypes::id::GPURenderBundleEncoder },
  { PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
drawIndexed(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderBundleEncoder.drawIndexed");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderBundleEncoder", "drawIndexed", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.drawIndexed", 1)) {
    return false;
  }
  uint32_t arg0;
  if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
    return false;
  }
  uint32_t arg1;
  if (args.hasDefined(1)) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
      return false;
    }
  } else {
    arg1 = 1U;
  }
  uint32_t arg2;
  if (args.hasDefined(2)) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
      return false;
    }
  } else {
    arg2 = 0U;
  }
  int32_t arg3;
  if (args.hasDefined(3)) {
    if (!ValueToPrimitive<int32_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
      return false;
    }
  } else {
    arg3 = 0;
  }
  uint32_t arg4;
  if (args.hasDefined(4)) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[4], "Argument 5", &arg4)) {
      return false;
    }
  } else {
    arg4 = 0U;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->DrawIndexed(arg0, arg1, arg2, arg3, arg4))>, "Should be returning void here");
  MOZ_KnownLive(self)->DrawIndexed(arg0, arg1, arg2, arg3, arg4);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo drawIndexed_methodinfo = {
  { (JSJitGetterOp)drawIndexed },
  { prototypes::id::GPURenderBundleEncoder },
  { PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
drawIndirect(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderBundleEncoder.drawIndirect");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderBundleEncoder", "drawIndirect", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.drawIndirect", 2)) {
    return false;
  }
  NonNull<mozilla::webgpu::Buffer> arg0;
  if (args[0].isObject()) {
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
      if (NS_FAILED(rv)) {
        cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
        return false;
      }
    }
  } else {
    cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
    return false;
  }
  uint64_t arg1;
  if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->DrawIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1))>, "Should be returning void here");
  MOZ_KnownLive(self)->DrawIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo drawIndirect_methodinfo = {
  { (JSJitGetterOp)drawIndirect },
  { prototypes::id::GPURenderBundleEncoder },
  { PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
drawIndexedIndirect(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderBundleEncoder.drawIndexedIndirect");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderBundleEncoder", "drawIndexedIndirect", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.drawIndexedIndirect", 2)) {
    return false;
  }
  NonNull<mozilla::webgpu::Buffer> arg0;
  if (args[0].isObject()) {
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
      if (NS_FAILED(rv)) {
        cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
        return false;
      }
    }
  } else {
    cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
    return false;
  }
  uint64_t arg1;
  if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->DrawIndexedIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1))>, "Should be returning void here");
  MOZ_KnownLive(self)->DrawIndexedIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo drawIndexedIndirect_methodinfo = {
  { (JSJitGetterOp)drawIndexedIndirect },
  { prototypes::id::GPURenderBundleEncoder },
  { PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
  JSJitInfo::Method,
  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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::RenderBundleEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderBundleEncoder>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::RenderBundleEncoder>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("finish", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&finish_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FS_END,
  JS_FNSPEC("setBindGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setBindGroup_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("pushDebugGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&pushDebugGroup_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("popDebugGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&popDebugGroup_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("insertDebugMarker", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&insertDebugMarker_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("setPipeline", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setPipeline_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("setIndexBuffer", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setIndexBuffer_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("setVertexBuffer", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setVertexBuffer_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("draw", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&draw_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("drawIndexed", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&drawIndexed_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("drawIndirect", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&drawIndirect_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("drawIndexedIndirect", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&drawIndexedIndirect_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};

static const PrefableDisablers sMethods_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSFunctionSpec> sMethods[] = {
  { &sMethods_disablers0, &sMethods_specs[0] },
  { nullptr, &sMethods_specs[2] },
  { nullptr, nullptr }
};

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

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};


static const Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_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(1 <= 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<2> sNativeProperties = {
  false, 0,
  false, 0,
  true,  0 /* sMethods */,
  true,  1 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  13,
  sNativeProperties_sortedPropertyIndices,
  {
    { sMethods, &sNativeProperties_propertyInfos[0] },
    { sAttributes, &sNativeProperties_propertyInfos[12] }
  }
};
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::GPURenderBundleEncoder,
  constructors::id::GPURenderBundleEncoder,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth,
  prototypes::id::GPURenderBundleEncoder,
  true,
  0,
  "GPURenderBundleEncoder",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPURenderBundleEncoderPrototype",
    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,
  prototypes::id::GPURenderBundleEncoder,
  PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPURenderBundleEncoder",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::RenderBundleEncoder>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPURenderBundleEncoder, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::RenderBundleEncoder>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::RenderBundleEncoder>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::RenderBundleEncoder>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::RenderBundleEncoder>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::RenderBundleEncoder* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::RenderBundleEncoder>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::RenderBundleEncoder*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::RenderBundleEncoder> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPURenderBundleEncoder);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPURenderBundleEncoder);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPURenderBundleEncoder",
                              ShouldExpose<GPURenderBundleEncoder_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPURenderBundleEncoder,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPURenderBundleEncoder,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPURenderBundleEncoder_Binding



namespace GPURenderPassEncoder_Binding {

MOZ_CAN_RUN_SCRIPT static bool
setViewport(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderPassEncoder.setViewport");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "setViewport", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderPassEncoder.setViewport", 6)) {
    return false;
  }
  float arg0;
  if (!ValueToPrimitive<float, eDefault>(cx, args[0], "Argument 1", &arg0)) {
    return false;
  } else if (!std::isfinite(arg0)) {
    cx.ThrowErrorMessage<MSG_NOT_FINITE>("Argument 1");
    return false;
  }
  float arg1;
  if (!ValueToPrimitive<float, eDefault>(cx, args[1], "Argument 2", &arg1)) {
    return false;
  } else if (!std::isfinite(arg1)) {
    cx.ThrowErrorMessage<MSG_NOT_FINITE>("Argument 2");
    return false;
  }
  float arg2;
  if (!ValueToPrimitive<float, eDefault>(cx, args[2], "Argument 3", &arg2)) {
    return false;
  } else if (!std::isfinite(arg2)) {
    cx.ThrowErrorMessage<MSG_NOT_FINITE>("Argument 3");
    return false;
  }
  float arg3;
  if (!ValueToPrimitive<float, eDefault>(cx, args[3], "Argument 4", &arg3)) {
    return false;
  } else if (!std::isfinite(arg3)) {
    cx.ThrowErrorMessage<MSG_NOT_FINITE>("Argument 4");
    return false;
  }
  float arg4;
  if (!ValueToPrimitive<float, eDefault>(cx, args[4], "Argument 5", &arg4)) {
    return false;
  } else if (!std::isfinite(arg4)) {
    cx.ThrowErrorMessage<MSG_NOT_FINITE>("Argument 5");
    return false;
  }
  float arg5;
  if (!ValueToPrimitive<float, eDefault>(cx, args[5], "Argument 6", &arg5)) {
    return false;
  } else if (!std::isfinite(arg5)) {
    cx.ThrowErrorMessage<MSG_NOT_FINITE>("Argument 6");
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetViewport(arg0, arg1, arg2, arg3, arg4, arg5))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetViewport(arg0, arg1, arg2, arg3, arg4, arg5);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo setViewport_methodinfo = {
  { (JSJitGetterOp)setViewport },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
setScissorRect(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderPassEncoder.setScissorRect");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "setScissorRect", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderPassEncoder.setScissorRect", 4)) {
    return false;
  }
  uint32_t arg0;
  if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
    return false;
  }
  uint32_t arg1;
  if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
    return false;
  }
  uint32_t arg2;
  if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
    return false;
  }
  uint32_t arg3;
  if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetScissorRect(arg0, arg1, arg2, arg3))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetScissorRect(arg0, arg1, arg2, arg3);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo setScissorRect_methodinfo = {
  { (JSJitGetterOp)setScissorRect },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
setBlendConstant(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderPassEncoder.setBlendConstant");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "setBlendConstant", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderPassEncoder.setBlendConstant", 1)) {
    return false;
  }
  DoubleSequenceOrGPUColorDict arg0;
  if (!arg0.Init(cx, args[0], "Argument 1", false)) {
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetBlendConstant(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetBlendConstant(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo setBlendConstant_methodinfo = {
  { (JSJitGetterOp)setBlendConstant },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
setStencilReference(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderPassEncoder.setStencilReference");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "setStencilReference", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderPassEncoder.setStencilReference", 1)) {
    return false;
  }
  uint32_t arg0;
  if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetStencilReference(arg0))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetStencilReference(arg0);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo setStencilReference_methodinfo = {
  { (JSJitGetterOp)setStencilReference },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
beginOcclusionQuery(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderPassEncoder.beginOcclusionQuery");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "beginOcclusionQuery", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderPassEncoder.beginOcclusionQuery", 1)) {
    return false;
  }
  uint32_t arg0;
  if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->BeginOcclusionQuery(arg0))>, "Should be returning void here");
  MOZ_KnownLive(self)->BeginOcclusionQuery(arg0);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo beginOcclusionQuery_methodinfo = {
  { (JSJitGetterOp)beginOcclusionQuery },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
endOcclusionQuery(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "endOcclusionQuery", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->EndOcclusionQuery())>, "Should be returning void here");
  MOZ_KnownLive(self)->EndOcclusionQuery();
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo endOcclusionQuery_methodinfo = {
  { (JSJitGetterOp)endOcclusionQuery },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
executeBundles(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderPassEncoder.executeBundles");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "executeBundles", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderPassEncoder.executeBundles", 1)) {
    return false;
  }
  binding_detail::AutoSequence<OwningNonNull<mozilla::webgpu::RenderBundle>> arg0;
  if (args[0].isObject()) {
    JS::ForOfIterator iter(cx);
    if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) {
      return false;
    }
    if (!iter.valueIsIterable()) {
      cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 1", "sequence");
      return false;
    }
    binding_detail::AutoSequence<OwningNonNull<mozilla::webgpu::RenderBundle>> &arr = arg0;
    JS::Rooted<JS::Value> temp(cx);
    while (true) {
      bool done;
      if (!iter.next(&temp, &done)) {
        return false;
      }
      if (done) {
        break;
      }
      OwningNonNull<mozilla::webgpu::RenderBundle>* slotPtr = arr.AppendElement(mozilla::fallible);
      if (!slotPtr) {
        JS_ReportOutOfMemory(cx);
        return false;
      }
      OwningNonNull<mozilla::webgpu::RenderBundle>& slot = *slotPtr;
      if (temp.isObject()) {
        static_assert(IsRefcounted<mozilla::webgpu::RenderBundle>::value, "We can only store refcounted classes.");
        {
          // Our JSContext should be in the right global to do unwrapping in.
          nsresult rv = UnwrapObject<prototypes::id::GPURenderBundle, mozilla::webgpu::RenderBundle>(&temp, slot, cx);
          if (NS_FAILED(rv)) {
            cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Element of argument 1", "GPURenderBundle");
            return false;
          }
        }
      } else {
        cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of argument 1");
        return false;
      }
    }
  } else {
    cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 1", "sequence");
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->ExecuteBundles(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->ExecuteBundles(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo executeBundles_methodinfo = {
  { (JSJitGetterOp)executeBundles },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
end(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "end", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->End())>, "Should be returning void here");
  MOZ_KnownLive(self)->End();
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo end_methodinfo = {
  { (JSJitGetterOp)end },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
setBindGroup(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderPassEncoder.setBindGroup");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "setBindGroup", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  unsigned argcount = std::min(args.length(), 5u);
  switch (argcount) {
    case 2: {
      [[fallthrough]];
    }
    case 3: {
      uint32_t arg0;
      if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
        return false;
      }
      mozilla::webgpu::BindGroup* arg1;
      if (args[1].isObject()) {
        {
          // Our JSContext should be in the right global to do unwrapping in.
          nsresult rv = UnwrapObject<prototypes::id::GPUBindGroup, mozilla::webgpu::BindGroup>(args[1], arg1, cx);
          if (NS_FAILED(rv)) {
            cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "GPUBindGroup");
            return false;
          }
        }
      } else if (args[1].isNullOrUndefined()) {
        arg1 = nullptr;
      } else {
        cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
        return false;
      }
      binding_detail::AutoSequence<uint32_t> arg2;
      if (args.hasDefined(2)) {
        if (args[2].isObject()) {
          JS::ForOfIterator iter(cx);
          if (!iter.init(args[2], JS::ForOfIterator::AllowNonIterable)) {
            return false;
          }
          if (!iter.valueIsIterable()) {
            cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 3", "sequence");
            return false;
          }
          binding_detail::AutoSequence<uint32_t> &arr = arg2;
          JS::Rooted<JS::Value> temp(cx);
          while (true) {
            bool done;
            if (!iter.next(&temp, &done)) {
              return false;
            }
            if (done) {
              break;
            }
            uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
            if (!slotPtr) {
              JS_ReportOutOfMemory(cx);
              return false;
            }
            uint32_t& slot = *slotPtr;
            if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp, "Element of argument 3", &slot)) {
              return false;
            }
          }
        } else {
          cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 3", "sequence");
          return false;
        }
      } else {
        /* arg2 array is already empty; nothing to do */
      }
      FastErrorResult rv;
      // NOTE: This assert does NOT call the function.
      static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), rv))>, "Should be returning void here");
      MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), rv);
      if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPURenderPassEncoder.setBindGroup"))) {
        return false;
      }
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
      args.rval().setUndefined();
      return true;
      break;
    }
    case 5: {
      uint32_t arg0;
      if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
        return false;
      }
      mozilla::webgpu::BindGroup* arg1;
      if (args[1].isObject()) {
        {
          // Our JSContext should be in the right global to do unwrapping in.
          nsresult rv = UnwrapObject<prototypes::id::GPUBindGroup, mozilla::webgpu::BindGroup>(args[1], arg1, cx);
          if (NS_FAILED(rv)) {
            cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "GPUBindGroup");
            return false;
          }
        }
      } else if (args[1].isNullOrUndefined()) {
        arg1 = nullptr;
      } else {
        cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
        return false;
      }
      RootedSpiderMonkeyInterface<Uint32Array> arg2(cx);
      if (args[2].isObject()) {
        if (!arg2.Init(&args[2].toObject())) {
          cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 3", "Uint32Array");
          return false;
        }
        if (JS::IsLargeArrayBufferView(arg2.Obj())) {
          cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("Argument 3");
          return false;
        }
        if (JS::IsResizableArrayBufferView(arg2.Obj())) {
          cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("Argument 3");
          return false;
        }
        if (JS::IsImmutableArrayBufferView(arg2.Obj())) {
          cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_IMMUTABLE>("Argument 3");
          return false;
        }
      } else {
        cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 3");
        return false;
      }
      uint64_t arg3;
      if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
        return false;
      }
      uint32_t arg4;
      if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[4], "Argument 5", &arg4)) {
        return false;
      }
      FastErrorResult rv;
      // NOTE: This assert does NOT call the function.
      static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), arg3, arg4, rv))>, "Should be returning void here");
      MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), arg3, arg4, rv);
      if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPURenderPassEncoder.setBindGroup"))) {
        return false;
      }
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
      args.rval().setUndefined();
      return true;
      break;
    }
    default: {
      // Using nsPrintfCString here would require including that
      // header.  Let's not worry about it.
      nsAutoCString argCountStr;
      argCountStr.AppendPrintf("%u", args.length());
      return cx.ThrowErrorMessage<MSG_INVALID_OVERLOAD_ARGCOUNT>(argCountStr.get());
    }
  }
  MOZ_CRASH("We have an always-returning default case");
  return false;
}

static const JSJitInfo setBindGroup_methodinfo = {
  { (JSJitGetterOp)setBindGroup },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
pushDebugGroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "pushDebugGroup", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderPassEncoder.pushDebugGroup", 1)) {
    return false;
  }
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->PushDebugGroup(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->PushDebugGroup(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo pushDebugGroup_methodinfo = {
  { (JSJitGetterOp)pushDebugGroup },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
popDebugGroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "popDebugGroup", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->PopDebugGroup())>, "Should be returning void here");
  MOZ_KnownLive(self)->PopDebugGroup();
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo popDebugGroup_methodinfo = {
  { (JSJitGetterOp)popDebugGroup },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
insertDebugMarker(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "insertDebugMarker", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderPassEncoder.insertDebugMarker", 1)) {
    return false;
  }
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->InsertDebugMarker(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->InsertDebugMarker(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo insertDebugMarker_methodinfo = {
  { (JSJitGetterOp)insertDebugMarker },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::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. */
};

MOZ_CAN_RUN_SCRIPT static bool
setPipeline(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderPassEncoder.setPipeline");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "setPipeline", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderPassEncoder.setPipeline", 1)) {
    return false;
  }
  NonNull<mozilla::webgpu::RenderPipeline> arg0;
  if (args[0].isObject()) {
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPURenderPipeline, mozilla::webgpu::RenderPipeline>(args[0], arg0, cx);
      if (NS_FAILED(rv)) {
        cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPURenderPipeline");
        return false;
      }
    }
  } else {
    cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetPipeline(MOZ_KnownLive(NonNullHelper(arg0))))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetPipeline(MOZ_KnownLive(NonNullHelper(arg0)));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo setPipeline_methodinfo = {
  { (JSJitGetterOp)setPipeline },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
setIndexBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderPassEncoder.setIndexBuffer");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "setIndexBuffer", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderPassEncoder.setIndexBuffer", 2)) {
    return false;
  }
  NonNull<mozilla::webgpu::Buffer> arg0;
  if (args[0].isObject()) {
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
      if (NS_FAILED(rv)) {
        cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
        return false;
      }
    }
  } else {
    cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
    return false;
  }
  GPUIndexFormat arg1;
  {
    int index;
    if (!binding_detail::FindEnumStringIndex<true>(cx, args[1],
                                                                       binding_detail::EnumStrings<GPUIndexFormat>::Values,
                                                                       "GPUIndexFormat", "argument 2",
                                                                       &index)) {
      return false;
    }
    MOZ_ASSERT(index >= 0);
    arg1 = static_cast<GPUIndexFormat>(index);
  }
  uint64_t arg2;
  if (args.hasDefined(2)) {
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
      return false;
    }
  } else {
    arg2 = 0ULL;
  }
  Optional<uint64_t> arg3;
  if (args.hasDefined(3)) {
    arg3.Construct();
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3.Value())) {
      return false;
    }
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetIndexBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, arg2, Constify(arg3)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetIndexBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, arg2, Constify(arg3));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo setIndexBuffer_methodinfo = {
  { (JSJitGetterOp)setIndexBuffer },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
setVertexBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderPassEncoder.setVertexBuffer");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "setVertexBuffer", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderPassEncoder.setVertexBuffer", 2)) {
    return false;
  }
  uint32_t arg0;
  if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
    return false;
  }
  NonNull<mozilla::webgpu::Buffer> arg1;
  if (args[1].isObject()) {
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[1], arg1, cx);
      if (NS_FAILED(rv)) {
        cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "GPUBuffer");
        return false;
      }
    }
  } else {
    cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
    return false;
  }
  uint64_t arg2;
  if (args.hasDefined(2)) {
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
      return false;
    }
  } else {
    arg2 = 0ULL;
  }
  Optional<uint64_t> arg3;
  if (args.hasDefined(3)) {
    arg3.Construct();
    if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3.Value())) {
      return false;
    }
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetVertexBuffer(arg0, MOZ_KnownLive(NonNullHelper(arg1)), arg2, Constify(arg3)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetVertexBuffer(arg0, MOZ_KnownLive(NonNullHelper(arg1)), arg2, Constify(arg3));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo setVertexBuffer_methodinfo = {
  { (JSJitGetterOp)setVertexBuffer },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
draw(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderPassEncoder.draw");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "draw", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderPassEncoder.draw", 1)) {
    return false;
  }
  uint32_t arg0;
  if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
    return false;
  }
  uint32_t arg1;
  if (args.hasDefined(1)) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
      return false;
    }
  } else {
    arg1 = 1U;
  }
  uint32_t arg2;
  if (args.hasDefined(2)) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
      return false;
    }
  } else {
    arg2 = 0U;
  }
  uint32_t arg3;
  if (args.hasDefined(3)) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
      return false;
    }
  } else {
    arg3 = 0U;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Draw(arg0, arg1, arg2, arg3))>, "Should be returning void here");
  MOZ_KnownLive(self)->Draw(arg0, arg1, arg2, arg3);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo draw_methodinfo = {
  { (JSJitGetterOp)draw },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
drawIndexed(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderPassEncoder.drawIndexed");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "drawIndexed", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderPassEncoder.drawIndexed", 1)) {
    return false;
  }
  uint32_t arg0;
  if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
    return false;
  }
  uint32_t arg1;
  if (args.hasDefined(1)) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
      return false;
    }
  } else {
    arg1 = 1U;
  }
  uint32_t arg2;
  if (args.hasDefined(2)) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
      return false;
    }
  } else {
    arg2 = 0U;
  }
  int32_t arg3;
  if (args.hasDefined(3)) {
    if (!ValueToPrimitive<int32_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
      return false;
    }
  } else {
    arg3 = 0;
  }
  uint32_t arg4;
  if (args.hasDefined(4)) {
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[4], "Argument 5", &arg4)) {
      return false;
    }
  } else {
    arg4 = 0U;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->DrawIndexed(arg0, arg1, arg2, arg3, arg4))>, "Should be returning void here");
  MOZ_KnownLive(self)->DrawIndexed(arg0, arg1, arg2, arg3, arg4);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo drawIndexed_methodinfo = {
  { (JSJitGetterOp)drawIndexed },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
drawIndirect(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderPassEncoder.drawIndirect");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "drawIndirect", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderPassEncoder.drawIndirect", 2)) {
    return false;
  }
  NonNull<mozilla::webgpu::Buffer> arg0;
  if (args[0].isObject()) {
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
      if (NS_FAILED(rv)) {
        cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
        return false;
      }
    }
  } else {
    cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
    return false;
  }
  uint64_t arg1;
  if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->DrawIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1))>, "Should be returning void here");
  MOZ_KnownLive(self)->DrawIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo drawIndirect_methodinfo = {
  { (JSJitGetterOp)drawIndirect },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
drawIndexedIndirect(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPURenderPassEncoder.drawIndexedIndirect");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPassEncoder", "drawIndexedIndirect", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderPassEncoder.drawIndexedIndirect", 2)) {
    return false;
  }
  NonNull<mozilla::webgpu::Buffer> arg0;
  if (args[0].isObject()) {
    {
      // Our JSContext should be in the right global to do unwrapping in.
      nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
      if (NS_FAILED(rv)) {
        cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
        return false;
      }
    }
  } else {
    cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
    return false;
  }
  uint64_t arg1;
  if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->DrawIndexedIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1))>, "Should be returning void here");
  MOZ_KnownLive(self)->DrawIndexedIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo drawIndexedIndirect_methodinfo = {
  { (JSJitGetterOp)drawIndexedIndirect },
  { prototypes::id::GPURenderPassEncoder },
  { PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
  JSJitInfo::Method,
  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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::RenderPassEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderPassEncoder>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::RenderPassEncoder>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("setViewport", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setViewport_methodinfo), 6, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("setScissorRect", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setScissorRect_methodinfo), 4, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("setBlendConstant", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setBlendConstant_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("setStencilReference", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setStencilReference_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("beginOcclusionQuery", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&beginOcclusionQuery_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("endOcclusionQuery", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&endOcclusionQuery_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("executeBundles", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&executeBundles_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("end", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&end_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FS_END,
  JS_FNSPEC("setBindGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setBindGroup_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("pushDebugGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&pushDebugGroup_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("popDebugGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&popDebugGroup_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("insertDebugMarker", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&insertDebugMarker_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("setPipeline", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setPipeline_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("setIndexBuffer", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setIndexBuffer_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("setVertexBuffer", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setVertexBuffer_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("draw", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&draw_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("drawIndexed", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&drawIndexed_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("drawIndirect", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&drawIndirect_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("drawIndexedIndirect", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&drawIndexedIndirect_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};

static const PrefableDisablers sMethods_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSFunctionSpec> sMethods[] = {
  { &sMethods_disablers0, &sMethods_specs[0] },
  { nullptr, &sMethods_specs[9] },
  { nullptr, nullptr }
};

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

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};


static const Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_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(1 <= 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[20];
static PropertyInfo sNativeProperties_propertyInfos[20];

static const NativePropertiesN<2> sNativeProperties = {
  false, 0,
  false, 0,
  true,  0 /* sMethods */,
  true,  1 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  20,
  sNativeProperties_sortedPropertyIndices,
  {
    { sMethods, &sNativeProperties_propertyInfos[0] },
    { sAttributes, &sNativeProperties_propertyInfos[19] }
  }
};
static_assert(20 < 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::GPURenderPassEncoder,
  constructors::id::GPURenderPassEncoder,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth,
  prototypes::id::GPURenderPassEncoder,
  true,
  0,
  "GPURenderPassEncoder",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPURenderPassEncoderPrototype",
    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,
  prototypes::id::GPURenderPassEncoder,
  PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPURenderPassEncoder",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::RenderPassEncoder>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPURenderPassEncoder, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::RenderPassEncoder>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::RenderPassEncoder>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::RenderPassEncoder>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::RenderPassEncoder>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::RenderPassEncoder* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::RenderPassEncoder>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::RenderPassEncoder*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::RenderPassEncoder> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPURenderPassEncoder);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPURenderPassEncoder);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPURenderPassEncoder",
                              ShouldExpose<GPURenderPassEncoder_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPURenderPassEncoder,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPURenderPassEncoder,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPURenderPassEncoder_Binding



namespace GPURenderPipeline_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPipeline", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPipeline*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPipeline", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPipeline*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPURenderPipeline },
  { PrototypeTraits<prototypes::id::GPURenderPipeline>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPURenderPipeline },
  { PrototypeTraits<prototypes::id::GPURenderPipeline>::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. */
};

MOZ_CAN_RUN_SCRIPT static bool
getBindGroupLayout(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPURenderPipeline", "getBindGroupLayout", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::RenderPipeline*>(void_self);
  if (!args.requireAtLeast(cx, "GPURenderPipeline.getBindGroupLayout", 1)) {
    return false;
  }
  uint32_t arg0;
  if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[0], "Argument 1", &arg0)) {
    return false;
  }
  auto result(StrongOrRawPtr<mozilla::webgpu::BindGroupLayout>(MOZ_KnownLive(self)->GetBindGroupLayout(arg0)));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo getBindGroupLayout_methodinfo = {
  { (JSJitGetterOp)getBindGroupLayout },
  { prototypes::id::GPURenderPipeline },
  { PrototypeTraits<prototypes::id::GPURenderPipeline>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::RenderPipeline* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderPipeline>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::RenderPipeline>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("getBindGroupLayout", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getBindGroupLayout_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};


static const Prefable<const JSFunctionSpec> sMethods[] = {
  { nullptr, &sMethods_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(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};


static const Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_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(1 <= 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[2];
static PropertyInfo sNativeProperties_propertyInfos[2];

static const NativePropertiesN<2> sNativeProperties = {
  false, 0,
  false, 0,
  true,  0 /* sMethods */,
  true,  1 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  2,
  sNativeProperties_sortedPropertyIndices,
  {
    { sMethods, &sNativeProperties_propertyInfos[0] },
    { sAttributes, &sNativeProperties_propertyInfos[1] }
  }
};
static_assert(2 < 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::GPURenderPipeline,
  constructors::id::GPURenderPipeline,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPURenderPipeline>::Depth,
  prototypes::id::GPURenderPipeline,
  true,
  0,
  "GPURenderPipeline",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPURenderPipelinePrototype",
    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,
  prototypes::id::GPURenderPipeline,
  PrototypeTraits<prototypes::id::GPURenderPipeline>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPURenderPipeline",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::RenderPipeline>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPURenderPipeline, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::RenderPipeline>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::RenderPipeline>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::RenderPipeline>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::RenderPipeline>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::RenderPipeline* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::RenderPipeline>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::RenderPipeline*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::RenderPipeline> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPURenderPipeline);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPURenderPipeline);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPURenderPipeline",
                              ShouldExpose<GPURenderPipeline_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPURenderPipeline,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPURenderPipeline,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPURenderPipeline_Binding



namespace GPUSampler_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSampler", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Sampler*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSampler", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Sampler*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPUSampler },
  { PrototypeTraits<prototypes::id::GPUSampler>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPUSampler },
  { PrototypeTraits<prototypes::id::GPUSampler>::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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::Sampler* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Sampler>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::Sampler>(self);
  }
}

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};


static const Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_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(1 <= 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[1];
static PropertyInfo sNativeProperties_propertyInfos[1];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  1,
  sNativeProperties_sortedPropertyIndices,
  {
    { sAttributes, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(1 < 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::GPUSampler,
  constructors::id::GPUSampler,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUSampler>::Depth,
  prototypes::id::GPUSampler,
  true,
  0,
  "GPUSampler",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUSamplerPrototype",
    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,
  prototypes::id::GPUSampler,
  PrototypeTraits<prototypes::id::GPUSampler>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUSampler",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::Sampler>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUSampler, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::Sampler>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::Sampler>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::Sampler>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::Sampler>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::Sampler* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::Sampler>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::Sampler*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::Sampler> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUSampler);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUSampler);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUSampler",
                              ShouldExpose<GPUSampler_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUSampler,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUSampler,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUSampler_Binding



namespace GPUShaderModule_Binding {

MOZ_CAN_RUN_SCRIPT static bool
getCompilationInfo(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUShaderModule", "getCompilationInfo", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::ShaderModule*>(void_self);
  FastErrorResult rv;
  auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->GetCompilationInfo(rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUShaderModule.getCompilationInfo"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
getCompilationInfo_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  bool ok = getCompilationInfo(cx, obj, void_self, args);
  if (ok) {
    return true;
  }
  return ConvertExceptionToPromise(cx, args.rval());
}

static const JSJitInfo getCompilationInfo_methodinfo = {
  { (JSJitGetterOp)getCompilationInfo_promiseWrapper },
  { prototypes::id::GPUShaderModule },
  { PrototypeTraits<prototypes::id::GPUShaderModule>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUShaderModule", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::ShaderModule*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUShaderModule", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::ShaderModule*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPUShaderModule },
  { PrototypeTraits<prototypes::id::GPUShaderModule>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPUShaderModule },
  { PrototypeTraits<prototypes::id::GPUShaderModule>::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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::ShaderModule* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ShaderModule>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::ShaderModule>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("getCompilationInfo", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&getCompilationInfo_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};

static const PrefableDisablers sMethods_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSFunctionSpec> sMethods[] = {
  { &sMethods_disablers0, &sMethods_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(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};


static const Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_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(1 <= 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[2];
static PropertyInfo sNativeProperties_propertyInfos[2];

static const NativePropertiesN<2> sNativeProperties = {
  false, 0,
  false, 0,
  true,  0 /* sMethods */,
  true,  1 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  2,
  sNativeProperties_sortedPropertyIndices,
  {
    { sMethods, &sNativeProperties_propertyInfos[0] },
    { sAttributes, &sNativeProperties_propertyInfos[1] }
  }
};
static_assert(2 < 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::GPUShaderModule,
  constructors::id::GPUShaderModule,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUShaderModule>::Depth,
  prototypes::id::GPUShaderModule,
  true,
  0,
  "GPUShaderModule",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUShaderModulePrototype",
    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,
  prototypes::id::GPUShaderModule,
  PrototypeTraits<prototypes::id::GPUShaderModule>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUShaderModule",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::ShaderModule>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUShaderModule, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::ShaderModule>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::ShaderModule>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::ShaderModule>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::ShaderModule>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::ShaderModule* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::ShaderModule>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::ShaderModule*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::ShaderModule> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUShaderModule);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUShaderModule);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUShaderModule",
                              ShouldExpose<GPUShaderModule_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUShaderModule,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUShaderModule,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUShaderModule_Binding



namespace GPUShaderStage_Binding {

MOZ_GLOBINIT static const ConstantSpec sConstants_specs[] = {
  { "VERTEX", JS::NumberValue(1U) },
  { "FRAGMENT", JS::NumberValue(2U) },
  { "COMPUTE", JS::NumberValue(4U) },
  { 0, JS::UndefinedValue() }
};

static const PrefableDisablers sConstants_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const ConstantSpec> sConstants[] = {
  { &sConstants_disablers0, &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(3 <= 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[3];
static PropertyInfo sNativeProperties_propertyInfos[3];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sConstants */,
  -1,
  3,
  sNativeProperties_sortedPropertyIndices,
  {
    { sConstants, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(3 < 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::GPUShaderStage,
  &DefaultXrayExpandoObjectClass
};

static const DOMIfaceAndProtoJSClass sNamespaceObjectClass = {
  {
    "GPUShaderStage",
    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 mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

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::GPUShaderStage);
  dom::CreateNamespaceObject(aCx, aGlobal, constructorProto,
                             sNamespaceObjectClass,
                             interfaceCache,
                             sNativeProperties.Upcast(),
                             nullptr,
                             "GPUShaderStage",
                             ShouldExpose<GPUShaderStage_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::GPUShaderStage,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUShaderStage_Binding



namespace GPUSupportedFeatures_Binding {

namespace SetlikeHelpers {
void
Clear(mozilla::webgpu::SupportedFeatures* self, ErrorResult& aRv)
{
  MOZ_ASSERT(self);
  AutoJSAPI jsapi;
  jsapi.Init();
  JSContext* cx = jsapi.cx();
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
  // all we want is to wrap into _some_ scope and then unwrap to find
  // the reflector, and wrapping has no side-effects.
  JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible);
  if (!scope) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
  JSAutoRealm tempRealm(cx, scope);
  JS::Rooted<JS::Value> v(cx);
  if(!ToJSValue(cx, self, &v)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
  // This is a reflector, but due to trying to name things
  // similarly across method generators, it's called obj here.
  JS::Rooted<JSObject*> obj(cx);
  obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
  JSAutoRealm reflectorRealm(cx, obj);

  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
  }
  if (!JS::SetClear(cx, backingObj)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
}
bool
Delete(mozilla::webgpu::SupportedFeatures* self, const nsAString& aKey, ErrorResult& aRv)
{
  MOZ_ASSERT(self);
  AutoJSAPI jsapi;
  jsapi.Init();
  JSContext* cx = jsapi.cx();
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
  // all we want is to wrap into _some_ scope and then unwrap to find
  // the reflector, and wrapping has no side-effects.
  JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible);
  if (!scope) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  JSAutoRealm tempRealm(cx, scope);
  JS::Rooted<JS::Value> v(cx);
  if(!ToJSValue(cx, self, &v)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  // This is a reflector, but due to trying to name things
  // similarly across method generators, it's called obj here.
  JS::Rooted<JSObject*> obj(cx);
  obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
  JSAutoRealm reflectorRealm(cx, obj);
  JS::RootedVector<JS::Value> argv(cx);
  if (!argv.resize(1)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  do {
    if (!xpc::NonVoidStringToJsval(cx, aKey, argv[0])) {
      aRv.Throw(NS_ERROR_UNEXPECTED);
      return bool(0);
    }
    break;
  } while (false);

  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
  }
  bool retVal;
  if (!JS::SetDelete(cx, backingObj, argv[0], &retVal)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  return retVal;
}
bool
Has(mozilla::webgpu::SupportedFeatures* self, const nsAString& aKey, ErrorResult& aRv)
{
  MOZ_ASSERT(self);
  AutoJSAPI jsapi;
  jsapi.Init();
  JSContext* cx = jsapi.cx();
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
  // all we want is to wrap into _some_ scope and then unwrap to find
  // the reflector, and wrapping has no side-effects.
  JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible);
  if (!scope) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  JSAutoRealm tempRealm(cx, scope);
  JS::Rooted<JS::Value> v(cx);
  if(!ToJSValue(cx, self, &v)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  // This is a reflector, but due to trying to name things
  // similarly across method generators, it's called obj here.
  JS::Rooted<JSObject*> obj(cx);
  obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
  JSAutoRealm reflectorRealm(cx, obj);
  JS::RootedVector<JS::Value> argv(cx);
  if (!argv.resize(1)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  do {
    if (!xpc::NonVoidStringToJsval(cx, aKey, argv[0])) {
      aRv.Throw(NS_ERROR_UNEXPECTED);
      return bool(0);
    }
    break;
  } while (false);

  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
  }
  bool retVal;
  if (!JS::SetHas(cx, backingObj, argv[0], &retVal)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  return retVal;
}
void
Add(mozilla::webgpu::SupportedFeatures* self, const nsAString& aKey, ErrorResult& aRv)
{
  MOZ_ASSERT(self);
  AutoJSAPI jsapi;
  jsapi.Init();
  JSContext* cx = jsapi.cx();
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
  // all we want is to wrap into _some_ scope and then unwrap to find
  // the reflector, and wrapping has no side-effects.
  JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible);
  if (!scope) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
  JSAutoRealm tempRealm(cx, scope);
  JS::Rooted<JS::Value> v(cx);
  if(!ToJSValue(cx, self, &v)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
  // This is a reflector, but due to trying to name things
  // similarly across method generators, it's called obj here.
  JS::Rooted<JSObject*> obj(cx);
  obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
  JSAutoRealm reflectorRealm(cx, obj);
  JS::RootedVector<JS::Value> argv(cx);
  if (!argv.resize(1)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
  do {
    if (!xpc::NonVoidStringToJsval(cx, aKey, argv[0])) {
      aRv.Throw(NS_ERROR_UNEXPECTED);
      return;
    }
    break;
  } while (false);

  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
  }
  if (!JS::SetAdd(cx, backingObj, argv[0])) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
}
} // namespace SetlikeHelpers

MOZ_CAN_RUN_SCRIPT static bool
get_size(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedFeatures", "size", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedFeatures*>(void_self);
  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    return false;
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
  }
  uint32_t result = JS::SetSize(cx, backingObj);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo size_getterinfo = {
  { get_size },
  { prototypes::id::GPUSupportedFeatures },
  { PrototypeTraits<prototypes::id::GPUSupportedFeatures>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
entries(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedFeatures", "entries", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedFeatures*>(void_self);
  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    return false;
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
  }
  // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
  // after bug 1023984 is fixed.
  if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    return false;
  }
  JS::Rooted<JSObject*> result(cx);
  JS::Rooted<JS::Value> v(cx);
  if (!JS::SetEntries(cx, backingObj, &v)) {
    return false;
  }
  result = &v.toObject();
  JS::ExposeObjectToActiveJS(result);
  args.rval().setObject(*result);
  if (!MaybeWrapObjectValue(cx, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo::ArgType entries_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
static const JSTypedMethodJitInfo entries_methodinfo = {
  {
    { (JSJitGetterOp)entries },
    { prototypes::id::GPUSupportedFeatures },
    { PrototypeTraits<prototypes::id::GPUSupportedFeatures>::Depth },
    JSJitInfo::Method,
    JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    JSVAL_TYPE_OBJECT,  /* 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. */
    true,  /* isTypedMethod.  Only relevant for methods. */
    0   /* Reserved slot index, if we're stored in a slot, else 0. */
  },
  entries_methodinfo_argTypes
};

MOZ_CAN_RUN_SCRIPT static bool
keys(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedFeatures", "keys", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedFeatures*>(void_self);
  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    return false;
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
  }
  // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
  // after bug 1023984 is fixed.
  if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    return false;
  }
  JS::Rooted<JSObject*> result(cx);
  JS::Rooted<JS::Value> v(cx);
  if (!JS::SetKeys(cx, backingObj, &v)) {
    return false;
  }
  result = &v.toObject();
  JS::ExposeObjectToActiveJS(result);
  args.rval().setObject(*result);
  if (!MaybeWrapObjectValue(cx, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo::ArgType keys_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
static const JSTypedMethodJitInfo keys_methodinfo = {
  {
    { (JSJitGetterOp)keys },
    { prototypes::id::GPUSupportedFeatures },
    { PrototypeTraits<prototypes::id::GPUSupportedFeatures>::Depth },
    JSJitInfo::Method,
    JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    JSVAL_TYPE_OBJECT,  /* 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. */
    true,  /* isTypedMethod.  Only relevant for methods. */
    0   /* Reserved slot index, if we're stored in a slot, else 0. */
  },
  keys_methodinfo_argTypes
};

MOZ_CAN_RUN_SCRIPT static bool
values(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedFeatures", "values", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedFeatures*>(void_self);
  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    return false;
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
  }
  // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
  // after bug 1023984 is fixed.
  if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    return false;
  }
  JS::Rooted<JSObject*> result(cx);
  JS::Rooted<JS::Value> v(cx);
  if (!JS::SetValues(cx, backingObj, &v)) {
    return false;
  }
  result = &v.toObject();
  JS::ExposeObjectToActiveJS(result);
  args.rval().setObject(*result);
  if (!MaybeWrapObjectValue(cx, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo::ArgType values_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
static const JSTypedMethodJitInfo values_methodinfo = {
  {
    { (JSJitGetterOp)values },
    { prototypes::id::GPUSupportedFeatures },
    { PrototypeTraits<prototypes::id::GPUSupportedFeatures>::Depth },
    JSJitInfo::Method,
    JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    JSVAL_TYPE_OBJECT,  /* 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. */
    true,  /* isTypedMethod.  Only relevant for methods. */
    0   /* Reserved slot index, if we're stored in a slot, else 0. */
  },
  values_methodinfo_argTypes
};

MOZ_CAN_RUN_SCRIPT static bool
forEach(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUSupportedFeatures.forEach");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedFeatures", "forEach", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedFeatures*>(void_self);
  JS::Rooted<JSObject*> arg0(cx);
  if (args.get(0).isObject()) {
    arg0 = &args.get(0).toObject();
  } else {
    cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
    return false;
  }
  JS::Rooted<JS::Value> arg1(cx);
  if (args.hasDefined(1)) {
    arg1 = args.get(1);
  } else {
    arg1 = JS::UndefinedValue();
  }
  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    return false;
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
  }
  // Create a wrapper function.
  JSFunction* func = js::NewFunctionWithReserved(cx, ForEachHandler, 3, 0, nullptr);
  if (!func) {
    return false;
  }
  JS::Rooted<JSObject*> funcObj(cx, JS_GetFunctionObject(func));
  JS::Rooted<JS::Value> funcVal(cx, JS::ObjectValue(*funcObj));
  js::SetFunctionNativeReserved(funcObj, FOREACH_CALLBACK_SLOT,
                                JS::ObjectValue(*arg0));
  js::SetFunctionNativeReserved(funcObj, FOREACH_MAPLIKEORSETLIKEOBJ_SLOT,
                                JS::ObjectValue(*obj));
  if (!JS::SetForEach(cx, backingObj, funcVal, arg1)) {
    return false;
  }
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo forEach_methodinfo = {
  { (JSJitGetterOp)forEach },
  { prototypes::id::GPUSupportedFeatures },
  { PrototypeTraits<prototypes::id::GPUSupportedFeatures>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
has(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedFeatures", "has", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedFeatures*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
    return false;
  }
  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    return false;
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
  }
  JS::Rooted<JS::Value> arg0Val(cx);
  if (!ToJSValue(cx, arg0, &arg0Val)) {
    return false;
  }
  bool result;
  if (!JS::SetHas(cx, backingObj, arg0Val, &result)) {
    return false;
  }
  args.rval().setBoolean(result);
  return true;
}

static const JSJitInfo::ArgType has_methodinfo_argTypes[] = { JSJitInfo::String, JSJitInfo::ArgTypeListEnd };
static const JSTypedMethodJitInfo has_methodinfo = {
  {
    { (JSJitGetterOp)has },
    { prototypes::id::GPUSupportedFeatures },
    { PrototypeTraits<prototypes::id::GPUSupportedFeatures>::Depth },
    JSJitInfo::Method,
    JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    JSVAL_TYPE_BOOLEAN,  /* 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. */
    true,  /* isTypedMethod.  Only relevant for methods. */
    0   /* Reserved slot index, if we're stored in a slot, else 0. */
  },
  has_methodinfo_argTypes
};

static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::SupportedFeatures* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::SupportedFeatures>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::SupportedFeatures>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("entries", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&entries_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("keys", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&keys_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("values", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&values_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("forEach", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&forEach_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("has", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&has_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};


static const Prefable<const JSFunctionSpec> sMethods[] = {
  { nullptr, &sMethods_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(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("size", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &size_getterinfo, nullptr, nullptr),
  JS_PS_END
};


static const Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_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(1 <= 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[6];
static PropertyInfo sNativeProperties_propertyInfos[6];

static const NativePropertiesN<2> sNativeProperties = {
  false, 0,
  false, 0,
  true,  0 /* sMethods */,
  true,  1 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  2,
  6,
  sNativeProperties_sortedPropertyIndices,
  {
    { sMethods, &sNativeProperties_propertyInfos[0] },
    { sAttributes, &sNativeProperties_propertyInfos[5] }
  }
};
static_assert(2 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.iteratorAliasMethodIndex) - 1),
    "We have an iterator alias index that is oversized");
static_assert(6 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
    "We have a property info count that is oversized");

// This may allocate too many slots, because we only really need
// slots for our non-interface-typed members that we cache.  But
// allocating slots only for those would make the slot index
// computations much more complicated, so let's do this the simple
// way for now.
DEFINE_XRAY_EXPANDO_CLASS_WITH_OPS(static, sXrayExpandoObjectClass, 1,
                                   &xpc::XrayExpandoObjectClassOps);

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

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUSupportedFeatures>::Depth,
  prototypes::id::GPUSupportedFeatures,
  true,
  0,
  "GPUSupportedFeatures",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUSupportedFeaturesPrototype",
    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,
  prototypes::id::GPUSupportedFeatures,
  PrototypeTraits<prototypes::id::GPUSupportedFeatures>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUSupportedFeatures",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::SupportedFeatures>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUSupportedFeatures, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::SupportedFeatures>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::SupportedFeatures>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::SupportedFeatures>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::SupportedFeatures>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(2 >= 2,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::SupportedFeatures* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::SupportedFeatures>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::SupportedFeatures*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::SupportedFeatures> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUSupportedFeatures);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUSupportedFeatures);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUSupportedFeatures",
                              ShouldExpose<GPUSupportedFeatures_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);

  JS::AssertObjectIsNotGray(*protoCache);
  JS::Handle<JSObject*> proto = JS::Handle<JSObject*>::fromMarkedLocation(protoCache->unsafeAddress());
  if (!proto) {
    *protoCache = nullptr;
    if (interfaceCache) {
      *interfaceCache = nullptr;
    }
    return;
  }

  // Set up aliases on the interface prototype object we just created.
  JS::Rooted<JS::Value> aliasedVal(aCx);

  if (!JS_GetProperty(aCx, proto, "values", &aliasedVal)) {
    *protoCache = nullptr;
    if (interfaceCache) {
      *interfaceCache = nullptr;
    }
    return;
  }
  JS::Rooted<jsid> iteratorId(aCx, JS::GetWellKnownSymbolKey(aCx, JS::SymbolCode::iterator));
  if (!JS_DefinePropertyById(aCx, proto, iteratorId, aliasedVal, 0)) {
    *protoCache = nullptr;
    if (interfaceCache) {
      *interfaceCache = nullptr;
    }
    return;
  }
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUSupportedFeatures,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUSupportedFeatures,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUSupportedFeatures_Binding



namespace GPUSupportedLimits_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_maxTextureDimension1D(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxTextureDimension1D", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxTextureDimension1D());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxTextureDimension1D_getterinfo = {
  { get_maxTextureDimension1D },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxTextureDimension2D(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxTextureDimension2D", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxTextureDimension2D());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxTextureDimension2D_getterinfo = {
  { get_maxTextureDimension2D },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxTextureDimension3D(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxTextureDimension3D", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxTextureDimension3D());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxTextureDimension3D_getterinfo = {
  { get_maxTextureDimension3D },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxTextureArrayLayers(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxTextureArrayLayers", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxTextureArrayLayers());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxTextureArrayLayers_getterinfo = {
  { get_maxTextureArrayLayers },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxBindGroups(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxBindGroups", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxBindGroups());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxBindGroups_getterinfo = {
  { get_maxBindGroups },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxBindGroupsPlusVertexBuffers(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxBindGroupsPlusVertexBuffers", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxBindGroupsPlusVertexBuffers());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxBindGroupsPlusVertexBuffers_getterinfo = {
  { get_maxBindGroupsPlusVertexBuffers },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxBindingsPerBindGroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxBindingsPerBindGroup", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxBindingsPerBindGroup());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxBindingsPerBindGroup_getterinfo = {
  { get_maxBindingsPerBindGroup },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxDynamicUniformBuffersPerPipelineLayout(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxDynamicUniformBuffersPerPipelineLayout", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxDynamicUniformBuffersPerPipelineLayout());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxDynamicUniformBuffersPerPipelineLayout_getterinfo = {
  { get_maxDynamicUniformBuffersPerPipelineLayout },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxDynamicStorageBuffersPerPipelineLayout(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxDynamicStorageBuffersPerPipelineLayout", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxDynamicStorageBuffersPerPipelineLayout());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxDynamicStorageBuffersPerPipelineLayout_getterinfo = {
  { get_maxDynamicStorageBuffersPerPipelineLayout },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxSampledTexturesPerShaderStage(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxSampledTexturesPerShaderStage", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxSampledTexturesPerShaderStage());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxSampledTexturesPerShaderStage_getterinfo = {
  { get_maxSampledTexturesPerShaderStage },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxSamplersPerShaderStage(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxSamplersPerShaderStage", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxSamplersPerShaderStage());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxSamplersPerShaderStage_getterinfo = {
  { get_maxSamplersPerShaderStage },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxStorageBuffersPerShaderStage(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxStorageBuffersPerShaderStage", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxStorageBuffersPerShaderStage());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxStorageBuffersPerShaderStage_getterinfo = {
  { get_maxStorageBuffersPerShaderStage },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxStorageTexturesPerShaderStage(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxStorageTexturesPerShaderStage", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxStorageTexturesPerShaderStage());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxStorageTexturesPerShaderStage_getterinfo = {
  { get_maxStorageTexturesPerShaderStage },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxUniformBuffersPerShaderStage(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxUniformBuffersPerShaderStage", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxUniformBuffersPerShaderStage());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxUniformBuffersPerShaderStage_getterinfo = {
  { get_maxUniformBuffersPerShaderStage },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxUniformBufferBindingSize(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxUniformBufferBindingSize", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint64_t result(MOZ_KnownLive(self)->MaxUniformBufferBindingSize());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().set(JS_NumberValue(double(result)));
  return true;
}

static const JSJitInfo maxUniformBufferBindingSize_getterinfo = {
  { get_maxUniformBufferBindingSize },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxStorageBufferBindingSize(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxStorageBufferBindingSize", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint64_t result(MOZ_KnownLive(self)->MaxStorageBufferBindingSize());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().set(JS_NumberValue(double(result)));
  return true;
}

static const JSJitInfo maxStorageBufferBindingSize_getterinfo = {
  { get_maxStorageBufferBindingSize },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_minUniformBufferOffsetAlignment(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "minUniformBufferOffsetAlignment", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MinUniformBufferOffsetAlignment());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo minUniformBufferOffsetAlignment_getterinfo = {
  { get_minUniformBufferOffsetAlignment },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_minStorageBufferOffsetAlignment(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "minStorageBufferOffsetAlignment", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MinStorageBufferOffsetAlignment());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo minStorageBufferOffsetAlignment_getterinfo = {
  { get_minStorageBufferOffsetAlignment },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxVertexBuffers(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxVertexBuffers", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxVertexBuffers());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxVertexBuffers_getterinfo = {
  { get_maxVertexBuffers },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxBufferSize(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxBufferSize", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint64_t result(MOZ_KnownLive(self)->MaxBufferSize());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().set(JS_NumberValue(double(result)));
  return true;
}

static const JSJitInfo maxBufferSize_getterinfo = {
  { get_maxBufferSize },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxVertexAttributes(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxVertexAttributes", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxVertexAttributes());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxVertexAttributes_getterinfo = {
  { get_maxVertexAttributes },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxVertexBufferArrayStride(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxVertexBufferArrayStride", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxVertexBufferArrayStride());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxVertexBufferArrayStride_getterinfo = {
  { get_maxVertexBufferArrayStride },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxInterStageShaderVariables(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxInterStageShaderVariables", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxInterStageShaderVariables());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxInterStageShaderVariables_getterinfo = {
  { get_maxInterStageShaderVariables },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxColorAttachments(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxColorAttachments", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxColorAttachments());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxColorAttachments_getterinfo = {
  { get_maxColorAttachments },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxColorAttachmentBytesPerSample(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxColorAttachmentBytesPerSample", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxColorAttachmentBytesPerSample());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxColorAttachmentBytesPerSample_getterinfo = {
  { get_maxColorAttachmentBytesPerSample },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxComputeWorkgroupStorageSize(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxComputeWorkgroupStorageSize", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxComputeWorkgroupStorageSize());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxComputeWorkgroupStorageSize_getterinfo = {
  { get_maxComputeWorkgroupStorageSize },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxComputeInvocationsPerWorkgroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxComputeInvocationsPerWorkgroup", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxComputeInvocationsPerWorkgroup());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxComputeInvocationsPerWorkgroup_getterinfo = {
  { get_maxComputeInvocationsPerWorkgroup },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxComputeWorkgroupSizeX(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxComputeWorkgroupSizeX", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxComputeWorkgroupSizeX());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxComputeWorkgroupSizeX_getterinfo = {
  { get_maxComputeWorkgroupSizeX },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxComputeWorkgroupSizeY(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxComputeWorkgroupSizeY", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxComputeWorkgroupSizeY());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxComputeWorkgroupSizeY_getterinfo = {
  { get_maxComputeWorkgroupSizeY },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxComputeWorkgroupSizeZ(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxComputeWorkgroupSizeZ", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxComputeWorkgroupSizeZ());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxComputeWorkgroupSizeZ_getterinfo = {
  { get_maxComputeWorkgroupSizeZ },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_maxComputeWorkgroupsPerDimension(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUSupportedLimits", "maxComputeWorkgroupsPerDimension", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MaxComputeWorkgroupsPerDimension());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo maxComputeWorkgroupsPerDimension_getterinfo = {
  { get_maxComputeWorkgroupsPerDimension },
  { prototypes::id::GPUSupportedLimits },
  { PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::SupportedLimits* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::SupportedLimits>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::SupportedLimits>(self);
  }
}

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("maxTextureDimension1D", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxTextureDimension1D_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxTextureDimension2D", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxTextureDimension2D_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxTextureDimension3D", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxTextureDimension3D_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxTextureArrayLayers", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxTextureArrayLayers_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxBindGroups", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxBindGroups_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxBindGroupsPlusVertexBuffers", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxBindGroupsPlusVertexBuffers_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxBindingsPerBindGroup", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxBindingsPerBindGroup_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxDynamicUniformBuffersPerPipelineLayout", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxDynamicUniformBuffersPerPipelineLayout_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxDynamicStorageBuffersPerPipelineLayout", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxDynamicStorageBuffersPerPipelineLayout_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxSampledTexturesPerShaderStage", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxSampledTexturesPerShaderStage_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxSamplersPerShaderStage", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxSamplersPerShaderStage_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxStorageBuffersPerShaderStage", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxStorageBuffersPerShaderStage_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxStorageTexturesPerShaderStage", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxStorageTexturesPerShaderStage_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxUniformBuffersPerShaderStage", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxUniformBuffersPerShaderStage_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxUniformBufferBindingSize", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxUniformBufferBindingSize_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxStorageBufferBindingSize", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxStorageBufferBindingSize_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("minUniformBufferOffsetAlignment", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &minUniformBufferOffsetAlignment_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("minStorageBufferOffsetAlignment", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &minStorageBufferOffsetAlignment_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxVertexBuffers", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxVertexBuffers_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxBufferSize", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxBufferSize_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxVertexAttributes", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxVertexAttributes_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxVertexBufferArrayStride", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxVertexBufferArrayStride_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxInterStageShaderVariables", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxInterStageShaderVariables_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxColorAttachments", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxColorAttachments_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxColorAttachmentBytesPerSample", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxColorAttachmentBytesPerSample_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxComputeWorkgroupStorageSize", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxComputeWorkgroupStorageSize_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxComputeInvocationsPerWorkgroup", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxComputeInvocationsPerWorkgroup_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxComputeWorkgroupSizeX", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxComputeWorkgroupSizeX_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxComputeWorkgroupSizeY", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxComputeWorkgroupSizeY_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxComputeWorkgroupSizeZ", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxComputeWorkgroupSizeZ_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("maxComputeWorkgroupsPerDimension", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxComputeWorkgroupsPerDimension_getterinfo, nullptr, nullptr),
  JS_PS_END
};

static const PrefableDisablers sAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSPropertySpec> sAttributes[] = {
  { &sAttributes_disablers0, &sAttributes_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(31 <= 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[31];
static PropertyInfo sNativeProperties_propertyInfos[31];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  31,
  sNativeProperties_sortedPropertyIndices,
  {
    { sAttributes, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(31 < 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::GPUSupportedLimits,
  constructors::id::GPUSupportedLimits,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth,
  prototypes::id::GPUSupportedLimits,
  true,
  0,
  "GPUSupportedLimits",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUSupportedLimitsPrototype",
    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,
  prototypes::id::GPUSupportedLimits,
  PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUSupportedLimits",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::SupportedLimits>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUSupportedLimits, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::SupportedLimits>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::SupportedLimits>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::SupportedLimits>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::SupportedLimits>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::SupportedLimits* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::SupportedLimits>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::SupportedLimits*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::SupportedLimits> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUSupportedLimits);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUSupportedLimits);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUSupportedLimits",
                              ShouldExpose<GPUSupportedLimits_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUSupportedLimits,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUSupportedLimits,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUSupportedLimits_Binding



namespace GPUTexture_Binding {

MOZ_CAN_RUN_SCRIPT static bool
createView(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "GPUTexture.createView");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUTexture", "createView", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
  binding_detail::FastGPUTextureViewDescriptor arg0;
  if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
    return false;
  }
  auto result(StrongOrRawPtr<mozilla::webgpu::TextureView>(MOZ_KnownLive(self)->CreateView(Constify(arg0))));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const JSJitInfo createView_methodinfo = {
  { (JSJitGetterOp)createView },
  { prototypes::id::GPUTexture },
  { PrototypeTraits<prototypes::id::GPUTexture>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_OBJECT,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
destroy(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUTexture", "destroy", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Destroy())>, "Should be returning void here");
  MOZ_KnownLive(self)->Destroy();
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo destroy_methodinfo = {
  { (JSJitGetterOp)destroy },
  { prototypes::id::GPUTexture },
  { PrototypeTraits<prototypes::id::GPUTexture>::Depth },
  JSJitInfo::Method,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_width(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUTexture", "width", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->Width());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo width_getterinfo = {
  { get_width },
  { prototypes::id::GPUTexture },
  { PrototypeTraits<prototypes::id::GPUTexture>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_height(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUTexture", "height", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->Height());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo height_getterinfo = {
  { get_height },
  { prototypes::id::GPUTexture },
  { PrototypeTraits<prototypes::id::GPUTexture>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_depthOrArrayLayers(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUTexture", "depthOrArrayLayers", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->DepthOrArrayLayers());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo depthOrArrayLayers_getterinfo = {
  { get_depthOrArrayLayers },
  { prototypes::id::GPUTexture },
  { PrototypeTraits<prototypes::id::GPUTexture>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_mipLevelCount(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUTexture", "mipLevelCount", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->MipLevelCount());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo mipLevelCount_getterinfo = {
  { get_mipLevelCount },
  { prototypes::id::GPUTexture },
  { PrototypeTraits<prototypes::id::GPUTexture>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_sampleCount(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUTexture", "sampleCount", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->SampleCount());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo sampleCount_getterinfo = {
  { get_sampleCount },
  { prototypes::id::GPUTexture },
  { PrototypeTraits<prototypes::id::GPUTexture>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_dimension(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUTexture", "dimension", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
  GPUTextureDimension result(MOZ_KnownLive(self)->Dimension());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo dimension_getterinfo = {
  { get_dimension },
  { prototypes::id::GPUTexture },
  { PrototypeTraits<prototypes::id::GPUTexture>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_format(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUTexture", "format", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
  GPUTextureFormat result(MOZ_KnownLive(self)->Format());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!ToJSValue(cx, result, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo format_getterinfo = {
  { get_format },
  { prototypes::id::GPUTexture },
  { PrototypeTraits<prototypes::id::GPUTexture>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_usage(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUTexture", "usage", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
  uint32_t result(MOZ_KnownLive(self)->Usage());
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo usage_getterinfo = {
  { get_usage },
  { prototypes::id::GPUTexture },
  { PrototypeTraits<prototypes::id::GPUTexture>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUTexture", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUTexture", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPUTexture },
  { PrototypeTraits<prototypes::id::GPUTexture>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPUTexture },
  { PrototypeTraits<prototypes::id::GPUTexture>::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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::Texture* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Texture>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::Texture>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("createView", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createView_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("destroy", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&destroy_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};

static const PrefableDisablers sMethods_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSFunctionSpec> sMethods[] = {
  { &sMethods_disablers0, &sMethods_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(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("width", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &width_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("height", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &height_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("depthOrArrayLayers", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &depthOrArrayLayers_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("mipLevelCount", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &mipLevelCount_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("sampleCount", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &sampleCount_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("dimension", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &dimension_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("format", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &format_getterinfo, nullptr, nullptr),
  JSPropertySpec::nativeAccessors("usage", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &usage_getterinfo, nullptr, nullptr),
  JS_PS_END,
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};

static const PrefableDisablers sAttributes_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const JSPropertySpec> sAttributes[] = {
  { &sAttributes_disablers0, &sAttributes_specs[0] },
  { nullptr, &sAttributes_specs[9] },
  { nullptr, nullptr }
};

static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(8 <= 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[11];
static PropertyInfo sNativeProperties_propertyInfos[11];

static const NativePropertiesN<2> sNativeProperties = {
  false, 0,
  false, 0,
  true,  0 /* sMethods */,
  true,  1 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  11,
  sNativeProperties_sortedPropertyIndices,
  {
    { sMethods, &sNativeProperties_propertyInfos[0] },
    { sAttributes, &sNativeProperties_propertyInfos[2] }
  }
};
static_assert(11 < 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::GPUTexture,
  constructors::id::GPUTexture,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUTexture>::Depth,
  prototypes::id::GPUTexture,
  true,
  0,
  "GPUTexture",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUTexturePrototype",
    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,
  prototypes::id::GPUTexture,
  PrototypeTraits<prototypes::id::GPUTexture>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUTexture",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::Texture>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUTexture, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::Texture>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::Texture>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::Texture>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::Texture>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::Texture* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::Texture>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::Texture*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::Texture> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUTexture);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUTexture);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUTexture",
                              ShouldExpose<GPUTexture_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUTexture,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUTexture,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUTexture_Binding



namespace GPUTextureUsage_Binding {

MOZ_GLOBINIT static const ConstantSpec sConstants_specs[] = {
  { "COPY_SRC", JS::NumberValue(1U) },
  { "COPY_DST", JS::NumberValue(2U) },
  { "TEXTURE_BINDING", JS::NumberValue(4U) },
  { "STORAGE_BINDING", JS::NumberValue(8U) },
  { "RENDER_ATTACHMENT", JS::NumberValue(16U) },
  { 0, JS::UndefinedValue() }
};

static const PrefableDisablers sConstants_disablers0 = {
  WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};

static const Prefable<const ConstantSpec> sConstants[] = {
  { &sConstants_disablers0, &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(5 <= 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[5];
static PropertyInfo sNativeProperties_propertyInfos[5];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sConstants */,
  -1,
  5,
  sNativeProperties_sortedPropertyIndices,
  {
    { sConstants, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(5 < 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::GPUTextureUsage,
  &DefaultXrayExpandoObjectClass
};

static const DOMIfaceAndProtoJSClass sNamespaceObjectClass = {
  {
    "GPUTextureUsage",
    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 mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

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::GPUTextureUsage);
  dom::CreateNamespaceObject(aCx, aGlobal, constructorProto,
                             sNamespaceObjectClass,
                             interfaceCache,
                             sNativeProperties.Upcast(),
                             nullptr,
                             "GPUTextureUsage",
                             ShouldExpose<GPUTextureUsage_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::GPUTextureUsage,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUTextureUsage_Binding



namespace GPUTextureView_Binding {

MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUTextureView", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::TextureView*>(void_self);
  DOMString result;
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
  MOZ_KnownLive(self)->GetLabel(result);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
    return false;
  }
  return true;
}

MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUTextureView", "label", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::TextureView*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  if (!NormalizeUSVString(arg0)) {
    JS_ReportOutOfMemory(cx);
    return false;
  }
  // NOTE: This assert does NOT call the function.
  static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
  MOZ_KnownLive(self)->SetLabel(Constify(arg0));
  MOZ_ASSERT(!JS_IsExceptionPending(cx));

  return true;
}

static const JSJitInfo label_getterinfo = {
  { get_label },
  { prototypes::id::GPUTextureView },
  { PrototypeTraits<prototypes::id::GPUTextureView>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_STRING,  /* 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 const JSJitInfo label_setterinfo = {
  { (JSJitGetterOp)set_label },
  { prototypes::id::GPUTextureView },
  { PrototypeTraits<prototypes::id::GPUTextureView>::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 void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::TextureView* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::TextureView>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::TextureView>(self);
  }
}

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
  JS_PS_END
};


static const Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_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(1 <= 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[1];
static PropertyInfo sNativeProperties_propertyInfos[1];

static const NativePropertiesN<1> sNativeProperties = {
  false, 0,
  false, 0,
  false, 0,
  true,  0 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  -1,
  1,
  sNativeProperties_sortedPropertyIndices,
  {
    { sAttributes, &sNativeProperties_propertyInfos[0] }
  }
};
static_assert(1 < 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::GPUTextureView,
  constructors::id::GPUTextureView,
  &DefaultXrayExpandoObjectClass
};

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::GPUTextureView>::Depth,
  prototypes::id::GPUTextureView,
  true,
  0,
  "GPUTextureView",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUTextureViewPrototype",
    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,
  prototypes::id::GPUTextureView,
  PrototypeTraits<prototypes::id::GPUTextureView>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUTextureView",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::TextureView>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUTextureView, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::TextureView>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::TextureView>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::TextureView>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::TextureView>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::TextureView* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::TextureView>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::TextureView*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::TextureView> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUTextureView);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUTextureView);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "GPUTextureView",
                              ShouldExpose<GPUTextureView_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUTextureView,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUTextureView,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUTextureView_Binding



namespace GPUValidationError_Binding {

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

static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::ValidationError* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ValidationError>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::ValidationError>(self);
  }
}

bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
  nullptr,
  { nullptr, nullptr, &sNativePropertiesInited },
  prototypes::id::GPUValidationError,
  constructors::id::GPUValidationError,
  &DefaultXrayExpandoObjectClass
};

static bool
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "GPUValidationError", "constructor", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
  JS::Rooted<JSObject*> obj(cx, &args.callee());
  if (!args.isConstructing()) {
    return ThrowConstructorWithoutNew(cx, "GPUValidationError");
  }

  JS::Rooted<JSObject*> desiredProto(cx);
  if (!GetDesiredProto(cx, args,
                       prototypes::id::GPUValidationError,
                       CreateInterfaceObjects,
                       &desiredProto)) {
    return false;
  }

  if (!args.requireAtLeast(cx, "GPUValidationError constructor", 1)) {
    return false;
  }
  GlobalObject global(cx, obj);
  if (global.Failed()) {
    return false;
  }

  bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
    return false;
  }
  Maybe<JSAutoRealm> ar;
  if (objIsXray) {
    // Since our object is an Xray, we can just CheckedUnwrapStatic:
    // we know Xrays have no dynamic unwrap behavior.
    obj = js::CheckedUnwrapStatic(obj);
    if (!obj) {
      return false;
    }
    ar.emplace(cx, obj);
    if (!JS_WrapObject(cx, &desiredProto)) {
      return false;
    }
  }
  FastErrorResult rv;
  auto result(StrongOrRawPtr<mozilla::webgpu::ValidationError>(mozilla::webgpu::ValidationError::Constructor(global, NonNullHelper(Constify(arg0)), rv)));
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUValidationError constructor"))) {
    return false;
  }
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  static_assert(!std::is_pointer_v<decltype(result)>,
                "NewObject implies that we need to keep the object alive with a strong reference.");
  if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
    MOZ_ASSERT(JS_IsExceptionPending(cx));
    return false;
  }
  return true;
}

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { _constructor, &sNativePropertyHooks },
  GPUError_Binding::GetConstructorObjectHandle,
  PrototypeTraits<prototypes::id::GPUValidationError>::Depth,
  prototypes::id::GPUValidationError,
  true,
  1,
  "GPUValidationError",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "GPUValidationErrorPrototype",
    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,
  prototypes::id::GPUValidationError,
  PrototypeTraits<prototypes::id::GPUValidationError>::Depth,
  &sNativePropertyHooks,
  GPUError_Binding::GetProtoObject
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "GPUValidationError",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::ValidationError>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::GPUError, prototypes::id::GPUValidationError, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::ValidationError>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::ValidationError>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::ValidationError>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::ValidationError>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::ValidationError* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::ValidationError>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::ValidationError*>);
  MOZ_ASSERT(static_cast<mozilla::webgpu::Error*>(aObject) ==
             reinterpret_cast<mozilla::webgpu::Error*>(aObject),
             "Multiple inheritance for mozilla::webgpu::Error is broken.");
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::ValidationError> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUValidationError);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUValidationError);

  JS::Handle<JSObject*> parentProto(GPUError_Binding::GetProtoObjectHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 1, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              nullptr,
                              nullptr,
                              "GPUValidationError",
                              ShouldExpose<GPUValidationError_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUValidationError,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::GPUValidationError,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace GPUValidationError_Binding



namespace WGSLLanguageFeatures_Binding {

namespace SetlikeHelpers {
void
Clear(mozilla::webgpu::WGSLLanguageFeatures* self, ErrorResult& aRv)
{
  MOZ_ASSERT(self);
  AutoJSAPI jsapi;
  jsapi.Init();
  JSContext* cx = jsapi.cx();
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
  // all we want is to wrap into _some_ scope and then unwrap to find
  // the reflector, and wrapping has no side-effects.
  JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible);
  if (!scope) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
  JSAutoRealm tempRealm(cx, scope);
  JS::Rooted<JS::Value> v(cx);
  if(!ToJSValue(cx, self, &v)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
  // This is a reflector, but due to trying to name things
  // similarly across method generators, it's called obj here.
  JS::Rooted<JSObject*> obj(cx);
  obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
  JSAutoRealm reflectorRealm(cx, obj);

  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
  }
  if (!JS::SetClear(cx, backingObj)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
}
bool
Delete(mozilla::webgpu::WGSLLanguageFeatures* self, const nsAString& aKey, ErrorResult& aRv)
{
  MOZ_ASSERT(self);
  AutoJSAPI jsapi;
  jsapi.Init();
  JSContext* cx = jsapi.cx();
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
  // all we want is to wrap into _some_ scope and then unwrap to find
  // the reflector, and wrapping has no side-effects.
  JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible);
  if (!scope) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  JSAutoRealm tempRealm(cx, scope);
  JS::Rooted<JS::Value> v(cx);
  if(!ToJSValue(cx, self, &v)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  // This is a reflector, but due to trying to name things
  // similarly across method generators, it's called obj here.
  JS::Rooted<JSObject*> obj(cx);
  obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
  JSAutoRealm reflectorRealm(cx, obj);
  JS::RootedVector<JS::Value> argv(cx);
  if (!argv.resize(1)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  do {
    if (!xpc::NonVoidStringToJsval(cx, aKey, argv[0])) {
      aRv.Throw(NS_ERROR_UNEXPECTED);
      return bool(0);
    }
    break;
  } while (false);

  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
  }
  bool retVal;
  if (!JS::SetDelete(cx, backingObj, argv[0], &retVal)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  return retVal;
}
bool
Has(mozilla::webgpu::WGSLLanguageFeatures* self, const nsAString& aKey, ErrorResult& aRv)
{
  MOZ_ASSERT(self);
  AutoJSAPI jsapi;
  jsapi.Init();
  JSContext* cx = jsapi.cx();
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
  // all we want is to wrap into _some_ scope and then unwrap to find
  // the reflector, and wrapping has no side-effects.
  JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible);
  if (!scope) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  JSAutoRealm tempRealm(cx, scope);
  JS::Rooted<JS::Value> v(cx);
  if(!ToJSValue(cx, self, &v)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  // This is a reflector, but due to trying to name things
  // similarly across method generators, it's called obj here.
  JS::Rooted<JSObject*> obj(cx);
  obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
  JSAutoRealm reflectorRealm(cx, obj);
  JS::RootedVector<JS::Value> argv(cx);
  if (!argv.resize(1)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  do {
    if (!xpc::NonVoidStringToJsval(cx, aKey, argv[0])) {
      aRv.Throw(NS_ERROR_UNEXPECTED);
      return bool(0);
    }
    break;
  } while (false);

  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
  }
  bool retVal;
  if (!JS::SetHas(cx, backingObj, argv[0], &retVal)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return bool(0);
  }
  return retVal;
}
void
Add(mozilla::webgpu::WGSLLanguageFeatures* self, const nsAString& aKey, ErrorResult& aRv)
{
  MOZ_ASSERT(self);
  AutoJSAPI jsapi;
  jsapi.Init();
  JSContext* cx = jsapi.cx();
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
  // all we want is to wrap into _some_ scope and then unwrap to find
  // the reflector, and wrapping has no side-effects.
  JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible);
  if (!scope) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
  JSAutoRealm tempRealm(cx, scope);
  JS::Rooted<JS::Value> v(cx);
  if(!ToJSValue(cx, self, &v)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
  // This is a reflector, but due to trying to name things
  // similarly across method generators, it's called obj here.
  JS::Rooted<JSObject*> obj(cx);
  obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
  JSAutoRealm reflectorRealm(cx, obj);
  JS::RootedVector<JS::Value> argv(cx);
  if (!argv.resize(1)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
  do {
    if (!xpc::NonVoidStringToJsval(cx, aKey, argv[0])) {
      aRv.Throw(NS_ERROR_UNEXPECTED);
      return;
    }
    break;
  } while (false);

  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
  }
  if (!JS::SetAdd(cx, backingObj, argv[0])) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return;
  }
}
} // namespace SetlikeHelpers

MOZ_CAN_RUN_SCRIPT static bool
get_size(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "WGSLLanguageFeatures", "size", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::WGSLLanguageFeatures*>(void_self);
  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    return false;
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
  }
  uint32_t result = JS::SetSize(cx, backingObj);
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
  args.rval().setNumber(result);
  return true;
}

static const JSJitInfo size_getterinfo = {
  { get_size },
  { prototypes::id::WGSLLanguageFeatures },
  { PrototypeTraits<prototypes::id::WGSLLanguageFeatures>::Depth },
  JSJitInfo::Getter,
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
  true,  /* 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. */
};

MOZ_CAN_RUN_SCRIPT static bool
entries(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "WGSLLanguageFeatures", "entries", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::WGSLLanguageFeatures*>(void_self);
  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    return false;
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
  }
  // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
  // after bug 1023984 is fixed.
  if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    return false;
  }
  JS::Rooted<JSObject*> result(cx);
  JS::Rooted<JS::Value> v(cx);
  if (!JS::SetEntries(cx, backingObj, &v)) {
    return false;
  }
  result = &v.toObject();
  JS::ExposeObjectToActiveJS(result);
  args.rval().setObject(*result);
  if (!MaybeWrapObjectValue(cx, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo::ArgType entries_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
static const JSTypedMethodJitInfo entries_methodinfo = {
  {
    { (JSJitGetterOp)entries },
    { prototypes::id::WGSLLanguageFeatures },
    { PrototypeTraits<prototypes::id::WGSLLanguageFeatures>::Depth },
    JSJitInfo::Method,
    JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    JSVAL_TYPE_OBJECT,  /* 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. */
    true,  /* isTypedMethod.  Only relevant for methods. */
    0   /* Reserved slot index, if we're stored in a slot, else 0. */
  },
  entries_methodinfo_argTypes
};

MOZ_CAN_RUN_SCRIPT static bool
keys(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "WGSLLanguageFeatures", "keys", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::WGSLLanguageFeatures*>(void_self);
  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    return false;
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
  }
  // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
  // after bug 1023984 is fixed.
  if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    return false;
  }
  JS::Rooted<JSObject*> result(cx);
  JS::Rooted<JS::Value> v(cx);
  if (!JS::SetKeys(cx, backingObj, &v)) {
    return false;
  }
  result = &v.toObject();
  JS::ExposeObjectToActiveJS(result);
  args.rval().setObject(*result);
  if (!MaybeWrapObjectValue(cx, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo::ArgType keys_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
static const JSTypedMethodJitInfo keys_methodinfo = {
  {
    { (JSJitGetterOp)keys },
    { prototypes::id::WGSLLanguageFeatures },
    { PrototypeTraits<prototypes::id::WGSLLanguageFeatures>::Depth },
    JSJitInfo::Method,
    JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    JSVAL_TYPE_OBJECT,  /* 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. */
    true,  /* isTypedMethod.  Only relevant for methods. */
    0   /* Reserved slot index, if we're stored in a slot, else 0. */
  },
  keys_methodinfo_argTypes
};

MOZ_CAN_RUN_SCRIPT static bool
values(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "WGSLLanguageFeatures", "values", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::WGSLLanguageFeatures*>(void_self);
  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    return false;
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
  }
  // TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
  // after bug 1023984 is fixed.
  if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
    JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
    return false;
  }
  JS::Rooted<JSObject*> result(cx);
  JS::Rooted<JS::Value> v(cx);
  if (!JS::SetValues(cx, backingObj, &v)) {
    return false;
  }
  result = &v.toObject();
  JS::ExposeObjectToActiveJS(result);
  args.rval().setObject(*result);
  if (!MaybeWrapObjectValue(cx, args.rval())) {
    return false;
  }
  return true;
}

static const JSJitInfo::ArgType values_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
static const JSTypedMethodJitInfo values_methodinfo = {
  {
    { (JSJitGetterOp)values },
    { prototypes::id::WGSLLanguageFeatures },
    { PrototypeTraits<prototypes::id::WGSLLanguageFeatures>::Depth },
    JSJitInfo::Method,
    JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
    JSVAL_TYPE_OBJECT,  /* 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. */
    true,  /* isTypedMethod.  Only relevant for methods. */
    0   /* Reserved slot index, if we're stored in a slot, else 0. */
  },
  values_methodinfo_argTypes
};

MOZ_CAN_RUN_SCRIPT static bool
forEach(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  BindingCallContext cx(cx_, "WGSLLanguageFeatures.forEach");
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "WGSLLanguageFeatures", "forEach", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::WGSLLanguageFeatures*>(void_self);
  JS::Rooted<JSObject*> arg0(cx);
  if (args.get(0).isObject()) {
    arg0 = &args.get(0).toObject();
  } else {
    cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
    return false;
  }
  JS::Rooted<JS::Value> arg1(cx);
  if (args.hasDefined(1)) {
    arg1 = args.get(1);
  } else {
    arg1 = JS::UndefinedValue();
  }
  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    return false;
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
  }
  // Create a wrapper function.
  JSFunction* func = js::NewFunctionWithReserved(cx, ForEachHandler, 3, 0, nullptr);
  if (!func) {
    return false;
  }
  JS::Rooted<JSObject*> funcObj(cx, JS_GetFunctionObject(func));
  JS::Rooted<JS::Value> funcVal(cx, JS::ObjectValue(*funcObj));
  js::SetFunctionNativeReserved(funcObj, FOREACH_CALLBACK_SLOT,
                                JS::ObjectValue(*arg0));
  js::SetFunctionNativeReserved(funcObj, FOREACH_MAPLIKEORSETLIKEOBJ_SLOT,
                                JS::ObjectValue(*obj));
  if (!JS::SetForEach(cx, backingObj, funcVal, arg1)) {
    return false;
  }
  args.rval().setUndefined();
  return true;
}

static const JSJitInfo forEach_methodinfo = {
  { (JSJitGetterOp)forEach },
  { prototypes::id::WGSLLanguageFeatures },
  { PrototypeTraits<prototypes::id::WGSLLanguageFeatures>::Depth },
  JSJitInfo::Method,
  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. */
};

MOZ_CAN_RUN_SCRIPT static bool
has(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
  AUTO_PROFILER_LABEL_DYNAMIC_FAST(
    "WGSLLanguageFeatures", "has", DOM, cx,
    uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
    uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));

  auto* self = static_cast<mozilla::webgpu::WGSLLanguageFeatures*>(void_self);
  binding_detail::FakeString<char16_t> arg0;
  if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
    return false;
  }
  JS::Rooted<JSObject*> backingObj(cx);
  bool created = false;
  if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
    return false;
  }
  if (created) {
    PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
  }
  JS::Rooted<JS::Value> arg0Val(cx);
  if (!ToJSValue(cx, arg0, &arg0Val)) {
    return false;
  }
  bool result;
  if (!JS::SetHas(cx, backingObj, arg0Val, &result)) {
    return false;
  }
  args.rval().setBoolean(result);
  return true;
}

static const JSJitInfo::ArgType has_methodinfo_argTypes[] = { JSJitInfo::String, JSJitInfo::ArgTypeListEnd };
static const JSTypedMethodJitInfo has_methodinfo = {
  {
    { (JSJitGetterOp)has },
    { prototypes::id::WGSLLanguageFeatures },
    { PrototypeTraits<prototypes::id::WGSLLanguageFeatures>::Depth },
    JSJitInfo::Method,
    JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
    JSVAL_TYPE_BOOLEAN,  /* 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. */
    true,  /* isTypedMethod.  Only relevant for methods. */
    0   /* Reserved slot index, if we're stored in a slot, else 0. */
  },
  has_methodinfo_argTypes
};

static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
  mozilla::webgpu::WGSLLanguageFeatures* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::WGSLLanguageFeatures>(obj);
  if (self) {
    JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
    ClearWrapper(self, self, obj);
    if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
      JS::RemoveAssociatedMemory(obj, mallocBytes,
                                 JS::MemoryUse::DOMBinding);
    }
    AddForDeferredFinalization<mozilla::webgpu::WGSLLanguageFeatures>(self);
  }
}

MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
  JS_FNSPEC("entries", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&entries_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("keys", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&keys_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("values", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&values_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("forEach", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&forEach_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FNSPEC("has", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&has_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
  JS_FS_END
};


static const Prefable<const JSFunctionSpec> sMethods[] = {
  { nullptr, &sMethods_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(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");

MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
  JSPropertySpec::nativeAccessors("size", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &size_getterinfo, nullptr, nullptr),
  JS_PS_END
};


static const Prefable<const JSPropertySpec> sAttributes[] = {
  { nullptr, &sAttributes_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(1 <= 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[6];
static PropertyInfo sNativeProperties_propertyInfos[6];

static const NativePropertiesN<2> sNativeProperties = {
  false, 0,
  false, 0,
  true,  0 /* sMethods */,
  true,  1 /* sAttributes */,
  false, 0,
  false, 0,
  false, 0,
  2,
  6,
  sNativeProperties_sortedPropertyIndices,
  {
    { sMethods, &sNativeProperties_propertyInfos[0] },
    { sAttributes, &sNativeProperties_propertyInfos[5] }
  }
};
static_assert(2 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.iteratorAliasMethodIndex) - 1),
    "We have an iterator alias index that is oversized");
static_assert(6 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
    "We have a property info count that is oversized");

// This may allocate too many slots, because we only really need
// slots for our non-interface-typed members that we cache.  But
// allocating slots only for those would make the slot index
// computations much more complicated, so let's do this the simple
// way for now.
DEFINE_XRAY_EXPANDO_CLASS_WITH_OPS(static, sXrayExpandoObjectClass, 1,
                                   &xpc::XrayExpandoObjectClassOps);

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

static const DOMInterfaceInfo sInterfaceObjectInfo = {
  { ThrowingConstructor, &sNativePropertyHooks },
  JS::GetRealmFunctionPrototypeHandle,
  PrototypeTraits<prototypes::id::WGSLLanguageFeatures>::Depth,
  prototypes::id::WGSLLanguageFeatures,
  true,
  0,
  "WGSLLanguageFeatures",
};

static const DOMIfaceAndProtoJSClass sPrototypeClass = {
  {
    "WGSLLanguageFeaturesPrototype",
    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,
  prototypes::id::WGSLLanguageFeatures,
  PrototypeTraits<prototypes::id::WGSLLanguageFeatures>::Depth,
  &sNativePropertyHooks,
  JS::GetRealmObjectPrototype
};

bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
  return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
         mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);

static const JSClassOps sClassOps = {
  nullptr,               /* addProperty */
  nullptr,               /* delProperty */
  nullptr,               /* enumerate */
  nullptr, /* newEnumerate */
  nullptr, /* resolve */
  nullptr, /* mayResolve */
  _finalize, /* finalize */
  nullptr, /* call */
  nullptr,               /* construct */
  nullptr, /* trace */
};

static const DOMJSClass sClass = {
  { "WGSLLanguageFeatures",
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_PRESERVES_WRAPPER,
    &sClassOps,
    JS_NULL_CLASS_SPEC,
    &NativeTypeHelpers<mozilla::webgpu::WGSLLanguageFeatures>::sClassExtension,
    JS_NULL_OBJECT_OPS
  },
  { prototypes::id::WGSLLanguageFeatures, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
  std::is_base_of_v<nsISupports, mozilla::webgpu::WGSLLanguageFeatures>,
  &sNativePropertyHooks,
  FindAssociatedGlobalForNative<mozilla::webgpu::WGSLLanguageFeatures>::Get,
  GetProtoObjectHandle,
  GetCCParticipant<mozilla::webgpu::WGSLLanguageFeatures>::Get(),
  nullptr,
  NativeTypeHelpers<mozilla::webgpu::WGSLLanguageFeatures>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
              "Must have the right minimal number of reserved slots.");
static_assert(2 >= 2,
              "Must have enough reserved slots.");

bool
Wrap(JSContext* aCx, mozilla::webgpu::WGSLLanguageFeatures* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
  static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::WGSLLanguageFeatures>,
                "Shouldn't have wrappercached things that are not refcounted.");
  static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::WGSLLanguageFeatures*>);
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
  MOZ_ASSERT(!aCache->GetWrapper(),
             "You should probably not be using Wrap() directly; use "
             "GetOrCreateDOMReflector instead");

  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
             "nsISupports must be on our primary inheritance chain");

  // If the wrapper cache contains a dead reflector then finalize that
  // now, ensuring that the finalizer for the old reflector always
  // runs before the new reflector is created and attached. This
  // avoids the awkward situation where there are multiple reflector
  // objects that contain pointers to the same native.

  if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
    _finalize(nullptr /* unused */, oldReflector);
    MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
  }

  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
  if (!global) {
    return false;
  }
  MOZ_ASSERT(JS_IsGlobalObject(global));
  JS::AssertObjectIsNotGray(global);

  // That might have ended up wrapping us already, due to the wonders
  // of XBL.  Check for that, and bail out as needed.
  aReflector.set(aCache->GetWrapper());
  if (aReflector) {
#ifdef DEBUG
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
    return true;
  }

  JSAutoRealm ar(aCx, global);
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
  if (!canonicalProto) {
    return false;
  }
  JS::Rooted<JSObject*> proto(aCx);
  if (aGivenProto) {
    proto = aGivenProto;
    // Unfortunately, while aGivenProto was in the compartment of aCx
    // coming in, we changed compartments to that of "parent" so may need
    // to wrap the proto here.
    if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
      if (!JS_WrapObject(aCx, &proto)) {
        return false;
      }
    }
  } else {
    proto = canonicalProto;
  }

  BindingJSObjectCreator<mozilla::webgpu::WGSLLanguageFeatures> creator(aCx);
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
  if (!aReflector) {
    return false;
  }

  aCache->SetWrapper(aReflector);
  creator.InitializationSucceeded();

  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
             aCache->GetWrapperPreserveColor() == aReflector);
  // If proto != canonicalProto, we have to preserve our wrapper;
  // otherwise we won't be able to properly recreate it later, since
  // we won't know what proto to use.  Note that we don't check
  // aGivenProto here, since it's entirely possible (and even
  // somewhat common) to have a non-null aGivenProto which is the
  // same as canonicalProto.
  if (proto != canonicalProto) {
    PreserveWrapper(aObject);
  }

  return true;
}

void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::WGSLLanguageFeatures);
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::WGSLLanguageFeatures);

  JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
  if (!parentProto) {
    return;
  }

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

  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
                              &sPrototypeClass, protoCache,
                              constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
                              interfaceCache,
                              sNativeProperties.Upcast(),
                              nullptr,
                              "WGSLLanguageFeatures",
                              ShouldExpose<WGSLLanguageFeatures_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
                              nullptr,
                              false,
                              nullptr);

  JS::AssertObjectIsNotGray(*protoCache);
  JS::Handle<JSObject*> proto = JS::Handle<JSObject*>::fromMarkedLocation(protoCache->unsafeAddress());
  if (!proto) {
    *protoCache = nullptr;
    if (interfaceCache) {
      *interfaceCache = nullptr;
    }
    return;
  }

  // Set up aliases on the interface prototype object we just created.
  JS::Rooted<JS::Value> aliasedVal(aCx);

  if (!JS_GetProperty(aCx, proto, "values", &aliasedVal)) {
    *protoCache = nullptr;
    if (interfaceCache) {
      *interfaceCache = nullptr;
    }
    return;
  }
  JS::Rooted<jsid> iteratorId(aCx, JS::GetWellKnownSymbolKey(aCx, JS::SymbolCode::iterator));
  if (!JS_DefinePropertyById(aCx, proto, iteratorId, aliasedVal, 0)) {
    *protoCache = nullptr;
    if (interfaceCache) {
      *interfaceCache = nullptr;
    }
    return;
  }
}

static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
  /* Get the interface prototype object for this class.  This will create the
     object as needed. */
  return GetPerInterfaceObjectHandle(aCx, prototypes::id::WGSLLanguageFeatures,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);

}

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::WGSLLanguageFeatures,
                                     &CreateInterfaceObjects,
                                     DefineInterfaceProperty::CheckExposure);
}

} // namespace WGSLLanguageFeatures_Binding



} // namespace dom


} // namespace mozilla
