Copy as Markdown

Other Tools

/* THIS FILE IS AUTOGENERATED FROM WebGPU.webidl BY Codegen.py - DO NOT EDIT */
#include <type_traits>
#include "AtomList.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/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/RootedDictionary.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/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/Instance.h"
#include "mozilla/webgpu/InternalError.h"
#include "mozilla/webgpu/OutOfMemoryError.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 "nsThreadUtils.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 {
const nsLiteralCString EnumStrings<GPUPowerPreference>::Values[2] = {
"low-power"_ns,
"high-performance"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUPowerPreference aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUFeatureName>::Values[11] = {
"depth-clip-control"_ns,
"depth32float-stencil8"_ns,
"texture-compression-bc"_ns,
"texture-compression-etc2"_ns,
"texture-compression-astc"_ns,
"timestamp-query"_ns,
"indirect-first-instance"_ns,
"shader-f16"_ns,
"rg11b10ufloat-renderable"_ns,
"bgra8unorm-storage"_ns,
"float32-filterable"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUFeatureName aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUBufferMapState>::Values[3] = {
"unmapped"_ns,
"pending"_ns,
"mapped"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUBufferMapState aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUTextureDimension>::Values[3] = {
"1d"_ns,
"2d"_ns,
"3d"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUTextureDimension aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUTextureViewDimension>::Values[6] = {
"1d"_ns,
"2d"_ns,
"2d-array"_ns,
"cube"_ns,
"cube-array"_ns,
"3d"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUTextureViewDimension aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUTextureAspect>::Values[3] = {
"all"_ns,
"stencil-only"_ns,
"depth-only"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUTextureAspect aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUTextureFormat>::Values[56] = {
"r8unorm"_ns,
"r8snorm"_ns,
"r8uint"_ns,
"r8sint"_ns,
"r16uint"_ns,
"r16sint"_ns,
"r16float"_ns,
"rg8unorm"_ns,
"rg8snorm"_ns,
"rg8uint"_ns,
"rg8sint"_ns,
"r32uint"_ns,
"r32sint"_ns,
"r32float"_ns,
"rg16uint"_ns,
"rg16sint"_ns,
"rg16float"_ns,
"rgba8unorm"_ns,
"rgba8unorm-srgb"_ns,
"rgba8snorm"_ns,
"rgba8uint"_ns,
"rgba8sint"_ns,
"bgra8unorm"_ns,
"bgra8unorm-srgb"_ns,
"rgb9e5ufloat"_ns,
"rgb10a2unorm"_ns,
"rg11b10ufloat"_ns,
"rg32uint"_ns,
"rg32sint"_ns,
"rg32float"_ns,
"rgba16uint"_ns,
"rgba16sint"_ns,
"rgba16float"_ns,
"rgba32uint"_ns,
"rgba32sint"_ns,
"rgba32float"_ns,
"stencil8"_ns,
"depth16unorm"_ns,
"depth24plus"_ns,
"depth24plus-stencil8"_ns,
"depth32float"_ns,
"depth32float-stencil8"_ns,
"bc1-rgba-unorm"_ns,
"bc1-rgba-unorm-srgb"_ns,
"bc2-rgba-unorm"_ns,
"bc2-rgba-unorm-srgb"_ns,
"bc3-rgba-unorm"_ns,
"bc3-rgba-unorm-srgb"_ns,
"bc4-r-unorm"_ns,
"bc4-r-snorm"_ns,
"bc5-rg-unorm"_ns,
"bc5-rg-snorm"_ns,
"bc6h-rgb-ufloat"_ns,
"bc6h-rgb-float"_ns,
"bc7-rgba-unorm"_ns,
"bc7-rgba-unorm-srgb"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUTextureFormat aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUAddressMode>::Values[3] = {
"clamp-to-edge"_ns,
"repeat"_ns,
"mirror-repeat"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUAddressMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUFilterMode>::Values[2] = {
"nearest"_ns,
"linear"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUFilterMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUMipmapFilterMode>::Values[2] = {
"nearest"_ns,
"linear"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUMipmapFilterMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUCompareFunction>::Values[8] = {
"never"_ns,
"less"_ns,
"equal"_ns,
"less-equal"_ns,
"greater"_ns,
"not-equal"_ns,
"greater-equal"_ns,
"always"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUCompareFunction aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUBufferBindingType>::Values[3] = {
"uniform"_ns,
"storage"_ns,
"read-only-storage"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUBufferBindingType aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUSamplerBindingType>::Values[3] = {
"filtering"_ns,
"non-filtering"_ns,
"comparison"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUSamplerBindingType aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUTextureSampleType>::Values[5] = {
"float"_ns,
"unfilterable-float"_ns,
"depth"_ns,
"sint"_ns,
"uint"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUTextureSampleType aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUStorageTextureAccess>::Values[3] = {
"write-only"_ns,
"read-only"_ns,
"read-write"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUStorageTextureAccess aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUCompilationMessageType>::Values[3] = {
"error"_ns,
"warning"_ns,
"info"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUCompilationMessageType aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUAutoLayoutMode>::Values[1] = {
"auto"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUAutoLayoutMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUPrimitiveTopology>::Values[5] = {
"point-list"_ns,
"line-list"_ns,
"line-strip"_ns,
"triangle-list"_ns,
"triangle-strip"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUPrimitiveTopology aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUFrontFace>::Values[2] = {
"ccw"_ns,
"cw"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUFrontFace aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUCullMode>::Values[3] = {
"none"_ns,
"front"_ns,
"back"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUCullMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUBlendFactor>::Values[13] = {
"zero"_ns,
"one"_ns,
"src"_ns,
"one-minus-src"_ns,
"src-alpha"_ns,
"one-minus-src-alpha"_ns,
"dst"_ns,
"one-minus-dst"_ns,
"dst-alpha"_ns,
"one-minus-dst-alpha"_ns,
"src-alpha-saturated"_ns,
"constant"_ns,
"one-minus-constant"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUBlendFactor aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUBlendOperation>::Values[5] = {
"add"_ns,
"subtract"_ns,
"reverse-subtract"_ns,
"min"_ns,
"max"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUBlendOperation aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUStencilOperation>::Values[8] = {
"keep"_ns,
"zero"_ns,
"replace"_ns,
"invert"_ns,
"increment-clamp"_ns,
"decrement-clamp"_ns,
"increment-wrap"_ns,
"decrement-wrap"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUStencilOperation aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUIndexFormat>::Values[2] = {
"uint16"_ns,
"uint32"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUIndexFormat aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUVertexFormat>::Values[30] = {
"uint8x2"_ns,
"uint8x4"_ns,
"sint8x2"_ns,
"sint8x4"_ns,
"unorm8x2"_ns,
"unorm8x4"_ns,
"snorm8x2"_ns,
"snorm8x4"_ns,
"uint16x2"_ns,
"uint16x4"_ns,
"sint16x2"_ns,
"sint16x4"_ns,
"unorm16x2"_ns,
"unorm16x4"_ns,
"snorm16x2"_ns,
"snorm16x4"_ns,
"float16x2"_ns,
"float16x4"_ns,
"float32"_ns,
"float32x2"_ns,
"float32x3"_ns,
"float32x4"_ns,
"uint32"_ns,
"uint32x2"_ns,
"uint32x3"_ns,
"uint32x4"_ns,
"sint32"_ns,
"sint32x2"_ns,
"sint32x3"_ns,
"sint32x4"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUVertexFormat aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUVertexStepMode>::Values[2] = {
"vertex"_ns,
"instance"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUVertexStepMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPULoadOp>::Values[2] = {
"load"_ns,
"clear"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPULoadOp aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUStoreOp>::Values[2] = {
"store"_ns,
"discard"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUStoreOp aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUPipelineStatisticName>::Values[5] = {
"vertex-shader-invocations"_ns,
"clipper-invocations"_ns,
"clipper-primitives-out"_ns,
"fragment-shader-invocations"_ns,
"compute-shader-invocations"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUPipelineStatisticName aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(binding_detail::EnumStrings<GPUPipelineStatisticName>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUPipelineStatisticName>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUPipelineStatisticName>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
const nsLiteralCString EnumStrings<GPUQueryType>::Values[3] = {
"occlusion"_ns,
"pipeline-statistics"_ns,
"timestamp"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUQueryType aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUCanvasAlphaMode>::Values[2] = {
"opaque"_ns,
"premultiplied"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUCanvasAlphaMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUDeviceLostReason>::Values[1] = {
"destroyed"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUDeviceLostReason aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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 {
const nsLiteralCString EnumStrings<GPUErrorFilter>::Values[3] = {
"validation"_ns,
"out-of-memory"_ns,
"internal"_ns,
};
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUErrorFilter aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(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, OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsGPUSampler()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUSampler(), "mGPUSampler", aFlags);
} else if (aUnion.IsGPUTextureView()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUTextureView(), "mGPUTextureView", aFlags);
} else if (aUnion.IsGPUBufferBinding()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUBufferBinding(), "mGPUBufferBinding", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsImageBitmap()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsImageBitmap(), "mImageBitmap", 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(OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas& 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);
}
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;
}
bool
GPUColorDict::operator==(const GPUColorDict& aOther) const
{
if (mA != aOther.mA) {
return false;
}
if (mB != aOther.mB) {
return false;
}
if (mG != aOther.mG) {
return false;
}
if (mR != aOther.mR) {
return false;
}
return true;
}
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;
}
bool
GPUExtent3DDict::operator==(const GPUExtent3DDict& aOther) const
{
if (mDepthOrArrayLayers != aOther.mDepthOrArrayLayers) {
return false;
}
if (mHeight != aOther.mHeight) {
return false;
}
if (mWidth != aOther.mWidth) {
return false;
}
return true;
}
GPUImageDataLayout::GPUImageDataLayout()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUImageDataLayout::InitIds(JSContext* cx, GPUImageDataLayoutAtoms* 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
GPUImageDataLayout::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());
GPUImageDataLayoutAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUImageDataLayoutAtoms>(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 GPUImageDataLayout", &(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 GPUImageDataLayout", &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 GPUImageDataLayout", &(mRowsPerImage.Value()))) {
return false;
}
mIsAnyMemberPresent = true;
}
return true;
}
bool
GPUImageDataLayout::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
GPUImageDataLayout::TraceDictionary(JSTracer* trc)
{
}
GPUImageDataLayout&
GPUImageDataLayout::operator=(const GPUImageDataLayout& 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;
}
bool
GPUImageDataLayout::operator==(const GPUImageDataLayout& aOther) const
{
if (mBytesPerRow != aOther.mBytesPerRow) {
return false;
}
if (mOffset != aOther.mOffset) {
return false;
}
if (mRowsPerImage != aOther.mRowsPerImage) {
return false;
}
return true;
}
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;
}
bool
GPUMultisampleState::operator==(const GPUMultisampleState& aOther) const
{
if (mAlphaToCoverageEnabled != aOther.mAlphaToCoverageEnabled) {
return false;
}
if (mCount != aOther.mCount) {
return false;
}
if (mMask != aOther.mMask) {
return false;
}
return true;
}
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;
}
bool
GPUObjectDescriptorBase::operator==(const GPUObjectDescriptorBase& aOther) const
{
if (mLabel != aOther.mLabel) {
return false;
}
return true;
}
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;
}
bool
GPUOrigin2DDict::operator==(const GPUOrigin2DDict& aOther) const
{
if (mX != aOther.mX) {
return false;
}
if (mY != aOther.mY) {
return false;
}
return true;
}
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;
}
bool
GPUOrigin3DDict::operator==(const GPUOrigin3DDict& aOther) const
{
if (mX != aOther.mX) {
return false;
}
if (mY != aOther.mY) {
return false;
}
if (mZ != aOther.mZ) {
return false;
}
return true;
}
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")) {
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->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)
{
}
GPUProgrammableStage&
GPUProgrammableStage::operator=(const GPUProgrammableStage& aOther)
{
DictionaryBase::operator=(aOther);
mEntryPoint.Reset();
if (aOther.mEntryPoint.WasPassed()) {
mEntryPoint.Construct(aOther.mEntryPoint.Value());
}
mModule = aOther.mModule;
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 (temp.ref().isObject()) {
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>(temp.ptr(), mView, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'view' member of GPURenderPassDepthStencilAttachment", "GPUTextureView");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'view' member of GPURenderPassDepthStencilAttachment");
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;
}
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->powerPreference_id.init(cx, "powerPreference") ||
!atomsCache->forceFallbackAdapter_id.init(cx, "forceFallbackAdapter")) {
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->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;
}
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);
mForceFallbackAdapter = aOther.mForceFallbackAdapter;
mPowerPreference.Reset();
if (aOther.mPowerPreference.WasPassed()) {
mPowerPreference.Construct(aOther.mPowerPreference.Value());
}
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;
}
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;
}
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
ImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::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
ImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::TrySetToImageBitmap(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToImageBitmap(cx, value, tryNext, passedToJSImpl);
}
bool
ImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::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
ImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLCanvasElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToHTMLCanvasElement(cx, value, tryNext, passedToJSImpl);
}
bool
ImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::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
ImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::TrySetToOffscreenCanvas(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToOffscreenCanvas(cx, value, tryNext, passedToJSImpl);
}
bool
ImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::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 = !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, HTMLCanvasElement, OffscreenCanvas");
return false;
}
return true;
}
bool
ImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::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 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;
}
}
}
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas(OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas&& 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 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
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::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
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::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>&
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::RawSetAsImageBitmap()
{
if (mType == eImageBitmap) {
return mValue.mImageBitmap.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eImageBitmap;
return mValue.mImageBitmap.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::ImageBitmap>&
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::SetAsImageBitmap()
{
if (mType == eImageBitmap) {
return mValue.mImageBitmap.Value();
}
Uninit();
mType = eImageBitmap;
return mValue.mImageBitmap.SetValue();
}
void
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::DestroyImageBitmap()
{
MOZ_RELEASE_ASSERT(IsImageBitmap(), "Wrong type!");
mValue.mImageBitmap.Destroy();
mType = eUninitialized;
}
bool
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::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
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::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>&
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::RawSetAsHTMLCanvasElement()
{
if (mType == eHTMLCanvasElement) {
return mValue.mHTMLCanvasElement.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eHTMLCanvasElement;
return mValue.mHTMLCanvasElement.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::HTMLCanvasElement>&
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::SetAsHTMLCanvasElement()
{
if (mType == eHTMLCanvasElement) {
return mValue.mHTMLCanvasElement.Value();
}
Uninit();
mType = eHTMLCanvasElement;
return mValue.mHTMLCanvasElement.SetValue();
}
void
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::DestroyHTMLCanvasElement()
{
MOZ_RELEASE_ASSERT(IsHTMLCanvasElement(), "Wrong type!");
mValue.mHTMLCanvasElement.Destroy();
mType = eUninitialized;
}
bool
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::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
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::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>&
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::RawSetAsOffscreenCanvas()
{
if (mType == eOffscreenCanvas) {
return mValue.mOffscreenCanvas.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eOffscreenCanvas;
return mValue.mOffscreenCanvas.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::OffscreenCanvas>&
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::SetAsOffscreenCanvas()
{
if (mType == eOffscreenCanvas) {
return mValue.mOffscreenCanvas.Value();
}
Uninit();
mType = eOffscreenCanvas;
return mValue.mOffscreenCanvas.SetValue();
}
void
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::DestroyOffscreenCanvas()
{
MOZ_RELEASE_ASSERT(IsOffscreenCanvas(), "Wrong type!");
mValue.mOffscreenCanvas.Destroy();
mType = eUninitialized;
}
bool
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::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 = !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, HTMLCanvasElement, OffscreenCanvas");
return false;
}
return true;
}
bool
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eImageBitmap: {
DestroyImageBitmap();
break;
}
case eHTMLCanvasElement: {
DestroyHTMLCanvasElement();
break;
}
case eOffscreenCanvas: {
DestroyOffscreenCanvas();
break;
}
}
}
bool
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::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 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;
}
}
}
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas&
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::operator=(OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas&& aOther)
{
this->~OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas();
new (this) OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas (std::move(aOther));
return *this;
}
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas&
OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas::operator=(const OwningImageBitmapOrHTMLCanvasElementOrOffscreenCanvas& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eImageBitmap: {
SetAsImageBitmap() = aOther.GetAsImageBitmap();
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->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->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());
}
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;
}
bool
GPUBufferDescriptor::operator==(const GPUBufferDescriptor& aOther) const
{
if (mMappedAtCreation != aOther.mMappedAtCreation) {
return false;
}
if (mSize != aOther.mSize) {
return false;
}
if (mUsage != aOther.mUsage) {
return false;
}
return true;
}
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;
}
bool
GPUCommandBufferDescriptor::operator==(const GPUCommandBufferDescriptor& aOther) const
{
return true;
}
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;
}
bool
GPUCommandEncoderDescriptor::operator==(const GPUCommandEncoderDescriptor& aOther) const
{
return true;
}
GPUComputePassDescriptor::GPUComputePassDescriptor()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
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());
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
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);
return *this;
}
bool
GPUComputePassDescriptor::operator==(const GPUComputePassDescriptor& aOther) const
{
return true;
}
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;
}
GPUImageCopyBuffer::GPUImageCopyBuffer()
: GPUImageDataLayout(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUImageCopyBuffer::InitIds(JSContext* cx, GPUImageCopyBufferAtoms* 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
GPUImageCopyBuffer::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());
GPUImageCopyBufferAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUImageCopyBufferAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUImageDataLayout::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 GPUImageCopyBuffer", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'buffer' member of GPUImageCopyBuffer");
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 GPUImageCopyBuffer");
}
return true;
}
bool
GPUImageCopyBuffer::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
GPUImageCopyBuffer::TraceDictionary(JSTracer* trc)
{
GPUImageDataLayout::TraceDictionary(trc);
}
GPUImageCopyBuffer&
GPUImageCopyBuffer::operator=(const GPUImageCopyBuffer& aOther)
{
GPUImageDataLayout::operator=(aOther);
mBuffer = aOther.mBuffer;
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();
}
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->pipelineStatistics_id.init(cx, "pipelineStatistics") ||
!atomsCache->count_id.init(cx, "count")) {
return false;
}
return true;
}
bool
GPUQuerySetDescriptor::Init(const char* sourceDescription, bool passedToJSImpl)
{
// We init the parent's members first
if (!GPUObjectDescriptorBase::Init(nullptr, JS::NullHandleValue)) {
return false;
}
{
// scope for any temporaries our default value setting needs.
/* mPipelineStatistics array is already empty; nothing to do */
}
mIsAnyMemberPresent = true;
return true;
}
void
GPUQuerySetDescriptor::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPUQuerySetDescriptor&
GPUQuerySetDescriptor::operator=(const GPUQuerySetDescriptor& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
mCount = aOther.mCount;
mPipelineStatistics = aOther.mPipelineStatistics;
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;
}
bool
GPUQueueDescriptor::operator==(const GPUQueueDescriptor& aOther) const
{
return true;
}
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;
}
bool
GPURenderBundleDescriptor::operator==(const GPURenderBundleDescriptor& aOther) const
{
return true;
}
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 = 1000.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
GPUSamplerOrGPUTextureViewOrGPUBufferBinding::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
GPUSamplerOrGPUTextureViewOrGPUBufferBinding::TrySetToGPUSampler(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUSampler(cx, value, tryNext, passedToJSImpl);
}
bool
GPUSamplerOrGPUTextureViewOrGPUBufferBinding::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
GPUSamplerOrGPUTextureViewOrGPUBufferBinding::TrySetToGPUTextureView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUTextureView(cx, value, tryNext, passedToJSImpl);
}
bool
GPUSamplerOrGPUTextureViewOrGPUBufferBinding::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 GPUTextureView or GPUBufferBinding)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
GPUSamplerOrGPUTextureViewOrGPUBufferBinding::TrySetToGPUBufferBinding(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUBufferBinding(cx, value, tryNext, passedToJSImpl);
}
bool
GPUSamplerOrGPUTextureViewOrGPUBufferBinding::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 = !TrySetToGPUTextureView(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, GPUTextureView, GPUBufferBinding");
return false;
}
return true;
}
bool
GPUSamplerOrGPUTextureViewOrGPUBufferBinding::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding(OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding&& 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 eGPUTextureView: {
mType = eGPUTextureView;
mValue.mGPUTextureView.SetValue(std::move(aOther.mValue.mGPUTextureView.Value()));
break;
}
case eGPUBufferBinding: {
mType = eGPUBufferBinding;
mValue.mGPUBufferBinding.SetValue(std::move(aOther.mValue.mGPUBufferBinding.Value()));
break;
}
}
}
bool
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::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
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::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>&
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::RawSetAsGPUSampler()
{
if (mType == eGPUSampler) {
return mValue.mGPUSampler.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eGPUSampler;
return mValue.mGPUSampler.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::webgpu::Sampler>&
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::SetAsGPUSampler()
{
if (mType == eGPUSampler) {
return mValue.mGPUSampler.Value();
}
Uninit();
mType = eGPUSampler;
return mValue.mGPUSampler.SetValue();
}
void
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::DestroyGPUSampler()
{
MOZ_RELEASE_ASSERT(IsGPUSampler(), "Wrong type!");
mValue.mGPUSampler.Destroy();
mType = eUninitialized;
}
bool
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::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
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::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>&
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::RawSetAsGPUTextureView()
{
if (mType == eGPUTextureView) {
return mValue.mGPUTextureView.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eGPUTextureView;
return mValue.mGPUTextureView.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::webgpu::TextureView>&
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::SetAsGPUTextureView()
{
if (mType == eGPUTextureView) {
return mValue.mGPUTextureView.Value();
}
Uninit();
mType = eGPUTextureView;
return mValue.mGPUTextureView.SetValue();
}
void
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::DestroyGPUTextureView()
{
MOZ_RELEASE_ASSERT(IsGPUTextureView(), "Wrong type!");
mValue.mGPUTextureView.Destroy();
mType = eUninitialized;
}
bool
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::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 GPUTextureView or GPUBufferBinding)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::TrySetToGPUBufferBinding(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUBufferBinding(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] GPUBufferBinding&
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::RawSetAsGPUBufferBinding()
{
if (mType == eGPUBufferBinding) {
return mValue.mGPUBufferBinding.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eGPUBufferBinding;
return mValue.mGPUBufferBinding.SetValue();
}
[[nodiscard]] GPUBufferBinding&
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::SetAsGPUBufferBinding()
{
if (mType == eGPUBufferBinding) {
return mValue.mGPUBufferBinding.Value();
}
Uninit();
mType = eGPUBufferBinding;
return mValue.mGPUBufferBinding.SetValue();
}
void
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::DestroyGPUBufferBinding()
{
MOZ_RELEASE_ASSERT(IsGPUBufferBinding(), "Wrong type!");
mValue.mGPUBufferBinding.Destroy();
mType = eUninitialized;
}
bool
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::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 = !TrySetToGPUTextureView(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, GPUTextureView, GPUBufferBinding");
return false;
}
return true;
}
bool
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eGPUSampler: {
DestroyGPUSampler();
break;
}
case eGPUTextureView: {
DestroyGPUTextureView();
break;
}
case eGPUBufferBinding: {
DestroyGPUBufferBinding();
break;
}
}
}
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding&
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::operator=(OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding&& aOther)
{
this->~OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding();
new (this) OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding (std::move(aOther));
return *this;
}
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding&
OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding::operator=(const OwningGPUSamplerOrGPUTextureViewOrGPUBufferBinding& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eGPUSampler: {
SetAsGPUSampler() = aOther.GetAsGPUSampler();
break;
}
case eGPUTextureView: {
SetAsGPUTextureView() = aOther.GetAsGPUTextureView();
break;
}
case eGPUBufferBinding: {
SetAsGPUBufferBinding() = aOther.GetAsGPUBufferBinding();
break;
}
}
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->sourceMap_id.init(cx, "sourceMap") ||
!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->sourceMap_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mSourceMap.Construct();
if (temp.ref().isObject()) {
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
#pragma clang diagnostic ignored "-Wunreachable-code-return"
#endif // __clang__
if ((passedToJSImpl) && !CallerSubsumes(temp.ref())) {
cx.ThrowErrorMessage<MSG_PERMISSION_DENIED_TO_PASS_ARG>("'sourceMap' member of GPUShaderModuleDescriptor");
return false;
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif // __clang__
(mSourceMap.Value()) = &temp.ref().toObject();
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'sourceMap' member of GPUShaderModuleDescriptor");
return false;
}
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);
if (mSourceMap.WasPassed()) {
JS::TraceRoot(trc, &mSourceMap.Value(), "GPUShaderModuleDescriptor.mSourceMap");
}
}
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);
}
GPUComputePipelineDescriptor&
GPUComputePipelineDescriptor::operator=(const GPUComputePipelineDescriptor& aOther)
{
GPUPipelineDescriptorBase::operator=(aOther);
mCompute = aOther.mCompute;
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);
}
GPUImageCopyExternalImage::GPUImageCopyExternalImage()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUImageCopyExternalImage::InitIds(JSContext* cx, GPUImageCopyExternalImageAtoms* 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
GPUImageCopyExternalImage::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());
GPUImageCopyExternalImageAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUImageCopyExternalImageAtoms>(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 GPUImageCopyExternalImage", &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 GPUImageCopyExternalImage", 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 GPUImageCopyExternalImage", 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 GPUImageCopyExternalImage");
}
return true;
}
bool
GPUImageCopyExternalImage::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
GPUImageCopyExternalImage::TraceDictionary(JSTracer* trc)
{
}
GPUImageCopyExternalImage&
GPUImageCopyExternalImage::operator=(const GPUImageCopyExternalImage& aOther)
{
DictionaryBase::operator=(aOther);
mFlipY = aOther.mFlipY;
mOrigin = aOther.mOrigin;
mSource = aOther.mSource;
return *this;
}
GPUImageCopyTexture::GPUImageCopyTexture()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUImageCopyTexture::InitIds(JSContext* cx, GPUImageCopyTextureAtoms* 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
GPUImageCopyTexture::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());
GPUImageCopyTextureAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUImageCopyTextureAtoms>(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 GPUImageCopyTexture",
&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 GPUImageCopyTexture", &mMipLevel)) {
return false;
}
} else {
mMipLevel = 0U;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->origin_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mOrigin.Construct();
if (!(mOrigin.Value()).Init(cx, temp.ref(), "'origin' member of GPUImageCopyTexture", 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 GPUImageCopyTexture", "GPUTexture");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'texture' member of GPUImageCopyTexture");
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 GPUImageCopyTexture");
}
return true;
}
bool
GPUImageCopyTexture::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
GPUImageCopyTexture::TraceDictionary(JSTracer* trc)
{
}
GPUImageCopyTexture&
GPUImageCopyTexture::operator=(const GPUImageCopyTexture& aOther)
{
DictionaryBase::operator=(aOther);
mAspect = aOther.mAspect;
mMipLevel = aOther.mMipLevel;
mOrigin.Reset();
if (aOther.mOrigin.WasPassed()) {
mOrigin.Construct(aOther.mOrigin.Value());
}
mTexture = aOther.mTexture;
return *this;
}
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;
}
bool
GPURenderBundleEncoderDescriptor::operator==(const GPURenderBundleEncoderDescriptor& aOther) const
{
if (mDepthReadOnly != aOther.mDepthReadOnly) {
return false;
}
if (mStencilReadOnly != aOther.mStencilReadOnly) {
return false;
}
return true;
}
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->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->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 (temp.ref().isObject()) {
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>(temp.ptr(), (mResolveTarget.Value()), cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'resolveTarget' member of GPURenderPassColorAttachment", "GPUTextureView");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'resolveTarget' member of GPURenderPassColorAttachment");
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 (temp.ref().isObject()) {
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>(temp.ptr(), mView, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'view' member of GPURenderPassColorAttachment", "GPUTextureView");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'view' member of GPURenderPassColorAttachment");
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());
}
mLoadOp = aOther.mLoadOp;
mResolveTarget.Reset();
if (aOther.mResolveTarget.WasPassed()) {
mResolveTarget.Construct(aOther.mResolveTarget.Value());
}
mStoreOp = aOther.mStoreOp;
mView = aOther.mView;
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);
}
GPUVertexState&
GPUVertexState::operator=(const GPUVertexState& aOther)
{
GPUProgrammableStage::operator=(aOther);
mBuffers = aOther.mBuffers;
return *this;
}
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;
}
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);
}
GPUFragmentState&
GPUFragmentState::operator=(const GPUFragmentState& aOther)
{
GPUProgrammableStage::operator=(aOther);
mTargets = aOther.mTargets;
return *this;
}
GPUImageCopyTextureTagged::GPUImageCopyTextureTagged()
: GPUImageCopyTexture(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUImageCopyTextureTagged::InitIds(JSContext* cx, GPUImageCopyTextureTaggedAtoms* 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
GPUImageCopyTextureTagged::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());
GPUImageCopyTextureTaggedAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUImageCopyTextureTaggedAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUImageCopyTexture::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 GPUImageCopyTextureTagged", &mPremultipliedAlpha)) {
return false;
}
} else {
mPremultipliedAlpha = false;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUImageCopyTextureTagged::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
GPUImageCopyTextureTagged::TraceDictionary(JSTracer* trc)
{
GPUImageCopyTexture::TraceDictionary(trc);
}
GPUImageCopyTextureTagged&
GPUImageCopyTextureTagged::operator=(const GPUImageCopyTextureTagged& aOther)
{
GPUImageCopyTexture::operator=(aOther);
mPremultipliedAlpha = aOther.mPremultipliedAlpha;
return *this;
}
bool
GPUImageCopyTextureTagged::operator==(const GPUImageCopyTextureTagged& aOther) const
{
if (mPremultipliedAlpha != aOther.mPremultipliedAlpha) {
return false;
}
return true;
}
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->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;
}
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());
}
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);
}
GPURenderPipelineDescriptor&
GPURenderPipelineDescriptor::operator=(const GPURenderPipelineDescriptor& aOther)
{
GPUPipelineDescriptorBase::operator=(aOther);
mDepthStencil.Reset();
if (aOther.mDepthStencil.WasPassed()) {
mDepthStencil.Construct(aOther.mDepthStencil.Value());
}
mFragment.Reset();
if (aOther.mFragment.WasPassed()) {
mFragment.Construct(aOther.mFragment.Value());
}
mMultisample = aOther.mMultisample;
mPrimitive = aOther.mPrimitive;
mVertex = aOther.mVertex;
return *this;
}
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. */
};
static bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::Instance* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Instance>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::Instance* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Instance>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::Instance* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Instance>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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)");
static uint16_t sNativeProperties_sortedPropertyIndices[2];
static PropertyInfo sNativeProperties_propertyInfos[2];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
false, 0,
false, 0,
false, 0,
false, 0,
-1,
2,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &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::GPU,
constructors::id::GPU,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::GPU,
PrototypeTraits<prototypes::id::GPU>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPU",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPU);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPU);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPU", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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_isFallbackAdapter(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapter", "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::Adapter*>(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::GPUAdapter },
{ PrototypeTraits<prototypes::id::GPUAdapter>::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
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
requestAdapterInfo(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUAdapter.requestAdapterInfo");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapter", "requestAdapterInfo", 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::AutoSequence<nsString> arg0;
if (args.hasDefined(0)) {
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<nsString> &arr = arg0;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
nsString* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
nsString& slot = *slotPtr;
if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 1", "sequence");
return false;
}
} else {
/* arg0 array is already empty; nothing to do */
}
FastErrorResult rv;
auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->RequestAdapterInfo(Constify(arg0), rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUAdapter.requestAdapterInfo"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
requestAdapterInfo_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
bool ok = requestAdapterInfo(cx, obj, void_self, args);
if (ok) {
return true;
}
return ConvertExceptionToPromise(cx, args.rval());
}
static const JSJitInfo requestAdapterInfo_methodinfo = {
{ (JSJitGetterOp)requestAdapterInfo_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. */
};
static bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::Adapter* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Adapter>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::Adapter* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Adapter>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::Adapter* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Adapter>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("requestDevice", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&requestDevice_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("requestAdapterInfo", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&requestAdapterInfo_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)");
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("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(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[2] }
}
};
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::GetRealmFunctionPrototype,
prototypes::id::GPUAdapter,
PrototypeTraits<prototypes::id::GPUAdapter>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUAdapter",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUAdapter);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUAdapter);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUAdapter", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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_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());
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::AdapterInfo>(self);
}
}
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),
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(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
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[4];
static PropertyInfo sNativeProperties_propertyInfos[4];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
4,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(4 < 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::GetRealmFunctionPrototype,
prototypes::id::GPUAdapterInfo,
PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
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 js::ClassExtension sClassExtension = {
nullptr /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUAdapterInfo",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
nullptr
};
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, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::AdapterInfo*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
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;
}
creator.InitializationSucceeded();
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUAdapterInfo);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUAdapterInfo);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(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", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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::StringToJsval(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], eNull, eNull, 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_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 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::BindGroup* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::BindGroup>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::BindGroup* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::BindGroup>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::BindGroup* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::BindGroup>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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::GetRealmFunctionPrototype,
prototypes::id::GPUBindGroup,
PrototypeTraits<prototypes::id::GPUBindGroup>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUBindGroup",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUBindGroup);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUBindGroup);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUBindGroup", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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::StringToJsval(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], eNull, eNull, 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_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 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::BindGroupLayout* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::BindGroupLayout>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::BindGroupLayout* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::BindGroupLayout>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::BindGroupLayout* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::BindGroupLayout>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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::GetRealmFunctionPrototype,
prototypes::id::GPUBindGroupLayout,
PrototypeTraits<prototypes::id::GPUBindGroupLayout>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUBindGroupLayout",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUBindGroupLayout);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUBindGroupLayout);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUBindGroupLayout", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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::StringToJsval(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], eNull, eNull, 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_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 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::Buffer* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Buffer>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::Buffer* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Buffer>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::Buffer* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Buffer>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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)");
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::GetRealmFunctionPrototype,
prototypes::id::GPUBuffer,
PrototypeTraits<prototypes::id::GPUBuffer>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUBuffer",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUBuffer);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUBuffer);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUBuffer", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace GPUBuffer_Binding
namespace GPUBufferUsage_Binding {
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 DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::_ID_Count,
0,
false,
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = nullptr;
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUBufferUsage);
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, nullptr,
nullptr, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUBufferUsage", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Configure(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->Configure(Constify(arg0));
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
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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::CanvasContext* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CanvasContext>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::CanvasContext* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CanvasContext>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::CanvasContext* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CanvasContext>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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("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(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
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[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[3] }
}
};
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::GPUCanvasContext,
constructors::id::GPUCanvasContext,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::GPUCanvasContext,
PrototypeTraits<prototypes::id::GPUCanvasContext>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUCanvasContext",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUCanvasContext);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUCanvasContext);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUCanvasContext", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace GPUCanvasContext_Binding
namespace GPUColorWrite_Binding {
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 DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::_ID_Count,
0,
false,
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = nullptr;
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUColorWrite);
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, nullptr,
nullptr, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUColorWrite", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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::StringToJsval(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], eNull, eNull, 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_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 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::CommandBuffer* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CommandBuffer>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::CommandBuffer* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CommandBuffer>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::CommandBuffer* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CommandBuffer>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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::GetRealmFunctionPrototype,
prototypes::id::GPUCommandBuffer,
PrototypeTraits<prototypes::id::GPUCommandBuffer>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUCommandBuffer",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUCommandBuffer);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUCommandBuffer);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUCommandBuffer", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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);
if (!args.requireAtLeast(cx, "GPUCommandEncoder.copyBufferToBuffer", 5)) {
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;
}
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;
}
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)->CopyBufferToBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, MOZ_KnownLive(NonNullHelper(arg2)), arg3, arg4))>, "Should be returning void here");
MOZ_KnownLive(self)->CopyBufferToBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, MOZ_KnownLive(NonNullHelper(arg2)), arg3, arg4);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
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::FastGPUImageCopyBuffer arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
binding_detail::FastGPUImageCopyTexture 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::FastGPUImageCopyTexture arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
binding_detail::FastGPUImageCopyBuffer 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::FastGPUImageCopyTexture arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
binding_detail::FastGPUImageCopyTexture 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
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::StringToJsval(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], eNull, eNull, 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_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 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::CommandEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CommandEncoder>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::CommandEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CommandEncoder>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::CommandEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CommandEncoder>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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), 5, 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("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[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 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[12];
static PropertyInfo sNativeProperties_propertyInfos[12];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
12,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[11] }
}
};
static_assert(12 < 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::GetRealmFunctionPrototype,
prototypes::id::GPUCommandEncoder,
PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUCommandEncoder",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUCommandEncoder);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUCommandEncoder);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUCommandEncoder", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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 ? (xpc::JSSLOT_EXPANDO_COUNT + 0) : (DOM_INSTANCE_RESERVED_SLOTS + 0);
MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(JS::GetClass(slotStorage)) > slotIndex);
{
// 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::CompilationInfo* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CompilationInfo>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::CompilationInfo* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CompilationInfo>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::CompilationInfo* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CompilationInfo>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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(static, sXrayExpandoObjectClass, 1);
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::GetRealmFunctionPrototype,
prototypes::id::GPUCompilationInfo,
PrototypeTraits<prototypes::id::GPUCompilationInfo>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUCompilationInfo",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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());
xpc::ClearXrayExpandoSlots(obj, (xpc::JSSLOT_EXPANDO_COUNT + 0));
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUCompilationInfo);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUCompilationInfo);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUCompilationInfo", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::CompilationMessage* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CompilationMessage>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::CompilationMessage* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CompilationMessage>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::CompilationMessage* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CompilationMessage>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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::GetRealmFunctionPrototype,
prototypes::id::GPUCompilationMessage,
PrototypeTraits<prototypes::id::GPUCompilationMessage>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUCompilationMessage",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUCompilationMessage);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUCompilationMessage);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUCompilationMessage", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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);
if (!args.requireAtLeast(cx, "GPUComputePassEncoder.setBindGroup", 2)) {
return false;
}
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
NonNull<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 {
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 */
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(NonNullHelper(arg1)), Constify(arg2)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(NonNullHelper(arg1)), Constify(arg2));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
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::StringToJsval(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], eNull, eNull, 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_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 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::ComputePassEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ComputePassEncoder>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::ComputePassEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ComputePassEncoder>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::ComputePassEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ComputePassEncoder>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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_FS_END,
JS_FNSPEC("dispatchWorkgroupsIndirect", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&dispatchWorkgroupsIndirect_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
JS_FS_END,
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 PrefableDisablers sMethods_disablers3 = {
WebIDLPrefIndex::dom_webgpu_indirect_dispatch_enabled, 0, true, OriginTrial(0), nullptr
};
static const PrefableDisablers sMethods_disablers5 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &sMethods_specs[0] },
{ &sMethods_disablers3, &sMethods_specs[3] },
{ &sMethods_disablers5, &sMethods_specs[5] },
{ nullptr, &sMethods_specs[7] },
{ nullptr, nullptr }
};
static_assert(4 <= 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)");
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::GetRealmFunctionPrototype,
prototypes::id::GPUComputePassEncoder,
PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUComputePassEncoder",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUComputePassEncoder);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUComputePassEncoder);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUComputePassEncoder", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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::StringToJsval(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], eNull, eNull, 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_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 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::ComputePipeline* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ComputePipeline>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::ComputePipeline* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ComputePipeline>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::ComputePipeline* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ComputePipeline>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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)");
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::GetRealmFunctionPrototype,
prototypes::id::GPUComputePipeline,
PrototypeTraits<prototypes::id::GPUComputePipeline>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUComputePipeline",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUComputePipeline);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUComputePipeline);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUComputePipeline", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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_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
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;
}
RootedDictionary<binding_detail::FastGPUShaderModuleDescriptor> arg0(cx);
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
FastErrorResult rv;
auto result(StrongOrRawPtr<mozilla::webgpu::ShaderModule>(MOZ_KnownLive(self)->CreateShaderModule(cx, 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
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::StringToJsval(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], eNull, eNull, 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_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 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::Device* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Device>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::Device* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Device>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::Device* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Device>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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_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("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 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(16 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
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("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[6] },
{ 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(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[22];
static PropertyInfo sNativeProperties_propertyInfos[22];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
22,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[16] }
}
};
static_assert(22 < 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::GetConstructorObject,
prototypes::id::GPUDevice,
PrototypeTraits<prototypes::id::GPUDevice>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUDevice",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool 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", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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);
JS::Rooted<JS::Value> result(cx);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetReason(cx, &result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetReason(cx, &result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
JS::ExposeValueToActiveJS(result);
args.rval().set(result);
if (!MaybeWrapValue(cx, 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_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
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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::DeviceLostInfo* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::DeviceLostInfo>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::DeviceLostInfo* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::DeviceLostInfo>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::DeviceLostInfo* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::DeviceLostInfo>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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::GetRealmFunctionPrototype,
prototypes::id::GPUDeviceLostInfo,
PrototypeTraits<prototypes::id::GPUDeviceLostInfo>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUDeviceLostInfo",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUDeviceLostInfo);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUDeviceLostInfo);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUDeviceLostInfo", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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. */
};
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::GetRealmFunctionPrototype,
prototypes::id::GPUError,
PrototypeTraits<prototypes::id::GPUError>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUError);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUError);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUError", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetProtoObject(JSContext* aCx)
{
return GetProtoObjectHandle(aCx);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace GPUError_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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::InternalError* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::InternalError>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::InternalError* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::InternalError>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::InternalError* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::InternalError>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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::GetConstructorObject,
prototypes::id::GPUInternalError,
PrototypeTraits<prototypes::id::GPUInternalError>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUInternalError",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool 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", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace GPUInternalError_Binding
namespace GPUMapMode_Binding {
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 DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::_ID_Count,
0,
false,
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = nullptr;
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUMapMode);
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, nullptr,
nullptr, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUMapMode", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::OutOfMemoryError* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::OutOfMemoryError>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::OutOfMemoryError* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::OutOfMemoryError>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::OutOfMemoryError* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::OutOfMemoryError>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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::GetConstructorObject,
prototypes::id::GPUOutOfMemoryError,
PrototypeTraits<prototypes::id::GPUOutOfMemoryError>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUOutOfMemoryError",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool 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", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace GPUOutOfMemoryError_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::StringToJsval(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], eNull, eNull, 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_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 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::PipelineLayout* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::PipelineLayout>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::PipelineLayout* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::PipelineLayout>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::PipelineLayout* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::PipelineLayout>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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::GetRealmFunctionPrototype,
prototypes::id::GPUPipelineLayout,
PrototypeTraits<prototypes::id::GPUPipelineLayout>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUPipelineLayout",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUPipelineLayout);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUPipelineLayout);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUPipelineLayout", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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_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::StringToJsval(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], eNull, eNull, 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_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 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::QuerySet* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::QuerySet>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::QuerySet* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::QuerySet>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::QuerySet* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::QuerySet>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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)");
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::GPUQuerySet,
constructors::id::GPUQuerySet,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::GPUQuerySet,
PrototypeTraits<prototypes::id::GPUQuerySet>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUQuerySet",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUQuerySet);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUQuerySet);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUQuerySet", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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;
}
ArrayBufferViewOrArrayBuffer 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::FastGPUImageCopyTexture arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
ArrayBufferViewOrArrayBuffer arg1;
if (!arg1.Init(cx, args[1], "Argument 2", false)) {
return false;
}
binding_detail::FastGPUImageDataLayout 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::FastGPUImageCopyExternalImage arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
binding_detail::FastGPUImageCopyTextureTagged 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::StringToJsval(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], eNull, eNull, 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_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 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::Queue* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Queue>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::Queue* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Queue>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::Queue* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Queue>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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)");
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::GetRealmFunctionPrototype,
prototypes::id::GPUQueue,
PrototypeTraits<prototypes::id::GPUQueue>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUQueue",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUQueue);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUQueue);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUQueue", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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::StringToJsval(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], eNull, eNull, 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_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 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::RenderBundle* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderBundle>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::RenderBundle* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderBundle>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::RenderBundle* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderBundle>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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::GetRealmFunctionPrototype,
prototypes::id::GPURenderBundle,
PrototypeTraits<prototypes::id::GPURenderBundle>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPURenderBundle",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPURenderBundle);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPURenderBundle);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPURenderBundle", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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);
if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.setBindGroup", 2)) {
return false;
}
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
NonNull<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 {
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 */
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(NonNullHelper(arg1)), Constify(arg2)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(NonNullHelper(arg1)), Constify(arg2));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
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::StringToJsval(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], eNull, eNull, 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_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 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;
}
uint64_t arg3;
if (args.hasDefined(3)) {
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
return false;
}
} else {
arg3 = 0ULL;
}
// 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, arg3))>, "Should be returning void here");
MOZ_KnownLive(self)->SetIndexBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, arg2, 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;
}
uint64_t arg3;
if (args.hasDefined(3)) {
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
return false;
}
} else {
arg3 = 0ULL;
}
// 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, arg3))>, "Should be returning void here");
MOZ_KnownLive(self)->SetVertexBuffer(arg0, MOZ_KnownLive(NonNullHelper(arg1)), arg2, 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::RenderBundleEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderBundleEncoder>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::RenderBundleEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderBundleEncoder>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::RenderBundleEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderBundleEncoder>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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_FS_END,
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 PrefableDisablers sMethods_disablers12 = {
WebIDLPrefIndex::dom_webgpu_indirect_dispatch_enabled, 0, false, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &sMethods_specs[0] },
{ nullptr, &sMethods_specs[2] },
{ &sMethods_disablers12, &sMethods_specs[12] },
{ 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(9 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
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::GetRealmFunctionPrototype,
prototypes::id::GPURenderBundleEncoder,
PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPURenderBundleEncoder",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPURenderBundleEncoder);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPURenderBundleEncoder);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPURenderBundleEncoder", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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
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);
if (!args.requireAtLeast(cx, "GPURenderPassEncoder.setBindGroup", 2)) {
return false;
}
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
NonNull<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 {
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 */
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(NonNullHelper(arg1)), Constify(arg2)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(NonNullHelper(arg1)), Constify(arg2));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
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::StringToJsval(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], eNull, eNull, 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_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 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;
}
uint64_t arg3;
if (args.hasDefined(3)) {
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
return false;
}
} else {
arg3 = 0ULL;
}
// 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, arg3))>, "Should be returning void here");
MOZ_KnownLive(self)->SetIndexBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, arg2, 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;
}
uint64_t arg3;
if (args.hasDefined(3)) {
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
return false;
}
} else {
arg3 = 0ULL;
}
// 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, arg3))>, "Should be returning void here");
MOZ_KnownLive(self)->SetVertexBuffer(arg0, MOZ_KnownLive(NonNullHelper(arg1)), arg2, 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::RenderPassEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderPassEncoder>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::RenderPassEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderPassEncoder>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::RenderPassEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderPassEncoder>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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("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_FS_END,
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 PrefableDisablers sMethods_disablers17 = {
WebIDLPrefIndex::dom_webgpu_indirect_dispatch_enabled, 0, false, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &sMethods_specs[0] },
{ nullptr, &sMethods_specs[7] },
{ &sMethods_disablers17, &sMethods_specs[17] },
{ 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(9 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
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[18];
static PropertyInfo sNativeProperties_propertyInfos[18];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
18,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[17] }
}
};
static_assert(18 < 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::GetRealmFunctionPrototype,
prototypes::id::GPURenderPassEncoder,
PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPURenderPassEncoder",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPURenderPassEncoder);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPURenderPassEncoder);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPURenderPassEncoder", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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::StringToJsval(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], eNull, eNull, 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_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 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::RenderPipeline* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderPipeline>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::RenderPipeline* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderPipeline>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::RenderPipeline* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderPipeline>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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)");
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::GetRealmFunctionPrototype,
prototypes::id::GPURenderPipeline,
PrototypeTraits<prototypes::id::GPURenderPipeline>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPURenderPipeline",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPURenderPipeline);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPURenderPipeline);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPURenderPipeline", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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::StringToJsval(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], eNull, eNull, 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_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 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::Sampler* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Sampler>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::Sampler* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Sampler>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::Sampler* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Sampler>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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::GetRealmFunctionPrototype,
prototypes::id::GPUSampler,
PrototypeTraits<prototypes::id::GPUSampler>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUSampler",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUSampler);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUSampler);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUSampler", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace GPUSampler_Binding
namespace GPUShaderModule_Binding {
MOZ_CAN_RUN_SCRIPT static bool
compilationInfo(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUShaderModule", "compilationInfo", 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)->CompilationInfo(rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUShaderModule.compilationInfo"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
compilationInfo_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
bool ok = compilationInfo(cx, obj, void_self, args);
if (ok) {
return true;
}
return ConvertExceptionToPromise(cx, args.rval());
}
static const JSJitInfo compilationInfo_methodinfo = {
{ (JSJitGetterOp)compilationInfo_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
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::StringToJsval(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], eNull, eNull, 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_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 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::ShaderModule* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ShaderModule>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::ShaderModule* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ShaderModule>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::ShaderModule* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ShaderModule>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("compilationInfo", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&compilationInfo_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
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(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
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[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::GPUShaderModule,
constructors::id::GPUShaderModule,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::GPUShaderModule,
PrototypeTraits<prototypes::id::GPUShaderModule>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUShaderModule",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUShaderModule);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUShaderModule);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUShaderModule", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace GPUShaderModule_Binding
namespace GPUShaderStage_Binding {
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 DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::_ID_Count,
0,
false,
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = nullptr;
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUShaderStage);
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, nullptr,
nullptr, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUShaderStage", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::SupportedFeatures* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::SupportedFeatures>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::SupportedFeatures* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::SupportedFeatures>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::SupportedFeatures* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::SupportedFeatures>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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)");
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(static, sXrayExpandoObjectClass, 1);
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::GetRealmFunctionPrototype,
prototypes::id::GPUSupportedFeatures,
PrototypeTraits<prototypes::id::GPUSupportedFeatures>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUSupportedFeatures",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUSupportedFeatures);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUSupportedFeatures);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUSupportedFeatures", aDefineOnGlobal,
nullptr,
false,
nullptr);
JS::AssertObjectIsNotGray(*protoCache);
JS::Handle<JSObject*> proto = JS::Handle<JSObject*>::fromMarkedLocation(protoCache->address());
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;
}
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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_maxInterStageShaderComponents(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxInterStageShaderComponents", 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)->MaxInterStageShaderComponents());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxInterStageShaderComponents_getterinfo = {
{ get_maxInterStageShaderComponents },
{ 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::SupportedLimits* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::SupportedLimits>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::SupportedLimits* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::SupportedLimits>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::SupportedLimits* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::SupportedLimits>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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("maxInterStageShaderComponents", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxInterStageShaderComponents_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(32 <= 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[32];
static PropertyInfo sNativeProperties_propertyInfos[32];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
32,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(32 < 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::GetRealmFunctionPrototype,
prototypes::id::GPUSupportedLimits,
PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUSupportedLimits",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUSupportedLimits);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUSupportedLimits);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUSupportedLimits", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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::StringToJsval(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], eNull, eNull, 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_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 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::Texture* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Texture>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::Texture* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Texture>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::Texture* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Texture>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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)");
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::GetRealmFunctionPrototype,
prototypes::id::GPUTexture,
PrototypeTraits<prototypes::id::GPUTexture>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUTexture",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUTexture);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUTexture);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUTexture", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace GPUTexture_Binding
namespace GPUTextureUsage_Binding {
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 DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototype,
prototypes::id::_ID_Count,
0,
false,
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = nullptr;
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUTextureUsage);
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, nullptr,
nullptr, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUTextureUsage", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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::StringToJsval(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], eNull, eNull, 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_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 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::TextureView* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::TextureView>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::TextureView* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::TextureView>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::TextureView* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::TextureView>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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::GetRealmFunctionPrototype,
prototypes::id::GPUTextureView,
PrototypeTraits<prototypes::id::GPUTextureView>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUTextureView",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUTextureView);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUTextureView);
JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!parentProto) {
return;
}
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUTextureView", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // 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 bool
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
{
mozilla::webgpu::ValidationError* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ValidationError>(obj);
// We don't want to preserve if we don't have a wrapper, and we
// obviously can't preserve if we're not initialized.
if (self && self->GetWrapperPreserveColor()) {
PreserveWrapper(self);
}
return true;
}
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);
}
}
static nsWrapperCache*
_getWrapperCache(JS::Handle<JSObject*> obj)
{
mozilla::webgpu::ValidationError* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ValidationError>(obj);
return self;
}
static size_t
_objectMoved(JSObject* obj, JSObject* old)
{
mozilla::webgpu::ValidationError* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ValidationError>(obj);
if (self) {
UpdateWrapper(self, self, obj, old);
}
return 0;
}
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::GetConstructorObject,
prototypes::id::GPUValidationError,
PrototypeTraits<prototypes::id::GPUValidationError>::Depth,
true,
};
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)
{
if (!NS_IsMainThread()) {
const char* name = JS::GetClass(aObj)->name;
if (strcmp(name, "DedicatedWorkerGlobalScope")) {
return false;
}
}
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static const JSClassOps sClassOps = {
_addProperty, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const js::ClassExtension sClassExtension = {
_objectMoved /* objectMovedOp */
};
static const DOMJSClass sClass = {
{ "GPUValidationError",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
&sClassOps,
JS_NULL_CLASS_SPEC,
&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,
_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, bool 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", aDefineOnGlobal,
nullptr,
false,
nullptr);
}
JSObject*
GetConstructorObject(JSContext* aCx)
{
return GetConstructorObjectHandle(aCx);
}
} // namespace GPUValidationError_Binding
} // namespace dom
} // namespace mozilla