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 "BufferSourceBinding.h"
#include "DOMExceptionBinding.h"
#include "EventHandlerBinding.h"
#include "EventTargetBinding.h"
#include "MainThreadUtils.h"
#include "WebGPUBinding.h"
#include "WrapperFactory.h"
#include "XrayWrapper.h"
#include "js/Array.h"
#include "js/CallAndConstruct.h"
#include "js/Exception.h"
#include "js/ForOfIterator.h"
#include "js/MapAndSet.h"
#include "js/Object.h"
#include "js/PropertyAndElement.h"
#include "js/PropertyDescriptor.h"
#include "js/Symbol.h"
#include "js/experimental/JitInfo.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "mozilla/Atomics.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/OwningNonNull.h"
#include "mozilla/ProfilerLabels.h"
#include "mozilla/dom/BindingCallContext.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/DOMJSClass.h"
#include "mozilla/dom/HTMLCanvasElement.h"
#include "mozilla/dom/HTMLImageElement.h"
#include "mozilla/dom/HTMLVideoElement.h"
#include "mozilla/dom/ImageBitmap.h"
#include "mozilla/dom/NonRefcountedDOMObject.h"
#include "mozilla/dom/Nullable.h"
#include "mozilla/dom/OffscreenCanvas.h"
#include "mozilla/dom/PrimitiveConversions.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/SimpleGlobalObject.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/dom/UnionTypes.h"
#include "mozilla/dom/VideoFrame.h"
#include "mozilla/dom/WebIDLPrefs.h"
#include "mozilla/dom/XrayExpandoClass.h"
#include "mozilla/webgpu/Adapter.h"
#include "mozilla/webgpu/BindGroup.h"
#include "mozilla/webgpu/BindGroupLayout.h"
#include "mozilla/webgpu/Buffer.h"
#include "mozilla/webgpu/CanvasContext.h"
#include "mozilla/webgpu/CommandBuffer.h"
#include "mozilla/webgpu/CommandEncoder.h"
#include "mozilla/webgpu/CompilationInfo.h"
#include "mozilla/webgpu/CompilationMessage.h"
#include "mozilla/webgpu/ComputePassEncoder.h"
#include "mozilla/webgpu/ComputePipeline.h"
#include "mozilla/webgpu/Device.h"
#include "mozilla/webgpu/DeviceLostInfo.h"
#include "mozilla/webgpu/Error.h"
#include "mozilla/webgpu/ExternalTexture.h"
#include "mozilla/webgpu/Instance.h"
#include "mozilla/webgpu/InternalError.h"
#include "mozilla/webgpu/OutOfMemoryError.h"
#include "mozilla/webgpu/PipelineError.h"
#include "mozilla/webgpu/PipelineLayout.h"
#include "mozilla/webgpu/QuerySet.h"
#include "mozilla/webgpu/Queue.h"
#include "mozilla/webgpu/RenderBundle.h"
#include "mozilla/webgpu/RenderBundleEncoder.h"
#include "mozilla/webgpu/RenderPassEncoder.h"
#include "mozilla/webgpu/RenderPipeline.h"
#include "mozilla/webgpu/Sampler.h"
#include "mozilla/webgpu/ShaderModule.h"
#include "mozilla/webgpu/SupportedFeatures.h"
#include "mozilla/webgpu/SupportedLimits.h"
#include "mozilla/webgpu/Texture.h"
#include "mozilla/webgpu/TextureView.h"
#include "mozilla/webgpu/ValidationError.h"
#include "nsContentUtils.h"
#include "nsRFPService.h"
namespace mozilla {
namespace dom {
namespace binding_detail {}; // Just to make sure it's known as a namespace
using namespace mozilla::dom::binding_detail;
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUPowerPreference>::Values[2];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUPowerPreference aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUPowerPreference>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUPowerPreference>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUPowerPreference>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUFeatureName>::Values[18];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUFeatureName aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUFeatureName>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUFeatureName>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUFeatureName>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUBufferMapState>::Values[3];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUBufferMapState aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUBufferMapState>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUBufferMapState>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUBufferMapState>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUTextureDimension>::Values[3];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUTextureDimension aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUTextureDimension>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUTextureDimension>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUTextureDimension>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUTextureViewDimension>::Values[6];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUTextureViewDimension aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUTextureViewDimension>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUTextureViewDimension>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUTextureViewDimension>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUTextureAspect>::Values[3];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUTextureAspect aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUTextureAspect>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUTextureAspect>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUTextureAspect>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUTextureFormat>::Values[95];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUTextureFormat aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUTextureFormat>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUTextureFormat>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUTextureFormat>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUAddressMode>::Values[3];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUAddressMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUAddressMode>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUAddressMode>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUAddressMode>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUFilterMode>::Values[2];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUFilterMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUFilterMode>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUFilterMode>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUFilterMode>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUMipmapFilterMode>::Values[2];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUMipmapFilterMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUMipmapFilterMode>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUMipmapFilterMode>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUMipmapFilterMode>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUCompareFunction>::Values[8];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUCompareFunction aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUCompareFunction>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUCompareFunction>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUCompareFunction>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUBufferBindingType>::Values[3];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUBufferBindingType aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUBufferBindingType>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUBufferBindingType>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUBufferBindingType>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUSamplerBindingType>::Values[3];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUSamplerBindingType aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUSamplerBindingType>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUSamplerBindingType>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUSamplerBindingType>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUTextureSampleType>::Values[5];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUTextureSampleType aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUTextureSampleType>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUTextureSampleType>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUTextureSampleType>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUStorageTextureAccess>::Values[3];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUStorageTextureAccess aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUStorageTextureAccess>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUStorageTextureAccess>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUStorageTextureAccess>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUCompilationMessageType>::Values[3];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUCompilationMessageType aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUCompilationMessageType>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUCompilationMessageType>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUCompilationMessageType>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUPipelineErrorReason>::Values[2];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUPipelineErrorReason aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUPipelineErrorReason>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUPipelineErrorReason>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUPipelineErrorReason>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUAutoLayoutMode>::Values[1];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUAutoLayoutMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUAutoLayoutMode>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUAutoLayoutMode>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUAutoLayoutMode>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUPrimitiveTopology>::Values[5];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUPrimitiveTopology aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUPrimitiveTopology>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUPrimitiveTopology>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUPrimitiveTopology>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUFrontFace>::Values[2];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUFrontFace aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUFrontFace>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUFrontFace>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUFrontFace>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUCullMode>::Values[3];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUCullMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUCullMode>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUCullMode>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUCullMode>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUBlendFactor>::Values[13];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUBlendFactor aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUBlendFactor>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUBlendFactor>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUBlendFactor>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUBlendOperation>::Values[5];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUBlendOperation aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUBlendOperation>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUBlendOperation>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUBlendOperation>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUStencilOperation>::Values[8];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUStencilOperation aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUStencilOperation>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUStencilOperation>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUStencilOperation>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUIndexFormat>::Values[2];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUIndexFormat aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUIndexFormat>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUIndexFormat>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUIndexFormat>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUVertexFormat>::Values[41];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUVertexFormat aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUVertexFormat>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUVertexFormat>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUVertexFormat>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUVertexStepMode>::Values[2];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUVertexStepMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUVertexStepMode>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUVertexStepMode>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUVertexStepMode>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPULoadOp>::Values[2];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPULoadOp aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPULoadOp>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPULoadOp>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPULoadOp>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUStoreOp>::Values[2];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUStoreOp aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUStoreOp>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUStoreOp>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUStoreOp>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUQueryType>::Values[2];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUQueryType aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUQueryType>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUQueryType>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUQueryType>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUCanvasAlphaMode>::Values[2];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUCanvasAlphaMode aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUCanvasAlphaMode>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUCanvasAlphaMode>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUCanvasAlphaMode>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUDeviceLostReason>::Values[2];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUDeviceLostReason aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUDeviceLostReason>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUDeviceLostReason>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUDeviceLostReason>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
namespace binding_detail {
constexpr nsLiteralCString EnumStrings<GPUErrorFilter>::Values[3];
} // namespace binding_detail
bool
ToJSValue(JSContext* aCx, GPUErrorFilter aArgument, JS::MutableHandle<JS::Value> aValue)
{
MOZ_ASSERT(uint32_t(aArgument) < std::size(binding_detail::EnumStrings<GPUErrorFilter>::Values));
JSString* resultStr =
JS_NewStringCopyN(aCx, binding_detail::EnumStrings<GPUErrorFilter>::Values[uint32_t(aArgument)].BeginReading(),
binding_detail::EnumStrings<GPUErrorFilter>::Values[uint32_t(aArgument)].Length());
if (!resultStr) {
return false;
}
aValue.setString(resultStr);
return true;
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningGPUPipelineLayoutOrGPUAutoLayoutMode& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsGPUPipelineLayout()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUPipelineLayout(), "mGPUPipelineLayout", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsGPUSampler()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUSampler(), "mGPUSampler", aFlags);
} else if (aUnion.IsGPUTexture()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUTexture(), "mGPUTexture", aFlags);
} else if (aUnion.IsGPUTextureView()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUTextureView(), "mGPUTextureView", aFlags);
} else if (aUnion.IsGPUBuffer()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUBuffer(), "mGPUBuffer", aFlags);
} else if (aUnion.IsGPUBufferBinding()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUBufferBinding(), "mGPUBufferBinding", aFlags);
} else if (aUnion.IsGPUExternalTexture()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUExternalTexture(), "mGPUExternalTexture", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningGPUTextureOrGPUTextureView& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsGPUTexture()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUTexture(), "mGPUTexture", aFlags);
} else if (aUnion.IsGPUTextureView()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsGPUTextureView(), "mGPUTextureView", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningHTMLVideoElementOrVideoFrame& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsHTMLVideoElement()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsHTMLVideoElement(), "mHTMLVideoElement", aFlags);
} else if (aUnion.IsVideoFrame()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsVideoFrame(), "mVideoFrame", aFlags);
}
}
void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas& aUnion, const char* aName, uint32_t aFlags)
{
if (aUnion.IsImageBitmap()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsImageBitmap(), "mImageBitmap", aFlags);
} else if (aUnion.IsHTMLImageElement()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsHTMLImageElement(), "mHTMLImageElement", aFlags);
} else if (aUnion.IsHTMLCanvasElement()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsHTMLCanvasElement(), "mHTMLCanvasElement", aFlags);
} else if (aUnion.IsOffscreenCanvas()) {
ImplCycleCollectionTraverse(aCallback, aUnion.GetAsOffscreenCanvas(), "mOffscreenCanvas", aFlags);
}
}
void
ImplCycleCollectionUnlink(OwningGPUPipelineLayoutOrGPUAutoLayoutMode& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningGPUTextureOrGPUTextureView& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningHTMLVideoElementOrVideoFrame& aUnion)
{
aUnion.Uninit();
}
void
ImplCycleCollectionUnlink(OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas& aUnion)
{
aUnion.Uninit();
}
GPUBlendComponent::GPUBlendComponent()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUBlendComponent::InitIds(JSContext* cx, GPUBlendComponentAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->srcFactor_id.init(cx, "srcFactor") ||
!atomsCache->operation_id.init(cx, "operation") ||
!atomsCache->dstFactor_id.init(cx, "dstFactor")) {
return false;
}
return true;
}
bool
GPUBlendComponent::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUBlendComponentAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUBlendComponentAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->dstFactor_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUBlendFactor>::Values,
"GPUBlendFactor", "'dstFactor' member of GPUBlendComponent",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mDstFactor = static_cast<GPUBlendFactor>(index);
}
} else {
mDstFactor = GPUBlendFactor::Zero;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->operation_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUBlendOperation>::Values,
"GPUBlendOperation", "'operation' member of GPUBlendComponent",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mOperation = static_cast<GPUBlendOperation>(index);
}
} else {
mOperation = GPUBlendOperation::Add;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->srcFactor_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUBlendFactor>::Values,
"GPUBlendFactor", "'srcFactor' member of GPUBlendComponent",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mSrcFactor = static_cast<GPUBlendFactor>(index);
}
} else {
mSrcFactor = GPUBlendFactor::One;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUBlendComponent::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUBlendComponent::TraceDictionary(JSTracer* trc)
{
}
GPUBlendComponent&
GPUBlendComponent::operator=(const GPUBlendComponent& aOther)
{
DictionaryBase::operator=(aOther);
mDstFactor = aOther.mDstFactor;
mOperation = aOther.mOperation;
mSrcFactor = aOther.mSrcFactor;
return *this;
}
GPUBufferBinding::GPUBufferBinding()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUBufferBinding::InitIds(JSContext* cx, GPUBufferBindingAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->size_id.init(cx, "size") ||
!atomsCache->offset_id.init(cx, "offset") ||
!atomsCache->buffer_id.init(cx, "buffer")) {
return false;
}
return true;
}
bool
GPUBufferBinding::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUBufferBindingAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUBufferBindingAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->buffer_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
static_assert(IsRefcounted<mozilla::webgpu::Buffer>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(temp.ptr(), mBuffer, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'buffer' member of GPUBufferBinding", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'buffer' member of GPUBufferBinding");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'buffer' member of GPUBufferBinding");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->offset_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, temp.ref(), "'offset' member of GPUBufferBinding", &mOffset)) {
return false;
}
} else {
mOffset = 0ULL;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->size_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mSize.Construct();
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, temp.ref(), "'size' member of GPUBufferBinding", &(mSize.Value()))) {
return false;
}
mIsAnyMemberPresent = true;
}
return true;
}
bool
GPUBufferBinding::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUBufferBinding::TraceDictionary(JSTracer* trc)
{
}
GPUBufferBinding&
GPUBufferBinding::operator=(const GPUBufferBinding& aOther)
{
DictionaryBase::operator=(aOther);
mBuffer = aOther.mBuffer;
mOffset = aOther.mOffset;
mSize.Reset();
if (aOther.mSize.WasPassed()) {
mSize.Construct(aOther.mSize.Value());
}
return *this;
}
GPUBufferBindingLayout::GPUBufferBindingLayout()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUBufferBindingLayout::InitIds(JSContext* cx, GPUBufferBindingLayoutAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->type_id.init(cx, "type") ||
!atomsCache->minBindingSize_id.init(cx, "minBindingSize") ||
!atomsCache->hasDynamicOffset_id.init(cx, "hasDynamicOffset")) {
return false;
}
return true;
}
bool
GPUBufferBindingLayout::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUBufferBindingLayoutAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUBufferBindingLayoutAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->hasDynamicOffset_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'hasDynamicOffset' member of GPUBufferBindingLayout", &mHasDynamicOffset)) {
return false;
}
} else {
mHasDynamicOffset = false;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->minBindingSize_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, temp.ref(), "'minBindingSize' member of GPUBufferBindingLayout", &mMinBindingSize)) {
return false;
}
} else {
mMinBindingSize = 0ULL;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->type_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUBufferBindingType>::Values,
"GPUBufferBindingType", "'type' member of GPUBufferBindingLayout",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mType = static_cast<GPUBufferBindingType>(index);
}
} else {
mType = GPUBufferBindingType::Uniform;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUBufferBindingLayout::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUBufferBindingLayout::TraceDictionary(JSTracer* trc)
{
}
GPUBufferBindingLayout&
GPUBufferBindingLayout::operator=(const GPUBufferBindingLayout& aOther)
{
DictionaryBase::operator=(aOther);
mHasDynamicOffset = aOther.mHasDynamicOffset;
mMinBindingSize = aOther.mMinBindingSize;
mType = aOther.mType;
return *this;
}
GPUCanvasConfiguration::GPUCanvasConfiguration()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUCanvasConfiguration::InitIds(JSContext* cx, GPUCanvasConfigurationAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->viewFormats_id.init(cx, "viewFormats") ||
!atomsCache->usage_id.init(cx, "usage") ||
!atomsCache->format_id.init(cx, "format") ||
!atomsCache->device_id.init(cx, "device") ||
!atomsCache->alphaMode_id.init(cx, "alphaMode")) {
return false;
}
return true;
}
bool
GPUCanvasConfiguration::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUCanvasConfigurationAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUCanvasConfigurationAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->alphaMode_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUCanvasAlphaMode>::Values,
"GPUCanvasAlphaMode", "'alphaMode' member of GPUCanvasConfiguration",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mAlphaMode = static_cast<GPUCanvasAlphaMode>(index);
}
} else {
mAlphaMode = GPUCanvasAlphaMode::Opaque;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->device_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
static_assert(IsRefcounted<mozilla::webgpu::Device>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUDevice, mozilla::webgpu::Device>(temp.ptr(), mDevice, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'device' member of GPUCanvasConfiguration", "GPUDevice");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'device' member of GPUCanvasConfiguration");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'device' member of GPUCanvasConfiguration");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->format_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUTextureFormat>::Values,
"GPUTextureFormat", "'format' member of GPUCanvasConfiguration",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mFormat = static_cast<GPUTextureFormat>(index);
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'format' member of GPUCanvasConfiguration");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->usage_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'usage' member of GPUCanvasConfiguration", &mUsage)) {
return false;
}
} else {
mUsage = 16U;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->viewFormats_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'viewFormats' member of GPUCanvasConfiguration", "sequence");
return false;
}
Sequence<GPUTextureFormat> &arr = mViewFormats;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
GPUTextureFormat* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
GPUTextureFormat& slot = *slotPtr;
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp,
binding_detail::EnumStrings<GPUTextureFormat>::Values,
"GPUTextureFormat", "element of 'viewFormats' member of GPUCanvasConfiguration",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
slot = static_cast<GPUTextureFormat>(index);
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'viewFormats' member of GPUCanvasConfiguration", "sequence");
return false;
}
} else {
/* mViewFormats array is already empty; nothing to do */
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUCanvasConfiguration::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
bool
GPUCanvasConfiguration::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
{
GPUCanvasConfigurationAtoms* atomsCache = GetAtomCache<GPUCanvasConfigurationAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
if (!obj) {
return false;
}
rval.set(JS::ObjectValue(*obj));
do {
// block for our 'break' successCode and scope for 'temp' and 'currentValue'
JS::Rooted<JS::Value> temp(cx);
GPUCanvasAlphaMode const & currentValue = mAlphaMode;
if (!ToJSValue(cx, currentValue, &temp)) {
return false;
}
if (!JS_DefinePropertyById(cx, obj, atomsCache->alphaMode_id, temp, JSPROP_ENUMERATE)) {
return false;
}
break;
} while(false);
do {
// block for our 'break' successCode and scope for 'temp' and 'currentValue'
JS::Rooted<JS::Value> temp(cx);
OwningNonNull<mozilla::webgpu::Device> const & currentValue = mDevice;
if (!GetOrCreateDOMReflector(cx, currentValue, &temp)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
if (!JS_DefinePropertyById(cx, obj, atomsCache->device_id, temp, JSPROP_ENUMERATE)) {
return false;
}
break;
} while(false);
do {
// block for our 'break' successCode and scope for 'temp' and 'currentValue'
JS::Rooted<JS::Value> temp(cx);
GPUTextureFormat const & currentValue = mFormat;
if (!ToJSValue(cx, currentValue, &temp)) {
return false;
}
if (!JS_DefinePropertyById(cx, obj, atomsCache->format_id, temp, JSPROP_ENUMERATE)) {
return false;
}
break;
} while(false);
do {
// block for our 'break' successCode and scope for 'temp' and 'currentValue'
JS::Rooted<JS::Value> temp(cx);
uint32_t const & currentValue = mUsage;
temp.setNumber(currentValue);
if (!JS_DefinePropertyById(cx, obj, atomsCache->usage_id, temp, JSPROP_ENUMERATE)) {
return false;
}
break;
} while(false);
do {
// block for our 'break' successCode and scope for 'temp' and 'currentValue'
JS::Rooted<JS::Value> temp(cx);
Sequence<GPUTextureFormat> const & currentValue = mViewFormats;
uint32_t length = currentValue.Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!ToJSValue(cx, currentValue[sequenceIdx0], &tmp)) {
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
temp.setObject(*returnArray);
if (!JS_DefinePropertyById(cx, obj, atomsCache->viewFormats_id, temp, JSPROP_ENUMERATE)) {
return false;
}
break;
} while(false);
return true;
}
void
GPUCanvasConfiguration::TraceDictionary(JSTracer* trc)
{
}
GPUCanvasConfiguration&
GPUCanvasConfiguration::operator=(const GPUCanvasConfiguration& aOther)
{
DictionaryBase::operator=(aOther);
mAlphaMode = aOther.mAlphaMode;
mDevice = aOther.mDevice;
mFormat = aOther.mFormat;
mUsage = aOther.mUsage;
mViewFormats = aOther.mViewFormats;
return *this;
}
GPUColorDict::GPUColorDict()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUColorDict::InitIds(JSContext* cx, GPUColorDictAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->r_id.init(cx, "r") ||
!atomsCache->g_id.init(cx, "g") ||
!atomsCache->b_id.init(cx, "b") ||
!atomsCache->a_id.init(cx, "a")) {
return false;
}
return true;
}
bool
GPUColorDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUColorDictAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUColorDictAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->a_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), "'a' member of GPUColorDict", &mA)) {
return false;
} else if (!std::isfinite(mA)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("'a' member of GPUColorDict");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'a' member of GPUColorDict");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->b_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), "'b' member of GPUColorDict", &mB)) {
return false;
} else if (!std::isfinite(mB)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("'b' member of GPUColorDict");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'b' member of GPUColorDict");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->g_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), "'g' member of GPUColorDict", &mG)) {
return false;
} else if (!std::isfinite(mG)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("'g' member of GPUColorDict");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'g' member of GPUColorDict");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->r_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<double, eDefault>(cx, temp.ref(), "'r' member of GPUColorDict", &mR)) {
return false;
} else if (!std::isfinite(mR)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("'r' member of GPUColorDict");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'r' member of GPUColorDict");
}
return true;
}
bool
GPUColorDict::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUColorDict::TraceDictionary(JSTracer* trc)
{
}
GPUColorDict&
GPUColorDict::operator=(const GPUColorDict& aOther)
{
DictionaryBase::operator=(aOther);
mA = aOther.mA;
mB = aOther.mB;
mG = aOther.mG;
mR = aOther.mR;
return *this;
}
GPUComputePassTimestampWrites::GPUComputePassTimestampWrites()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUComputePassTimestampWrites::InitIds(JSContext* cx, GPUComputePassTimestampWritesAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->querySet_id.init(cx, "querySet") ||
!atomsCache->endOfPassWriteIndex_id.init(cx, "endOfPassWriteIndex") ||
!atomsCache->beginningOfPassWriteIndex_id.init(cx, "beginningOfPassWriteIndex")) {
return false;
}
return true;
}
bool
GPUComputePassTimestampWrites::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUComputePassTimestampWritesAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUComputePassTimestampWritesAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->beginningOfPassWriteIndex_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mBeginningOfPassWriteIndex.Construct();
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'beginningOfPassWriteIndex' member of GPUComputePassTimestampWrites", &(mBeginningOfPassWriteIndex.Value()))) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->endOfPassWriteIndex_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mEndOfPassWriteIndex.Construct();
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'endOfPassWriteIndex' member of GPUComputePassTimestampWrites", &(mEndOfPassWriteIndex.Value()))) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->querySet_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
static_assert(IsRefcounted<mozilla::webgpu::QuerySet>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUQuerySet, mozilla::webgpu::QuerySet>(temp.ptr(), mQuerySet, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'querySet' member of GPUComputePassTimestampWrites", "GPUQuerySet");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'querySet' member of GPUComputePassTimestampWrites");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'querySet' member of GPUComputePassTimestampWrites");
}
return true;
}
bool
GPUComputePassTimestampWrites::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUComputePassTimestampWrites::TraceDictionary(JSTracer* trc)
{
}
GPUComputePassTimestampWrites&
GPUComputePassTimestampWrites::operator=(const GPUComputePassTimestampWrites& aOther)
{
DictionaryBase::operator=(aOther);
mBeginningOfPassWriteIndex.Reset();
if (aOther.mBeginningOfPassWriteIndex.WasPassed()) {
mBeginningOfPassWriteIndex.Construct(aOther.mBeginningOfPassWriteIndex.Value());
}
mEndOfPassWriteIndex.Reset();
if (aOther.mEndOfPassWriteIndex.WasPassed()) {
mEndOfPassWriteIndex.Construct(aOther.mEndOfPassWriteIndex.Value());
}
mQuerySet = aOther.mQuerySet;
return *this;
}
GPUExtent3DDict::GPUExtent3DDict()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUExtent3DDict::InitIds(JSContext* cx, GPUExtent3DDictAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->width_id.init(cx, "width") ||
!atomsCache->height_id.init(cx, "height") ||
!atomsCache->depthOrArrayLayers_id.init(cx, "depthOrArrayLayers")) {
return false;
}
return true;
}
bool
GPUExtent3DDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUExtent3DDictAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUExtent3DDictAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depthOrArrayLayers_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'depthOrArrayLayers' member of GPUExtent3DDict", &mDepthOrArrayLayers)) {
return false;
}
} else {
mDepthOrArrayLayers = 1U;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->height_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'height' member of GPUExtent3DDict", &mHeight)) {
return false;
}
} else {
mHeight = 1U;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->width_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'width' member of GPUExtent3DDict", &mWidth)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'width' member of GPUExtent3DDict");
}
return true;
}
bool
GPUExtent3DDict::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUExtent3DDict::TraceDictionary(JSTracer* trc)
{
}
GPUExtent3DDict&
GPUExtent3DDict::operator=(const GPUExtent3DDict& aOther)
{
DictionaryBase::operator=(aOther);
mDepthOrArrayLayers = aOther.mDepthOrArrayLayers;
mHeight = aOther.mHeight;
mWidth = aOther.mWidth;
return *this;
}
GPUExternalTextureBindingLayout::GPUExternalTextureBindingLayout()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUExternalTextureBindingLayout::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
return true;
}
bool
GPUExternalTextureBindingLayout::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUExternalTextureBindingLayout::TraceDictionary(JSTracer* trc)
{
}
GPUExternalTextureBindingLayout&
GPUExternalTextureBindingLayout::operator=(const GPUExternalTextureBindingLayout& aOther)
{
DictionaryBase::operator=(aOther);
return *this;
}
GPUMultisampleState::GPUMultisampleState()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUMultisampleState::InitIds(JSContext* cx, GPUMultisampleStateAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->mask_id.init(cx, "mask") ||
!atomsCache->count_id.init(cx, "count") ||
!atomsCache->alphaToCoverageEnabled_id.init(cx, "alphaToCoverageEnabled")) {
return false;
}
return true;
}
bool
GPUMultisampleState::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUMultisampleStateAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUMultisampleStateAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->alphaToCoverageEnabled_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'alphaToCoverageEnabled' member of GPUMultisampleState", &mAlphaToCoverageEnabled)) {
return false;
}
} else {
mAlphaToCoverageEnabled = false;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->count_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'count' member of GPUMultisampleState", &mCount)) {
return false;
}
} else {
mCount = 1U;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->mask_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'mask' member of GPUMultisampleState", &mMask)) {
return false;
}
} else {
mMask = 4294967295U;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUMultisampleState::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUMultisampleState::TraceDictionary(JSTracer* trc)
{
}
GPUMultisampleState&
GPUMultisampleState::operator=(const GPUMultisampleState& aOther)
{
DictionaryBase::operator=(aOther);
mAlphaToCoverageEnabled = aOther.mAlphaToCoverageEnabled;
mCount = aOther.mCount;
mMask = aOther.mMask;
return *this;
}
GPUObjectDescriptorBase::GPUObjectDescriptorBase()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUObjectDescriptorBase::InitIds(JSContext* cx, GPUObjectDescriptorBaseAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->label_id.init(cx, "label")) {
return false;
}
return true;
}
bool
GPUObjectDescriptorBase::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUObjectDescriptorBaseAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUObjectDescriptorBaseAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->label_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mLabel)) {
return false;
}
if (!NormalizeUSVString(mLabel)) {
JS_ReportOutOfMemory(cx);
return false;
}
} else {
mLabel.AssignLiteral(u"");
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUObjectDescriptorBase::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUObjectDescriptorBase::TraceDictionary(JSTracer* trc)
{
}
GPUObjectDescriptorBase&
GPUObjectDescriptorBase::operator=(const GPUObjectDescriptorBase& aOther)
{
DictionaryBase::operator=(aOther);
mLabel = aOther.mLabel;
return *this;
}
GPUOrigin2DDict::GPUOrigin2DDict()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUOrigin2DDict::InitIds(JSContext* cx, GPUOrigin2DDictAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->y_id.init(cx, "y") ||
!atomsCache->x_id.init(cx, "x")) {
return false;
}
return true;
}
bool
GPUOrigin2DDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUOrigin2DDictAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUOrigin2DDictAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->x_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'x' member of GPUOrigin2DDict", &mX)) {
return false;
}
} else {
mX = 0U;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->y_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'y' member of GPUOrigin2DDict", &mY)) {
return false;
}
} else {
mY = 0U;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUOrigin2DDict::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUOrigin2DDict::TraceDictionary(JSTracer* trc)
{
}
GPUOrigin2DDict&
GPUOrigin2DDict::operator=(const GPUOrigin2DDict& aOther)
{
DictionaryBase::operator=(aOther);
mX = aOther.mX;
mY = aOther.mY;
return *this;
}
GPUOrigin3DDict::GPUOrigin3DDict()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUOrigin3DDict::InitIds(JSContext* cx, GPUOrigin3DDictAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->z_id.init(cx, "z") ||
!atomsCache->y_id.init(cx, "y") ||
!atomsCache->x_id.init(cx, "x")) {
return false;
}
return true;
}
bool
GPUOrigin3DDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUOrigin3DDictAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUOrigin3DDictAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->x_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'x' member of GPUOrigin3DDict", &mX)) {
return false;
}
} else {
mX = 0U;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->y_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'y' member of GPUOrigin3DDict", &mY)) {
return false;
}
} else {
mY = 0U;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->z_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'z' member of GPUOrigin3DDict", &mZ)) {
return false;
}
} else {
mZ = 0U;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUOrigin3DDict::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUOrigin3DDict::TraceDictionary(JSTracer* trc)
{
}
GPUOrigin3DDict&
GPUOrigin3DDict::operator=(const GPUOrigin3DDict& aOther)
{
DictionaryBase::operator=(aOther);
mX = aOther.mX;
mY = aOther.mY;
mZ = aOther.mZ;
return *this;
}
GPUPipelineErrorInit::GPUPipelineErrorInit()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUPipelineErrorInit::InitIds(JSContext* cx, GPUPipelineErrorInitAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->reason_id.init(cx, "reason")) {
return false;
}
return true;
}
bool
GPUPipelineErrorInit::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUPipelineErrorInitAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUPipelineErrorInitAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->reason_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUPipelineErrorReason>::Values,
"GPUPipelineErrorReason", "'reason' member of GPUPipelineErrorInit",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mReason = static_cast<GPUPipelineErrorReason>(index);
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'reason' member of GPUPipelineErrorInit");
}
return true;
}
bool
GPUPipelineErrorInit::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUPipelineErrorInit::TraceDictionary(JSTracer* trc)
{
}
GPUPipelineErrorInit&
GPUPipelineErrorInit::operator=(const GPUPipelineErrorInit& aOther)
{
DictionaryBase::operator=(aOther);
mReason = aOther.mReason;
return *this;
}
bool
GPUPipelineLayoutOrGPUAutoLayoutMode::TrySetToGPUPipelineLayout(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::webgpu::PipelineLayout>& memberSlot = RawSetAsGPUPipelineLayout();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUPipelineLayout, mozilla::webgpu::PipelineLayout>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyGPUPipelineLayout();
tryNext = true;
return true;
}
}
}
return true;
}
bool
GPUPipelineLayoutOrGPUAutoLayoutMode::TrySetToGPUPipelineLayout(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUPipelineLayout(cx, value, tryNext, passedToJSImpl);
}
bool
GPUPipelineLayoutOrGPUAutoLayoutMode::TrySetToGPUAutoLayoutMode(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
GPUAutoLayoutMode& memberSlot = RawSetAsGPUAutoLayoutMode();
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, value,
binding_detail::EnumStrings<GPUAutoLayoutMode>::Values,
"GPUAutoLayoutMode", "GPUAutoLayoutMode branch of (GPUPipelineLayout or GPUAutoLayoutMode)",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
memberSlot = static_cast<GPUAutoLayoutMode>(index);
}
}
return true;
}
bool
GPUPipelineLayoutOrGPUAutoLayoutMode::TrySetToGPUAutoLayoutMode(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUAutoLayoutMode(cx, value, tryNext, passedToJSImpl);
}
bool
GPUPipelineLayoutOrGPUAutoLayoutMode::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToGPUPipelineLayout(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToGPUAutoLayoutMode(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "GPUPipelineLayout");
return false;
}
return true;
}
bool
GPUPipelineLayoutOrGPUAutoLayoutMode::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
GPUPipelineLayoutOrGPUAutoLayoutMode::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eGPUPipelineLayout: {
if (!GetOrCreateDOMReflector(cx, mValue.mGPUPipelineLayout.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eGPUAutoLayoutMode: {
if (!ToJSValue(cx, mValue.mGPUAutoLayoutMode.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::OwningGPUPipelineLayoutOrGPUAutoLayoutMode(OwningGPUPipelineLayoutOrGPUAutoLayoutMode&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eGPUPipelineLayout: {
mType = eGPUPipelineLayout;
mValue.mGPUPipelineLayout.SetValue(std::move(aOther.mValue.mGPUPipelineLayout.Value()));
break;
}
case eGPUAutoLayoutMode: {
mType = eGPUAutoLayoutMode;
mValue.mGPUAutoLayoutMode.SetValue(std::move(aOther.mValue.mGPUAutoLayoutMode.Value()));
break;
}
}
}
bool
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::TrySetToGPUPipelineLayout(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::webgpu::PipelineLayout>& memberSlot = RawSetAsGPUPipelineLayout();
static_assert(IsRefcounted<mozilla::webgpu::PipelineLayout>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUPipelineLayout, mozilla::webgpu::PipelineLayout>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyGPUPipelineLayout();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::TrySetToGPUPipelineLayout(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUPipelineLayout(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::webgpu::PipelineLayout>&
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::RawSetAsGPUPipelineLayout()
{
if (mType == eGPUPipelineLayout) {
return mValue.mGPUPipelineLayout.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eGPUPipelineLayout;
return mValue.mGPUPipelineLayout.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::webgpu::PipelineLayout>&
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::SetAsGPUPipelineLayout()
{
if (mType == eGPUPipelineLayout) {
return mValue.mGPUPipelineLayout.Value();
}
Uninit();
mType = eGPUPipelineLayout;
return mValue.mGPUPipelineLayout.SetValue();
}
void
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::DestroyGPUPipelineLayout()
{
MOZ_RELEASE_ASSERT(IsGPUPipelineLayout(), "Wrong type!");
mValue.mGPUPipelineLayout.Destroy();
mType = eUninitialized;
}
bool
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::TrySetToGPUAutoLayoutMode(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
GPUAutoLayoutMode& memberSlot = RawSetAsGPUAutoLayoutMode();
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, value,
binding_detail::EnumStrings<GPUAutoLayoutMode>::Values,
"GPUAutoLayoutMode", "GPUAutoLayoutMode branch of (GPUPipelineLayout or GPUAutoLayoutMode)",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
memberSlot = static_cast<GPUAutoLayoutMode>(index);
}
}
return true;
}
bool
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::TrySetToGPUAutoLayoutMode(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUAutoLayoutMode(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] GPUAutoLayoutMode&
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::RawSetAsGPUAutoLayoutMode()
{
if (mType == eGPUAutoLayoutMode) {
return mValue.mGPUAutoLayoutMode.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eGPUAutoLayoutMode;
return mValue.mGPUAutoLayoutMode.SetValue();
}
[[nodiscard]] GPUAutoLayoutMode&
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::SetAsGPUAutoLayoutMode()
{
if (mType == eGPUAutoLayoutMode) {
return mValue.mGPUAutoLayoutMode.Value();
}
Uninit();
mType = eGPUAutoLayoutMode;
return mValue.mGPUAutoLayoutMode.SetValue();
}
void
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::DestroyGPUAutoLayoutMode()
{
MOZ_RELEASE_ASSERT(IsGPUAutoLayoutMode(), "Wrong type!");
mValue.mGPUAutoLayoutMode.Destroy();
mType = eUninitialized;
}
bool
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToGPUPipelineLayout(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
do {
done = (failed = !TrySetToGPUAutoLayoutMode(cx, value, tryNext)) || !tryNext;
break;
} while (false);
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "GPUPipelineLayout");
return false;
}
return true;
}
bool
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eGPUPipelineLayout: {
DestroyGPUPipelineLayout();
break;
}
case eGPUAutoLayoutMode: {
DestroyGPUAutoLayoutMode();
break;
}
}
}
bool
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eGPUPipelineLayout: {
if (!GetOrCreateDOMReflector(cx, mValue.mGPUPipelineLayout.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eGPUAutoLayoutMode: {
if (!ToJSValue(cx, mValue.mGPUAutoLayoutMode.Value(), rval)) {
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningGPUPipelineLayoutOrGPUAutoLayoutMode&
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::operator=(OwningGPUPipelineLayoutOrGPUAutoLayoutMode&& aOther)
{
this->~OwningGPUPipelineLayoutOrGPUAutoLayoutMode();
new (this) OwningGPUPipelineLayoutOrGPUAutoLayoutMode (std::move(aOther));
return *this;
}
OwningGPUPipelineLayoutOrGPUAutoLayoutMode&
OwningGPUPipelineLayoutOrGPUAutoLayoutMode::operator=(const OwningGPUPipelineLayoutOrGPUAutoLayoutMode& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eGPUPipelineLayout: {
SetAsGPUPipelineLayout() = aOther.GetAsGPUPipelineLayout();
break;
}
case eGPUAutoLayoutMode: {
SetAsGPUAutoLayoutMode() = aOther.GetAsGPUAutoLayoutMode();
break;
}
}
return *this;
}
GPUPrimitiveState::GPUPrimitiveState()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUPrimitiveState::InitIds(JSContext* cx, GPUPrimitiveStateAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->unclippedDepth_id.init(cx, "unclippedDepth") ||
!atomsCache->topology_id.init(cx, "topology") ||
!atomsCache->stripIndexFormat_id.init(cx, "stripIndexFormat") ||
!atomsCache->frontFace_id.init(cx, "frontFace") ||
!atomsCache->cullMode_id.init(cx, "cullMode")) {
return false;
}
return true;
}
bool
GPUPrimitiveState::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUPrimitiveStateAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUPrimitiveStateAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->cullMode_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUCullMode>::Values,
"GPUCullMode", "'cullMode' member of GPUPrimitiveState",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mCullMode = static_cast<GPUCullMode>(index);
}
} else {
mCullMode = GPUCullMode::None;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->frontFace_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUFrontFace>::Values,
"GPUFrontFace", "'frontFace' member of GPUPrimitiveState",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mFrontFace = static_cast<GPUFrontFace>(index);
}
} else {
mFrontFace = GPUFrontFace::Ccw;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->stripIndexFormat_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mStripIndexFormat.Construct();
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUIndexFormat>::Values,
"GPUIndexFormat", "'stripIndexFormat' member of GPUPrimitiveState",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
(mStripIndexFormat.Value()) = static_cast<GPUIndexFormat>(index);
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->topology_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUPrimitiveTopology>::Values,
"GPUPrimitiveTopology", "'topology' member of GPUPrimitiveState",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mTopology = static_cast<GPUPrimitiveTopology>(index);
}
} else {
mTopology = GPUPrimitiveTopology::Triangle_list;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->unclippedDepth_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'unclippedDepth' member of GPUPrimitiveState", &mUnclippedDepth)) {
return false;
}
} else {
mUnclippedDepth = false;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUPrimitiveState::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUPrimitiveState::TraceDictionary(JSTracer* trc)
{
}
GPUPrimitiveState&
GPUPrimitiveState::operator=(const GPUPrimitiveState& aOther)
{
DictionaryBase::operator=(aOther);
mCullMode = aOther.mCullMode;
mFrontFace = aOther.mFrontFace;
mStripIndexFormat.Reset();
if (aOther.mStripIndexFormat.WasPassed()) {
mStripIndexFormat.Construct(aOther.mStripIndexFormat.Value());
}
mTopology = aOther.mTopology;
mUnclippedDepth = aOther.mUnclippedDepth;
return *this;
}
GPUProgrammableStage::GPUProgrammableStage()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUProgrammableStage::InitIds(JSContext* cx, GPUProgrammableStageAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->module_id.init(cx, "module") ||
!atomsCache->entryPoint_id.init(cx, "entryPoint") ||
!atomsCache->constants_id.init(cx, "constants")) {
return false;
}
return true;
}
bool
GPUProgrammableStage::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUProgrammableStageAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUProgrammableStageAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->constants_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mConstants.Construct();
if (temp.ref().isObject()) {
auto& recordEntries = (mConstants.Value()).Entries();
JS::Rooted<JSObject*> recordObj(cx, &temp.ref().toObject());
JS::RootedVector<jsid> ids(cx);
if (!js::GetPropertyKeys(cx, recordObj,
JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
return false;
}
if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
JS_ReportOutOfMemory(cx);
return false;
}
JS::Rooted<JS::Value> propNameValue(cx);
JS::Rooted<JS::Value> temp(cx);
JS::Rooted<jsid> curId(cx);
JS::Rooted<JS::Value> idVal(cx);
// Use a hashset to keep track of ids seen, to avoid
// introducing nasty O(N^2) behavior scanning for them all the
// time. Ideally we'd use a data structure with O(1) lookup
// _and_ ordering for the MozMap, but we don't have one lying
// around.
nsTHashtable<nsStringHashKey> idsSeen;
for (size_t i = 0; i < ids.length(); ++i) {
curId = ids[i];
JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
&desc)) {
return false;
}
if (desc.isNothing() || !desc->enumerable()) {
continue;
}
idVal = js::IdToValue(curId);
nsString propName;
// This will just throw if idVal is a Symbol, like the spec says
// to do.
if (!ConvertJSValueToUSVString(cx, idVal, "key of 'constants' member of GPUProgrammableStage", propName)) {
return false;
}
if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
return false;
}
Record<nsString, double>::EntryType* entry;
if (!idsSeen.EnsureInserted(propName)) {
// Find the existing entry.
auto idx = recordEntries.IndexOf(propName);
MOZ_ASSERT(idx != recordEntries.NoIndex,
"Why is it not found?");
// Now blow it away to make it look like it was just added
// to the array, because it's not obvious that it's
// safe to write to its already-initialized mValue via our
// normal codegen conversions. For example, the value
// could be a union and this would change its type, but
// codegen assumes we won't do that.
entry = recordEntries.ReconstructElementAt(idx);
} else {
// Safe to do an infallible append here, because we did a
// SetCapacity above to the right capacity.
entry = recordEntries.AppendElement();
}
entry->mKey = propName;
double& slot = entry->mValue;
if (!ValueToPrimitive<double, eDefault>(cx, temp, "Value in 'constants' member of GPUProgrammableStage", &slot)) {
return false;
} else if (!std::isfinite(slot)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Value in 'constants' member of GPUProgrammableStage");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'constants' member of GPUProgrammableStage");
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->entryPoint_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mEntryPoint.Construct();
if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mEntryPoint.Value()))) {
return false;
}
if (!NormalizeUSVString((mEntryPoint.Value()))) {
JS_ReportOutOfMemory(cx);
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->module_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
static_assert(IsRefcounted<mozilla::webgpu::ShaderModule>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUShaderModule, mozilla::webgpu::ShaderModule>(temp.ptr(), mModule, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'module' member of GPUProgrammableStage", "GPUShaderModule");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'module' member of GPUProgrammableStage");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'module' member of GPUProgrammableStage");
}
return true;
}
bool
GPUProgrammableStage::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUProgrammableStage::TraceDictionary(JSTracer* trc)
{
}
GPURenderPassTimestampWrites::GPURenderPassTimestampWrites()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPURenderPassTimestampWrites::InitIds(JSContext* cx, GPURenderPassTimestampWritesAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->querySet_id.init(cx, "querySet") ||
!atomsCache->endOfPassWriteIndex_id.init(cx, "endOfPassWriteIndex") ||
!atomsCache->beginningOfPassWriteIndex_id.init(cx, "beginningOfPassWriteIndex")) {
return false;
}
return true;
}
bool
GPURenderPassTimestampWrites::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPURenderPassTimestampWritesAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPURenderPassTimestampWritesAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->beginningOfPassWriteIndex_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mBeginningOfPassWriteIndex.Construct();
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'beginningOfPassWriteIndex' member of GPURenderPassTimestampWrites", &(mBeginningOfPassWriteIndex.Value()))) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->endOfPassWriteIndex_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mEndOfPassWriteIndex.Construct();
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'endOfPassWriteIndex' member of GPURenderPassTimestampWrites", &(mEndOfPassWriteIndex.Value()))) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->querySet_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
static_assert(IsRefcounted<mozilla::webgpu::QuerySet>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUQuerySet, mozilla::webgpu::QuerySet>(temp.ptr(), mQuerySet, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'querySet' member of GPURenderPassTimestampWrites", "GPUQuerySet");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'querySet' member of GPURenderPassTimestampWrites");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'querySet' member of GPURenderPassTimestampWrites");
}
return true;
}
bool
GPURenderPassTimestampWrites::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPURenderPassTimestampWrites::TraceDictionary(JSTracer* trc)
{
}
GPURenderPassTimestampWrites&
GPURenderPassTimestampWrites::operator=(const GPURenderPassTimestampWrites& aOther)
{
DictionaryBase::operator=(aOther);
mBeginningOfPassWriteIndex.Reset();
if (aOther.mBeginningOfPassWriteIndex.WasPassed()) {
mBeginningOfPassWriteIndex.Construct(aOther.mBeginningOfPassWriteIndex.Value());
}
mEndOfPassWriteIndex.Reset();
if (aOther.mEndOfPassWriteIndex.WasPassed()) {
mEndOfPassWriteIndex.Construct(aOther.mEndOfPassWriteIndex.Value());
}
mQuerySet = aOther.mQuerySet;
return *this;
}
GPURequestAdapterOptions::GPURequestAdapterOptions()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPURequestAdapterOptions::InitIds(JSContext* cx, GPURequestAdapterOptionsAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->xrCompatible_id.init(cx, "xrCompatible") ||
!atomsCache->powerPreference_id.init(cx, "powerPreference") ||
!atomsCache->forceFallbackAdapter_id.init(cx, "forceFallbackAdapter") ||
!atomsCache->featureLevel_id.init(cx, "featureLevel")) {
return false;
}
return true;
}
bool
GPURequestAdapterOptions::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPURequestAdapterOptionsAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPURequestAdapterOptionsAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->featureLevel_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mFeatureLevel)) {
return false;
}
} else {
mFeatureLevel.AssignLiteral(u"core");
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->forceFallbackAdapter_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'forceFallbackAdapter' member of GPURequestAdapterOptions", &mForceFallbackAdapter)) {
return false;
}
} else {
mForceFallbackAdapter = false;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->powerPreference_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mPowerPreference.Construct();
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUPowerPreference>::Values,
"GPUPowerPreference", "'powerPreference' member of GPURequestAdapterOptions",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
(mPowerPreference.Value()) = static_cast<GPUPowerPreference>(index);
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->xrCompatible_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'xrCompatible' member of GPURequestAdapterOptions", &mXrCompatible)) {
return false;
}
} else {
mXrCompatible = false;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPURequestAdapterOptions::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPURequestAdapterOptions::TraceDictionary(JSTracer* trc)
{
}
GPURequestAdapterOptions&
GPURequestAdapterOptions::operator=(const GPURequestAdapterOptions& aOther)
{
DictionaryBase::operator=(aOther);
mFeatureLevel = aOther.mFeatureLevel;
mForceFallbackAdapter = aOther.mForceFallbackAdapter;
mPowerPreference.Reset();
if (aOther.mPowerPreference.WasPassed()) {
mPowerPreference.Construct(aOther.mPowerPreference.Value());
}
mXrCompatible = aOther.mXrCompatible;
return *this;
}
GPUSamplerBindingLayout::GPUSamplerBindingLayout()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUSamplerBindingLayout::InitIds(JSContext* cx, GPUSamplerBindingLayoutAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->type_id.init(cx, "type")) {
return false;
}
return true;
}
bool
GPUSamplerBindingLayout::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUSamplerBindingLayoutAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUSamplerBindingLayoutAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->type_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUSamplerBindingType>::Values,
"GPUSamplerBindingType", "'type' member of GPUSamplerBindingLayout",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mType = static_cast<GPUSamplerBindingType>(index);
}
} else {
mType = GPUSamplerBindingType::Filtering;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUSamplerBindingLayout::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUSamplerBindingLayout::TraceDictionary(JSTracer* trc)
{
}
GPUSamplerBindingLayout&
GPUSamplerBindingLayout::operator=(const GPUSamplerBindingLayout& aOther)
{
DictionaryBase::operator=(aOther);
mType = aOther.mType;
return *this;
}
GPUStencilFaceState::GPUStencilFaceState()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUStencilFaceState::InitIds(JSContext* cx, GPUStencilFaceStateAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->passOp_id.init(cx, "passOp") ||
!atomsCache->failOp_id.init(cx, "failOp") ||
!atomsCache->depthFailOp_id.init(cx, "depthFailOp") ||
!atomsCache->compare_id.init(cx, "compare")) {
return false;
}
return true;
}
bool
GPUStencilFaceState::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUStencilFaceStateAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUStencilFaceStateAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->compare_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUCompareFunction>::Values,
"GPUCompareFunction", "'compare' member of GPUStencilFaceState",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mCompare = static_cast<GPUCompareFunction>(index);
}
} else {
mCompare = GPUCompareFunction::Always;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depthFailOp_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUStencilOperation>::Values,
"GPUStencilOperation", "'depthFailOp' member of GPUStencilFaceState",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mDepthFailOp = static_cast<GPUStencilOperation>(index);
}
} else {
mDepthFailOp = GPUStencilOperation::Keep;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->failOp_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUStencilOperation>::Values,
"GPUStencilOperation", "'failOp' member of GPUStencilFaceState",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mFailOp = static_cast<GPUStencilOperation>(index);
}
} else {
mFailOp = GPUStencilOperation::Keep;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->passOp_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUStencilOperation>::Values,
"GPUStencilOperation", "'passOp' member of GPUStencilFaceState",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mPassOp = static_cast<GPUStencilOperation>(index);
}
} else {
mPassOp = GPUStencilOperation::Keep;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUStencilFaceState::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUStencilFaceState::TraceDictionary(JSTracer* trc)
{
}
GPUStencilFaceState&
GPUStencilFaceState::operator=(const GPUStencilFaceState& aOther)
{
DictionaryBase::operator=(aOther);
mCompare = aOther.mCompare;
mDepthFailOp = aOther.mDepthFailOp;
mFailOp = aOther.mFailOp;
mPassOp = aOther.mPassOp;
return *this;
}
GPUStorageTextureBindingLayout::GPUStorageTextureBindingLayout()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUStorageTextureBindingLayout::InitIds(JSContext* cx, GPUStorageTextureBindingLayoutAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->viewDimension_id.init(cx, "viewDimension") ||
!atomsCache->format_id.init(cx, "format") ||
!atomsCache->access_id.init(cx, "access")) {
return false;
}
return true;
}
bool
GPUStorageTextureBindingLayout::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUStorageTextureBindingLayoutAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUStorageTextureBindingLayoutAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->access_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUStorageTextureAccess>::Values,
"GPUStorageTextureAccess", "'access' member of GPUStorageTextureBindingLayout",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mAccess = static_cast<GPUStorageTextureAccess>(index);
}
} else {
mAccess = GPUStorageTextureAccess::Write_only;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->format_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUTextureFormat>::Values,
"GPUTextureFormat", "'format' member of GPUStorageTextureBindingLayout",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mFormat = static_cast<GPUTextureFormat>(index);
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'format' member of GPUStorageTextureBindingLayout");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->viewDimension_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUTextureViewDimension>::Values,
"GPUTextureViewDimension", "'viewDimension' member of GPUStorageTextureBindingLayout",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mViewDimension = static_cast<GPUTextureViewDimension>(index);
}
} else {
mViewDimension = GPUTextureViewDimension::_2d;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUStorageTextureBindingLayout::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUStorageTextureBindingLayout::TraceDictionary(JSTracer* trc)
{
}
GPUStorageTextureBindingLayout&
GPUStorageTextureBindingLayout::operator=(const GPUStorageTextureBindingLayout& aOther)
{
DictionaryBase::operator=(aOther);
mAccess = aOther.mAccess;
mFormat = aOther.mFormat;
mViewDimension = aOther.mViewDimension;
return *this;
}
GPUTexelCopyBufferLayout::GPUTexelCopyBufferLayout()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUTexelCopyBufferLayout::InitIds(JSContext* cx, GPUTexelCopyBufferLayoutAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->rowsPerImage_id.init(cx, "rowsPerImage") ||
!atomsCache->offset_id.init(cx, "offset") ||
!atomsCache->bytesPerRow_id.init(cx, "bytesPerRow")) {
return false;
}
return true;
}
bool
GPUTexelCopyBufferLayout::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUTexelCopyBufferLayoutAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUTexelCopyBufferLayoutAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->bytesPerRow_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mBytesPerRow.Construct();
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'bytesPerRow' member of GPUTexelCopyBufferLayout", &(mBytesPerRow.Value()))) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->offset_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, temp.ref(), "'offset' member of GPUTexelCopyBufferLayout", &mOffset)) {
return false;
}
} else {
mOffset = 0ULL;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->rowsPerImage_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mRowsPerImage.Construct();
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'rowsPerImage' member of GPUTexelCopyBufferLayout", &(mRowsPerImage.Value()))) {
return false;
}
mIsAnyMemberPresent = true;
}
return true;
}
bool
GPUTexelCopyBufferLayout::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUTexelCopyBufferLayout::TraceDictionary(JSTracer* trc)
{
}
GPUTexelCopyBufferLayout&
GPUTexelCopyBufferLayout::operator=(const GPUTexelCopyBufferLayout& aOther)
{
DictionaryBase::operator=(aOther);
mBytesPerRow.Reset();
if (aOther.mBytesPerRow.WasPassed()) {
mBytesPerRow.Construct(aOther.mBytesPerRow.Value());
}
mOffset = aOther.mOffset;
mRowsPerImage.Reset();
if (aOther.mRowsPerImage.WasPassed()) {
mRowsPerImage.Construct(aOther.mRowsPerImage.Value());
}
return *this;
}
GPUTextureBindingLayout::GPUTextureBindingLayout()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUTextureBindingLayout::InitIds(JSContext* cx, GPUTextureBindingLayoutAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->viewDimension_id.init(cx, "viewDimension") ||
!atomsCache->sampleType_id.init(cx, "sampleType") ||
!atomsCache->multisampled_id.init(cx, "multisampled")) {
return false;
}
return true;
}
bool
GPUTextureBindingLayout::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUTextureBindingLayoutAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUTextureBindingLayoutAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->multisampled_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'multisampled' member of GPUTextureBindingLayout", &mMultisampled)) {
return false;
}
} else {
mMultisampled = false;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->sampleType_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUTextureSampleType>::Values,
"GPUTextureSampleType", "'sampleType' member of GPUTextureBindingLayout",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mSampleType = static_cast<GPUTextureSampleType>(index);
}
} else {
mSampleType = GPUTextureSampleType::Float;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->viewDimension_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUTextureViewDimension>::Values,
"GPUTextureViewDimension", "'viewDimension' member of GPUTextureBindingLayout",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mViewDimension = static_cast<GPUTextureViewDimension>(index);
}
} else {
mViewDimension = GPUTextureViewDimension::_2d;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUTextureBindingLayout::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUTextureBindingLayout::TraceDictionary(JSTracer* trc)
{
}
GPUTextureBindingLayout&
GPUTextureBindingLayout::operator=(const GPUTextureBindingLayout& aOther)
{
DictionaryBase::operator=(aOther);
mMultisampled = aOther.mMultisampled;
mSampleType = aOther.mSampleType;
mViewDimension = aOther.mViewDimension;
return *this;
}
bool
GPUTextureOrGPUTextureView::TrySetToGPUTexture(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::webgpu::Texture>& memberSlot = RawSetAsGPUTexture();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUTexture, mozilla::webgpu::Texture>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyGPUTexture();
tryNext = true;
return true;
}
}
}
return true;
}
bool
GPUTextureOrGPUTextureView::TrySetToGPUTexture(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUTexture(cx, value, tryNext, passedToJSImpl);
}
bool
GPUTextureOrGPUTextureView::TrySetToGPUTextureView(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::webgpu::TextureView>& memberSlot = RawSetAsGPUTextureView();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUTextureView, mozilla::webgpu::TextureView>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyGPUTextureView();
tryNext = true;
return true;
}
}
}
return true;
}
bool
GPUTextureOrGPUTextureView::TrySetToGPUTextureView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUTextureView(cx, value, tryNext, passedToJSImpl);
}
bool
GPUTextureOrGPUTextureView::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToGPUTexture(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToGPUTextureView(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "GPUTexture, GPUTextureView");
return false;
}
return true;
}
bool
GPUTextureOrGPUTextureView::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
GPUTextureOrGPUTextureView::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eGPUTexture: {
if (!GetOrCreateDOMReflector(cx, mValue.mGPUTexture.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eGPUTextureView: {
if (!GetOrCreateDOMReflector(cx, mValue.mGPUTextureView.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningGPUTextureOrGPUTextureView::OwningGPUTextureOrGPUTextureView(OwningGPUTextureOrGPUTextureView&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eGPUTexture: {
mType = eGPUTexture;
mValue.mGPUTexture.SetValue(std::move(aOther.mValue.mGPUTexture.Value()));
break;
}
case eGPUTextureView: {
mType = eGPUTextureView;
mValue.mGPUTextureView.SetValue(std::move(aOther.mValue.mGPUTextureView.Value()));
break;
}
}
}
bool
OwningGPUTextureOrGPUTextureView::TrySetToGPUTexture(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::webgpu::Texture>& memberSlot = RawSetAsGPUTexture();
static_assert(IsRefcounted<mozilla::webgpu::Texture>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUTexture, mozilla::webgpu::Texture>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyGPUTexture();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningGPUTextureOrGPUTextureView::TrySetToGPUTexture(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUTexture(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::webgpu::Texture>&
OwningGPUTextureOrGPUTextureView::RawSetAsGPUTexture()
{
if (mType == eGPUTexture) {
return mValue.mGPUTexture.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eGPUTexture;
return mValue.mGPUTexture.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::webgpu::Texture>&
OwningGPUTextureOrGPUTextureView::SetAsGPUTexture()
{
if (mType == eGPUTexture) {
return mValue.mGPUTexture.Value();
}
Uninit();
mType = eGPUTexture;
return mValue.mGPUTexture.SetValue();
}
void
OwningGPUTextureOrGPUTextureView::DestroyGPUTexture()
{
MOZ_RELEASE_ASSERT(IsGPUTexture(), "Wrong type!");
mValue.mGPUTexture.Destroy();
mType = eUninitialized;
}
bool
OwningGPUTextureOrGPUTextureView::TrySetToGPUTextureView(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::webgpu::TextureView>& memberSlot = RawSetAsGPUTextureView();
static_assert(IsRefcounted<mozilla::webgpu::TextureView>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUTextureView, mozilla::webgpu::TextureView>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyGPUTextureView();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningGPUTextureOrGPUTextureView::TrySetToGPUTextureView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUTextureView(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::webgpu::TextureView>&
OwningGPUTextureOrGPUTextureView::RawSetAsGPUTextureView()
{
if (mType == eGPUTextureView) {
return mValue.mGPUTextureView.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eGPUTextureView;
return mValue.mGPUTextureView.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::webgpu::TextureView>&
OwningGPUTextureOrGPUTextureView::SetAsGPUTextureView()
{
if (mType == eGPUTextureView) {
return mValue.mGPUTextureView.Value();
}
Uninit();
mType = eGPUTextureView;
return mValue.mGPUTextureView.SetValue();
}
void
OwningGPUTextureOrGPUTextureView::DestroyGPUTextureView()
{
MOZ_RELEASE_ASSERT(IsGPUTextureView(), "Wrong type!");
mValue.mGPUTextureView.Destroy();
mType = eUninitialized;
}
bool
OwningGPUTextureOrGPUTextureView::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToGPUTexture(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToGPUTextureView(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "GPUTexture, GPUTextureView");
return false;
}
return true;
}
bool
OwningGPUTextureOrGPUTextureView::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningGPUTextureOrGPUTextureView::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eGPUTexture: {
DestroyGPUTexture();
break;
}
case eGPUTextureView: {
DestroyGPUTextureView();
break;
}
}
}
bool
OwningGPUTextureOrGPUTextureView::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eGPUTexture: {
if (!GetOrCreateDOMReflector(cx, mValue.mGPUTexture.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eGPUTextureView: {
if (!GetOrCreateDOMReflector(cx, mValue.mGPUTextureView.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningGPUTextureOrGPUTextureView&
OwningGPUTextureOrGPUTextureView::operator=(OwningGPUTextureOrGPUTextureView&& aOther)
{
this->~OwningGPUTextureOrGPUTextureView();
new (this) OwningGPUTextureOrGPUTextureView (std::move(aOther));
return *this;
}
OwningGPUTextureOrGPUTextureView&
OwningGPUTextureOrGPUTextureView::operator=(const OwningGPUTextureOrGPUTextureView& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eGPUTexture: {
SetAsGPUTexture() = aOther.GetAsGPUTexture();
break;
}
case eGPUTextureView: {
SetAsGPUTextureView() = aOther.GetAsGPUTextureView();
break;
}
}
return *this;
}
GPUVertexAttribute::GPUVertexAttribute()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUVertexAttribute::InitIds(JSContext* cx, GPUVertexAttributeAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->shaderLocation_id.init(cx, "shaderLocation") ||
!atomsCache->offset_id.init(cx, "offset") ||
!atomsCache->format_id.init(cx, "format")) {
return false;
}
return true;
}
bool
GPUVertexAttribute::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUVertexAttributeAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUVertexAttributeAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->format_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUVertexFormat>::Values,
"GPUVertexFormat", "'format' member of GPUVertexAttribute",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mFormat = static_cast<GPUVertexFormat>(index);
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'format' member of GPUVertexAttribute");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->offset_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, temp.ref(), "'offset' member of GPUVertexAttribute", &mOffset)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'offset' member of GPUVertexAttribute");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->shaderLocation_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'shaderLocation' member of GPUVertexAttribute", &mShaderLocation)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'shaderLocation' member of GPUVertexAttribute");
}
return true;
}
bool
GPUVertexAttribute::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUVertexAttribute::TraceDictionary(JSTracer* trc)
{
}
GPUVertexAttribute&
GPUVertexAttribute::operator=(const GPUVertexAttribute& aOther)
{
DictionaryBase::operator=(aOther);
mFormat = aOther.mFormat;
mOffset = aOther.mOffset;
mShaderLocation = aOther.mShaderLocation;
return *this;
}
bool
HTMLVideoElementOrVideoFrame::TrySetToHTMLVideoElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::HTMLVideoElement>& memberSlot = RawSetAsHTMLVideoElement();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::HTMLVideoElement, mozilla::dom::HTMLVideoElement>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyHTMLVideoElement();
tryNext = true;
return true;
}
}
}
return true;
}
bool
HTMLVideoElementOrVideoFrame::TrySetToHTMLVideoElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToHTMLVideoElement(cx, value, tryNext, passedToJSImpl);
}
bool
HTMLVideoElementOrVideoFrame::TrySetToVideoFrame(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::VideoFrame>& memberSlot = RawSetAsVideoFrame();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::VideoFrame, mozilla::dom::VideoFrame>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyVideoFrame();
tryNext = true;
return true;
}
}
}
return true;
}
bool
HTMLVideoElementOrVideoFrame::TrySetToVideoFrame(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToVideoFrame(cx, value, tryNext, passedToJSImpl);
}
bool
HTMLVideoElementOrVideoFrame::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToHTMLVideoElement(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToVideoFrame(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "HTMLVideoElement, VideoFrame");
return false;
}
return true;
}
bool
HTMLVideoElementOrVideoFrame::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
HTMLVideoElementOrVideoFrame::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eHTMLVideoElement: {
if (!GetOrCreateDOMReflector(cx, mValue.mHTMLVideoElement.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eVideoFrame: {
if (!GetOrCreateDOMReflector(cx, mValue.mVideoFrame.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningHTMLVideoElementOrVideoFrame::OwningHTMLVideoElementOrVideoFrame(OwningHTMLVideoElementOrVideoFrame&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eHTMLVideoElement: {
mType = eHTMLVideoElement;
mValue.mHTMLVideoElement.SetValue(std::move(aOther.mValue.mHTMLVideoElement.Value()));
break;
}
case eVideoFrame: {
mType = eVideoFrame;
mValue.mVideoFrame.SetValue(std::move(aOther.mValue.mVideoFrame.Value()));
break;
}
}
}
bool
OwningHTMLVideoElementOrVideoFrame::TrySetToHTMLVideoElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::HTMLVideoElement>& memberSlot = RawSetAsHTMLVideoElement();
static_assert(IsRefcounted<mozilla::dom::HTMLVideoElement>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::HTMLVideoElement, mozilla::dom::HTMLVideoElement>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyHTMLVideoElement();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningHTMLVideoElementOrVideoFrame::TrySetToHTMLVideoElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToHTMLVideoElement(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::HTMLVideoElement>&
OwningHTMLVideoElementOrVideoFrame::RawSetAsHTMLVideoElement()
{
if (mType == eHTMLVideoElement) {
return mValue.mHTMLVideoElement.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eHTMLVideoElement;
return mValue.mHTMLVideoElement.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::HTMLVideoElement>&
OwningHTMLVideoElementOrVideoFrame::SetAsHTMLVideoElement()
{
if (mType == eHTMLVideoElement) {
return mValue.mHTMLVideoElement.Value();
}
Uninit();
mType = eHTMLVideoElement;
return mValue.mHTMLVideoElement.SetValue();
}
void
OwningHTMLVideoElementOrVideoFrame::DestroyHTMLVideoElement()
{
MOZ_RELEASE_ASSERT(IsHTMLVideoElement(), "Wrong type!");
mValue.mHTMLVideoElement.Destroy();
mType = eUninitialized;
}
bool
OwningHTMLVideoElementOrVideoFrame::TrySetToVideoFrame(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::VideoFrame>& memberSlot = RawSetAsVideoFrame();
static_assert(IsRefcounted<mozilla::dom::VideoFrame>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::VideoFrame, mozilla::dom::VideoFrame>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyVideoFrame();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningHTMLVideoElementOrVideoFrame::TrySetToVideoFrame(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToVideoFrame(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::VideoFrame>&
OwningHTMLVideoElementOrVideoFrame::RawSetAsVideoFrame()
{
if (mType == eVideoFrame) {
return mValue.mVideoFrame.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eVideoFrame;
return mValue.mVideoFrame.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::VideoFrame>&
OwningHTMLVideoElementOrVideoFrame::SetAsVideoFrame()
{
if (mType == eVideoFrame) {
return mValue.mVideoFrame.Value();
}
Uninit();
mType = eVideoFrame;
return mValue.mVideoFrame.SetValue();
}
void
OwningHTMLVideoElementOrVideoFrame::DestroyVideoFrame()
{
MOZ_RELEASE_ASSERT(IsVideoFrame(), "Wrong type!");
mValue.mVideoFrame.Destroy();
mType = eUninitialized;
}
bool
OwningHTMLVideoElementOrVideoFrame::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToHTMLVideoElement(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToVideoFrame(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "HTMLVideoElement, VideoFrame");
return false;
}
return true;
}
bool
OwningHTMLVideoElementOrVideoFrame::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningHTMLVideoElementOrVideoFrame::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eHTMLVideoElement: {
DestroyHTMLVideoElement();
break;
}
case eVideoFrame: {
DestroyVideoFrame();
break;
}
}
}
bool
OwningHTMLVideoElementOrVideoFrame::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eHTMLVideoElement: {
if (!GetOrCreateDOMReflector(cx, mValue.mHTMLVideoElement.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eVideoFrame: {
if (!GetOrCreateDOMReflector(cx, mValue.mVideoFrame.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningHTMLVideoElementOrVideoFrame&
OwningHTMLVideoElementOrVideoFrame::operator=(OwningHTMLVideoElementOrVideoFrame&& aOther)
{
this->~OwningHTMLVideoElementOrVideoFrame();
new (this) OwningHTMLVideoElementOrVideoFrame (std::move(aOther));
return *this;
}
OwningHTMLVideoElementOrVideoFrame&
OwningHTMLVideoElementOrVideoFrame::operator=(const OwningHTMLVideoElementOrVideoFrame& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eHTMLVideoElement: {
SetAsHTMLVideoElement() = aOther.GetAsHTMLVideoElement();
break;
}
case eVideoFrame: {
SetAsVideoFrame() = aOther.GetAsVideoFrame();
break;
}
}
return *this;
}
bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToImageBitmap(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::ImageBitmap>& memberSlot = RawSetAsImageBitmap();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::ImageBitmap, mozilla::dom::ImageBitmap>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyImageBitmap();
tryNext = true;
return true;
}
}
}
return true;
}
bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToImageBitmap(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToImageBitmap(cx, value, tryNext, passedToJSImpl);
}
bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLImageElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::HTMLImageElement>& memberSlot = RawSetAsHTMLImageElement();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::HTMLImageElement, mozilla::dom::HTMLImageElement>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyHTMLImageElement();
tryNext = true;
return true;
}
}
}
return true;
}
bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLImageElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToHTMLImageElement(cx, value, tryNext, passedToJSImpl);
}
bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLCanvasElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::HTMLCanvasElement>& memberSlot = RawSetAsHTMLCanvasElement();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::HTMLCanvasElement, mozilla::dom::HTMLCanvasElement>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyHTMLCanvasElement();
tryNext = true;
return true;
}
}
}
return true;
}
bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLCanvasElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToHTMLCanvasElement(cx, value, tryNext, passedToJSImpl);
}
bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToOffscreenCanvas(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::dom::OffscreenCanvas>& memberSlot = RawSetAsOffscreenCanvas();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::OffscreenCanvas, mozilla::dom::OffscreenCanvas>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyOffscreenCanvas();
tryNext = true;
return true;
}
}
}
return true;
}
bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToOffscreenCanvas(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToOffscreenCanvas(cx, value, tryNext, passedToJSImpl);
}
bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToImageBitmap(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToHTMLImageElement(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToHTMLCanvasElement(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToOffscreenCanvas(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ImageBitmap, HTMLImageElement, HTMLCanvasElement, OffscreenCanvas");
return false;
}
return true;
}
bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
bool
ImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eImageBitmap: {
if (!GetOrCreateDOMReflector(cx, mValue.mImageBitmap.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eHTMLImageElement: {
if (!GetOrCreateDOMReflector(cx, mValue.mHTMLImageElement.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eHTMLCanvasElement: {
if (!GetOrCreateDOMReflector(cx, mValue.mHTMLCanvasElement.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eOffscreenCanvas: {
if (!GetOrCreateDOMReflector(cx, mValue.mOffscreenCanvas.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas(OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eImageBitmap: {
mType = eImageBitmap;
mValue.mImageBitmap.SetValue(std::move(aOther.mValue.mImageBitmap.Value()));
break;
}
case eHTMLImageElement: {
mType = eHTMLImageElement;
mValue.mHTMLImageElement.SetValue(std::move(aOther.mValue.mHTMLImageElement.Value()));
break;
}
case eHTMLCanvasElement: {
mType = eHTMLCanvasElement;
mValue.mHTMLCanvasElement.SetValue(std::move(aOther.mValue.mHTMLCanvasElement.Value()));
break;
}
case eOffscreenCanvas: {
mType = eOffscreenCanvas;
mValue.mOffscreenCanvas.SetValue(std::move(aOther.mValue.mOffscreenCanvas.Value()));
break;
}
}
}
bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToImageBitmap(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::ImageBitmap>& memberSlot = RawSetAsImageBitmap();
static_assert(IsRefcounted<mozilla::dom::ImageBitmap>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::ImageBitmap, mozilla::dom::ImageBitmap>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyImageBitmap();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToImageBitmap(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToImageBitmap(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::ImageBitmap>&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::RawSetAsImageBitmap()
{
if (mType == eImageBitmap) {
return mValue.mImageBitmap.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eImageBitmap;
return mValue.mImageBitmap.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::ImageBitmap>&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::SetAsImageBitmap()
{
if (mType == eImageBitmap) {
return mValue.mImageBitmap.Value();
}
Uninit();
mType = eImageBitmap;
return mValue.mImageBitmap.SetValue();
}
void
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::DestroyImageBitmap()
{
MOZ_RELEASE_ASSERT(IsImageBitmap(), "Wrong type!");
mValue.mImageBitmap.Destroy();
mType = eUninitialized;
}
bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLImageElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::HTMLImageElement>& memberSlot = RawSetAsHTMLImageElement();
static_assert(IsRefcounted<mozilla::dom::HTMLImageElement>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::HTMLImageElement, mozilla::dom::HTMLImageElement>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyHTMLImageElement();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLImageElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToHTMLImageElement(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::HTMLImageElement>&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::RawSetAsHTMLImageElement()
{
if (mType == eHTMLImageElement) {
return mValue.mHTMLImageElement.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eHTMLImageElement;
return mValue.mHTMLImageElement.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::HTMLImageElement>&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::SetAsHTMLImageElement()
{
if (mType == eHTMLImageElement) {
return mValue.mHTMLImageElement.Value();
}
Uninit();
mType = eHTMLImageElement;
return mValue.mHTMLImageElement.SetValue();
}
void
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::DestroyHTMLImageElement()
{
MOZ_RELEASE_ASSERT(IsHTMLImageElement(), "Wrong type!");
mValue.mHTMLImageElement.Destroy();
mType = eUninitialized;
}
bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLCanvasElement(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::HTMLCanvasElement>& memberSlot = RawSetAsHTMLCanvasElement();
static_assert(IsRefcounted<mozilla::dom::HTMLCanvasElement>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::HTMLCanvasElement, mozilla::dom::HTMLCanvasElement>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyHTMLCanvasElement();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToHTMLCanvasElement(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToHTMLCanvasElement(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::HTMLCanvasElement>&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::RawSetAsHTMLCanvasElement()
{
if (mType == eHTMLCanvasElement) {
return mValue.mHTMLCanvasElement.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eHTMLCanvasElement;
return mValue.mHTMLCanvasElement.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::HTMLCanvasElement>&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::SetAsHTMLCanvasElement()
{
if (mType == eHTMLCanvasElement) {
return mValue.mHTMLCanvasElement.Value();
}
Uninit();
mType = eHTMLCanvasElement;
return mValue.mHTMLCanvasElement.SetValue();
}
void
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::DestroyHTMLCanvasElement()
{
MOZ_RELEASE_ASSERT(IsHTMLCanvasElement(), "Wrong type!");
mValue.mHTMLCanvasElement.Destroy();
mType = eUninitialized;
}
bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToOffscreenCanvas(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::dom::OffscreenCanvas>& memberSlot = RawSetAsOffscreenCanvas();
static_assert(IsRefcounted<mozilla::dom::OffscreenCanvas>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::OffscreenCanvas, mozilla::dom::OffscreenCanvas>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyOffscreenCanvas();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::TrySetToOffscreenCanvas(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToOffscreenCanvas(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::dom::OffscreenCanvas>&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::RawSetAsOffscreenCanvas()
{
if (mType == eOffscreenCanvas) {
return mValue.mOffscreenCanvas.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eOffscreenCanvas;
return mValue.mOffscreenCanvas.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::dom::OffscreenCanvas>&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::SetAsOffscreenCanvas()
{
if (mType == eOffscreenCanvas) {
return mValue.mOffscreenCanvas.Value();
}
Uninit();
mType = eOffscreenCanvas;
return mValue.mOffscreenCanvas.SetValue();
}
void
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::DestroyOffscreenCanvas()
{
MOZ_RELEASE_ASSERT(IsOffscreenCanvas(), "Wrong type!");
mValue.mOffscreenCanvas.Destroy();
mType = eUninitialized;
}
bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToImageBitmap(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToHTMLImageElement(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToHTMLCanvasElement(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToOffscreenCanvas(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "ImageBitmap, HTMLImageElement, HTMLCanvasElement, OffscreenCanvas");
return false;
}
return true;
}
bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eImageBitmap: {
DestroyImageBitmap();
break;
}
case eHTMLImageElement: {
DestroyHTMLImageElement();
break;
}
case eHTMLCanvasElement: {
DestroyHTMLCanvasElement();
break;
}
case eOffscreenCanvas: {
DestroyOffscreenCanvas();
break;
}
}
}
bool
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
{
switch (mType) {
case eUninitialized: {
return false;
}
case eImageBitmap: {
if (!GetOrCreateDOMReflector(cx, mValue.mImageBitmap.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eHTMLImageElement: {
if (!GetOrCreateDOMReflector(cx, mValue.mHTMLImageElement.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eHTMLCanvasElement: {
if (!GetOrCreateDOMReflector(cx, mValue.mHTMLCanvasElement.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
case eOffscreenCanvas: {
if (!GetOrCreateDOMReflector(cx, mValue.mOffscreenCanvas.Value(), rval)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
default: {
return false;
}
}
}
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::operator=(OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas&& aOther)
{
this->~OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas();
new (this) OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas (std::move(aOther));
return *this;
}
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas&
OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas::operator=(const OwningImageBitmapOrHTMLImageElementOrHTMLCanvasElementOrOffscreenCanvas& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eImageBitmap: {
SetAsImageBitmap() = aOther.GetAsImageBitmap();
break;
}
case eHTMLImageElement: {
SetAsHTMLImageElement() = aOther.GetAsHTMLImageElement();
break;
}
case eHTMLCanvasElement: {
SetAsHTMLCanvasElement() = aOther.GetAsHTMLCanvasElement();
break;
}
case eOffscreenCanvas: {
SetAsOffscreenCanvas() = aOther.GetAsOffscreenCanvas();
break;
}
}
return *this;
}
bool
DoubleSequenceOrGPUColorDict::TrySetToDoubleSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::AutoSequence<double>& memberSlot = RawSetAsDoubleSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyDoubleSequence();
tryNext = true;
return true;
}
binding_detail::AutoSequence<double> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
double* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
double& slot = *slotPtr;
if (!ValueToPrimitive<double, eDefault>(cx, temp, "Element of sequence<double> branch of (sequence<double> or GPUColorDict)", &slot)) {
return false;
} else if (!std::isfinite(slot)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Element of sequence<double> branch of (sequence<double> or GPUColorDict)");
return false;
}
}
}
return true;
}
bool
DoubleSequenceOrGPUColorDict::TrySetToDoubleSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToDoubleSequence(cx, value, tryNext, passedToJSImpl);
}
bool
DoubleSequenceOrGPUColorDict::TrySetToGPUColorDict(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FastGPUColorDict& memberSlot = RawSetAsGPUColorDict();
if (!IsConvertibleToDictionary(value)) {
DestroyGPUColorDict();
tryNext = true;
return true;
}
if (!memberSlot.Init(cx, value, "GPUColorDict branch of (sequence<double> or GPUColorDict)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
DoubleSequenceOrGPUColorDict::TrySetToGPUColorDict(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUColorDict(cx, value, tryNext, passedToJSImpl);
}
bool
DoubleSequenceOrGPUColorDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToDoubleSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
done = (failed = !TrySetToGPUColorDict(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<double>, GPUColorDict");
return false;
}
return true;
}
bool
DoubleSequenceOrGPUColorDict::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
OwningDoubleSequenceOrGPUColorDict::OwningDoubleSequenceOrGPUColorDict(OwningDoubleSequenceOrGPUColorDict&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eDoubleSequence: {
mType = eDoubleSequence;
mValue.mDoubleSequence.SetValue(std::move(aOther.mValue.mDoubleSequence.Value()));
break;
}
case eGPUColorDict: {
mType = eGPUColorDict;
mValue.mGPUColorDict.SetValue(std::move(aOther.mValue.mGPUColorDict.Value()));
break;
}
}
}
bool
OwningDoubleSequenceOrGPUColorDict::TrySetToDoubleSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Sequence<double>& memberSlot = RawSetAsDoubleSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyDoubleSequence();
tryNext = true;
return true;
}
Sequence<double> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
double* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
double& slot = *slotPtr;
if (!ValueToPrimitive<double, eDefault>(cx, temp, "Element of sequence<double> branch of (sequence<double> or GPUColorDict)", &slot)) {
return false;
} else if (!std::isfinite(slot)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Element of sequence<double> branch of (sequence<double> or GPUColorDict)");
return false;
}
}
}
return true;
}
bool
OwningDoubleSequenceOrGPUColorDict::TrySetToDoubleSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToDoubleSequence(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Sequence<double>&
OwningDoubleSequenceOrGPUColorDict::RawSetAsDoubleSequence()
{
if (mType == eDoubleSequence) {
return mValue.mDoubleSequence.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eDoubleSequence;
return mValue.mDoubleSequence.SetValue();
}
[[nodiscard]] Sequence<double>&
OwningDoubleSequenceOrGPUColorDict::SetAsDoubleSequence()
{
if (mType == eDoubleSequence) {
return mValue.mDoubleSequence.Value();
}
Uninit();
mType = eDoubleSequence;
return mValue.mDoubleSequence.SetValue();
}
void
OwningDoubleSequenceOrGPUColorDict::DestroyDoubleSequence()
{
MOZ_RELEASE_ASSERT(IsDoubleSequence(), "Wrong type!");
mValue.mDoubleSequence.Destroy();
mType = eUninitialized;
}
bool
OwningDoubleSequenceOrGPUColorDict::TrySetToGPUColorDict(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
GPUColorDict& memberSlot = RawSetAsGPUColorDict();
if (!IsConvertibleToDictionary(value)) {
DestroyGPUColorDict();
tryNext = true;
return true;
}
if (!memberSlot.Init(cx, value, "GPUColorDict branch of (sequence<double> or GPUColorDict)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
OwningDoubleSequenceOrGPUColorDict::TrySetToGPUColorDict(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUColorDict(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] GPUColorDict&
OwningDoubleSequenceOrGPUColorDict::RawSetAsGPUColorDict()
{
if (mType == eGPUColorDict) {
return mValue.mGPUColorDict.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eGPUColorDict;
return mValue.mGPUColorDict.SetValue();
}
[[nodiscard]] GPUColorDict&
OwningDoubleSequenceOrGPUColorDict::SetAsGPUColorDict()
{
if (mType == eGPUColorDict) {
return mValue.mGPUColorDict.Value();
}
Uninit();
mType = eGPUColorDict;
return mValue.mGPUColorDict.SetValue();
}
void
OwningDoubleSequenceOrGPUColorDict::DestroyGPUColorDict()
{
MOZ_RELEASE_ASSERT(IsGPUColorDict(), "Wrong type!");
mValue.mGPUColorDict.Destroy();
mType = eUninitialized;
}
bool
OwningDoubleSequenceOrGPUColorDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToDoubleSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
done = (failed = !TrySetToGPUColorDict(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<double>, GPUColorDict");
return false;
}
return true;
}
bool
OwningDoubleSequenceOrGPUColorDict::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningDoubleSequenceOrGPUColorDict::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eDoubleSequence: {
DestroyDoubleSequence();
break;
}
case eGPUColorDict: {
DestroyGPUColorDict();
break;
}
}
}
OwningDoubleSequenceOrGPUColorDict&
OwningDoubleSequenceOrGPUColorDict::operator=(OwningDoubleSequenceOrGPUColorDict&& aOther)
{
this->~OwningDoubleSequenceOrGPUColorDict();
new (this) OwningDoubleSequenceOrGPUColorDict (std::move(aOther));
return *this;
}
OwningDoubleSequenceOrGPUColorDict&
OwningDoubleSequenceOrGPUColorDict::operator=(const OwningDoubleSequenceOrGPUColorDict& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eDoubleSequence: {
SetAsDoubleSequence() = aOther.GetAsDoubleSequence();
break;
}
case eGPUColorDict: {
SetAsGPUColorDict() = aOther.GetAsGPUColorDict();
break;
}
}
return *this;
}
GPUBindGroupLayoutEntry::GPUBindGroupLayoutEntry()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUBindGroupLayoutEntry::InitIds(JSContext* cx, GPUBindGroupLayoutEntryAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->visibility_id.init(cx, "visibility") ||
!atomsCache->texture_id.init(cx, "texture") ||
!atomsCache->storageTexture_id.init(cx, "storageTexture") ||
!atomsCache->sampler_id.init(cx, "sampler") ||
!atomsCache->externalTexture_id.init(cx, "externalTexture") ||
!atomsCache->buffer_id.init(cx, "buffer") ||
!atomsCache->binding_id.init(cx, "binding")) {
return false;
}
return true;
}
bool
GPUBindGroupLayoutEntry::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUBindGroupLayoutEntryAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUBindGroupLayoutEntryAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->binding_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'binding' member of GPUBindGroupLayoutEntry", &mBinding)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'binding' member of GPUBindGroupLayoutEntry");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->buffer_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mBuffer.Construct();
if (!(mBuffer.Value()).Init(cx, temp.ref(), "'buffer' member of GPUBindGroupLayoutEntry", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->externalTexture_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mExternalTexture.Construct();
if (!(mExternalTexture.Value()).Init(cx, temp.ref(), "'externalTexture' member of GPUBindGroupLayoutEntry", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->sampler_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mSampler.Construct();
if (!(mSampler.Value()).Init(cx, temp.ref(), "'sampler' member of GPUBindGroupLayoutEntry", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->storageTexture_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mStorageTexture.Construct();
if (!(mStorageTexture.Value()).Init(cx, temp.ref(), "'storageTexture' member of GPUBindGroupLayoutEntry", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->texture_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mTexture.Construct();
if (!(mTexture.Value()).Init(cx, temp.ref(), "'texture' member of GPUBindGroupLayoutEntry", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->visibility_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'visibility' member of GPUBindGroupLayoutEntry", &mVisibility)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'visibility' member of GPUBindGroupLayoutEntry");
}
return true;
}
bool
GPUBindGroupLayoutEntry::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUBindGroupLayoutEntry::TraceDictionary(JSTracer* trc)
{
}
GPUBindGroupLayoutEntry&
GPUBindGroupLayoutEntry::operator=(const GPUBindGroupLayoutEntry& aOther)
{
DictionaryBase::operator=(aOther);
mBinding = aOther.mBinding;
mBuffer.Reset();
if (aOther.mBuffer.WasPassed()) {
mBuffer.Construct(aOther.mBuffer.Value());
}
mExternalTexture.Reset();
if (aOther.mExternalTexture.WasPassed()) {
mExternalTexture.Construct(aOther.mExternalTexture.Value());
}
mSampler.Reset();
if (aOther.mSampler.WasPassed()) {
mSampler.Construct(aOther.mSampler.Value());
}
mStorageTexture.Reset();
if (aOther.mStorageTexture.WasPassed()) {
mStorageTexture.Construct(aOther.mStorageTexture.Value());
}
mTexture.Reset();
if (aOther.mTexture.WasPassed()) {
mTexture.Construct(aOther.mTexture.Value());
}
mVisibility = aOther.mVisibility;
return *this;
}
GPUBlendState::GPUBlendState()
: mAlpha(FastDictionaryInitializer()),
mColor(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUBlendState::InitIds(JSContext* cx, GPUBlendStateAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->color_id.init(cx, "color") ||
!atomsCache->alpha_id.init(cx, "alpha")) {
return false;
}
return true;
}
bool
GPUBlendState::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUBlendStateAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUBlendStateAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->alpha_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!mAlpha.Init(cx, temp.ref(), "'alpha' member of GPUBlendState", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'alpha' member of GPUBlendState");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->color_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!mColor.Init(cx, temp.ref(), "'color' member of GPUBlendState", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'color' member of GPUBlendState");
}
return true;
}
bool
GPUBlendState::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUBlendState::TraceDictionary(JSTracer* trc)
{
}
GPUBlendState&
GPUBlendState::operator=(const GPUBlendState& aOther)
{
DictionaryBase::operator=(aOther);
mAlpha = aOther.mAlpha;
mColor = aOther.mColor;
return *this;
}
GPUBufferDescriptor::GPUBufferDescriptor()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUBufferDescriptor::InitIds(JSContext* cx, GPUBufferDescriptorAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->usage_id.init(cx, "usage") ||
!atomsCache->size_id.init(cx, "size") ||
!atomsCache->mappedAtCreation_id.init(cx, "mappedAtCreation")) {
return false;
}
return true;
}
bool
GPUBufferDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUBufferDescriptorAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUBufferDescriptorAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->mappedAtCreation_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'mappedAtCreation' member of GPUBufferDescriptor", &mMappedAtCreation)) {
return false;
}
} else {
mMappedAtCreation = false;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->size_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, temp.ref(), "'size' member of GPUBufferDescriptor", &mSize)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'size' member of GPUBufferDescriptor");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->usage_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'usage' member of GPUBufferDescriptor", &mUsage)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'usage' member of GPUBufferDescriptor");
}
return true;
}
bool
GPUBufferDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUBufferDescriptor::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPUBufferDescriptor&
GPUBufferDescriptor::operator=(const GPUBufferDescriptor& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
mMappedAtCreation = aOther.mMappedAtCreation;
mSize = aOther.mSize;
mUsage = aOther.mUsage;
return *this;
}
GPUCommandBufferDescriptor::GPUCommandBufferDescriptor()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUCommandBufferDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
return true;
}
bool
GPUCommandBufferDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUCommandBufferDescriptor::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPUCommandBufferDescriptor&
GPUCommandBufferDescriptor::operator=(const GPUCommandBufferDescriptor& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
return *this;
}
GPUCommandEncoderDescriptor::GPUCommandEncoderDescriptor()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUCommandEncoderDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
return true;
}
bool
GPUCommandEncoderDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUCommandEncoderDescriptor::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPUCommandEncoderDescriptor&
GPUCommandEncoderDescriptor::operator=(const GPUCommandEncoderDescriptor& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
return *this;
}
GPUComputePassDescriptor::GPUComputePassDescriptor()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUComputePassDescriptor::InitIds(JSContext* cx, GPUComputePassDescriptorAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->timestampWrites_id.init(cx, "timestampWrites")) {
return false;
}
return true;
}
bool
GPUComputePassDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUComputePassDescriptorAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUComputePassDescriptorAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->timestampWrites_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mTimestampWrites.Construct();
if (!(mTimestampWrites.Value()).Init(cx, temp.ref(), "'timestampWrites' member of GPUComputePassDescriptor", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
}
return true;
}
bool
GPUComputePassDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUComputePassDescriptor::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPUComputePassDescriptor&
GPUComputePassDescriptor::operator=(const GPUComputePassDescriptor& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
mTimestampWrites.Reset();
if (aOther.mTimestampWrites.WasPassed()) {
mTimestampWrites.Construct(aOther.mTimestampWrites.Value());
}
return *this;
}
GPUDepthStencilState::GPUDepthStencilState()
: mStencilBack(FastDictionaryInitializer()),
mStencilFront(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUDepthStencilState::InitIds(JSContext* cx, GPUDepthStencilStateAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->stencilWriteMask_id.init(cx, "stencilWriteMask") ||
!atomsCache->stencilReadMask_id.init(cx, "stencilReadMask") ||
!atomsCache->stencilFront_id.init(cx, "stencilFront") ||
!atomsCache->stencilBack_id.init(cx, "stencilBack") ||
!atomsCache->format_id.init(cx, "format") ||
!atomsCache->depthWriteEnabled_id.init(cx, "depthWriteEnabled") ||
!atomsCache->depthCompare_id.init(cx, "depthCompare") ||
!atomsCache->depthBiasSlopeScale_id.init(cx, "depthBiasSlopeScale") ||
!atomsCache->depthBiasClamp_id.init(cx, "depthBiasClamp") ||
!atomsCache->depthBias_id.init(cx, "depthBias")) {
return false;
}
return true;
}
bool
GPUDepthStencilState::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUDepthStencilStateAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUDepthStencilStateAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depthBias_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<int32_t, eEnforceRange>(cx, temp.ref(), "'depthBias' member of GPUDepthStencilState", &mDepthBias)) {
return false;
}
} else {
mDepthBias = 0;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depthBiasClamp_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<float, eDefault>(cx, temp.ref(), "'depthBiasClamp' member of GPUDepthStencilState", &mDepthBiasClamp)) {
return false;
} else if (!std::isfinite(mDepthBiasClamp)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("'depthBiasClamp' member of GPUDepthStencilState");
return false;
}
} else {
mDepthBiasClamp = 0.0F;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depthBiasSlopeScale_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<float, eDefault>(cx, temp.ref(), "'depthBiasSlopeScale' member of GPUDepthStencilState", &mDepthBiasSlopeScale)) {
return false;
} else if (!std::isfinite(mDepthBiasSlopeScale)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("'depthBiasSlopeScale' member of GPUDepthStencilState");
return false;
}
} else {
mDepthBiasSlopeScale = 0.0F;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depthCompare_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUCompareFunction>::Values,
"GPUCompareFunction", "'depthCompare' member of GPUDepthStencilState",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mDepthCompare = static_cast<GPUCompareFunction>(index);
}
} else {
mDepthCompare = GPUCompareFunction::Always;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depthWriteEnabled_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'depthWriteEnabled' member of GPUDepthStencilState", &mDepthWriteEnabled)) {
return false;
}
} else {
mDepthWriteEnabled = false;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->format_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUTextureFormat>::Values,
"GPUTextureFormat", "'format' member of GPUDepthStencilState",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mFormat = static_cast<GPUTextureFormat>(index);
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'format' member of GPUDepthStencilState");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->stencilBack_id, temp.ptr())) {
return false;
}
}
if (!mStencilBack.Init(cx, (!isNull && !temp->isUndefined()) ? temp.ref() : JS::NullHandleValue, "'stencilBack' member of GPUDepthStencilState", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->stencilFront_id, temp.ptr())) {
return false;
}
}
if (!mStencilFront.Init(cx, (!isNull && !temp->isUndefined()) ? temp.ref() : JS::NullHandleValue, "'stencilFront' member of GPUDepthStencilState", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->stencilReadMask_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'stencilReadMask' member of GPUDepthStencilState", &mStencilReadMask)) {
return false;
}
} else {
mStencilReadMask = 4294967295U;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->stencilWriteMask_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'stencilWriteMask' member of GPUDepthStencilState", &mStencilWriteMask)) {
return false;
}
} else {
mStencilWriteMask = 4294967295U;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUDepthStencilState::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUDepthStencilState::TraceDictionary(JSTracer* trc)
{
}
GPUDepthStencilState&
GPUDepthStencilState::operator=(const GPUDepthStencilState& aOther)
{
DictionaryBase::operator=(aOther);
mDepthBias = aOther.mDepthBias;
mDepthBiasClamp = aOther.mDepthBiasClamp;
mDepthBiasSlopeScale = aOther.mDepthBiasSlopeScale;
mDepthCompare = aOther.mDepthCompare;
mDepthWriteEnabled = aOther.mDepthWriteEnabled;
mFormat = aOther.mFormat;
mStencilBack = aOther.mStencilBack;
mStencilFront = aOther.mStencilFront;
mStencilReadMask = aOther.mStencilReadMask;
mStencilWriteMask = aOther.mStencilWriteMask;
return *this;
}
GPUExternalTextureDescriptor::GPUExternalTextureDescriptor()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUExternalTextureDescriptor::InitIds(JSContext* cx, GPUExternalTextureDescriptorAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->source_id.init(cx, "source") ||
!atomsCache->colorSpace_id.init(cx, "colorSpace")) {
return false;
}
return true;
}
bool
GPUExternalTextureDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUExternalTextureDescriptorAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUExternalTextureDescriptorAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->colorSpace_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<PredefinedColorSpace>::Values,
"PredefinedColorSpace", "'colorSpace' member of GPUExternalTextureDescriptor",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mColorSpace = static_cast<PredefinedColorSpace>(index);
}
} else {
mColorSpace = PredefinedColorSpace::Srgb;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->source_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!mSource.Init(cx, temp.ref(), "'source' member of GPUExternalTextureDescriptor", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'source' member of GPUExternalTextureDescriptor");
}
return true;
}
bool
GPUExternalTextureDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUExternalTextureDescriptor::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPUExternalTextureDescriptor&
GPUExternalTextureDescriptor::operator=(const GPUExternalTextureDescriptor& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
mColorSpace = aOther.mColorSpace;
mSource = aOther.mSource;
return *this;
}
GPUPipelineDescriptorBase::GPUPipelineDescriptorBase()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUPipelineDescriptorBase::InitIds(JSContext* cx, GPUPipelineDescriptorBaseAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->layout_id.init(cx, "layout")) {
return false;
}
return true;
}
bool
GPUPipelineDescriptorBase::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUPipelineDescriptorBaseAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUPipelineDescriptorBaseAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->layout_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!mLayout.Init(cx, temp.ref(), "'layout' member of GPUPipelineDescriptorBase", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'layout' member of GPUPipelineDescriptorBase");
}
return true;
}
bool
GPUPipelineDescriptorBase::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUPipelineDescriptorBase::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPUPipelineDescriptorBase&
GPUPipelineDescriptorBase::operator=(const GPUPipelineDescriptorBase& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
mLayout = aOther.mLayout;
return *this;
}
GPUPipelineLayoutDescriptor::GPUPipelineLayoutDescriptor()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUPipelineLayoutDescriptor::InitIds(JSContext* cx, GPUPipelineLayoutDescriptorAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->bindGroupLayouts_id.init(cx, "bindGroupLayouts")) {
return false;
}
return true;
}
bool
GPUPipelineLayoutDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUPipelineLayoutDescriptorAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUPipelineLayoutDescriptorAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->bindGroupLayouts_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'bindGroupLayouts' member of GPUPipelineLayoutDescriptor", "sequence");
return false;
}
Sequence<OwningNonNull<mozilla::webgpu::BindGroupLayout>> &arr = mBindGroupLayouts;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
OwningNonNull<mozilla::webgpu::BindGroupLayout>* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
OwningNonNull<mozilla::webgpu::BindGroupLayout>& slot = *slotPtr;
if (temp.isObject()) {
static_assert(IsRefcounted<mozilla::webgpu::BindGroupLayout>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBindGroupLayout, mozilla::webgpu::BindGroupLayout>(&temp, slot, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Element of 'bindGroupLayouts' member of GPUPipelineLayoutDescriptor", "GPUBindGroupLayout");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of 'bindGroupLayouts' member of GPUPipelineLayoutDescriptor");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'bindGroupLayouts' member of GPUPipelineLayoutDescriptor", "sequence");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'bindGroupLayouts' member of GPUPipelineLayoutDescriptor");
}
return true;
}
bool
GPUPipelineLayoutDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUPipelineLayoutDescriptor::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPUPipelineLayoutDescriptor&
GPUPipelineLayoutDescriptor::operator=(const GPUPipelineLayoutDescriptor& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
mBindGroupLayouts = aOther.mBindGroupLayouts;
return *this;
}
GPUQuerySetDescriptor::GPUQuerySetDescriptor()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUQuerySetDescriptor::InitIds(JSContext* cx, GPUQuerySetDescriptorAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->type_id.init(cx, "type") ||
!atomsCache->count_id.init(cx, "count")) {
return false;
}
return true;
}
bool
GPUQuerySetDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUQuerySetDescriptorAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUQuerySetDescriptorAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->count_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'count' member of GPUQuerySetDescriptor", &mCount)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'count' member of GPUQuerySetDescriptor");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->type_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUQueryType>::Values,
"GPUQueryType", "'type' member of GPUQuerySetDescriptor",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mType = static_cast<GPUQueryType>(index);
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'type' member of GPUQuerySetDescriptor");
}
return true;
}
bool
GPUQuerySetDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUQuerySetDescriptor::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPUQuerySetDescriptor&
GPUQuerySetDescriptor::operator=(const GPUQuerySetDescriptor& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
mCount = aOther.mCount;
mType = aOther.mType;
return *this;
}
GPUQueueDescriptor::GPUQueueDescriptor()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUQueueDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
return true;
}
bool
GPUQueueDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUQueueDescriptor::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPUQueueDescriptor&
GPUQueueDescriptor::operator=(const GPUQueueDescriptor& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
return *this;
}
GPURenderBundleDescriptor::GPURenderBundleDescriptor()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPURenderBundleDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
return true;
}
bool
GPURenderBundleDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPURenderBundleDescriptor::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPURenderBundleDescriptor&
GPURenderBundleDescriptor::operator=(const GPURenderBundleDescriptor& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
return *this;
}
GPURenderPassDepthStencilAttachment::GPURenderPassDepthStencilAttachment()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPURenderPassDepthStencilAttachment::InitIds(JSContext* cx, GPURenderPassDepthStencilAttachmentAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->view_id.init(cx, "view") ||
!atomsCache->stencilStoreOp_id.init(cx, "stencilStoreOp") ||
!atomsCache->stencilReadOnly_id.init(cx, "stencilReadOnly") ||
!atomsCache->stencilLoadOp_id.init(cx, "stencilLoadOp") ||
!atomsCache->stencilClearValue_id.init(cx, "stencilClearValue") ||
!atomsCache->depthStoreOp_id.init(cx, "depthStoreOp") ||
!atomsCache->depthReadOnly_id.init(cx, "depthReadOnly") ||
!atomsCache->depthLoadOp_id.init(cx, "depthLoadOp") ||
!atomsCache->depthClearValue_id.init(cx, "depthClearValue")) {
return false;
}
return true;
}
bool
GPURenderPassDepthStencilAttachment::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPURenderPassDepthStencilAttachmentAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPURenderPassDepthStencilAttachmentAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depthClearValue_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mDepthClearValue.Construct();
if (!ValueToPrimitive<float, eDefault>(cx, temp.ref(), "'depthClearValue' member of GPURenderPassDepthStencilAttachment", &(mDepthClearValue.Value()))) {
return false;
} else if (!std::isfinite((mDepthClearValue.Value()))) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("'depthClearValue' member of GPURenderPassDepthStencilAttachment");
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depthLoadOp_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mDepthLoadOp.Construct();
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPULoadOp>::Values,
"GPULoadOp", "'depthLoadOp' member of GPURenderPassDepthStencilAttachment",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
(mDepthLoadOp.Value()) = static_cast<GPULoadOp>(index);
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depthReadOnly_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'depthReadOnly' member of GPURenderPassDepthStencilAttachment", &mDepthReadOnly)) {
return false;
}
} else {
mDepthReadOnly = false;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depthStoreOp_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mDepthStoreOp.Construct();
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUStoreOp>::Values,
"GPUStoreOp", "'depthStoreOp' member of GPURenderPassDepthStencilAttachment",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
(mDepthStoreOp.Value()) = static_cast<GPUStoreOp>(index);
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->stencilClearValue_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'stencilClearValue' member of GPURenderPassDepthStencilAttachment", &mStencilClearValue)) {
return false;
}
} else {
mStencilClearValue = 0U;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->stencilLoadOp_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mStencilLoadOp.Construct();
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPULoadOp>::Values,
"GPULoadOp", "'stencilLoadOp' member of GPURenderPassDepthStencilAttachment",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
(mStencilLoadOp.Value()) = static_cast<GPULoadOp>(index);
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->stencilReadOnly_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'stencilReadOnly' member of GPURenderPassDepthStencilAttachment", &mStencilReadOnly)) {
return false;
}
} else {
mStencilReadOnly = false;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->stencilStoreOp_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mStencilStoreOp.Construct();
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUStoreOp>::Values,
"GPUStoreOp", "'stencilStoreOp' member of GPURenderPassDepthStencilAttachment",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
(mStencilStoreOp.Value()) = static_cast<GPUStoreOp>(index);
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->view_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!mView.Init(cx, temp.ref(), "'view' member of GPURenderPassDepthStencilAttachment", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'view' member of GPURenderPassDepthStencilAttachment");
}
return true;
}
bool
GPURenderPassDepthStencilAttachment::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPURenderPassDepthStencilAttachment::TraceDictionary(JSTracer* trc)
{
}
GPURenderPassDepthStencilAttachment&
GPURenderPassDepthStencilAttachment::operator=(const GPURenderPassDepthStencilAttachment& aOther)
{
DictionaryBase::operator=(aOther);
mDepthClearValue.Reset();
if (aOther.mDepthClearValue.WasPassed()) {
mDepthClearValue.Construct(aOther.mDepthClearValue.Value());
}
mDepthLoadOp.Reset();
if (aOther.mDepthLoadOp.WasPassed()) {
mDepthLoadOp.Construct(aOther.mDepthLoadOp.Value());
}
mDepthReadOnly = aOther.mDepthReadOnly;
mDepthStoreOp.Reset();
if (aOther.mDepthStoreOp.WasPassed()) {
mDepthStoreOp.Construct(aOther.mDepthStoreOp.Value());
}
mStencilClearValue = aOther.mStencilClearValue;
mStencilLoadOp.Reset();
if (aOther.mStencilLoadOp.WasPassed()) {
mStencilLoadOp.Construct(aOther.mStencilLoadOp.Value());
}
mStencilReadOnly = aOther.mStencilReadOnly;
mStencilStoreOp.Reset();
if (aOther.mStencilStoreOp.WasPassed()) {
mStencilStoreOp.Construct(aOther.mStencilStoreOp.Value());
}
mView = aOther.mView;
return *this;
}
GPURenderPassLayout::GPURenderPassLayout()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPURenderPassLayout::InitIds(JSContext* cx, GPURenderPassLayoutAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->sampleCount_id.init(cx, "sampleCount") ||
!atomsCache->depthStencilFormat_id.init(cx, "depthStencilFormat") ||
!atomsCache->colorFormats_id.init(cx, "colorFormats")) {
return false;
}
return true;
}
bool
GPURenderPassLayout::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPURenderPassLayoutAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPURenderPassLayoutAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->colorFormats_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'colorFormats' member of GPURenderPassLayout", "sequence");
return false;
}
Sequence<GPUTextureFormat> &arr = mColorFormats;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
GPUTextureFormat* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
GPUTextureFormat& slot = *slotPtr;
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp,
binding_detail::EnumStrings<GPUTextureFormat>::Values,
"GPUTextureFormat", "element of 'colorFormats' member of GPURenderPassLayout",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
slot = static_cast<GPUTextureFormat>(index);
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'colorFormats' member of GPURenderPassLayout", "sequence");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'colorFormats' member of GPURenderPassLayout");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depthStencilFormat_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mDepthStencilFormat.Construct();
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUTextureFormat>::Values,
"GPUTextureFormat", "'depthStencilFormat' member of GPURenderPassLayout",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
(mDepthStencilFormat.Value()) = static_cast<GPUTextureFormat>(index);
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->sampleCount_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'sampleCount' member of GPURenderPassLayout", &mSampleCount)) {
return false;
}
} else {
mSampleCount = 1U;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPURenderPassLayout::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPURenderPassLayout::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPURenderPassLayout&
GPURenderPassLayout::operator=(const GPURenderPassLayout& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
mColorFormats = aOther.mColorFormats;
mDepthStencilFormat.Reset();
if (aOther.mDepthStencilFormat.WasPassed()) {
mDepthStencilFormat.Construct(aOther.mDepthStencilFormat.Value());
}
mSampleCount = aOther.mSampleCount;
return *this;
}
GPUSamplerDescriptor::GPUSamplerDescriptor()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUSamplerDescriptor::InitIds(JSContext* cx, GPUSamplerDescriptorAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->mipmapFilter_id.init(cx, "mipmapFilter") ||
!atomsCache->minFilter_id.init(cx, "minFilter") ||
!atomsCache->maxAnisotropy_id.init(cx, "maxAnisotropy") ||
!atomsCache->magFilter_id.init(cx, "magFilter") ||
!atomsCache->lodMinClamp_id.init(cx, "lodMinClamp") ||
!atomsCache->lodMaxClamp_id.init(cx, "lodMaxClamp") ||
!atomsCache->compare_id.init(cx, "compare") ||
!atomsCache->addressModeW_id.init(cx, "addressModeW") ||
!atomsCache->addressModeV_id.init(cx, "addressModeV") ||
!atomsCache->addressModeU_id.init(cx, "addressModeU")) {
return false;
}
return true;
}
bool
GPUSamplerDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUSamplerDescriptorAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUSamplerDescriptorAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->addressModeU_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUAddressMode>::Values,
"GPUAddressMode", "'addressModeU' member of GPUSamplerDescriptor",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mAddressModeU = static_cast<GPUAddressMode>(index);
}
} else {
mAddressModeU = GPUAddressMode::Clamp_to_edge;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->addressModeV_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUAddressMode>::Values,
"GPUAddressMode", "'addressModeV' member of GPUSamplerDescriptor",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mAddressModeV = static_cast<GPUAddressMode>(index);
}
} else {
mAddressModeV = GPUAddressMode::Clamp_to_edge;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->addressModeW_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUAddressMode>::Values,
"GPUAddressMode", "'addressModeW' member of GPUSamplerDescriptor",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mAddressModeW = static_cast<GPUAddressMode>(index);
}
} else {
mAddressModeW = GPUAddressMode::Clamp_to_edge;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->compare_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mCompare.Construct();
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUCompareFunction>::Values,
"GPUCompareFunction", "'compare' member of GPUSamplerDescriptor",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
(mCompare.Value()) = static_cast<GPUCompareFunction>(index);
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->lodMaxClamp_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<float, eDefault>(cx, temp.ref(), "'lodMaxClamp' member of GPUSamplerDescriptor", &mLodMaxClamp)) {
return false;
} else if (!std::isfinite(mLodMaxClamp)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("'lodMaxClamp' member of GPUSamplerDescriptor");
return false;
}
} else {
mLodMaxClamp = 32.0F;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->lodMinClamp_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<float, eDefault>(cx, temp.ref(), "'lodMinClamp' member of GPUSamplerDescriptor", &mLodMinClamp)) {
return false;
} else if (!std::isfinite(mLodMinClamp)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("'lodMinClamp' member of GPUSamplerDescriptor");
return false;
}
} else {
mLodMinClamp = 0.0F;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->magFilter_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUFilterMode>::Values,
"GPUFilterMode", "'magFilter' member of GPUSamplerDescriptor",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mMagFilter = static_cast<GPUFilterMode>(index);
}
} else {
mMagFilter = GPUFilterMode::Nearest;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->maxAnisotropy_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint16_t, eClamp>(cx, temp.ref(), "'maxAnisotropy' member of GPUSamplerDescriptor", &mMaxAnisotropy)) {
return false;
}
} else {
mMaxAnisotropy = 1;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->minFilter_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUFilterMode>::Values,
"GPUFilterMode", "'minFilter' member of GPUSamplerDescriptor",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mMinFilter = static_cast<GPUFilterMode>(index);
}
} else {
mMinFilter = GPUFilterMode::Nearest;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->mipmapFilter_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUMipmapFilterMode>::Values,
"GPUMipmapFilterMode", "'mipmapFilter' member of GPUSamplerDescriptor",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mMipmapFilter = static_cast<GPUMipmapFilterMode>(index);
}
} else {
mMipmapFilter = GPUMipmapFilterMode::Nearest;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUSamplerDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUSamplerDescriptor::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPUSamplerDescriptor&
GPUSamplerDescriptor::operator=(const GPUSamplerDescriptor& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
mAddressModeU = aOther.mAddressModeU;
mAddressModeV = aOther.mAddressModeV;
mAddressModeW = aOther.mAddressModeW;
mCompare.Reset();
if (aOther.mCompare.WasPassed()) {
mCompare.Construct(aOther.mCompare.Value());
}
mLodMaxClamp = aOther.mLodMaxClamp;
mLodMinClamp = aOther.mLodMinClamp;
mMagFilter = aOther.mMagFilter;
mMaxAnisotropy = aOther.mMaxAnisotropy;
mMinFilter = aOther.mMinFilter;
mMipmapFilter = aOther.mMipmapFilter;
return *this;
}
bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUSampler(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::webgpu::Sampler>& memberSlot = RawSetAsGPUSampler();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUSampler, mozilla::webgpu::Sampler>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyGPUSampler();
tryNext = true;
return true;
}
}
}
return true;
}
bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUSampler(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUSampler(cx, value, tryNext, passedToJSImpl);
}
bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUTexture(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::webgpu::Texture>& memberSlot = RawSetAsGPUTexture();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUTexture, mozilla::webgpu::Texture>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyGPUTexture();
tryNext = true;
return true;
}
}
}
return true;
}
bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUTexture(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUTexture(cx, value, tryNext, passedToJSImpl);
}
bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUTextureView(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::webgpu::TextureView>& memberSlot = RawSetAsGPUTextureView();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUTextureView, mozilla::webgpu::TextureView>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyGPUTextureView();
tryNext = true;
return true;
}
}
}
return true;
}
bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUTextureView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUTextureView(cx, value, tryNext, passedToJSImpl);
}
bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUBuffer(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::webgpu::Buffer>& memberSlot = RawSetAsGPUBuffer();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyGPUBuffer();
tryNext = true;
return true;
}
}
}
return true;
}
bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUBuffer(cx, value, tryNext, passedToJSImpl);
}
bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUBufferBinding(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FastGPUBufferBinding& memberSlot = RawSetAsGPUBufferBinding();
if (!IsConvertibleToDictionary(value)) {
DestroyGPUBufferBinding();
tryNext = true;
return true;
}
if (!memberSlot.Init(cx, value, "GPUBufferBinding branch of (GPUSampler or GPUTexture or GPUTextureView or GPUBuffer or GPUBufferBinding or GPUExternalTexture)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUBufferBinding(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUBufferBinding(cx, value, tryNext, passedToJSImpl);
}
bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUExternalTexture(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
NonNull<mozilla::webgpu::ExternalTexture>& memberSlot = RawSetAsGPUExternalTexture();
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUExternalTexture, mozilla::webgpu::ExternalTexture>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyGPUExternalTexture();
tryNext = true;
return true;
}
}
}
return true;
}
bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUExternalTexture(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUExternalTexture(cx, value, tryNext, passedToJSImpl);
}
bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToGPUSampler(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToGPUTexture(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToGPUTextureView(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToGPUBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToGPUExternalTexture(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
done = (failed = !TrySetToGPUBufferBinding(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "GPUSampler, GPUTexture, GPUTextureView, GPUBuffer, GPUExternalTexture, GPUBufferBinding");
return false;
}
return true;
}
bool
GPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture(OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eGPUSampler: {
mType = eGPUSampler;
mValue.mGPUSampler.SetValue(std::move(aOther.mValue.mGPUSampler.Value()));
break;
}
case eGPUTexture: {
mType = eGPUTexture;
mValue.mGPUTexture.SetValue(std::move(aOther.mValue.mGPUTexture.Value()));
break;
}
case eGPUTextureView: {
mType = eGPUTextureView;
mValue.mGPUTextureView.SetValue(std::move(aOther.mValue.mGPUTextureView.Value()));
break;
}
case eGPUBuffer: {
mType = eGPUBuffer;
mValue.mGPUBuffer.SetValue(std::move(aOther.mValue.mGPUBuffer.Value()));
break;
}
case eGPUBufferBinding: {
mType = eGPUBufferBinding;
mValue.mGPUBufferBinding.SetValue(std::move(aOther.mValue.mGPUBufferBinding.Value()));
break;
}
case eGPUExternalTexture: {
mType = eGPUExternalTexture;
mValue.mGPUExternalTexture.SetValue(std::move(aOther.mValue.mGPUExternalTexture.Value()));
break;
}
}
}
bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUSampler(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::webgpu::Sampler>& memberSlot = RawSetAsGPUSampler();
static_assert(IsRefcounted<mozilla::webgpu::Sampler>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUSampler, mozilla::webgpu::Sampler>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyGPUSampler();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUSampler(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUSampler(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::webgpu::Sampler>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::RawSetAsGPUSampler()
{
if (mType == eGPUSampler) {
return mValue.mGPUSampler.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eGPUSampler;
return mValue.mGPUSampler.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::webgpu::Sampler>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::SetAsGPUSampler()
{
if (mType == eGPUSampler) {
return mValue.mGPUSampler.Value();
}
Uninit();
mType = eGPUSampler;
return mValue.mGPUSampler.SetValue();
}
void
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::DestroyGPUSampler()
{
MOZ_RELEASE_ASSERT(IsGPUSampler(), "Wrong type!");
mValue.mGPUSampler.Destroy();
mType = eUninitialized;
}
bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUTexture(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::webgpu::Texture>& memberSlot = RawSetAsGPUTexture();
static_assert(IsRefcounted<mozilla::webgpu::Texture>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUTexture, mozilla::webgpu::Texture>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyGPUTexture();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUTexture(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUTexture(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::webgpu::Texture>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::RawSetAsGPUTexture()
{
if (mType == eGPUTexture) {
return mValue.mGPUTexture.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eGPUTexture;
return mValue.mGPUTexture.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::webgpu::Texture>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::SetAsGPUTexture()
{
if (mType == eGPUTexture) {
return mValue.mGPUTexture.Value();
}
Uninit();
mType = eGPUTexture;
return mValue.mGPUTexture.SetValue();
}
void
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::DestroyGPUTexture()
{
MOZ_RELEASE_ASSERT(IsGPUTexture(), "Wrong type!");
mValue.mGPUTexture.Destroy();
mType = eUninitialized;
}
bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUTextureView(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::webgpu::TextureView>& memberSlot = RawSetAsGPUTextureView();
static_assert(IsRefcounted<mozilla::webgpu::TextureView>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUTextureView, mozilla::webgpu::TextureView>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyGPUTextureView();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUTextureView(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUTextureView(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::webgpu::TextureView>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::RawSetAsGPUTextureView()
{
if (mType == eGPUTextureView) {
return mValue.mGPUTextureView.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eGPUTextureView;
return mValue.mGPUTextureView.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::webgpu::TextureView>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::SetAsGPUTextureView()
{
if (mType == eGPUTextureView) {
return mValue.mGPUTextureView.Value();
}
Uninit();
mType = eGPUTextureView;
return mValue.mGPUTextureView.SetValue();
}
void
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::DestroyGPUTextureView()
{
MOZ_RELEASE_ASSERT(IsGPUTextureView(), "Wrong type!");
mValue.mGPUTextureView.Destroy();
mType = eUninitialized;
}
bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUBuffer(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::webgpu::Buffer>& memberSlot = RawSetAsGPUBuffer();
static_assert(IsRefcounted<mozilla::webgpu::Buffer>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyGPUBuffer();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUBuffer(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUBuffer(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::webgpu::Buffer>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::RawSetAsGPUBuffer()
{
if (mType == eGPUBuffer) {
return mValue.mGPUBuffer.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eGPUBuffer;
return mValue.mGPUBuffer.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::webgpu::Buffer>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::SetAsGPUBuffer()
{
if (mType == eGPUBuffer) {
return mValue.mGPUBuffer.Value();
}
Uninit();
mType = eGPUBuffer;
return mValue.mGPUBuffer.SetValue();
}
void
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::DestroyGPUBuffer()
{
MOZ_RELEASE_ASSERT(IsGPUBuffer(), "Wrong type!");
mValue.mGPUBuffer.Destroy();
mType = eUninitialized;
}
bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUBufferBinding(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
GPUBufferBinding& memberSlot = RawSetAsGPUBufferBinding();
if (!IsConvertibleToDictionary(value)) {
DestroyGPUBufferBinding();
tryNext = true;
return true;
}
if (!memberSlot.Init(cx, value, "GPUBufferBinding branch of (GPUSampler or GPUTexture or GPUTextureView or GPUBuffer or GPUBufferBinding or GPUExternalTexture)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUBufferBinding(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUBufferBinding(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] GPUBufferBinding&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::RawSetAsGPUBufferBinding()
{
if (mType == eGPUBufferBinding) {
return mValue.mGPUBufferBinding.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eGPUBufferBinding;
return mValue.mGPUBufferBinding.SetValue();
}
[[nodiscard]] GPUBufferBinding&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::SetAsGPUBufferBinding()
{
if (mType == eGPUBufferBinding) {
return mValue.mGPUBufferBinding.Value();
}
Uninit();
mType = eGPUBufferBinding;
return mValue.mGPUBufferBinding.SetValue();
}
void
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::DestroyGPUBufferBinding()
{
MOZ_RELEASE_ASSERT(IsGPUBufferBinding(), "Wrong type!");
mValue.mGPUBufferBinding.Destroy();
mType = eUninitialized;
}
bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUExternalTexture(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
OwningNonNull<mozilla::webgpu::ExternalTexture>& memberSlot = RawSetAsGPUExternalTexture();
static_assert(IsRefcounted<mozilla::webgpu::ExternalTexture>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUExternalTexture, mozilla::webgpu::ExternalTexture>(value, memberSlot, cx);
if (NS_FAILED(rv)) {
DestroyGPUExternalTexture();
tryNext = true;
return true;
}
}
}
return true;
}
bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::TrySetToGPUExternalTexture(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUExternalTexture(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] OwningNonNull<mozilla::webgpu::ExternalTexture>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::RawSetAsGPUExternalTexture()
{
if (mType == eGPUExternalTexture) {
return mValue.mGPUExternalTexture.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eGPUExternalTexture;
return mValue.mGPUExternalTexture.SetValue();
}
[[nodiscard]] OwningNonNull<mozilla::webgpu::ExternalTexture>&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::SetAsGPUExternalTexture()
{
if (mType == eGPUExternalTexture) {
return mValue.mGPUExternalTexture.Value();
}
Uninit();
mType = eGPUExternalTexture;
return mValue.mGPUExternalTexture.SetValue();
}
void
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::DestroyGPUExternalTexture()
{
MOZ_RELEASE_ASSERT(IsGPUExternalTexture(), "Wrong type!");
mValue.mGPUExternalTexture.Destroy();
mType = eUninitialized;
}
bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToGPUSampler(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToGPUTexture(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToGPUTextureView(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToGPUBuffer(cx, value, tryNext, passedToJSImpl)) || !tryNext ||
(failed = !TrySetToGPUExternalTexture(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
done = (failed = !TrySetToGPUBufferBinding(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "GPUSampler, GPUTexture, GPUTextureView, GPUBuffer, GPUExternalTexture, GPUBufferBinding");
return false;
}
return true;
}
bool
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eGPUSampler: {
DestroyGPUSampler();
break;
}
case eGPUTexture: {
DestroyGPUTexture();
break;
}
case eGPUTextureView: {
DestroyGPUTextureView();
break;
}
case eGPUBuffer: {
DestroyGPUBuffer();
break;
}
case eGPUBufferBinding: {
DestroyGPUBufferBinding();
break;
}
case eGPUExternalTexture: {
DestroyGPUExternalTexture();
break;
}
}
}
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::operator=(OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture&& aOther)
{
this->~OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture();
new (this) OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture (std::move(aOther));
return *this;
}
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture&
OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture::operator=(const OwningGPUSamplerOrGPUTextureOrGPUTextureViewOrGPUBufferOrGPUBufferBindingOrGPUExternalTexture& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eGPUSampler: {
SetAsGPUSampler() = aOther.GetAsGPUSampler();
break;
}
case eGPUTexture: {
SetAsGPUTexture() = aOther.GetAsGPUTexture();
break;
}
case eGPUTextureView: {
SetAsGPUTextureView() = aOther.GetAsGPUTextureView();
break;
}
case eGPUBuffer: {
SetAsGPUBuffer() = aOther.GetAsGPUBuffer();
break;
}
case eGPUBufferBinding: {
SetAsGPUBufferBinding() = aOther.GetAsGPUBufferBinding();
break;
}
case eGPUExternalTexture: {
SetAsGPUExternalTexture() = aOther.GetAsGPUExternalTexture();
break;
}
}
return *this;
}
GPUShaderModuleCompilationHint::GPUShaderModuleCompilationHint()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUShaderModuleCompilationHint::InitIds(JSContext* cx, GPUShaderModuleCompilationHintAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->layout_id.init(cx, "layout") ||
!atomsCache->entryPoint_id.init(cx, "entryPoint")) {
return false;
}
return true;
}
bool
GPUShaderModuleCompilationHint::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUShaderModuleCompilationHintAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUShaderModuleCompilationHintAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->entryPoint_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mEntryPoint)) {
return false;
}
if (!NormalizeUSVString(mEntryPoint)) {
JS_ReportOutOfMemory(cx);
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'entryPoint' member of GPUShaderModuleCompilationHint");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->layout_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mLayout.Construct();
if (!(mLayout.Value()).Init(cx, temp.ref(), "'layout' member of GPUShaderModuleCompilationHint", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
}
return true;
}
bool
GPUShaderModuleCompilationHint::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUShaderModuleCompilationHint::TraceDictionary(JSTracer* trc)
{
}
GPUShaderModuleCompilationHint&
GPUShaderModuleCompilationHint::operator=(const GPUShaderModuleCompilationHint& aOther)
{
DictionaryBase::operator=(aOther);
mEntryPoint = aOther.mEntryPoint;
mLayout.Reset();
if (aOther.mLayout.WasPassed()) {
mLayout.Construct(aOther.mLayout.Value());
}
return *this;
}
GPUTexelCopyBufferInfo::GPUTexelCopyBufferInfo()
: GPUTexelCopyBufferLayout(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUTexelCopyBufferInfo::InitIds(JSContext* cx, GPUTexelCopyBufferInfoAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->buffer_id.init(cx, "buffer")) {
return false;
}
return true;
}
bool
GPUTexelCopyBufferInfo::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUTexelCopyBufferInfoAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUTexelCopyBufferInfoAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUTexelCopyBufferLayout::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->buffer_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
static_assert(IsRefcounted<mozilla::webgpu::Buffer>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(temp.ptr(), mBuffer, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'buffer' member of GPUTexelCopyBufferInfo", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'buffer' member of GPUTexelCopyBufferInfo");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'buffer' member of GPUTexelCopyBufferInfo");
}
return true;
}
bool
GPUTexelCopyBufferInfo::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUTexelCopyBufferInfo::TraceDictionary(JSTracer* trc)
{
GPUTexelCopyBufferLayout::TraceDictionary(trc);
}
GPUTexelCopyBufferInfo&
GPUTexelCopyBufferInfo::operator=(const GPUTexelCopyBufferInfo& aOther)
{
GPUTexelCopyBufferLayout::operator=(aOther);
mBuffer = aOther.mBuffer;
return *this;
}
GPUTextureViewDescriptor::GPUTextureViewDescriptor()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUTextureViewDescriptor::InitIds(JSContext* cx, GPUTextureViewDescriptorAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->mipLevelCount_id.init(cx, "mipLevelCount") ||
!atomsCache->format_id.init(cx, "format") ||
!atomsCache->dimension_id.init(cx, "dimension") ||
!atomsCache->baseMipLevel_id.init(cx, "baseMipLevel") ||
!atomsCache->baseArrayLayer_id.init(cx, "baseArrayLayer") ||
!atomsCache->aspect_id.init(cx, "aspect") ||
!atomsCache->arrayLayerCount_id.init(cx, "arrayLayerCount")) {
return false;
}
return true;
}
bool
GPUTextureViewDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUTextureViewDescriptorAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUTextureViewDescriptorAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->arrayLayerCount_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mArrayLayerCount.Construct();
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'arrayLayerCount' member of GPUTextureViewDescriptor", &(mArrayLayerCount.Value()))) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->aspect_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUTextureAspect>::Values,
"GPUTextureAspect", "'aspect' member of GPUTextureViewDescriptor",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mAspect = static_cast<GPUTextureAspect>(index);
}
} else {
mAspect = GPUTextureAspect::All;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->baseArrayLayer_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'baseArrayLayer' member of GPUTextureViewDescriptor", &mBaseArrayLayer)) {
return false;
}
} else {
mBaseArrayLayer = 0U;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->baseMipLevel_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'baseMipLevel' member of GPUTextureViewDescriptor", &mBaseMipLevel)) {
return false;
}
} else {
mBaseMipLevel = 0U;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->dimension_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mDimension.Construct();
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUTextureViewDimension>::Values,
"GPUTextureViewDimension", "'dimension' member of GPUTextureViewDescriptor",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
(mDimension.Value()) = static_cast<GPUTextureViewDimension>(index);
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->format_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mFormat.Construct();
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUTextureFormat>::Values,
"GPUTextureFormat", "'format' member of GPUTextureViewDescriptor",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
(mFormat.Value()) = static_cast<GPUTextureFormat>(index);
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->mipLevelCount_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mMipLevelCount.Construct();
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'mipLevelCount' member of GPUTextureViewDescriptor", &(mMipLevelCount.Value()))) {
return false;
}
mIsAnyMemberPresent = true;
}
return true;
}
bool
GPUTextureViewDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUTextureViewDescriptor::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPUTextureViewDescriptor&
GPUTextureViewDescriptor::operator=(const GPUTextureViewDescriptor& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
mArrayLayerCount.Reset();
if (aOther.mArrayLayerCount.WasPassed()) {
mArrayLayerCount.Construct(aOther.mArrayLayerCount.Value());
}
mAspect = aOther.mAspect;
mBaseArrayLayer = aOther.mBaseArrayLayer;
mBaseMipLevel = aOther.mBaseMipLevel;
mDimension.Reset();
if (aOther.mDimension.WasPassed()) {
mDimension.Construct(aOther.mDimension.Value());
}
mFormat.Reset();
if (aOther.mFormat.WasPassed()) {
mFormat.Construct(aOther.mFormat.Value());
}
mMipLevelCount.Reset();
if (aOther.mMipLevelCount.WasPassed()) {
mMipLevelCount.Construct(aOther.mMipLevelCount.Value());
}
return *this;
}
GPUVertexBufferLayout::GPUVertexBufferLayout()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUVertexBufferLayout::InitIds(JSContext* cx, GPUVertexBufferLayoutAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->stepMode_id.init(cx, "stepMode") ||
!atomsCache->attributes_id.init(cx, "attributes") ||
!atomsCache->arrayStride_id.init(cx, "arrayStride")) {
return false;
}
return true;
}
bool
GPUVertexBufferLayout::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUVertexBufferLayoutAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUVertexBufferLayoutAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->arrayStride_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, temp.ref(), "'arrayStride' member of GPUVertexBufferLayout", &mArrayStride)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'arrayStride' member of GPUVertexBufferLayout");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->attributes_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'attributes' member of GPUVertexBufferLayout", "sequence");
return false;
}
Sequence<GPUVertexAttribute> &arr = mAttributes;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
GPUVertexAttribute* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
GPUVertexAttribute& slot = *slotPtr;
if (!slot.Init(cx, temp, "Element of 'attributes' member of GPUVertexBufferLayout", passedToJSImpl)) {
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'attributes' member of GPUVertexBufferLayout", "sequence");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'attributes' member of GPUVertexBufferLayout");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->stepMode_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUVertexStepMode>::Values,
"GPUVertexStepMode", "'stepMode' member of GPUVertexBufferLayout",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mStepMode = static_cast<GPUVertexStepMode>(index);
}
} else {
mStepMode = GPUVertexStepMode::Vertex;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUVertexBufferLayout::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUVertexBufferLayout::TraceDictionary(JSTracer* trc)
{
}
GPUVertexBufferLayout&
GPUVertexBufferLayout::operator=(const GPUVertexBufferLayout& aOther)
{
DictionaryBase::operator=(aOther);
mArrayStride = aOther.mArrayStride;
mAttributes = aOther.mAttributes;
mStepMode = aOther.mStepMode;
return *this;
}
bool
RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::TrySetToRangeEnforcedUnsignedLongSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::AutoSequence<uint32_t>& memberSlot = RawSetAsRangeEnforcedUnsignedLongSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyRangeEnforcedUnsignedLongSequence();
tryNext = true;
return true;
}
binding_detail::AutoSequence<uint32_t> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
uint32_t& slot = *slotPtr;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp, "Element of sequence<unsigned long> branch of (sequence<unsigned long> or GPUExtent3DDict)", &slot)) {
return false;
}
}
}
return true;
}
bool
RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::TrySetToRangeEnforcedUnsignedLongSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl);
}
bool
RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::TrySetToGPUExtent3DDict(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FastGPUExtent3DDict& memberSlot = RawSetAsGPUExtent3DDict();
if (!IsConvertibleToDictionary(value)) {
DestroyGPUExtent3DDict();
tryNext = true;
return true;
}
if (!memberSlot.Init(cx, value, "GPUExtent3DDict branch of (sequence<unsigned long> or GPUExtent3DDict)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::TrySetToGPUExtent3DDict(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUExtent3DDict(cx, value, tryNext, passedToJSImpl);
}
bool
RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
done = (failed = !TrySetToGPUExtent3DDict(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<unsigned long>, GPUExtent3DDict");
return false;
}
return true;
}
bool
RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict(OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eRangeEnforcedUnsignedLongSequence: {
mType = eRangeEnforcedUnsignedLongSequence;
mValue.mRangeEnforcedUnsignedLongSequence.SetValue(std::move(aOther.mValue.mRangeEnforcedUnsignedLongSequence.Value()));
break;
}
case eGPUExtent3DDict: {
mType = eGPUExtent3DDict;
mValue.mGPUExtent3DDict.SetValue(std::move(aOther.mValue.mGPUExtent3DDict.Value()));
break;
}
}
}
bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::TrySetToRangeEnforcedUnsignedLongSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Sequence<uint32_t>& memberSlot = RawSetAsRangeEnforcedUnsignedLongSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyRangeEnforcedUnsignedLongSequence();
tryNext = true;
return true;
}
Sequence<uint32_t> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
uint32_t& slot = *slotPtr;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp, "Element of sequence<unsigned long> branch of (sequence<unsigned long> or GPUExtent3DDict)", &slot)) {
return false;
}
}
}
return true;
}
bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::TrySetToRangeEnforcedUnsignedLongSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Sequence<uint32_t>&
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::RawSetAsRangeEnforcedUnsignedLongSequence()
{
if (mType == eRangeEnforcedUnsignedLongSequence) {
return mValue.mRangeEnforcedUnsignedLongSequence.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eRangeEnforcedUnsignedLongSequence;
return mValue.mRangeEnforcedUnsignedLongSequence.SetValue();
}
[[nodiscard]] Sequence<uint32_t>&
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::SetAsRangeEnforcedUnsignedLongSequence()
{
if (mType == eRangeEnforcedUnsignedLongSequence) {
return mValue.mRangeEnforcedUnsignedLongSequence.Value();
}
Uninit();
mType = eRangeEnforcedUnsignedLongSequence;
return mValue.mRangeEnforcedUnsignedLongSequence.SetValue();
}
void
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::DestroyRangeEnforcedUnsignedLongSequence()
{
MOZ_RELEASE_ASSERT(IsRangeEnforcedUnsignedLongSequence(), "Wrong type!");
mValue.mRangeEnforcedUnsignedLongSequence.Destroy();
mType = eUninitialized;
}
bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::TrySetToGPUExtent3DDict(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
GPUExtent3DDict& memberSlot = RawSetAsGPUExtent3DDict();
if (!IsConvertibleToDictionary(value)) {
DestroyGPUExtent3DDict();
tryNext = true;
return true;
}
if (!memberSlot.Init(cx, value, "GPUExtent3DDict branch of (sequence<unsigned long> or GPUExtent3DDict)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::TrySetToGPUExtent3DDict(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUExtent3DDict(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] GPUExtent3DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::RawSetAsGPUExtent3DDict()
{
if (mType == eGPUExtent3DDict) {
return mValue.mGPUExtent3DDict.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eGPUExtent3DDict;
return mValue.mGPUExtent3DDict.SetValue();
}
[[nodiscard]] GPUExtent3DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::SetAsGPUExtent3DDict()
{
if (mType == eGPUExtent3DDict) {
return mValue.mGPUExtent3DDict.Value();
}
Uninit();
mType = eGPUExtent3DDict;
return mValue.mGPUExtent3DDict.SetValue();
}
void
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::DestroyGPUExtent3DDict()
{
MOZ_RELEASE_ASSERT(IsGPUExtent3DDict(), "Wrong type!");
mValue.mGPUExtent3DDict.Destroy();
mType = eUninitialized;
}
bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
done = (failed = !TrySetToGPUExtent3DDict(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<unsigned long>, GPUExtent3DDict");
return false;
}
return true;
}
bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eRangeEnforcedUnsignedLongSequence: {
DestroyRangeEnforcedUnsignedLongSequence();
break;
}
case eGPUExtent3DDict: {
DestroyGPUExtent3DDict();
break;
}
}
}
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::operator=(OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict&& aOther)
{
this->~OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict();
new (this) OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict (std::move(aOther));
return *this;
}
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict::operator=(const OwningRangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eRangeEnforcedUnsignedLongSequence: {
SetAsRangeEnforcedUnsignedLongSequence() = aOther.GetAsRangeEnforcedUnsignedLongSequence();
break;
}
case eGPUExtent3DDict: {
SetAsGPUExtent3DDict() = aOther.GetAsGPUExtent3DDict();
break;
}
}
return *this;
}
bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::TrySetToRangeEnforcedUnsignedLongSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::AutoSequence<uint32_t>& memberSlot = RawSetAsRangeEnforcedUnsignedLongSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyRangeEnforcedUnsignedLongSequence();
tryNext = true;
return true;
}
binding_detail::AutoSequence<uint32_t> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
uint32_t& slot = *slotPtr;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp, "Element of sequence<unsigned long> branch of (sequence<unsigned long> or GPUOrigin2DDict)", &slot)) {
return false;
}
}
}
return true;
}
bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::TrySetToRangeEnforcedUnsignedLongSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl);
}
bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::TrySetToGPUOrigin2DDict(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FastGPUOrigin2DDict& memberSlot = RawSetAsGPUOrigin2DDict();
if (!IsConvertibleToDictionary(value)) {
DestroyGPUOrigin2DDict();
tryNext = true;
return true;
}
if (!memberSlot.Init(cx, value, "GPUOrigin2DDict branch of (sequence<unsigned long> or GPUOrigin2DDict)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::TrySetToGPUOrigin2DDict(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUOrigin2DDict(cx, value, tryNext, passedToJSImpl);
}
bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
done = (failed = !TrySetToGPUOrigin2DDict(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<unsigned long>, GPUOrigin2DDict");
return false;
}
return true;
}
bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict(OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eRangeEnforcedUnsignedLongSequence: {
mType = eRangeEnforcedUnsignedLongSequence;
mValue.mRangeEnforcedUnsignedLongSequence.SetValue(std::move(aOther.mValue.mRangeEnforcedUnsignedLongSequence.Value()));
break;
}
case eGPUOrigin2DDict: {
mType = eGPUOrigin2DDict;
mValue.mGPUOrigin2DDict.SetValue(std::move(aOther.mValue.mGPUOrigin2DDict.Value()));
break;
}
}
}
bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::TrySetToRangeEnforcedUnsignedLongSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Sequence<uint32_t>& memberSlot = RawSetAsRangeEnforcedUnsignedLongSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyRangeEnforcedUnsignedLongSequence();
tryNext = true;
return true;
}
Sequence<uint32_t> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
uint32_t& slot = *slotPtr;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp, "Element of sequence<unsigned long> branch of (sequence<unsigned long> or GPUOrigin2DDict)", &slot)) {
return false;
}
}
}
return true;
}
bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::TrySetToRangeEnforcedUnsignedLongSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Sequence<uint32_t>&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::RawSetAsRangeEnforcedUnsignedLongSequence()
{
if (mType == eRangeEnforcedUnsignedLongSequence) {
return mValue.mRangeEnforcedUnsignedLongSequence.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eRangeEnforcedUnsignedLongSequence;
return mValue.mRangeEnforcedUnsignedLongSequence.SetValue();
}
[[nodiscard]] Sequence<uint32_t>&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::SetAsRangeEnforcedUnsignedLongSequence()
{
if (mType == eRangeEnforcedUnsignedLongSequence) {
return mValue.mRangeEnforcedUnsignedLongSequence.Value();
}
Uninit();
mType = eRangeEnforcedUnsignedLongSequence;
return mValue.mRangeEnforcedUnsignedLongSequence.SetValue();
}
void
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::DestroyRangeEnforcedUnsignedLongSequence()
{
MOZ_RELEASE_ASSERT(IsRangeEnforcedUnsignedLongSequence(), "Wrong type!");
mValue.mRangeEnforcedUnsignedLongSequence.Destroy();
mType = eUninitialized;
}
bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::TrySetToGPUOrigin2DDict(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
GPUOrigin2DDict& memberSlot = RawSetAsGPUOrigin2DDict();
if (!IsConvertibleToDictionary(value)) {
DestroyGPUOrigin2DDict();
tryNext = true;
return true;
}
if (!memberSlot.Init(cx, value, "GPUOrigin2DDict branch of (sequence<unsigned long> or GPUOrigin2DDict)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::TrySetToGPUOrigin2DDict(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUOrigin2DDict(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] GPUOrigin2DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::RawSetAsGPUOrigin2DDict()
{
if (mType == eGPUOrigin2DDict) {
return mValue.mGPUOrigin2DDict.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eGPUOrigin2DDict;
return mValue.mGPUOrigin2DDict.SetValue();
}
[[nodiscard]] GPUOrigin2DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::SetAsGPUOrigin2DDict()
{
if (mType == eGPUOrigin2DDict) {
return mValue.mGPUOrigin2DDict.Value();
}
Uninit();
mType = eGPUOrigin2DDict;
return mValue.mGPUOrigin2DDict.SetValue();
}
void
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::DestroyGPUOrigin2DDict()
{
MOZ_RELEASE_ASSERT(IsGPUOrigin2DDict(), "Wrong type!");
mValue.mGPUOrigin2DDict.Destroy();
mType = eUninitialized;
}
bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
done = (failed = !TrySetToGPUOrigin2DDict(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<unsigned long>, GPUOrigin2DDict");
return false;
}
return true;
}
bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eRangeEnforcedUnsignedLongSequence: {
DestroyRangeEnforcedUnsignedLongSequence();
break;
}
case eGPUOrigin2DDict: {
DestroyGPUOrigin2DDict();
break;
}
}
}
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::operator=(OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict&& aOther)
{
this->~OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict();
new (this) OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict (std::move(aOther));
return *this;
}
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict::operator=(const OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin2DDict& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eRangeEnforcedUnsignedLongSequence: {
SetAsRangeEnforcedUnsignedLongSequence() = aOther.GetAsRangeEnforcedUnsignedLongSequence();
break;
}
case eGPUOrigin2DDict: {
SetAsGPUOrigin2DDict() = aOther.GetAsGPUOrigin2DDict();
break;
}
}
return *this;
}
bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::TrySetToRangeEnforcedUnsignedLongSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::AutoSequence<uint32_t>& memberSlot = RawSetAsRangeEnforcedUnsignedLongSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyRangeEnforcedUnsignedLongSequence();
tryNext = true;
return true;
}
binding_detail::AutoSequence<uint32_t> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
uint32_t& slot = *slotPtr;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp, "Element of sequence<unsigned long> branch of (sequence<unsigned long> or GPUOrigin3DDict)", &slot)) {
return false;
}
}
}
return true;
}
bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::TrySetToRangeEnforcedUnsignedLongSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl);
}
bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::TrySetToGPUOrigin3DDict(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
binding_detail::FastGPUOrigin3DDict& memberSlot = RawSetAsGPUOrigin3DDict();
if (!IsConvertibleToDictionary(value)) {
DestroyGPUOrigin3DDict();
tryNext = true;
return true;
}
if (!memberSlot.Init(cx, value, "GPUOrigin3DDict branch of (sequence<unsigned long> or GPUOrigin3DDict)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::TrySetToGPUOrigin3DDict(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUOrigin3DDict(cx, value, tryNext, passedToJSImpl);
}
bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
done = (failed = !TrySetToGPUOrigin3DDict(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<unsigned long>, GPUOrigin3DDict");
return false;
}
return true;
}
bool
RangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict(OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict&& aOther)
: mType(eUninitialized)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eRangeEnforcedUnsignedLongSequence: {
mType = eRangeEnforcedUnsignedLongSequence;
mValue.mRangeEnforcedUnsignedLongSequence.SetValue(std::move(aOther.mValue.mRangeEnforcedUnsignedLongSequence.Value()));
break;
}
case eGPUOrigin3DDict: {
mType = eGPUOrigin3DDict;
mValue.mGPUOrigin3DDict.SetValue(std::move(aOther.mValue.mGPUOrigin3DDict.Value()));
break;
}
}
}
bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::TrySetToRangeEnforcedUnsignedLongSequence(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
Sequence<uint32_t>& memberSlot = RawSetAsRangeEnforcedUnsignedLongSequence();
JS::ForOfIterator iter(cx);
if (!iter.init(value, JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
DestroyRangeEnforcedUnsignedLongSequence();
tryNext = true;
return true;
}
Sequence<uint32_t> &arr = memberSlot;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
uint32_t& slot = *slotPtr;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp, "Element of sequence<unsigned long> branch of (sequence<unsigned long> or GPUOrigin3DDict)", &slot)) {
return false;
}
}
}
return true;
}
bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::TrySetToRangeEnforcedUnsignedLongSequence(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] Sequence<uint32_t>&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::RawSetAsRangeEnforcedUnsignedLongSequence()
{
if (mType == eRangeEnforcedUnsignedLongSequence) {
return mValue.mRangeEnforcedUnsignedLongSequence.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eRangeEnforcedUnsignedLongSequence;
return mValue.mRangeEnforcedUnsignedLongSequence.SetValue();
}
[[nodiscard]] Sequence<uint32_t>&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::SetAsRangeEnforcedUnsignedLongSequence()
{
if (mType == eRangeEnforcedUnsignedLongSequence) {
return mValue.mRangeEnforcedUnsignedLongSequence.Value();
}
Uninit();
mType = eRangeEnforcedUnsignedLongSequence;
return mValue.mRangeEnforcedUnsignedLongSequence.SetValue();
}
void
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::DestroyRangeEnforcedUnsignedLongSequence()
{
MOZ_RELEASE_ASSERT(IsRangeEnforcedUnsignedLongSequence(), "Wrong type!");
mValue.mRangeEnforcedUnsignedLongSequence.Destroy();
mType = eUninitialized;
}
bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::TrySetToGPUOrigin3DDict(BindingCallContext& cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
tryNext = false;
{ // scope for memberSlot
GPUOrigin3DDict& memberSlot = RawSetAsGPUOrigin3DDict();
if (!IsConvertibleToDictionary(value)) {
DestroyGPUOrigin3DDict();
tryNext = true;
return true;
}
if (!memberSlot.Init(cx, value, "GPUOrigin3DDict branch of (sequence<unsigned long> or GPUOrigin3DDict)", passedToJSImpl)) {
return false;
}
}
return true;
}
bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::TrySetToGPUOrigin3DDict(JSContext* cx_, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return TrySetToGPUOrigin3DDict(cx, value, tryNext, passedToJSImpl);
}
[[nodiscard]] GPUOrigin3DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::RawSetAsGPUOrigin3DDict()
{
if (mType == eGPUOrigin3DDict) {
return mValue.mGPUOrigin3DDict.Value();
}
MOZ_ASSERT(mType == eUninitialized);
mType = eGPUOrigin3DDict;
return mValue.mGPUOrigin3DDict.SetValue();
}
[[nodiscard]] GPUOrigin3DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::SetAsGPUOrigin3DDict()
{
if (mType == eGPUOrigin3DDict) {
return mValue.mGPUOrigin3DDict.Value();
}
Uninit();
mType = eGPUOrigin3DDict;
return mValue.mGPUOrigin3DDict.SetValue();
}
void
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::DestroyGPUOrigin3DDict()
{
MOZ_RELEASE_ASSERT(IsGPUOrigin3DDict(), "Wrong type!");
mValue.mGPUOrigin3DDict.Destroy();
mType = eUninitialized;
}
bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::Init(BindingCallContext& cx, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
MOZ_ASSERT(mType == eUninitialized);
bool done = false, failed = false, tryNext;
if (value.isObject()) {
done = (failed = !TrySetToRangeEnforcedUnsignedLongSequence(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (!done) {
done = (failed = !TrySetToGPUOrigin3DDict(cx, value, tryNext, passedToJSImpl)) || !tryNext;
}
if (failed) {
return false;
}
if (!done) {
cx.ThrowErrorMessage<MSG_NOT_IN_UNION>(sourceDescription, "sequence<unsigned long>, GPUOrigin3DDict");
return false;
}
return true;
}
bool
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::Init(JSContext* cx_, JS::Handle<JS::Value> value, const char* sourceDescription, bool passedToJSImpl)
{
BindingCallContext cx(cx_, nullptr);
return Init(cx, value, sourceDescription, passedToJSImpl);
}
void
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::Uninit()
{
switch (mType) {
case eUninitialized: {
break;
}
case eRangeEnforcedUnsignedLongSequence: {
DestroyRangeEnforcedUnsignedLongSequence();
break;
}
case eGPUOrigin3DDict: {
DestroyGPUOrigin3DDict();
break;
}
}
}
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::operator=(OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict&& aOther)
{
this->~OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict();
new (this) OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict (std::move(aOther));
return *this;
}
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict&
OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict::operator=(const OwningRangeEnforcedUnsignedLongSequenceOrGPUOrigin3DDict& aOther)
{
switch (aOther.mType) {
case eUninitialized: {
MOZ_ASSERT(mType == eUninitialized,
"We need to destroy ourselves?");
break;
}
case eRangeEnforcedUnsignedLongSequence: {
SetAsRangeEnforcedUnsignedLongSequence() = aOther.GetAsRangeEnforcedUnsignedLongSequence();
break;
}
case eGPUOrigin3DDict: {
SetAsGPUOrigin3DDict() = aOther.GetAsGPUOrigin3DDict();
break;
}
}
return *this;
}
GPUBindGroupEntry::GPUBindGroupEntry()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUBindGroupEntry::InitIds(JSContext* cx, GPUBindGroupEntryAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->resource_id.init(cx, "resource") ||
!atomsCache->binding_id.init(cx, "binding")) {
return false;
}
return true;
}
bool
GPUBindGroupEntry::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUBindGroupEntryAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUBindGroupEntryAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->binding_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'binding' member of GPUBindGroupEntry", &mBinding)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'binding' member of GPUBindGroupEntry");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->resource_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!mResource.Init(cx, temp.ref(), "'resource' member of GPUBindGroupEntry", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'resource' member of GPUBindGroupEntry");
}
return true;
}
bool
GPUBindGroupEntry::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUBindGroupEntry::TraceDictionary(JSTracer* trc)
{
}
GPUBindGroupEntry&
GPUBindGroupEntry::operator=(const GPUBindGroupEntry& aOther)
{
DictionaryBase::operator=(aOther);
mBinding = aOther.mBinding;
mResource = aOther.mResource;
return *this;
}
GPUBindGroupLayoutDescriptor::GPUBindGroupLayoutDescriptor()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUBindGroupLayoutDescriptor::InitIds(JSContext* cx, GPUBindGroupLayoutDescriptorAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->entries_id.init(cx, "entries")) {
return false;
}
return true;
}
bool
GPUBindGroupLayoutDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUBindGroupLayoutDescriptorAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUBindGroupLayoutDescriptorAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->entries_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'entries' member of GPUBindGroupLayoutDescriptor", "sequence");
return false;
}
Sequence<GPUBindGroupLayoutEntry> &arr = mEntries;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
GPUBindGroupLayoutEntry* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
GPUBindGroupLayoutEntry& slot = *slotPtr;
if (!slot.Init(cx, temp, "Element of 'entries' member of GPUBindGroupLayoutDescriptor", passedToJSImpl)) {
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'entries' member of GPUBindGroupLayoutDescriptor", "sequence");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'entries' member of GPUBindGroupLayoutDescriptor");
}
return true;
}
bool
GPUBindGroupLayoutDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUBindGroupLayoutDescriptor::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPUBindGroupLayoutDescriptor&
GPUBindGroupLayoutDescriptor::operator=(const GPUBindGroupLayoutDescriptor& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
mEntries = aOther.mEntries;
return *this;
}
GPUColorTargetState::GPUColorTargetState()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUColorTargetState::InitIds(JSContext* cx, GPUColorTargetStateAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->writeMask_id.init(cx, "writeMask") ||
!atomsCache->format_id.init(cx, "format") ||
!atomsCache->blend_id.init(cx, "blend")) {
return false;
}
return true;
}
bool
GPUColorTargetState::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUColorTargetStateAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUColorTargetStateAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->blend_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mBlend.Construct();
if (!(mBlend.Value()).Init(cx, temp.ref(), "'blend' member of GPUColorTargetState", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->format_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUTextureFormat>::Values,
"GPUTextureFormat", "'format' member of GPUColorTargetState",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mFormat = static_cast<GPUTextureFormat>(index);
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'format' member of GPUColorTargetState");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->writeMask_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'writeMask' member of GPUColorTargetState", &mWriteMask)) {
return false;
}
} else {
mWriteMask = 15U;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUColorTargetState::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUColorTargetState::TraceDictionary(JSTracer* trc)
{
}
GPUColorTargetState&
GPUColorTargetState::operator=(const GPUColorTargetState& aOther)
{
DictionaryBase::operator=(aOther);
mBlend.Reset();
if (aOther.mBlend.WasPassed()) {
mBlend.Construct(aOther.mBlend.Value());
}
mFormat = aOther.mFormat;
mWriteMask = aOther.mWriteMask;
return *this;
}
GPUComputePipelineDescriptor::GPUComputePipelineDescriptor()
: GPUPipelineDescriptorBase(FastDictionaryInitializer()),
mCompute(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUComputePipelineDescriptor::InitIds(JSContext* cx, GPUComputePipelineDescriptorAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->compute_id.init(cx, "compute")) {
return false;
}
return true;
}
bool
GPUComputePipelineDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUComputePipelineDescriptorAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUComputePipelineDescriptorAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUPipelineDescriptorBase::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->compute_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!mCompute.Init(cx, temp.ref(), "'compute' member of GPUComputePipelineDescriptor", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'compute' member of GPUComputePipelineDescriptor");
}
return true;
}
bool
GPUComputePipelineDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUComputePipelineDescriptor::TraceDictionary(JSTracer* trc)
{
GPUPipelineDescriptorBase::TraceDictionary(trc);
}
GPUCopyExternalImageSourceInfo::GPUCopyExternalImageSourceInfo()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUCopyExternalImageSourceInfo::InitIds(JSContext* cx, GPUCopyExternalImageSourceInfoAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->source_id.init(cx, "source") ||
!atomsCache->origin_id.init(cx, "origin") ||
!atomsCache->flipY_id.init(cx, "flipY")) {
return false;
}
return true;
}
bool
GPUCopyExternalImageSourceInfo::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUCopyExternalImageSourceInfoAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUCopyExternalImageSourceInfoAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->flipY_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'flipY' member of GPUCopyExternalImageSourceInfo", &mFlipY)) {
return false;
}
} else {
mFlipY = false;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->origin_id, temp.ptr())) {
return false;
}
}
mOrigin.Uninit();
if (!(!isNull && !temp->isUndefined())) {
if (!mOrigin.RawSetAsGPUOrigin2DDict().Init(cx, JS::NullHandleValue, "Member of (sequence<unsigned long> or GPUOrigin2DDict)")) {
return false;
}
} else {
if (!mOrigin.Init(cx, temp.ref(), "'origin' member of GPUCopyExternalImageSourceInfo", passedToJSImpl)) {
return false;
}
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->source_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!mSource.Init(cx, temp.ref(), "'source' member of GPUCopyExternalImageSourceInfo", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'source' member of GPUCopyExternalImageSourceInfo");
}
return true;
}
bool
GPUCopyExternalImageSourceInfo::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUCopyExternalImageSourceInfo::TraceDictionary(JSTracer* trc)
{
}
GPUCopyExternalImageSourceInfo&
GPUCopyExternalImageSourceInfo::operator=(const GPUCopyExternalImageSourceInfo& aOther)
{
DictionaryBase::operator=(aOther);
mFlipY = aOther.mFlipY;
mOrigin = aOther.mOrigin;
mSource = aOther.mSource;
return *this;
}
GPUDeviceDescriptor::GPUDeviceDescriptor()
: GPUObjectDescriptorBase(FastDictionaryInitializer()),
mDefaultQueue(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUDeviceDescriptor::InitIds(JSContext* cx, GPUDeviceDescriptorAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->requiredLimits_id.init(cx, "requiredLimits") ||
!atomsCache->requiredFeatures_id.init(cx, "requiredFeatures") ||
!atomsCache->defaultQueue_id.init(cx, "defaultQueue")) {
return false;
}
return true;
}
bool
GPUDeviceDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUDeviceDescriptorAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUDeviceDescriptorAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->defaultQueue_id, temp.ptr())) {
return false;
}
}
if (!mDefaultQueue.Init(cx, (!isNull && !temp->isUndefined()) ? temp.ref() : JS::NullHandleValue, "'defaultQueue' member of GPUDeviceDescriptor", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->requiredFeatures_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'requiredFeatures' member of GPUDeviceDescriptor", "sequence");
return false;
}
Sequence<GPUFeatureName> &arr = mRequiredFeatures;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
GPUFeatureName* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
GPUFeatureName& slot = *slotPtr;
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp,
binding_detail::EnumStrings<GPUFeatureName>::Values,
"GPUFeatureName", "element of 'requiredFeatures' member of GPUDeviceDescriptor",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
slot = static_cast<GPUFeatureName>(index);
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'requiredFeatures' member of GPUDeviceDescriptor", "sequence");
return false;
}
} else {
/* mRequiredFeatures array is already empty; nothing to do */
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->requiredLimits_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mRequiredLimits.Construct();
if (temp.ref().isObject()) {
auto& recordEntries = (mRequiredLimits.Value()).Entries();
JS::Rooted<JSObject*> recordObj(cx, &temp.ref().toObject());
JS::RootedVector<jsid> ids(cx);
if (!js::GetPropertyKeys(cx, recordObj,
JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &ids)) {
return false;
}
if (!recordEntries.SetCapacity(ids.length(), mozilla::fallible)) {
JS_ReportOutOfMemory(cx);
return false;
}
JS::Rooted<JS::Value> propNameValue(cx);
JS::Rooted<JS::Value> temp(cx);
JS::Rooted<jsid> curId(cx);
JS::Rooted<JS::Value> idVal(cx);
// Use a hashset to keep track of ids seen, to avoid
// introducing nasty O(N^2) behavior scanning for them all the
// time. Ideally we'd use a data structure with O(1) lookup
// _and_ ordering for the MozMap, but we don't have one lying
// around.
nsTHashtable<nsStringHashKey> idsSeen;
for (size_t i = 0; i < ids.length(); ++i) {
curId = ids[i];
JS::Rooted<mozilla::Maybe<JS::PropertyDescriptor>> desc(cx);
if (!JS_GetOwnPropertyDescriptorById(cx, recordObj, curId,
&desc)) {
return false;
}
if (desc.isNothing() || !desc->enumerable()) {
continue;
}
idVal = js::IdToValue(curId);
nsString propName;
// This will just throw if idVal is a Symbol, like the spec says
// to do.
if (!ConvertJSValueToString(cx, idVal, "key of 'requiredLimits' member of GPUDeviceDescriptor", propName)) {
return false;
}
if (!JS_GetPropertyById(cx, recordObj, curId, &temp)) {
return false;
}
Record<nsString, uint64_t>::EntryType* entry;
if (!idsSeen.EnsureInserted(propName)) {
// Find the existing entry.
auto idx = recordEntries.IndexOf(propName);
MOZ_ASSERT(idx != recordEntries.NoIndex,
"Why is it not found?");
// Now blow it away to make it look like it was just added
// to the array, because it's not obvious that it's
// safe to write to its already-initialized mValue via our
// normal codegen conversions. For example, the value
// could be a union and this would change its type, but
// codegen assumes we won't do that.
entry = recordEntries.ReconstructElementAt(idx);
} else {
// Safe to do an infallible append here, because we did a
// SetCapacity above to the right capacity.
entry = recordEntries.AppendElement();
}
entry->mKey = propName;
uint64_t& slot = entry->mValue;
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, temp, "Value in 'requiredLimits' member of GPUDeviceDescriptor", &slot)) {
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'requiredLimits' member of GPUDeviceDescriptor");
return false;
}
mIsAnyMemberPresent = true;
}
return true;
}
bool
GPUDeviceDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUDeviceDescriptor::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPURenderBundleEncoderDescriptor::GPURenderBundleEncoderDescriptor()
: GPURenderPassLayout(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPURenderBundleEncoderDescriptor::InitIds(JSContext* cx, GPURenderBundleEncoderDescriptorAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->stencilReadOnly_id.init(cx, "stencilReadOnly") ||
!atomsCache->depthReadOnly_id.init(cx, "depthReadOnly")) {
return false;
}
return true;
}
bool
GPURenderBundleEncoderDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPURenderBundleEncoderDescriptorAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPURenderBundleEncoderDescriptorAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPURenderPassLayout::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depthReadOnly_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'depthReadOnly' member of GPURenderBundleEncoderDescriptor", &mDepthReadOnly)) {
return false;
}
} else {
mDepthReadOnly = false;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->stencilReadOnly_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'stencilReadOnly' member of GPURenderBundleEncoderDescriptor", &mStencilReadOnly)) {
return false;
}
} else {
mStencilReadOnly = false;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPURenderBundleEncoderDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPURenderBundleEncoderDescriptor::TraceDictionary(JSTracer* trc)
{
GPURenderPassLayout::TraceDictionary(trc);
}
GPURenderBundleEncoderDescriptor&
GPURenderBundleEncoderDescriptor::operator=(const GPURenderBundleEncoderDescriptor& aOther)
{
GPURenderPassLayout::operator=(aOther);
mDepthReadOnly = aOther.mDepthReadOnly;
mStencilReadOnly = aOther.mStencilReadOnly;
return *this;
}
GPURenderPassColorAttachment::GPURenderPassColorAttachment()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPURenderPassColorAttachment::InitIds(JSContext* cx, GPURenderPassColorAttachmentAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->view_id.init(cx, "view") ||
!atomsCache->storeOp_id.init(cx, "storeOp") ||
!atomsCache->resolveTarget_id.init(cx, "resolveTarget") ||
!atomsCache->loadOp_id.init(cx, "loadOp") ||
!atomsCache->depthSlice_id.init(cx, "depthSlice") ||
!atomsCache->clearValue_id.init(cx, "clearValue")) {
return false;
}
return true;
}
bool
GPURenderPassColorAttachment::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPURenderPassColorAttachmentAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPURenderPassColorAttachmentAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->clearValue_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mClearValue.Construct();
if (!(mClearValue.Value()).Init(cx, temp.ref(), "'clearValue' member of GPURenderPassColorAttachment", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depthSlice_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mDepthSlice.Construct();
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'depthSlice' member of GPURenderPassColorAttachment", &(mDepthSlice.Value()))) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->loadOp_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPULoadOp>::Values,
"GPULoadOp", "'loadOp' member of GPURenderPassColorAttachment",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mLoadOp = static_cast<GPULoadOp>(index);
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'loadOp' member of GPURenderPassColorAttachment");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->resolveTarget_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mResolveTarget.Construct();
if (!(mResolveTarget.Value()).Init(cx, temp.ref(), "'resolveTarget' member of GPURenderPassColorAttachment", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->storeOp_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUStoreOp>::Values,
"GPUStoreOp", "'storeOp' member of GPURenderPassColorAttachment",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mStoreOp = static_cast<GPUStoreOp>(index);
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'storeOp' member of GPURenderPassColorAttachment");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->view_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!mView.Init(cx, temp.ref(), "'view' member of GPURenderPassColorAttachment", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'view' member of GPURenderPassColorAttachment");
}
return true;
}
bool
GPURenderPassColorAttachment::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPURenderPassColorAttachment::TraceDictionary(JSTracer* trc)
{
}
GPURenderPassColorAttachment&
GPURenderPassColorAttachment::operator=(const GPURenderPassColorAttachment& aOther)
{
DictionaryBase::operator=(aOther);
mClearValue.Reset();
if (aOther.mClearValue.WasPassed()) {
mClearValue.Construct(aOther.mClearValue.Value());
}
mDepthSlice.Reset();
if (aOther.mDepthSlice.WasPassed()) {
mDepthSlice.Construct(aOther.mDepthSlice.Value());
}
mLoadOp = aOther.mLoadOp;
mResolveTarget.Reset();
if (aOther.mResolveTarget.WasPassed()) {
mResolveTarget.Construct(aOther.mResolveTarget.Value());
}
mStoreOp = aOther.mStoreOp;
mView = aOther.mView;
return *this;
}
GPUShaderModuleDescriptor::GPUShaderModuleDescriptor()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUShaderModuleDescriptor::InitIds(JSContext* cx, GPUShaderModuleDescriptorAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->compilationHints_id.init(cx, "compilationHints") ||
!atomsCache->code_id.init(cx, "code")) {
return false;
}
return true;
}
bool
GPUShaderModuleDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUShaderModuleDescriptorAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUShaderModuleDescriptorAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->code_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mCode)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'code' member of GPUShaderModuleDescriptor");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->compilationHints_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'compilationHints' member of GPUShaderModuleDescriptor", "sequence");
return false;
}
Sequence<GPUShaderModuleCompilationHint> &arr = mCompilationHints;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
GPUShaderModuleCompilationHint* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
GPUShaderModuleCompilationHint& slot = *slotPtr;
if (!slot.Init(cx, temp, "Element of 'compilationHints' member of GPUShaderModuleDescriptor", passedToJSImpl)) {
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'compilationHints' member of GPUShaderModuleDescriptor", "sequence");
return false;
}
} else {
/* mCompilationHints array is already empty; nothing to do */
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUShaderModuleDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUShaderModuleDescriptor::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPUShaderModuleDescriptor&
GPUShaderModuleDescriptor::operator=(const GPUShaderModuleDescriptor& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
mCode = aOther.mCode;
mCompilationHints = aOther.mCompilationHints;
return *this;
}
GPUTexelCopyTextureInfo::GPUTexelCopyTextureInfo()
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUTexelCopyTextureInfo::InitIds(JSContext* cx, GPUTexelCopyTextureInfoAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->texture_id.init(cx, "texture") ||
!atomsCache->origin_id.init(cx, "origin") ||
!atomsCache->mipLevel_id.init(cx, "mipLevel") ||
!atomsCache->aspect_id.init(cx, "aspect")) {
return false;
}
return true;
}
bool
GPUTexelCopyTextureInfo::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUTexelCopyTextureInfoAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUTexelCopyTextureInfoAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
if (!IsConvertibleToDictionary(val)) {
return cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>(sourceDescription, "dictionary");
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->aspect_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUTextureAspect>::Values,
"GPUTextureAspect", "'aspect' member of GPUTexelCopyTextureInfo",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mAspect = static_cast<GPUTextureAspect>(index);
}
} else {
mAspect = GPUTextureAspect::All;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->mipLevel_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'mipLevel' member of GPUTexelCopyTextureInfo", &mMipLevel)) {
return false;
}
} else {
mMipLevel = 0U;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->origin_id, temp.ptr())) {
return false;
}
}
mOrigin.Uninit();
if (!(!isNull && !temp->isUndefined())) {
if (!mOrigin.RawSetAsGPUOrigin3DDict().Init(cx, JS::NullHandleValue, "Member of (sequence<unsigned long> or GPUOrigin3DDict)")) {
return false;
}
} else {
if (!mOrigin.Init(cx, temp.ref(), "'origin' member of GPUTexelCopyTextureInfo", passedToJSImpl)) {
return false;
}
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->texture_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
static_assert(IsRefcounted<mozilla::webgpu::Texture>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUTexture, mozilla::webgpu::Texture>(temp.ptr(), mTexture, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'texture' member of GPUTexelCopyTextureInfo", "GPUTexture");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'texture' member of GPUTexelCopyTextureInfo");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'texture' member of GPUTexelCopyTextureInfo");
}
return true;
}
bool
GPUTexelCopyTextureInfo::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUTexelCopyTextureInfo::TraceDictionary(JSTracer* trc)
{
}
GPUTexelCopyTextureInfo&
GPUTexelCopyTextureInfo::operator=(const GPUTexelCopyTextureInfo& aOther)
{
DictionaryBase::operator=(aOther);
mAspect = aOther.mAspect;
mMipLevel = aOther.mMipLevel;
mOrigin = aOther.mOrigin;
mTexture = aOther.mTexture;
return *this;
}
GPUTextureDescriptor::GPUTextureDescriptor()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUTextureDescriptor::InitIds(JSContext* cx, GPUTextureDescriptorAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->viewFormats_id.init(cx, "viewFormats") ||
!atomsCache->usage_id.init(cx, "usage") ||
!atomsCache->size_id.init(cx, "size") ||
!atomsCache->sampleCount_id.init(cx, "sampleCount") ||
!atomsCache->mipLevelCount_id.init(cx, "mipLevelCount") ||
!atomsCache->format_id.init(cx, "format") ||
!atomsCache->dimension_id.init(cx, "dimension")) {
return false;
}
return true;
}
bool
GPUTextureDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUTextureDescriptorAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUTextureDescriptorAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->dimension_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUTextureDimension>::Values,
"GPUTextureDimension", "'dimension' member of GPUTextureDescriptor",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mDimension = static_cast<GPUTextureDimension>(index);
}
} else {
mDimension = GPUTextureDimension::_2d;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->format_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp.ref(),
binding_detail::EnumStrings<GPUTextureFormat>::Values,
"GPUTextureFormat", "'format' member of GPUTextureDescriptor",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
mFormat = static_cast<GPUTextureFormat>(index);
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'format' member of GPUTextureDescriptor");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->mipLevelCount_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'mipLevelCount' member of GPUTextureDescriptor", &mMipLevelCount)) {
return false;
}
} else {
mMipLevelCount = 1U;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->sampleCount_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'sampleCount' member of GPUTextureDescriptor", &mSampleCount)) {
return false;
}
} else {
mSampleCount = 1U;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->size_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!mSize.Init(cx, temp.ref(), "'size' member of GPUTextureDescriptor", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'size' member of GPUTextureDescriptor");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->usage_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), "'usage' member of GPUTextureDescriptor", &mUsage)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'usage' member of GPUTextureDescriptor");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->viewFormats_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'viewFormats' member of GPUTextureDescriptor", "sequence");
return false;
}
Sequence<GPUTextureFormat> &arr = mViewFormats;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
GPUTextureFormat* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
GPUTextureFormat& slot = *slotPtr;
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, temp,
binding_detail::EnumStrings<GPUTextureFormat>::Values,
"GPUTextureFormat", "element of 'viewFormats' member of GPUTextureDescriptor",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
slot = static_cast<GPUTextureFormat>(index);
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'viewFormats' member of GPUTextureDescriptor", "sequence");
return false;
}
} else {
/* mViewFormats array is already empty; nothing to do */
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUTextureDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUTextureDescriptor::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPUTextureDescriptor&
GPUTextureDescriptor::operator=(const GPUTextureDescriptor& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
mDimension = aOther.mDimension;
mFormat = aOther.mFormat;
mMipLevelCount = aOther.mMipLevelCount;
mSampleCount = aOther.mSampleCount;
mSize = aOther.mSize;
mUsage = aOther.mUsage;
mViewFormats = aOther.mViewFormats;
return *this;
}
GPUVertexState::GPUVertexState()
: GPUProgrammableStage(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUVertexState::InitIds(JSContext* cx, GPUVertexStateAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->buffers_id.init(cx, "buffers")) {
return false;
}
return true;
}
bool
GPUVertexState::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUVertexStateAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUVertexStateAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUProgrammableStage::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->buffers_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'buffers' member of GPUVertexState", "sequence");
return false;
}
Sequence<Nullable<GPUVertexBufferLayout>> &arr = mBuffers;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
Nullable<GPUVertexBufferLayout>* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
Nullable<GPUVertexBufferLayout>& slot = *slotPtr;
if (temp.isNullOrUndefined()) {
slot.SetNull();
} else {
if (!slot.SetValue().Init(cx, temp, "Element of 'buffers' member of GPUVertexState", passedToJSImpl)) {
return false;
}
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'buffers' member of GPUVertexState", "sequence");
return false;
}
} else {
/* mBuffers array is already empty; nothing to do */
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUVertexState::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUVertexState::TraceDictionary(JSTracer* trc)
{
GPUProgrammableStage::TraceDictionary(trc);
}
GPUBindGroupDescriptor::GPUBindGroupDescriptor()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUBindGroupDescriptor::InitIds(JSContext* cx, GPUBindGroupDescriptorAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->layout_id.init(cx, "layout") ||
!atomsCache->entries_id.init(cx, "entries")) {
return false;
}
return true;
}
bool
GPUBindGroupDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUBindGroupDescriptorAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUBindGroupDescriptorAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->entries_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'entries' member of GPUBindGroupDescriptor", "sequence");
return false;
}
Sequence<GPUBindGroupEntry> &arr = mEntries;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
GPUBindGroupEntry* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
GPUBindGroupEntry& slot = *slotPtr;
if (!slot.Init(cx, temp, "Element of 'entries' member of GPUBindGroupDescriptor", passedToJSImpl)) {
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'entries' member of GPUBindGroupDescriptor", "sequence");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'entries' member of GPUBindGroupDescriptor");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->layout_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
static_assert(IsRefcounted<mozilla::webgpu::BindGroupLayout>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBindGroupLayout, mozilla::webgpu::BindGroupLayout>(temp.ptr(), mLayout, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'layout' member of GPUBindGroupDescriptor", "GPUBindGroupLayout");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'layout' member of GPUBindGroupDescriptor");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'layout' member of GPUBindGroupDescriptor");
}
return true;
}
bool
GPUBindGroupDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUBindGroupDescriptor::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPUBindGroupDescriptor&
GPUBindGroupDescriptor::operator=(const GPUBindGroupDescriptor& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
mEntries = aOther.mEntries;
mLayout = aOther.mLayout;
return *this;
}
GPUCopyExternalImageDestInfo::GPUCopyExternalImageDestInfo()
: GPUTexelCopyTextureInfo(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUCopyExternalImageDestInfo::InitIds(JSContext* cx, GPUCopyExternalImageDestInfoAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->premultipliedAlpha_id.init(cx, "premultipliedAlpha")) {
return false;
}
return true;
}
bool
GPUCopyExternalImageDestInfo::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUCopyExternalImageDestInfoAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUCopyExternalImageDestInfoAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUTexelCopyTextureInfo::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->premultipliedAlpha_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), "'premultipliedAlpha' member of GPUCopyExternalImageDestInfo", &mPremultipliedAlpha)) {
return false;
}
} else {
mPremultipliedAlpha = false;
}
mIsAnyMemberPresent = true;
return true;
}
bool
GPUCopyExternalImageDestInfo::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUCopyExternalImageDestInfo::TraceDictionary(JSTracer* trc)
{
GPUTexelCopyTextureInfo::TraceDictionary(trc);
}
GPUCopyExternalImageDestInfo&
GPUCopyExternalImageDestInfo::operator=(const GPUCopyExternalImageDestInfo& aOther)
{
GPUTexelCopyTextureInfo::operator=(aOther);
mPremultipliedAlpha = aOther.mPremultipliedAlpha;
return *this;
}
GPUFragmentState::GPUFragmentState()
: GPUProgrammableStage(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPUFragmentState::InitIds(JSContext* cx, GPUFragmentStateAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->targets_id.init(cx, "targets")) {
return false;
}
return true;
}
bool
GPUFragmentState::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPUFragmentStateAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPUFragmentStateAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUProgrammableStage::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->targets_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'targets' member of GPUFragmentState", "sequence");
return false;
}
Sequence<GPUColorTargetState> &arr = mTargets;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
GPUColorTargetState* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
GPUColorTargetState& slot = *slotPtr;
if (!slot.Init(cx, temp, "Element of 'targets' member of GPUFragmentState", passedToJSImpl)) {
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'targets' member of GPUFragmentState", "sequence");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'targets' member of GPUFragmentState");
}
return true;
}
bool
GPUFragmentState::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPUFragmentState::TraceDictionary(JSTracer* trc)
{
GPUProgrammableStage::TraceDictionary(trc);
}
GPURenderPassDescriptor::GPURenderPassDescriptor()
: GPUObjectDescriptorBase(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPURenderPassDescriptor::InitIds(JSContext* cx, GPURenderPassDescriptorAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->timestampWrites_id.init(cx, "timestampWrites") ||
!atomsCache->occlusionQuerySet_id.init(cx, "occlusionQuerySet") ||
!atomsCache->depthStencilAttachment_id.init(cx, "depthStencilAttachment") ||
!atomsCache->colorAttachments_id.init(cx, "colorAttachments")) {
return false;
}
return true;
}
bool
GPURenderPassDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPURenderPassDescriptorAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPURenderPassDescriptorAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUObjectDescriptorBase::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->colorAttachments_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (temp.ref().isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'colorAttachments' member of GPURenderPassDescriptor", "sequence");
return false;
}
Sequence<GPURenderPassColorAttachment> &arr = mColorAttachments;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
GPURenderPassColorAttachment* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
GPURenderPassColorAttachment& slot = *slotPtr;
if (!slot.Init(cx, temp, "Element of 'colorAttachments' member of GPURenderPassDescriptor", passedToJSImpl)) {
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("'colorAttachments' member of GPURenderPassDescriptor", "sequence");
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'colorAttachments' member of GPURenderPassDescriptor");
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depthStencilAttachment_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mDepthStencilAttachment.Construct();
if (!(mDepthStencilAttachment.Value()).Init(cx, temp.ref(), "'depthStencilAttachment' member of GPURenderPassDescriptor", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->occlusionQuerySet_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mOcclusionQuerySet.Construct();
if (temp.ref().isObject()) {
static_assert(IsRefcounted<mozilla::webgpu::QuerySet>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUQuerySet, mozilla::webgpu::QuerySet>(temp.ptr(), (mOcclusionQuerySet.Value()), cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("'occlusionQuerySet' member of GPURenderPassDescriptor", "GPUQuerySet");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("'occlusionQuerySet' member of GPURenderPassDescriptor");
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->timestampWrites_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mTimestampWrites.Construct();
if (!(mTimestampWrites.Value()).Init(cx, temp.ref(), "'timestampWrites' member of GPURenderPassDescriptor", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
}
return true;
}
bool
GPURenderPassDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPURenderPassDescriptor::TraceDictionary(JSTracer* trc)
{
GPUObjectDescriptorBase::TraceDictionary(trc);
}
GPURenderPassDescriptor&
GPURenderPassDescriptor::operator=(const GPURenderPassDescriptor& aOther)
{
GPUObjectDescriptorBase::operator=(aOther);
mColorAttachments = aOther.mColorAttachments;
mDepthStencilAttachment.Reset();
if (aOther.mDepthStencilAttachment.WasPassed()) {
mDepthStencilAttachment.Construct(aOther.mDepthStencilAttachment.Value());
}
mOcclusionQuerySet.Reset();
if (aOther.mOcclusionQuerySet.WasPassed()) {
mOcclusionQuerySet.Construct(aOther.mOcclusionQuerySet.Value());
}
mTimestampWrites.Reset();
if (aOther.mTimestampWrites.WasPassed()) {
mTimestampWrites.Construct(aOther.mTimestampWrites.Value());
}
return *this;
}
GPURenderPipelineDescriptor::GPURenderPipelineDescriptor()
: GPUPipelineDescriptorBase(FastDictionaryInitializer()),
mMultisample(FastDictionaryInitializer()),
mPrimitive(FastDictionaryInitializer()),
mVertex(FastDictionaryInitializer())
{
// Safe to pass a null context if we pass a null value
Init(nullptr, JS::NullHandleValue);
}
bool
GPURenderPipelineDescriptor::InitIds(JSContext* cx, GPURenderPipelineDescriptorAtoms* atomsCache)
{
MOZ_ASSERT(reinterpret_cast<jsid*>(atomsCache)->isVoid());
// Initialize these in reverse order so that any failure leaves the first one
// uninitialized.
if (!atomsCache->vertex_id.init(cx, "vertex") ||
!atomsCache->primitive_id.init(cx, "primitive") ||
!atomsCache->multisample_id.init(cx, "multisample") ||
!atomsCache->fragment_id.init(cx, "fragment") ||
!atomsCache->depthStencil_id.init(cx, "depthStencil")) {
return false;
}
return true;
}
bool
GPURenderPipelineDescriptor::Init(BindingCallContext& cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// Passing a null JSContext is OK only if we're initing from null,
// Since in that case we will not have to do any property gets
// Also evaluate isNullOrUndefined in order to avoid false-positive
// checkers by static analysis tools
MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
GPURenderPipelineDescriptorAtoms* atomsCache = nullptr;
if (cx) {
atomsCache = GetAtomCache<GPURenderPipelineDescriptorAtoms>(cx);
if (reinterpret_cast<jsid*>(atomsCache)->isVoid() &&
!InitIds(cx, atomsCache)) {
return false;
}
}
// Per spec, we init the parent's members first
if (!GPUPipelineDescriptorBase::Init(cx, val)) {
return false;
}
bool isNull = val.isNullOrUndefined();
// We only need these if !isNull, in which case we have |cx|.
Maybe<JS::Rooted<JSObject *> > object;
Maybe<JS::Rooted<JS::Value> > temp;
if (!isNull) {
MOZ_ASSERT(cx);
object.emplace(cx, &val.toObject());
temp.emplace(cx);
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->depthStencil_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mDepthStencil.Construct();
if (!(mDepthStencil.Value()).Init(cx, temp.ref(), "'depthStencil' member of GPURenderPipelineDescriptor", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->fragment_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
mFragment.Construct();
if (!(mFragment.Value()).Init(cx, temp.ref(), "'fragment' member of GPURenderPipelineDescriptor", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
}
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->multisample_id, temp.ptr())) {
return false;
}
}
if (!mMultisample.Init(cx, (!isNull && !temp->isUndefined()) ? temp.ref() : JS::NullHandleValue, "'multisample' member of GPURenderPipelineDescriptor", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->primitive_id, temp.ptr())) {
return false;
}
}
if (!mPrimitive.Init(cx, (!isNull && !temp->isUndefined()) ? temp.ref() : JS::NullHandleValue, "'primitive' member of GPURenderPipelineDescriptor", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
if (!isNull) {
if (!JS_GetPropertyById(cx, *object, atomsCache->vertex_id, temp.ptr())) {
return false;
}
}
if (!isNull && !temp->isUndefined()) {
if (!mVertex.Init(cx, temp.ref(), "'vertex' member of GPURenderPipelineDescriptor", passedToJSImpl)) {
return false;
}
mIsAnyMemberPresent = true;
} else if (cx) {
// Don't error out if we have no cx. In that
// situation the caller is default-constructing us and we'll
// just assume they know what they're doing.
return cx.ThrowErrorMessage<MSG_MISSING_REQUIRED_DICTIONARY_MEMBER>("'vertex' member of GPURenderPipelineDescriptor");
}
return true;
}
bool
GPURenderPipelineDescriptor::Init(JSContext* cx_, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
{
// We don't want to use sourceDescription for our context here;
// that's not really what it's formatted for.
BindingCallContext cx(cx_, nullptr);
return Init(cx, val, sourceDescription, passedToJSImpl);
}
void
GPURenderPipelineDescriptor::TraceDictionary(JSTracer* trc)
{
GPUPipelineDescriptorBase::TraceDictionary(trc);
}
namespace GPU_Binding {
MOZ_CAN_RUN_SCRIPT static bool
requestAdapter(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPU.requestAdapter");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPU", "requestAdapter", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Instance*>(void_self);
binding_detail::FastGPURequestAdapterOptions arg0;
if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
return false;
}
FastErrorResult rv;
auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->RequestAdapter(Constify(arg0), rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPU.requestAdapter"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
requestAdapter_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
bool ok = requestAdapter(cx, obj, void_self, args);
if (ok) {
return true;
}
return ConvertExceptionToPromise(cx, args.rval());
}
static const JSJitInfo requestAdapter_methodinfo = {
{ (JSJitGetterOp)requestAdapter_promiseWrapper },
{ prototypes::id::GPU },
{ PrototypeTraits<prototypes::id::GPU>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
getPreferredCanvasFormat(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPU", "getPreferredCanvasFormat", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Instance*>(void_self);
GPUTextureFormat result(MOZ_KnownLive(self)->GetPreferredCanvasFormat());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo getPreferredCanvasFormat_methodinfo = {
{ (JSJitGetterOp)getPreferredCanvasFormat },
{ prototypes::id::GPU },
{ PrototypeTraits<prototypes::id::GPU>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_wgslLanguageFeatures(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPU", "wgslLanguageFeatures", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Instance*>(void_self);
auto result(StrongOrRawPtr<mozilla::webgpu::WGSLLanguageFeatures>(MOZ_KnownLive(self)->WgslLanguageFeatures()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo wgslLanguageFeatures_getterinfo = {
{ get_wgslLanguageFeatures },
{ prototypes::id::GPU },
{ PrototypeTraits<prototypes::id::GPU>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::Instance* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Instance>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::Instance>(self);
}
}
MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("requestAdapter", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&requestAdapter_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("getPreferredCanvasFormat", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getPreferredCanvasFormat_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &sMethods_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("wgslLanguageFeatures", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &wgslLanguageFeatures_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[3];
static PropertyInfo sNativeProperties_propertyInfos[3];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
3,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[2] }
}
};
static_assert(3 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPU,
constructors::id::GPU,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPU>::Depth,
prototypes::id::GPU,
true,
0,
"GPU",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPU,
PrototypeTraits<prototypes::id::GPU>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPU",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::Instance>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPU, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::Instance>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::Instance>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::Instance>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::Instance>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::Instance* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::Instance>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::Instance*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::Instance> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPU);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPU);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPU",
ShouldExpose<GPU_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPU,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPU,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPU_Binding
namespace GPUAdapter_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_features(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapter", "features", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Adapter*>(void_self);
auto result(StrongOrRawPtr<mozilla::webgpu::SupportedFeatures>(MOZ_KnownLive(self)->Features()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo features_getterinfo = {
{ get_features },
{ prototypes::id::GPUAdapter },
{ PrototypeTraits<prototypes::id::GPUAdapter>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_limits(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapter", "limits", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Adapter*>(void_self);
auto result(StrongOrRawPtr<mozilla::webgpu::SupportedLimits>(MOZ_KnownLive(self)->Limits()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo limits_getterinfo = {
{ get_limits },
{ prototypes::id::GPUAdapter },
{ PrototypeTraits<prototypes::id::GPUAdapter>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_info(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapter", "info", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Adapter*>(void_self);
auto result(StrongOrRawPtr<mozilla::webgpu::AdapterInfo>(MOZ_KnownLive(self)->Info()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo info_getterinfo = {
{ get_info },
{ prototypes::id::GPUAdapter },
{ PrototypeTraits<prototypes::id::GPUAdapter>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
requestDevice(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUAdapter.requestDevice");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapter", "requestDevice", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Adapter*>(void_self);
binding_detail::FastGPUDeviceDescriptor arg0;
if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
return false;
}
FastErrorResult rv;
auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->RequestDevice(Constify(arg0), rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUAdapter.requestDevice"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
requestDevice_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
bool ok = requestDevice(cx, obj, void_self, args);
if (ok) {
return true;
}
return ConvertExceptionToPromise(cx, args.rval());
}
static const JSJitInfo requestDevice_methodinfo = {
{ (JSJitGetterOp)requestDevice_promiseWrapper },
{ prototypes::id::GPUAdapter },
{ PrototypeTraits<prototypes::id::GPUAdapter>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_missingFeatures(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapter", "missingFeatures", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Adapter*>(void_self);
uint64_t result(MOZ_KnownLive(self)->MissingFeatures());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().set(JS_NumberValue(double(result)));
return true;
}
static const JSJitInfo missingFeatures_getterinfo = {
{ get_missingFeatures },
{ prototypes::id::GPUAdapter },
{ PrototypeTraits<prototypes::id::GPUAdapter>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::Adapter* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Adapter>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::Adapter>(self);
}
}
MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("requestDevice", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&requestDevice_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &sMethods_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("features", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &features_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("limits", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &limits_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("info", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &info_getterinfo, nullptr, nullptr),
JS_PS_END,
JSPropertySpec::nativeAccessors("missingFeatures", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &missingFeatures_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const PrefableDisablers sAttributes_disablers4 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), &nsRFPService::IsSystemPrincipalOrAboutFingerprintingProtection
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_specs[0] },
{ &sAttributes_disablers4, &sAttributes_specs[4] },
{ nullptr, nullptr }
};
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[5];
static PropertyInfo sNativeProperties_propertyInfos[5];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
5,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[1] }
}
};
static_assert(5 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUAdapter,
constructors::id::GPUAdapter,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUAdapter>::Depth,
prototypes::id::GPUAdapter,
true,
0,
"GPUAdapter",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUAdapterPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUAdapter,
PrototypeTraits<prototypes::id::GPUAdapter>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUAdapter",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::Adapter>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUAdapter, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::Adapter>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::Adapter>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::Adapter>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::Adapter>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::Adapter* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::Adapter>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::Adapter*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::Adapter> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUAdapter);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUAdapter);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUAdapter",
ShouldExpose<GPUAdapter_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUAdapter,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUAdapter,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUAdapter_Binding
namespace GPUAdapterInfo_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_vendor(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapterInfo", "vendor", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetVendor(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetVendor(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo vendor_getterinfo = {
{ get_vendor },
{ prototypes::id::GPUAdapterInfo },
{ PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_architecture(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapterInfo", "architecture", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetArchitecture(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetArchitecture(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo architecture_getterinfo = {
{ get_architecture },
{ prototypes::id::GPUAdapterInfo },
{ PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_device(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapterInfo", "device", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetDevice(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetDevice(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo device_getterinfo = {
{ get_device },
{ prototypes::id::GPUAdapterInfo },
{ PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_description(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapterInfo", "description", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetDescription(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetDescription(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo description_getterinfo = {
{ get_description },
{ prototypes::id::GPUAdapterInfo },
{ PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_subgroupMinSize(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapterInfo", "subgroupMinSize", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
uint32_t result(MOZ_KnownLive(self)->SubgroupMinSize());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo subgroupMinSize_getterinfo = {
{ get_subgroupMinSize },
{ prototypes::id::GPUAdapterInfo },
{ PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_subgroupMaxSize(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapterInfo", "subgroupMaxSize", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
uint32_t result(MOZ_KnownLive(self)->SubgroupMaxSize());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo subgroupMaxSize_getterinfo = {
{ get_subgroupMaxSize },
{ prototypes::id::GPUAdapterInfo },
{ PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_isFallbackAdapter(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapterInfo", "isFallbackAdapter", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
bool result(MOZ_KnownLive(self)->IsFallbackAdapter());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setBoolean(result);
return true;
}
static const JSJitInfo isFallbackAdapter_getterinfo = {
{ get_isFallbackAdapter },
{ prototypes::id::GPUAdapterInfo },
{ PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_wgpuName(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapterInfo", "wgpuName", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetWgpuName(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetWgpuName(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo wgpuName_getterinfo = {
{ get_wgpuName },
{ prototypes::id::GPUAdapterInfo },
{ PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_wgpuVendor(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapterInfo", "wgpuVendor", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
uint32_t result(MOZ_KnownLive(self)->WgpuVendor());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo wgpuVendor_getterinfo = {
{ get_wgpuVendor },
{ prototypes::id::GPUAdapterInfo },
{ PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_wgpuDevice(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapterInfo", "wgpuDevice", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
uint32_t result(MOZ_KnownLive(self)->WgpuDevice());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo wgpuDevice_getterinfo = {
{ get_wgpuDevice },
{ prototypes::id::GPUAdapterInfo },
{ PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_wgpuDeviceType(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapterInfo", "wgpuDeviceType", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetWgpuDeviceType(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetWgpuDeviceType(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo wgpuDeviceType_getterinfo = {
{ get_wgpuDeviceType },
{ prototypes::id::GPUAdapterInfo },
{ PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_wgpuDriver(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapterInfo", "wgpuDriver", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetWgpuDriver(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetWgpuDriver(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo wgpuDriver_getterinfo = {
{ get_wgpuDriver },
{ prototypes::id::GPUAdapterInfo },
{ PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_wgpuDriverInfo(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapterInfo", "wgpuDriverInfo", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetWgpuDriverInfo(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetWgpuDriverInfo(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo wgpuDriverInfo_getterinfo = {
{ get_wgpuDriverInfo },
{ prototypes::id::GPUAdapterInfo },
{ PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_wgpuBackend(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUAdapterInfo", "wgpuBackend", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::AdapterInfo*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetWgpuBackend(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetWgpuBackend(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo wgpuBackend_getterinfo = {
{ get_wgpuBackend },
{ prototypes::id::GPUAdapterInfo },
{ PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::AdapterInfo* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::AdapterInfo>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::AdapterInfo>(self);
}
}
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("vendor", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &vendor_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("architecture", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &architecture_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("device", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &device_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("description", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &description_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("subgroupMinSize", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &subgroupMinSize_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("subgroupMaxSize", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &subgroupMaxSize_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("isFallbackAdapter", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &isFallbackAdapter_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(7 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
MOZ_GLOBINIT static const JSPropertySpec sChromeAttributes_specs[] = {
JSPropertySpec::nativeAccessors("wgpuName", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &wgpuName_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("wgpuVendor", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &wgpuVendor_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("wgpuDevice", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &wgpuDevice_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("wgpuDeviceType", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &wgpuDeviceType_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("wgpuDriver", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &wgpuDriver_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("wgpuDriverInfo", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &wgpuDriverInfo_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("wgpuBackend", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &wgpuBackend_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sChromeAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sChromeAttributes[] = {
{ &sChromeAttributes_disablers0, &sChromeAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(7 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[7];
static PropertyInfo sNativeProperties_propertyInfos[7];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
7,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(7 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[7];
static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[7];
static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sChromeAttributes */,
false, 0,
false, 0,
false, 0,
-1,
7,
sChromeOnlyNativeProperties_sortedPropertyIndices,
{
{ sChromeAttributes, &sChromeOnlyNativeProperties_propertyInfos[0] }
}
};
static_assert(7 < 1ull << (CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast(), &sNativePropertiesInited },
prototypes::id::GPUAdapterInfo,
constructors::id::GPUAdapterInfo,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth,
prototypes::id::GPUAdapterInfo,
true,
0,
"GPUAdapterInfo",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUAdapterInfoPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUAdapterInfo,
PrototypeTraits<prototypes::id::GPUAdapterInfo>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUAdapterInfo",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::AdapterInfo>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUAdapterInfo, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::AdapterInfo>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::AdapterInfo>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::AdapterInfo>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::AdapterInfo>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::AdapterInfo* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::AdapterInfo>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::AdapterInfo*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::AdapterInfo> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUAdapterInfo);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUAdapterInfo);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
sChromeOnlyNativeProperties.Upcast(),
"GPUAdapterInfo",
ShouldExpose<GPUAdapterInfo_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUAdapterInfo,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUAdapterInfo,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUAdapterInfo_Binding
namespace GPUBindGroup_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUBindGroup", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::BindGroup*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUBindGroup", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::BindGroup*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPUBindGroup },
{ PrototypeTraits<prototypes::id::GPUBindGroup>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPUBindGroup },
{ PrototypeTraits<prototypes::id::GPUBindGroup>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::BindGroup* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::BindGroup>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::BindGroup>(self);
}
}
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[1];
static PropertyInfo sNativeProperties_propertyInfos[1];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
1,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(1 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUBindGroup,
constructors::id::GPUBindGroup,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUBindGroup>::Depth,
prototypes::id::GPUBindGroup,
true,
0,
"GPUBindGroup",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUBindGroupPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUBindGroup,
PrototypeTraits<prototypes::id::GPUBindGroup>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUBindGroup",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::BindGroup>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUBindGroup, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::BindGroup>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::BindGroup>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::BindGroup>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::BindGroup>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::BindGroup* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::BindGroup>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::BindGroup*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::BindGroup> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUBindGroup);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUBindGroup);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUBindGroup",
ShouldExpose<GPUBindGroup_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUBindGroup,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUBindGroup,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUBindGroup_Binding
namespace GPUBindGroupLayout_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUBindGroupLayout", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::BindGroupLayout*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUBindGroupLayout", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::BindGroupLayout*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPUBindGroupLayout },
{ PrototypeTraits<prototypes::id::GPUBindGroupLayout>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPUBindGroupLayout },
{ PrototypeTraits<prototypes::id::GPUBindGroupLayout>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::BindGroupLayout* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::BindGroupLayout>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::BindGroupLayout>(self);
}
}
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[1];
static PropertyInfo sNativeProperties_propertyInfos[1];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
1,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(1 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUBindGroupLayout,
constructors::id::GPUBindGroupLayout,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUBindGroupLayout>::Depth,
prototypes::id::GPUBindGroupLayout,
true,
0,
"GPUBindGroupLayout",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUBindGroupLayoutPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUBindGroupLayout,
PrototypeTraits<prototypes::id::GPUBindGroupLayout>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUBindGroupLayout",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::BindGroupLayout>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUBindGroupLayout, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::BindGroupLayout>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::BindGroupLayout>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::BindGroupLayout>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::BindGroupLayout>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::BindGroupLayout* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::BindGroupLayout>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::BindGroupLayout*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::BindGroupLayout> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUBindGroupLayout);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUBindGroupLayout);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUBindGroupLayout",
ShouldExpose<GPUBindGroupLayout_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUBindGroupLayout,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUBindGroupLayout,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUBindGroupLayout_Binding
namespace GPUBuffer_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_size(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUBuffer", "size", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Buffer*>(void_self);
uint64_t result(MOZ_KnownLive(self)->Size());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().set(JS_NumberValue(double(result)));
return true;
}
static const JSJitInfo size_getterinfo = {
{ get_size },
{ prototypes::id::GPUBuffer },
{ PrototypeTraits<prototypes::id::GPUBuffer>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_usage(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUBuffer", "usage", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Buffer*>(void_self);
uint32_t result(MOZ_KnownLive(self)->Usage());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo usage_getterinfo = {
{ get_usage },
{ prototypes::id::GPUBuffer },
{ PrototypeTraits<prototypes::id::GPUBuffer>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_mapState(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUBuffer", "mapState", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Buffer*>(void_self);
GPUBufferMapState result(MOZ_KnownLive(self)->MapState());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo mapState_getterinfo = {
{ get_mapState },
{ prototypes::id::GPUBuffer },
{ PrototypeTraits<prototypes::id::GPUBuffer>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
mapAsync(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUBuffer.mapAsync");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUBuffer", "mapAsync", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Buffer*>(void_self);
if (!args.requireAtLeast(cx, "GPUBuffer.mapAsync", 1)) {
return false;
}
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
uint64_t arg1;
if (args.hasDefined(1)) {
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
return false;
}
} else {
arg1 = 0ULL;
}
Optional<uint64_t> arg2;
if (args.hasDefined(2)) {
arg2.Construct();
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2.Value())) {
return false;
}
}
FastErrorResult rv;
auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->MapAsync(arg0, arg1, Constify(arg2), rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUBuffer.mapAsync"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
mapAsync_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
bool ok = mapAsync(cx, obj, void_self, args);
if (ok) {
return true;
}
return ConvertExceptionToPromise(cx, args.rval());
}
static const JSJitInfo mapAsync_methodinfo = {
{ (JSJitGetterOp)mapAsync_promiseWrapper },
{ prototypes::id::GPUBuffer },
{ PrototypeTraits<prototypes::id::GPUBuffer>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
getMappedRange(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUBuffer.getMappedRange");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUBuffer", "getMappedRange", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Buffer*>(void_self);
uint64_t arg0;
if (args.hasDefined(0)) {
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
} else {
arg0 = 0ULL;
}
Optional<uint64_t> arg1;
if (args.hasDefined(1)) {
arg1.Construct();
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1.Value())) {
return false;
}
}
FastErrorResult rv;
JS::Rooted<JSObject*> result(cx);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetMappedRange(cx, arg0, Constify(arg1), &result, rv))>, "Should be returning void here");
MOZ_KnownLive(self)->GetMappedRange(cx, arg0, Constify(arg1), &result, rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUBuffer.getMappedRange"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
JS::ExposeObjectToActiveJS(result);
args.rval().setObject(*result);
if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo getMappedRange_methodinfo = {
{ (JSJitGetterOp)getMappedRange },
{ prototypes::id::GPUBuffer },
{ PrototypeTraits<prototypes::id::GPUBuffer>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
unmap(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUBuffer", "unmap", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Buffer*>(void_self);
FastErrorResult rv;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Unmap(cx, rv))>, "Should be returning void here");
MOZ_KnownLive(self)->Unmap(cx, rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUBuffer.unmap"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo unmap_methodinfo = {
{ (JSJitGetterOp)unmap },
{ prototypes::id::GPUBuffer },
{ PrototypeTraits<prototypes::id::GPUBuffer>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
destroy(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUBuffer", "destroy", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Buffer*>(void_self);
FastErrorResult rv;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Destroy(cx, rv))>, "Should be returning void here");
MOZ_KnownLive(self)->Destroy(cx, rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUBuffer.destroy"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo destroy_methodinfo = {
{ (JSJitGetterOp)destroy },
{ prototypes::id::GPUBuffer },
{ PrototypeTraits<prototypes::id::GPUBuffer>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUBuffer", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Buffer*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUBuffer", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Buffer*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPUBuffer },
{ PrototypeTraits<prototypes::id::GPUBuffer>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPUBuffer },
{ PrototypeTraits<prototypes::id::GPUBuffer>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::Buffer* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Buffer>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::Buffer>(self);
}
}
MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("mapAsync", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&mapAsync_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("getMappedRange", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getMappedRange_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("unmap", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&unmap_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("destroy", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&destroy_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &sMethods_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("size", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &size_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("usage", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &usage_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("mapState", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &mapState_getterinfo, nullptr, nullptr),
JS_PS_END,
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_specs[0] },
{ nullptr, &sAttributes_specs[4] },
{ nullptr, nullptr }
};
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[8];
static PropertyInfo sNativeProperties_propertyInfos[8];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
8,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[4] }
}
};
static_assert(8 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUBuffer,
constructors::id::GPUBuffer,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUBuffer>::Depth,
prototypes::id::GPUBuffer,
true,
0,
"GPUBuffer",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUBufferPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUBuffer,
PrototypeTraits<prototypes::id::GPUBuffer>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUBuffer",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::Buffer>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUBuffer, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::Buffer>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::Buffer>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::Buffer>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::Buffer>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::Buffer* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::Buffer>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::Buffer*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::Buffer> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUBuffer);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUBuffer);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUBuffer",
ShouldExpose<GPUBuffer_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUBuffer,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUBuffer,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUBuffer_Binding
namespace GPUBufferUsage_Binding {
MOZ_GLOBINIT static const ConstantSpec sConstants_specs[] = {
{ "MAP_READ", JS::NumberValue(1U) },
{ "MAP_WRITE", JS::NumberValue(2U) },
{ "COPY_SRC", JS::NumberValue(4U) },
{ "COPY_DST", JS::NumberValue(8U) },
{ "INDEX", JS::NumberValue(16U) },
{ "VERTEX", JS::NumberValue(32U) },
{ "UNIFORM", JS::NumberValue(64U) },
{ "STORAGE", JS::NumberValue(128U) },
{ "INDIRECT", JS::NumberValue(256U) },
{ "QUERY_RESOLVE", JS::NumberValue(512U) },
{ 0, JS::UndefinedValue() }
};
static const PrefableDisablers sConstants_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const ConstantSpec> sConstants[] = {
{ &sConstants_disablers0, &sConstants_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(10 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[10];
static PropertyInfo sNativeProperties_propertyInfos[10];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
false, 0,
false, 0,
false, 0,
true, 0 /* sConstants */,
-1,
10,
sNativeProperties_sortedPropertyIndices,
{
{ sConstants, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(10 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::_ID_Count,
constructors::id::GPUBufferUsage,
&DefaultXrayExpandoObjectClass
};
static const DOMIfaceAndProtoJSClass sNamespaceObjectClass = {
{
"GPUBufferUsage",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS,
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eNamespace,
prototypes::id::_ID_Count,
0,
&sNativePropertyHooks,
// This isn't strictly following the spec (see
// but should be ok for Xrays.
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!constructorProto) {
return;
}
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUBufferUsage);
dom::CreateNamespaceObject(aCx, aGlobal, constructorProto,
sNamespaceObjectClass,
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUBufferUsage",
ShouldExpose<GPUBufferUsage_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal));
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUBufferUsage,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUBufferUsage_Binding
namespace GPUCanvasContext_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_canvas(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCanvasContext", "canvas", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CanvasContext*>(void_self);
OwningHTMLCanvasElementOrOffscreenCanvas result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetCanvas(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetCanvas(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!result.ToJSVal(cx, obj, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo canvas_getterinfo = {
{ get_canvas },
{ prototypes::id::GPUCanvasContext },
{ PrototypeTraits<prototypes::id::GPUCanvasContext>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
configure(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUCanvasContext.configure");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCanvasContext", "configure", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CanvasContext*>(void_self);
if (!args.requireAtLeast(cx, "GPUCanvasContext.configure", 1)) {
return false;
}
binding_detail::FastGPUCanvasConfiguration arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
FastErrorResult rv;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Configure(Constify(arg0), rv))>, "Should be returning void here");
MOZ_KnownLive(self)->Configure(Constify(arg0), rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUCanvasContext.configure"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo configure_methodinfo = {
{ (JSJitGetterOp)configure },
{ prototypes::id::GPUCanvasContext },
{ PrototypeTraits<prototypes::id::GPUCanvasContext>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
unconfigure(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCanvasContext", "unconfigure", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CanvasContext*>(void_self);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Unconfigure())>, "Should be returning void here");
MOZ_KnownLive(self)->Unconfigure();
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo unconfigure_methodinfo = {
{ (JSJitGetterOp)unconfigure },
{ prototypes::id::GPUCanvasContext },
{ PrototypeTraits<prototypes::id::GPUCanvasContext>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
getConfiguration(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCanvasContext", "getConfiguration", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CanvasContext*>(void_self);
Nullable<GPUCanvasConfiguration> result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetConfiguration(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetConfiguration(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (result.IsNull()) {
args.rval().setNull();
return true;
}
if (!result.Value().ToObjectInternal(cx, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo getConfiguration_methodinfo = {
{ (JSJitGetterOp)getConfiguration },
{ prototypes::id::GPUCanvasContext },
{ PrototypeTraits<prototypes::id::GPUCanvasContext>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
getCurrentTexture(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCanvasContext", "getCurrentTexture", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CanvasContext*>(void_self);
FastErrorResult rv;
auto result(StrongOrRawPtr<mozilla::webgpu::Texture>(MOZ_KnownLive(self)->GetCurrentTexture(rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUCanvasContext.getCurrentTexture"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo getCurrentTexture_methodinfo = {
{ (JSJitGetterOp)getCurrentTexture },
{ prototypes::id::GPUCanvasContext },
{ PrototypeTraits<prototypes::id::GPUCanvasContext>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::CanvasContext* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CanvasContext>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::CanvasContext>(self);
}
}
MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("configure", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&configure_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("unconfigure", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&unconfigure_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("getConfiguration", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getConfiguration_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("getCurrentTexture", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getCurrentTexture_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &sMethods_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("canvas", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &canvas_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[5];
static PropertyInfo sNativeProperties_propertyInfos[5];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
5,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[4] }
}
};
static_assert(5 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUCanvasContext,
constructors::id::GPUCanvasContext,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUCanvasContext>::Depth,
prototypes::id::GPUCanvasContext,
true,
0,
"GPUCanvasContext",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUCanvasContextPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUCanvasContext,
PrototypeTraits<prototypes::id::GPUCanvasContext>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUCanvasContext",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::CanvasContext>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUCanvasContext, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::CanvasContext>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::CanvasContext>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::CanvasContext>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::CanvasContext>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::CanvasContext* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::CanvasContext>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::CanvasContext*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::CanvasContext> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUCanvasContext);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUCanvasContext);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUCanvasContext",
ShouldExpose<GPUCanvasContext_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUCanvasContext,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUCanvasContext,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUCanvasContext_Binding
namespace GPUColorWrite_Binding {
MOZ_GLOBINIT static const ConstantSpec sConstants_specs[] = {
{ "RED", JS::NumberValue(1U) },
{ "GREEN", JS::NumberValue(2U) },
{ "BLUE", JS::NumberValue(4U) },
{ "ALPHA", JS::NumberValue(8U) },
{ "ALL", JS::NumberValue(15U) },
{ 0, JS::UndefinedValue() }
};
static const PrefableDisablers sConstants_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const ConstantSpec> sConstants[] = {
{ &sConstants_disablers0, &sConstants_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[5];
static PropertyInfo sNativeProperties_propertyInfos[5];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
false, 0,
false, 0,
false, 0,
true, 0 /* sConstants */,
-1,
5,
sNativeProperties_sortedPropertyIndices,
{
{ sConstants, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(5 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::_ID_Count,
constructors::id::GPUColorWrite,
&DefaultXrayExpandoObjectClass
};
static const DOMIfaceAndProtoJSClass sNamespaceObjectClass = {
{
"GPUColorWrite",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS,
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eNamespace,
prototypes::id::_ID_Count,
0,
&sNativePropertyHooks,
// This isn't strictly following the spec (see
// but should be ok for Xrays.
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!constructorProto) {
return;
}
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUColorWrite);
dom::CreateNamespaceObject(aCx, aGlobal, constructorProto,
sNamespaceObjectClass,
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUColorWrite",
ShouldExpose<GPUColorWrite_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal));
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUColorWrite,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUColorWrite_Binding
namespace GPUCommandBuffer_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCommandBuffer", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CommandBuffer*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCommandBuffer", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CommandBuffer*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPUCommandBuffer },
{ PrototypeTraits<prototypes::id::GPUCommandBuffer>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPUCommandBuffer },
{ PrototypeTraits<prototypes::id::GPUCommandBuffer>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::CommandBuffer* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CommandBuffer>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::CommandBuffer>(self);
}
}
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[1];
static PropertyInfo sNativeProperties_propertyInfos[1];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
1,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(1 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUCommandBuffer,
constructors::id::GPUCommandBuffer,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUCommandBuffer>::Depth,
prototypes::id::GPUCommandBuffer,
true,
0,
"GPUCommandBuffer",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUCommandBufferPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUCommandBuffer,
PrototypeTraits<prototypes::id::GPUCommandBuffer>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUCommandBuffer",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::CommandBuffer>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUCommandBuffer, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::CommandBuffer>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::CommandBuffer>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::CommandBuffer>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::CommandBuffer>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::CommandBuffer* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::CommandBuffer>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::CommandBuffer*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::CommandBuffer> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUCommandBuffer);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUCommandBuffer);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUCommandBuffer",
ShouldExpose<GPUCommandBuffer_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUCommandBuffer,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUCommandBuffer,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUCommandBuffer_Binding
namespace GPUCommandEncoder_Binding {
MOZ_CAN_RUN_SCRIPT static bool
beginRenderPass(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUCommandEncoder.beginRenderPass");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCommandEncoder", "beginRenderPass", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPUCommandEncoder.beginRenderPass", 1)) {
return false;
}
binding_detail::FastGPURenderPassDescriptor arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
auto result(StrongOrRawPtr<mozilla::webgpu::RenderPassEncoder>(MOZ_KnownLive(self)->BeginRenderPass(Constify(arg0))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo beginRenderPass_methodinfo = {
{ (JSJitGetterOp)beginRenderPass },
{ prototypes::id::GPUCommandEncoder },
{ PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
beginComputePass(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUCommandEncoder.beginComputePass");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCommandEncoder", "beginComputePass", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
binding_detail::FastGPUComputePassDescriptor arg0;
if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
return false;
}
auto result(StrongOrRawPtr<mozilla::webgpu::ComputePassEncoder>(MOZ_KnownLive(self)->BeginComputePass(Constify(arg0))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo beginComputePass_methodinfo = {
{ (JSJitGetterOp)beginComputePass },
{ prototypes::id::GPUCommandEncoder },
{ PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
copyBufferToBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUCommandEncoder.copyBufferToBuffer");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCommandEncoder", "copyBufferToBuffer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
unsigned argcount = std::min(args.length(), 5u);
switch (argcount) {
case 2: {
[[fallthrough]];
}
case 3: {
NonNull<mozilla::webgpu::Buffer> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
NonNull<mozilla::webgpu::Buffer> arg1;
if (args[1].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[1], arg1, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
return false;
}
Optional<uint64_t> arg2;
if (args.hasDefined(2)) {
arg2.Construct();
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2.Value())) {
return false;
}
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->CopyBufferToBuffer(MOZ_KnownLive(NonNullHelper(arg0)), MOZ_KnownLive(NonNullHelper(arg1)), Constify(arg2)))>, "Should be returning void here");
MOZ_KnownLive(self)->CopyBufferToBuffer(MOZ_KnownLive(NonNullHelper(arg0)), MOZ_KnownLive(NonNullHelper(arg1)), Constify(arg2));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
break;
}
case 4: {
[[fallthrough]];
}
case 5: {
NonNull<mozilla::webgpu::Buffer> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
uint64_t arg1;
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
return false;
}
NonNull<mozilla::webgpu::Buffer> arg2;
if (args[2].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[2], arg2, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 3", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 3");
return false;
}
uint64_t arg3;
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
return false;
}
Optional<uint64_t> arg4;
if (args.hasDefined(4)) {
arg4.Construct();
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[4], "Argument 5", &arg4.Value())) {
return false;
}
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->CopyBufferToBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, MOZ_KnownLive(NonNullHelper(arg2)), arg3, Constify(arg4)))>, "Should be returning void here");
MOZ_KnownLive(self)->CopyBufferToBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, MOZ_KnownLive(NonNullHelper(arg2)), arg3, Constify(arg4));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
break;
}
default: {
// Using nsPrintfCString here would require including that
// header. Let's not worry about it.
nsAutoCString argCountStr;
argCountStr.AppendPrintf("%u", args.length());
return cx.ThrowErrorMessage<MSG_INVALID_OVERLOAD_ARGCOUNT>(argCountStr.get());
}
}
MOZ_CRASH("We have an always-returning default case");
return false;
}
static const JSJitInfo copyBufferToBuffer_methodinfo = {
{ (JSJitGetterOp)copyBufferToBuffer },
{ prototypes::id::GPUCommandEncoder },
{ PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
copyBufferToTexture(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUCommandEncoder.copyBufferToTexture");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCommandEncoder", "copyBufferToTexture", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPUCommandEncoder.copyBufferToTexture", 3)) {
return false;
}
binding_detail::FastGPUTexelCopyBufferInfo arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
binding_detail::FastGPUTexelCopyTextureInfo arg1;
if (!arg1.Init(cx, args[1], "Argument 2", false)) {
return false;
}
RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict arg2;
if (!arg2.Init(cx, args[2], "Argument 3", false)) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->CopyBufferToTexture(Constify(arg0), Constify(arg1), Constify(arg2)))>, "Should be returning void here");
MOZ_KnownLive(self)->CopyBufferToTexture(Constify(arg0), Constify(arg1), Constify(arg2));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo copyBufferToTexture_methodinfo = {
{ (JSJitGetterOp)copyBufferToTexture },
{ prototypes::id::GPUCommandEncoder },
{ PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
copyTextureToBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUCommandEncoder.copyTextureToBuffer");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCommandEncoder", "copyTextureToBuffer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPUCommandEncoder.copyTextureToBuffer", 3)) {
return false;
}
binding_detail::FastGPUTexelCopyTextureInfo arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
binding_detail::FastGPUTexelCopyBufferInfo arg1;
if (!arg1.Init(cx, args[1], "Argument 2", false)) {
return false;
}
RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict arg2;
if (!arg2.Init(cx, args[2], "Argument 3", false)) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->CopyTextureToBuffer(Constify(arg0), Constify(arg1), Constify(arg2)))>, "Should be returning void here");
MOZ_KnownLive(self)->CopyTextureToBuffer(Constify(arg0), Constify(arg1), Constify(arg2));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo copyTextureToBuffer_methodinfo = {
{ (JSJitGetterOp)copyTextureToBuffer },
{ prototypes::id::GPUCommandEncoder },
{ PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
copyTextureToTexture(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUCommandEncoder.copyTextureToTexture");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCommandEncoder", "copyTextureToTexture", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPUCommandEncoder.copyTextureToTexture", 3)) {
return false;
}
binding_detail::FastGPUTexelCopyTextureInfo arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
binding_detail::FastGPUTexelCopyTextureInfo arg1;
if (!arg1.Init(cx, args[1], "Argument 2", false)) {
return false;
}
RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict arg2;
if (!arg2.Init(cx, args[2], "Argument 3", false)) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->CopyTextureToTexture(Constify(arg0), Constify(arg1), Constify(arg2)))>, "Should be returning void here");
MOZ_KnownLive(self)->CopyTextureToTexture(Constify(arg0), Constify(arg1), Constify(arg2));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo copyTextureToTexture_methodinfo = {
{ (JSJitGetterOp)copyTextureToTexture },
{ prototypes::id::GPUCommandEncoder },
{ PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
clearBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUCommandEncoder.clearBuffer");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCommandEncoder", "clearBuffer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPUCommandEncoder.clearBuffer", 1)) {
return false;
}
NonNull<mozilla::webgpu::Buffer> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
uint64_t arg1;
if (args.hasDefined(1)) {
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
return false;
}
} else {
arg1 = 0ULL;
}
Optional<uint64_t> arg2;
if (args.hasDefined(2)) {
arg2.Construct();
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2.Value())) {
return false;
}
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->ClearBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, Constify(arg2)))>, "Should be returning void here");
MOZ_KnownLive(self)->ClearBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, Constify(arg2));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo clearBuffer_methodinfo = {
{ (JSJitGetterOp)clearBuffer },
{ prototypes::id::GPUCommandEncoder },
{ PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
resolveQuerySet(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUCommandEncoder.resolveQuerySet");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCommandEncoder", "resolveQuerySet", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPUCommandEncoder.resolveQuerySet", 5)) {
return false;
}
NonNull<mozilla::webgpu::QuerySet> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUQuerySet, mozilla::webgpu::QuerySet>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUQuerySet");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
uint32_t arg1;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
return false;
}
uint32_t arg2;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
return false;
}
NonNull<mozilla::webgpu::Buffer> arg3;
if (args[3].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[3], arg3, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 4", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 4");
return false;
}
uint64_t arg4;
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[4], "Argument 5", &arg4)) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->ResolveQuerySet(MOZ_KnownLive(NonNullHelper(arg0)), arg1, arg2, MOZ_KnownLive(NonNullHelper(arg3)), arg4))>, "Should be returning void here");
MOZ_KnownLive(self)->ResolveQuerySet(MOZ_KnownLive(NonNullHelper(arg0)), arg1, arg2, MOZ_KnownLive(NonNullHelper(arg3)), arg4);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo resolveQuerySet_methodinfo = {
{ (JSJitGetterOp)resolveQuerySet },
{ prototypes::id::GPUCommandEncoder },
{ PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
finish(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUCommandEncoder.finish");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCommandEncoder", "finish", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
binding_detail::FastGPUCommandBufferDescriptor arg0;
if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
return false;
}
auto result(StrongOrRawPtr<mozilla::webgpu::CommandBuffer>(MOZ_KnownLive(self)->Finish(Constify(arg0))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo finish_methodinfo = {
{ (JSJitGetterOp)finish },
{ prototypes::id::GPUCommandEncoder },
{ PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
pushDebugGroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCommandEncoder", "pushDebugGroup", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPUCommandEncoder.pushDebugGroup", 1)) {
return false;
}
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->PushDebugGroup(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->PushDebugGroup(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo pushDebugGroup_methodinfo = {
{ (JSJitGetterOp)pushDebugGroup },
{ prototypes::id::GPUCommandEncoder },
{ PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
popDebugGroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCommandEncoder", "popDebugGroup", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->PopDebugGroup())>, "Should be returning void here");
MOZ_KnownLive(self)->PopDebugGroup();
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo popDebugGroup_methodinfo = {
{ (JSJitGetterOp)popDebugGroup },
{ prototypes::id::GPUCommandEncoder },
{ PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
insertDebugMarker(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCommandEncoder", "insertDebugMarker", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPUCommandEncoder.insertDebugMarker", 1)) {
return false;
}
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->InsertDebugMarker(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->InsertDebugMarker(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo insertDebugMarker_methodinfo = {
{ (JSJitGetterOp)insertDebugMarker },
{ prototypes::id::GPUCommandEncoder },
{ PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCommandEncoder", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCommandEncoder", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CommandEncoder*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPUCommandEncoder },
{ PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPUCommandEncoder },
{ PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::CommandEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CommandEncoder>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::CommandEncoder>(self);
}
}
MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("beginRenderPass", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&beginRenderPass_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("beginComputePass", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&beginComputePass_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("copyBufferToBuffer", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&copyBufferToBuffer_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("copyBufferToTexture", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&copyBufferToTexture_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("copyTextureToBuffer", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&copyTextureToBuffer_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("copyTextureToTexture", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&copyTextureToTexture_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("clearBuffer", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&clearBuffer_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("resolveQuerySet", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&resolveQuerySet_methodinfo), 5, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("finish", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&finish_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FS_END,
JS_FNSPEC("pushDebugGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&pushDebugGroup_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("popDebugGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&popDebugGroup_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("insertDebugMarker", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&insertDebugMarker_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &sMethods_specs[0] },
{ nullptr, &sMethods_specs[10] },
{ nullptr, nullptr }
};
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(9 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[13];
static PropertyInfo sNativeProperties_propertyInfos[13];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
13,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[12] }
}
};
static_assert(13 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUCommandEncoder,
constructors::id::GPUCommandEncoder,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth,
prototypes::id::GPUCommandEncoder,
true,
0,
"GPUCommandEncoder",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUCommandEncoderPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUCommandEncoder,
PrototypeTraits<prototypes::id::GPUCommandEncoder>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUCommandEncoder",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::CommandEncoder>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUCommandEncoder, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::CommandEncoder>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::CommandEncoder>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::CommandEncoder>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::CommandEncoder>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::CommandEncoder* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::CommandEncoder>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::CommandEncoder*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::CommandEncoder> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUCommandEncoder);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUCommandEncoder);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUCommandEncoder",
ShouldExpose<GPUCommandEncoder_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUCommandEncoder,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUCommandEncoder,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUCommandEncoder_Binding
namespace GPUCompilationInfo_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_messages(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCompilationInfo", "messages", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CompilationInfo*>(void_self);
// Have to either root across the getter call or reget after.
bool isXray;
JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
if (!slotStorage) {
return false;
}
const size_t slotIndex = isXray ? (DOM_EXPANDO_RESERVED_SLOTS + 0) : (DOM_INSTANCE_RESERVED_SLOTS + 0);
MOZ_ASSERT(slotIndex < JSCLASS_RESERVED_SLOTS(JS::GetClass(slotStorage)));
{
// Scope for cachedVal
JS::Value cachedVal = JS::GetReservedSlot(slotStorage, slotIndex);
if (!cachedVal.isUndefined()) {
args.rval().set(cachedVal);
// The cached value is in the compartment of slotStorage,
// so wrap into the caller compartment as needed.
return MaybeWrapNonDOMObjectValue(cx, args.rval());
}
}
nsTArray<StrongPtrForMember<mozilla::webgpu::CompilationMessage>> result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetMessages(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetMessages(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
{
JS::Rooted<JSObject*> conversionScope(cx, isXray ? JS::CurrentGlobalOrNull(cx) : slotStorage);
JSAutoRealm ar(cx, conversionScope);
do { // block we break out of when done wrapping
uint32_t length = result.Length();
JS::Rooted<JSObject*> returnArray(cx, JS::NewArrayObject(cx, length));
if (!returnArray) {
return false;
}
// Scope for 'tmp'
{
JS::Rooted<JS::Value> tmp(cx);
for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
// Control block to let us common up the JS_DefineElement calls when there
// are different ways to succeed at wrapping the object.
do {
if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
break;
} while (false);
if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
JSPROP_ENUMERATE)) {
return false;
}
}
}
args.rval().setObject(*returnArray);
break;
} while (false);
JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
if (!JS_FreezeObject(cx, rvalObj)) {
return false;
}
}
{ // And now store things in the realm of our slotStorage.
JSAutoRealm ar(cx, slotStorage);
// Make a copy so that we don't do unnecessary wrapping on args.rval().
JS::Rooted<JS::Value> storedVal(cx, args.rval());
if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
return false;
}
JS::SetReservedSlot(slotStorage, slotIndex, storedVal);
if (!isXray) {
// In the Xray case we don't need to do this, because getting the
// expando object already preserved our wrapper.
PreserveWrapper(self);
}
}
// And now make sure args.rval() is in the caller realm.
return MaybeWrapNonDOMObjectValue(cx, args.rval());
}
static const JSJitInfo messages_getterinfo = {
{ get_messages },
{ prototypes::id::GPUCompilationInfo },
{ PrototypeTraits<prototypes::id::GPUCompilationInfo>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
true, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
(DOM_INSTANCE_RESERVED_SLOTS + 0) /* Reserved slot index, if we're stored in a slot, else 0. */
};
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit");
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 2, "There is no slot for us");
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::CompilationInfo* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CompilationInfo>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::CompilationInfo>(self);
}
}
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("messages", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &messages_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[1];
static PropertyInfo sNativeProperties_propertyInfos[1];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
1,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(1 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
// This may allocate too many slots, because we only really need
// slots for our non-interface-typed members that we cache. But
// allocating slots only for those would make the slot index
// computations much more complicated, so let's do this the simple
// way for now.
DEFINE_XRAY_EXPANDO_CLASS_WITH_OPS(static, sXrayExpandoObjectClass, 1,
&xpc::XrayExpandoObjectClassOps);
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUCompilationInfo,
constructors::id::GPUCompilationInfo,
&sXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUCompilationInfo>::Depth,
prototypes::id::GPUCompilationInfo,
true,
0,
"GPUCompilationInfo",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUCompilationInfoPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUCompilationInfo,
PrototypeTraits<prototypes::id::GPUCompilationInfo>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUCompilationInfo",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::CompilationInfo>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUCompilationInfo, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::CompilationInfo>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::CompilationInfo>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::CompilationInfo>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::CompilationInfo>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(2 >= 2,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::CompilationInfo* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::CompilationInfo>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::CompilationInfo*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::CompilationInfo> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
ClearCachedMessagesValue(mozilla::webgpu::CompilationInfo* aObject)
{
JSObject* obj;
obj = aObject->GetWrapper();
if (!obj) {
return;
}
JS::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), JS::UndefinedValue());
ClearXrayExpandoSlots(RootingCx(), obj, (DOM_EXPANDO_RESERVED_SLOTS + 0));
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUCompilationInfo);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUCompilationInfo);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUCompilationInfo",
ShouldExpose<GPUCompilationInfo_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUCompilationInfo,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUCompilationInfo,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUCompilationInfo_Binding
namespace GPUCompilationMessage_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_message(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCompilationMessage", "message", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CompilationMessage*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetMessage(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetMessage(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo message_getterinfo = {
{ get_message },
{ prototypes::id::GPUCompilationMessage },
{ PrototypeTraits<prototypes::id::GPUCompilationMessage>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_type(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCompilationMessage", "type", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CompilationMessage*>(void_self);
GPUCompilationMessageType result(MOZ_KnownLive(self)->Type());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo type_getterinfo = {
{ get_type },
{ prototypes::id::GPUCompilationMessage },
{ PrototypeTraits<prototypes::id::GPUCompilationMessage>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_lineNum(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCompilationMessage", "lineNum", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CompilationMessage*>(void_self);
uint64_t result(MOZ_KnownLive(self)->LineNum());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().set(JS_NumberValue(double(result)));
return true;
}
static const JSJitInfo lineNum_getterinfo = {
{ get_lineNum },
{ prototypes::id::GPUCompilationMessage },
{ PrototypeTraits<prototypes::id::GPUCompilationMessage>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_linePos(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCompilationMessage", "linePos", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CompilationMessage*>(void_self);
uint64_t result(MOZ_KnownLive(self)->LinePos());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().set(JS_NumberValue(double(result)));
return true;
}
static const JSJitInfo linePos_getterinfo = {
{ get_linePos },
{ prototypes::id::GPUCompilationMessage },
{ PrototypeTraits<prototypes::id::GPUCompilationMessage>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_offset(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCompilationMessage", "offset", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CompilationMessage*>(void_self);
uint64_t result(MOZ_KnownLive(self)->Offset());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().set(JS_NumberValue(double(result)));
return true;
}
static const JSJitInfo offset_getterinfo = {
{ get_offset },
{ prototypes::id::GPUCompilationMessage },
{ PrototypeTraits<prototypes::id::GPUCompilationMessage>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_length(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUCompilationMessage", "length", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::CompilationMessage*>(void_self);
uint64_t result(MOZ_KnownLive(self)->Length());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().set(JS_NumberValue(double(result)));
return true;
}
static const JSJitInfo length_getterinfo = {
{ get_length },
{ prototypes::id::GPUCompilationMessage },
{ PrototypeTraits<prototypes::id::GPUCompilationMessage>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::CompilationMessage* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::CompilationMessage>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::CompilationMessage>(self);
}
}
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("message", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &message_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("type", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &type_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("lineNum", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &lineNum_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("linePos", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &linePos_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("offset", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &offset_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("length", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &length_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(6 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[6];
static PropertyInfo sNativeProperties_propertyInfos[6];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
6,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(6 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUCompilationMessage,
constructors::id::GPUCompilationMessage,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUCompilationMessage>::Depth,
prototypes::id::GPUCompilationMessage,
true,
0,
"GPUCompilationMessage",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUCompilationMessagePrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUCompilationMessage,
PrototypeTraits<prototypes::id::GPUCompilationMessage>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUCompilationMessage",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::CompilationMessage>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUCompilationMessage, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::CompilationMessage>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::CompilationMessage>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::CompilationMessage>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::CompilationMessage>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::CompilationMessage* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::CompilationMessage>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::CompilationMessage*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::CompilationMessage> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUCompilationMessage);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUCompilationMessage);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUCompilationMessage",
ShouldExpose<GPUCompilationMessage_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUCompilationMessage,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUCompilationMessage,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUCompilationMessage_Binding
namespace GPUComputePassEncoder_Binding {
MOZ_CAN_RUN_SCRIPT static bool
setPipeline(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUComputePassEncoder.setPipeline");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUComputePassEncoder", "setPipeline", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPUComputePassEncoder.setPipeline", 1)) {
return false;
}
NonNull<mozilla::webgpu::ComputePipeline> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUComputePipeline, mozilla::webgpu::ComputePipeline>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUComputePipeline");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetPipeline(MOZ_KnownLive(NonNullHelper(arg0))))>, "Should be returning void here");
MOZ_KnownLive(self)->SetPipeline(MOZ_KnownLive(NonNullHelper(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo setPipeline_methodinfo = {
{ (JSJitGetterOp)setPipeline },
{ prototypes::id::GPUComputePassEncoder },
{ PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
dispatchWorkgroups(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUComputePassEncoder.dispatchWorkgroups");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUComputePassEncoder", "dispatchWorkgroups", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPUComputePassEncoder.dispatchWorkgroups", 1)) {
return false;
}
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
uint32_t arg1;
if (args.hasDefined(1)) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
return false;
}
} else {
arg1 = 1U;
}
uint32_t arg2;
if (args.hasDefined(2)) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
return false;
}
} else {
arg2 = 1U;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->DispatchWorkgroups(arg0, arg1, arg2))>, "Should be returning void here");
MOZ_KnownLive(self)->DispatchWorkgroups(arg0, arg1, arg2);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo dispatchWorkgroups_methodinfo = {
{ (JSJitGetterOp)dispatchWorkgroups },
{ prototypes::id::GPUComputePassEncoder },
{ PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
dispatchWorkgroupsIndirect(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUComputePassEncoder.dispatchWorkgroupsIndirect");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUComputePassEncoder", "dispatchWorkgroupsIndirect", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPUComputePassEncoder.dispatchWorkgroupsIndirect", 2)) {
return false;
}
NonNull<mozilla::webgpu::Buffer> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
uint64_t arg1;
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->DispatchWorkgroupsIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1))>, "Should be returning void here");
MOZ_KnownLive(self)->DispatchWorkgroupsIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo dispatchWorkgroupsIndirect_methodinfo = {
{ (JSJitGetterOp)dispatchWorkgroupsIndirect },
{ prototypes::id::GPUComputePassEncoder },
{ PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
end(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUComputePassEncoder", "end", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->End())>, "Should be returning void here");
MOZ_KnownLive(self)->End();
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo end_methodinfo = {
{ (JSJitGetterOp)end },
{ prototypes::id::GPUComputePassEncoder },
{ PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
setBindGroup(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUComputePassEncoder.setBindGroup");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUComputePassEncoder", "setBindGroup", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
unsigned argcount = std::min(args.length(), 5u);
switch (argcount) {
case 2: {
[[fallthrough]];
}
case 3: {
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
mozilla::webgpu::BindGroup* arg1;
if (args[1].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBindGroup, mozilla::webgpu::BindGroup>(args[1], arg1, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "GPUBindGroup");
return false;
}
}
} else if (args[1].isNullOrUndefined()) {
arg1 = nullptr;
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
return false;
}
binding_detail::AutoSequence<uint32_t> arg2;
if (args.hasDefined(2)) {
if (args[2].isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(args[2], JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 3", "sequence");
return false;
}
binding_detail::AutoSequence<uint32_t> &arr = arg2;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
uint32_t& slot = *slotPtr;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp, "Element of argument 3", &slot)) {
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 3", "sequence");
return false;
}
} else {
/* arg2 array is already empty; nothing to do */
}
FastErrorResult rv;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), rv))>, "Should be returning void here");
MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUComputePassEncoder.setBindGroup"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
break;
}
case 5: {
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
mozilla::webgpu::BindGroup* arg1;
if (args[1].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBindGroup, mozilla::webgpu::BindGroup>(args[1], arg1, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "GPUBindGroup");
return false;
}
}
} else if (args[1].isNullOrUndefined()) {
arg1 = nullptr;
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
return false;
}
RootedSpiderMonkeyInterface<Uint32Array> arg2(cx);
if (args[2].isObject()) {
if (!arg2.Init(&args[2].toObject())) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 3", "Uint32Array");
return false;
}
if (JS::IsLargeArrayBufferView(arg2.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("Argument 3");
return false;
}
if (JS::IsResizableArrayBufferView(arg2.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("Argument 3");
return false;
}
if (JS::IsImmutableArrayBufferView(arg2.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_IMMUTABLE>("Argument 3");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 3");
return false;
}
uint64_t arg3;
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
return false;
}
uint32_t arg4;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[4], "Argument 5", &arg4)) {
return false;
}
FastErrorResult rv;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), arg3, arg4, rv))>, "Should be returning void here");
MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), arg3, arg4, rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUComputePassEncoder.setBindGroup"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
break;
}
default: {
// Using nsPrintfCString here would require including that
// header. Let's not worry about it.
nsAutoCString argCountStr;
argCountStr.AppendPrintf("%u", args.length());
return cx.ThrowErrorMessage<MSG_INVALID_OVERLOAD_ARGCOUNT>(argCountStr.get());
}
}
MOZ_CRASH("We have an always-returning default case");
return false;
}
static const JSJitInfo setBindGroup_methodinfo = {
{ (JSJitGetterOp)setBindGroup },
{ prototypes::id::GPUComputePassEncoder },
{ PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
pushDebugGroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUComputePassEncoder", "pushDebugGroup", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPUComputePassEncoder.pushDebugGroup", 1)) {
return false;
}
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->PushDebugGroup(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->PushDebugGroup(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo pushDebugGroup_methodinfo = {
{ (JSJitGetterOp)pushDebugGroup },
{ prototypes::id::GPUComputePassEncoder },
{ PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
popDebugGroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUComputePassEncoder", "popDebugGroup", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->PopDebugGroup())>, "Should be returning void here");
MOZ_KnownLive(self)->PopDebugGroup();
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo popDebugGroup_methodinfo = {
{ (JSJitGetterOp)popDebugGroup },
{ prototypes::id::GPUComputePassEncoder },
{ PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
insertDebugMarker(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUComputePassEncoder", "insertDebugMarker", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPUComputePassEncoder.insertDebugMarker", 1)) {
return false;
}
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->InsertDebugMarker(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->InsertDebugMarker(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo insertDebugMarker_methodinfo = {
{ (JSJitGetterOp)insertDebugMarker },
{ prototypes::id::GPUComputePassEncoder },
{ PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUComputePassEncoder", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUComputePassEncoder", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::ComputePassEncoder*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPUComputePassEncoder },
{ PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPUComputePassEncoder },
{ PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::ComputePassEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ComputePassEncoder>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::ComputePassEncoder>(self);
}
}
MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("setPipeline", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setPipeline_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("dispatchWorkgroups", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&dispatchWorkgroups_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("dispatchWorkgroupsIndirect", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&dispatchWorkgroupsIndirect_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("end", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&end_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FS_END,
JS_FNSPEC("setBindGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setBindGroup_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("pushDebugGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&pushDebugGroup_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("popDebugGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&popDebugGroup_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("insertDebugMarker", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&insertDebugMarker_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &sMethods_specs[0] },
{ nullptr, &sMethods_specs[5] },
{ nullptr, nullptr }
};
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[9];
static PropertyInfo sNativeProperties_propertyInfos[9];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
9,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[8] }
}
};
static_assert(9 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUComputePassEncoder,
constructors::id::GPUComputePassEncoder,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth,
prototypes::id::GPUComputePassEncoder,
true,
0,
"GPUComputePassEncoder",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUComputePassEncoderPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUComputePassEncoder,
PrototypeTraits<prototypes::id::GPUComputePassEncoder>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUComputePassEncoder",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::ComputePassEncoder>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUComputePassEncoder, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::ComputePassEncoder>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::ComputePassEncoder>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::ComputePassEncoder>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::ComputePassEncoder>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::ComputePassEncoder* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::ComputePassEncoder>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::ComputePassEncoder*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::ComputePassEncoder> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUComputePassEncoder);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUComputePassEncoder);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUComputePassEncoder",
ShouldExpose<GPUComputePassEncoder_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUComputePassEncoder,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUComputePassEncoder,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUComputePassEncoder_Binding
namespace GPUComputePipeline_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUComputePipeline", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::ComputePipeline*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUComputePipeline", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::ComputePipeline*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPUComputePipeline },
{ PrototypeTraits<prototypes::id::GPUComputePipeline>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPUComputePipeline },
{ PrototypeTraits<prototypes::id::GPUComputePipeline>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
getBindGroupLayout(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUComputePipeline", "getBindGroupLayout", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::ComputePipeline*>(void_self);
if (!args.requireAtLeast(cx, "GPUComputePipeline.getBindGroupLayout", 1)) {
return false;
}
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
auto result(StrongOrRawPtr<mozilla::webgpu::BindGroupLayout>(MOZ_KnownLive(self)->GetBindGroupLayout(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo getBindGroupLayout_methodinfo = {
{ (JSJitGetterOp)getBindGroupLayout },
{ prototypes::id::GPUComputePipeline },
{ PrototypeTraits<prototypes::id::GPUComputePipeline>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::ComputePipeline* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ComputePipeline>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::ComputePipeline>(self);
}
}
MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("getBindGroupLayout", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getBindGroupLayout_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ nullptr, &sMethods_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[2];
static PropertyInfo sNativeProperties_propertyInfos[2];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
2,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[1] }
}
};
static_assert(2 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUComputePipeline,
constructors::id::GPUComputePipeline,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUComputePipeline>::Depth,
prototypes::id::GPUComputePipeline,
true,
0,
"GPUComputePipeline",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUComputePipelinePrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUComputePipeline,
PrototypeTraits<prototypes::id::GPUComputePipeline>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUComputePipeline",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::ComputePipeline>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUComputePipeline, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::ComputePipeline>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::ComputePipeline>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::ComputePipeline>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::ComputePipeline>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::ComputePipeline* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::ComputePipeline>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::ComputePipeline*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::ComputePipeline> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUComputePipeline);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUComputePipeline);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUComputePipeline",
ShouldExpose<GPUComputePipeline_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUComputePipeline,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUComputePipeline,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUComputePipeline_Binding
namespace GPUDevice_Binding {
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventTarget_Binding::NativeType>::value,
"Can't inherit from an interface with a different ownership model.");
MOZ_CAN_RUN_SCRIPT static bool
get_features(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "features", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
auto result(StrongOrRawPtr<mozilla::webgpu::SupportedFeatures>(MOZ_KnownLive(self)->Features()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo features_getterinfo = {
{ get_features },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_limits(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "limits", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
auto result(StrongOrRawPtr<mozilla::webgpu::SupportedLimits>(MOZ_KnownLive(self)->Limits()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo limits_getterinfo = {
{ get_limits },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_adapterInfo(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "adapterInfo", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
auto result(StrongOrRawPtr<mozilla::webgpu::AdapterInfo>(MOZ_KnownLive(self)->GetAdapterInfo()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo adapterInfo_getterinfo = {
{ get_adapterInfo },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_queue(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "queue", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
auto result(StrongOrRawPtr<mozilla::webgpu::Queue>(MOZ_KnownLive(self)->GetQueue()));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo queue_getterinfo = {
{ get_queue },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
true, /* isMovable. Not relevant for setters. */
true, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
destroy(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "destroy", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Destroy())>, "Should be returning void here");
MOZ_KnownLive(self)->Destroy();
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo destroy_methodinfo = {
{ (JSJitGetterOp)destroy },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
createBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUDevice.createBuffer");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "createBuffer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
if (!args.requireAtLeast(cx, "GPUDevice.createBuffer", 1)) {
return false;
}
binding_detail::FastGPUBufferDescriptor arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
FastErrorResult rv;
auto result(StrongOrRawPtr<mozilla::webgpu::Buffer>(MOZ_KnownLive(self)->CreateBuffer(Constify(arg0), rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUDevice.createBuffer"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo createBuffer_methodinfo = {
{ (JSJitGetterOp)createBuffer },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
createTexture(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUDevice.createTexture");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "createTexture", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
if (!args.requireAtLeast(cx, "GPUDevice.createTexture", 1)) {
return false;
}
binding_detail::FastGPUTextureDescriptor arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
auto result(StrongOrRawPtr<mozilla::webgpu::Texture>(MOZ_KnownLive(self)->CreateTexture(Constify(arg0))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo createTexture_methodinfo = {
{ (JSJitGetterOp)createTexture },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
importExternalTexture(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUDevice.importExternalTexture");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "importExternalTexture", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
if (!args.requireAtLeast(cx, "GPUDevice.importExternalTexture", 1)) {
return false;
}
binding_detail::FastGPUExternalTextureDescriptor arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
FastErrorResult rv;
auto result(StrongOrRawPtr<mozilla::webgpu::ExternalTexture>(MOZ_KnownLive(self)->ImportExternalTexture(Constify(arg0), rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUDevice.importExternalTexture"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo importExternalTexture_methodinfo = {
{ (JSJitGetterOp)importExternalTexture },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
createSampler(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUDevice.createSampler");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "createSampler", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
binding_detail::FastGPUSamplerDescriptor arg0;
if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
return false;
}
auto result(StrongOrRawPtr<mozilla::webgpu::Sampler>(MOZ_KnownLive(self)->CreateSampler(Constify(arg0))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo createSampler_methodinfo = {
{ (JSJitGetterOp)createSampler },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
createBindGroupLayout(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUDevice.createBindGroupLayout");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "createBindGroupLayout", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
if (!args.requireAtLeast(cx, "GPUDevice.createBindGroupLayout", 1)) {
return false;
}
binding_detail::FastGPUBindGroupLayoutDescriptor arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
auto result(StrongOrRawPtr<mozilla::webgpu::BindGroupLayout>(MOZ_KnownLive(self)->CreateBindGroupLayout(Constify(arg0))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo createBindGroupLayout_methodinfo = {
{ (JSJitGetterOp)createBindGroupLayout },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
createPipelineLayout(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUDevice.createPipelineLayout");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "createPipelineLayout", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
if (!args.requireAtLeast(cx, "GPUDevice.createPipelineLayout", 1)) {
return false;
}
binding_detail::FastGPUPipelineLayoutDescriptor arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
auto result(StrongOrRawPtr<mozilla::webgpu::PipelineLayout>(MOZ_KnownLive(self)->CreatePipelineLayout(Constify(arg0))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo createPipelineLayout_methodinfo = {
{ (JSJitGetterOp)createPipelineLayout },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
createBindGroup(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUDevice.createBindGroup");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "createBindGroup", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
if (!args.requireAtLeast(cx, "GPUDevice.createBindGroup", 1)) {
return false;
}
binding_detail::FastGPUBindGroupDescriptor arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
auto result(StrongOrRawPtr<mozilla::webgpu::BindGroup>(MOZ_KnownLive(self)->CreateBindGroup(Constify(arg0))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo createBindGroup_methodinfo = {
{ (JSJitGetterOp)createBindGroup },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
createShaderModule(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUDevice.createShaderModule");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "createShaderModule", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
if (!args.requireAtLeast(cx, "GPUDevice.createShaderModule", 1)) {
return false;
}
binding_detail::FastGPUShaderModuleDescriptor arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
FastErrorResult rv;
auto result(StrongOrRawPtr<mozilla::webgpu::ShaderModule>(MOZ_KnownLive(self)->CreateShaderModule(Constify(arg0), rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUDevice.createShaderModule"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo createShaderModule_methodinfo = {
{ (JSJitGetterOp)createShaderModule },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
createComputePipeline(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUDevice.createComputePipeline");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "createComputePipeline", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
if (!args.requireAtLeast(cx, "GPUDevice.createComputePipeline", 1)) {
return false;
}
binding_detail::FastGPUComputePipelineDescriptor arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
auto result(StrongOrRawPtr<mozilla::webgpu::ComputePipeline>(MOZ_KnownLive(self)->CreateComputePipeline(Constify(arg0))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo createComputePipeline_methodinfo = {
{ (JSJitGetterOp)createComputePipeline },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
createRenderPipeline(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUDevice.createRenderPipeline");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "createRenderPipeline", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
if (!args.requireAtLeast(cx, "GPUDevice.createRenderPipeline", 1)) {
return false;
}
binding_detail::FastGPURenderPipelineDescriptor arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
auto result(StrongOrRawPtr<mozilla::webgpu::RenderPipeline>(MOZ_KnownLive(self)->CreateRenderPipeline(Constify(arg0))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo createRenderPipeline_methodinfo = {
{ (JSJitGetterOp)createRenderPipeline },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
createComputePipelineAsync(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUDevice.createComputePipelineAsync");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "createComputePipelineAsync", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
if (!args.requireAtLeast(cx, "GPUDevice.createComputePipelineAsync", 1)) {
return false;
}
binding_detail::FastGPUComputePipelineDescriptor arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
FastErrorResult rv;
auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->CreateComputePipelineAsync(Constify(arg0), rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUDevice.createComputePipelineAsync"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
createComputePipelineAsync_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
bool ok = createComputePipelineAsync(cx, obj, void_self, args);
if (ok) {
return true;
}
return ConvertExceptionToPromise(cx, args.rval());
}
static const JSJitInfo createComputePipelineAsync_methodinfo = {
{ (JSJitGetterOp)createComputePipelineAsync_promiseWrapper },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
createRenderPipelineAsync(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUDevice.createRenderPipelineAsync");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "createRenderPipelineAsync", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
if (!args.requireAtLeast(cx, "GPUDevice.createRenderPipelineAsync", 1)) {
return false;
}
binding_detail::FastGPURenderPipelineDescriptor arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
FastErrorResult rv;
auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->CreateRenderPipelineAsync(Constify(arg0), rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUDevice.createRenderPipelineAsync"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
createRenderPipelineAsync_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
bool ok = createRenderPipelineAsync(cx, obj, void_self, args);
if (ok) {
return true;
}
return ConvertExceptionToPromise(cx, args.rval());
}
static const JSJitInfo createRenderPipelineAsync_methodinfo = {
{ (JSJitGetterOp)createRenderPipelineAsync_promiseWrapper },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
createCommandEncoder(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUDevice.createCommandEncoder");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "createCommandEncoder", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
binding_detail::FastGPUCommandEncoderDescriptor arg0;
if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
return false;
}
auto result(StrongOrRawPtr<mozilla::webgpu::CommandEncoder>(MOZ_KnownLive(self)->CreateCommandEncoder(Constify(arg0))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo createCommandEncoder_methodinfo = {
{ (JSJitGetterOp)createCommandEncoder },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
createRenderBundleEncoder(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUDevice.createRenderBundleEncoder");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "createRenderBundleEncoder", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
if (!args.requireAtLeast(cx, "GPUDevice.createRenderBundleEncoder", 1)) {
return false;
}
binding_detail::FastGPURenderBundleEncoderDescriptor arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
auto result(StrongOrRawPtr<mozilla::webgpu::RenderBundleEncoder>(MOZ_KnownLive(self)->CreateRenderBundleEncoder(Constify(arg0))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo createRenderBundleEncoder_methodinfo = {
{ (JSJitGetterOp)createRenderBundleEncoder },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
createQuerySet(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUDevice.createQuerySet");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "createQuerySet", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
if (!args.requireAtLeast(cx, "GPUDevice.createQuerySet", 1)) {
return false;
}
binding_detail::FastGPUQuerySetDescriptor arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
FastErrorResult rv;
auto result(StrongOrRawPtr<mozilla::webgpu::QuerySet>(MOZ_KnownLive(self)->CreateQuerySet(Constify(arg0), rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUDevice.createQuerySet"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo createQuerySet_methodinfo = {
{ (JSJitGetterOp)createQuerySet },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_lost(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "lost", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
FastErrorResult rv;
auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->GetLost(rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUDevice.lost getter"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
get_lost_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
bool ok = get_lost(cx, obj, void_self, args);
if (ok) {
return true;
}
return ConvertExceptionToPromise(cx, args.rval());
}
static const JSJitInfo lost_getterinfo = {
{ get_lost_promiseWrapper },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
pushErrorScope(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUDevice.pushErrorScope");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "pushErrorScope", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
if (!args.requireAtLeast(cx, "GPUDevice.pushErrorScope", 1)) {
return false;
}
GPUErrorFilter arg0;
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, args[0],
binding_detail::EnumStrings<GPUErrorFilter>::Values,
"GPUErrorFilter", "argument 1",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
arg0 = static_cast<GPUErrorFilter>(index);
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->PushErrorScope(arg0))>, "Should be returning void here");
MOZ_KnownLive(self)->PushErrorScope(arg0);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo pushErrorScope_methodinfo = {
{ (JSJitGetterOp)pushErrorScope },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
popErrorScope(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "popErrorScope", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
FastErrorResult rv;
auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->PopErrorScope(rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUDevice.popErrorScope"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
popErrorScope_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
bool ok = popErrorScope(cx, obj, void_self, args);
if (ok) {
return true;
}
return ConvertExceptionToPromise(cx, args.rval());
}
static const JSJitInfo popErrorScope_methodinfo = {
{ (JSJitGetterOp)popErrorScope_promiseWrapper },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_onuncapturederror(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "onuncapturederror", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
RefPtr<EventHandlerNonNull> result(MOZ_KnownLive(self)->GetOnuncapturederror());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (result) {
args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
return false;
}
return true;
} else {
args.rval().setNull();
return true;
}
}
MOZ_CAN_RUN_SCRIPT static bool
set_onuncapturederror(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "onuncapturederror", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
if (args[0].isObject()) {
{ // scope for tempRoot and tempGlobalRoot if needed
arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
}
} else {
arg0 = nullptr;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetOnuncapturederror(MOZ_KnownLive(Constify(arg0))))>, "Should be returning void here");
MOZ_KnownLive(self)->SetOnuncapturederror(MOZ_KnownLive(Constify(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo onuncapturederror_getterinfo = {
{ get_onuncapturederror },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo onuncapturederror_setterinfo = {
{ (JSJitGetterOp)set_onuncapturederror },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDevice", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Device*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPUDevice },
{ PrototypeTraits<prototypes::id::GPUDevice>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::Device* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Device>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::Device>(self);
}
}
MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("destroy", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&destroy_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("createBuffer", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createBuffer_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("createTexture", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createTexture_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FS_END,
JS_FNSPEC("importExternalTexture", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&importExternalTexture_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FS_END,
JS_FNSPEC("createSampler", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createSampler_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("createBindGroupLayout", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createBindGroupLayout_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("createPipelineLayout", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createPipelineLayout_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("createBindGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createBindGroup_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("createShaderModule", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createShaderModule_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("createComputePipeline", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createComputePipeline_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("createRenderPipeline", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createRenderPipeline_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("createComputePipelineAsync", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&createComputePipelineAsync_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("createRenderPipelineAsync", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&createRenderPipelineAsync_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("createCommandEncoder", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createCommandEncoder_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("createRenderBundleEncoder", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createRenderBundleEncoder_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("createQuerySet", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createQuerySet_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("pushErrorScope", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&pushErrorScope_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("popErrorScope", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&popErrorScope_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const PrefableDisablers sMethods_disablers4 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), &mozilla::webgpu::Instance::ExternalTexturePrefEnabled
};
static const PrefableDisablers sMethods_disablers6 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &sMethods_specs[0] },
{ &sMethods_disablers4, &sMethods_specs[4] },
{ &sMethods_disablers6, &sMethods_specs[6] },
{ nullptr, nullptr }
};
static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(14 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("features", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &features_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("limits", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &limits_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("adapterInfo", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &adapterInfo_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("queue", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &queue_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("lost", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ConvertExceptionsToPromises>, &lost_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("onuncapturederror", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &onuncapturederror_getterinfo, GenericSetter<NormalThisPolicy>, &onuncapturederror_setterinfo),
JS_PS_END,
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_specs[0] },
{ nullptr, &sAttributes_specs[7] },
{ nullptr, nullptr }
};
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(6 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[25];
static PropertyInfo sNativeProperties_propertyInfos[25];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
25,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[18] }
}
};
static_assert(25 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUDevice,
constructors::id::GPUDevice,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
EventTarget_Binding::GetConstructorObjectHandle,
PrototypeTraits<prototypes::id::GPUDevice>::Depth,
prototypes::id::GPUDevice,
true,
0,
"GPUDevice",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUDevicePrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUDevice,
PrototypeTraits<prototypes::id::GPUDevice>::Depth,
&sNativePropertyHooks,
EventTarget_Binding::GetProtoObject
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUDevice",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::Device>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::EventTarget, prototypes::id::GPUDevice, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::Device>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::Device>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::Device>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::Device>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::Device* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::Device>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::Device*>);
MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
"Multiple inheritance for mozilla::dom::EventTarget is broken.");
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::Device> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUDevice);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUDevice);
JS::Handle<JSObject*> parentProto(EventTarget_Binding::GetProtoObjectHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(EventTarget_Binding::GetConstructorObjectHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUDevice",
ShouldExpose<GPUDevice_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUDevice,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUDevice,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUDevice_Binding
namespace GPUDeviceLostInfo_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_reason(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDeviceLostInfo", "reason", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::DeviceLostInfo*>(void_self);
GPUDeviceLostReason result(MOZ_KnownLive(self)->Reason());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo reason_getterinfo = {
{ get_reason },
{ prototypes::id::GPUDeviceLostInfo },
{ PrototypeTraits<prototypes::id::GPUDeviceLostInfo>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_message(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUDeviceLostInfo", "message", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::DeviceLostInfo*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetMessage(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetMessage(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo message_getterinfo = {
{ get_message },
{ prototypes::id::GPUDeviceLostInfo },
{ PrototypeTraits<prototypes::id::GPUDeviceLostInfo>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::DeviceLostInfo* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::DeviceLostInfo>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::DeviceLostInfo>(self);
}
}
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("reason", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &reason_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("message", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &message_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[2];
static PropertyInfo sNativeProperties_propertyInfos[2];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
2,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(2 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUDeviceLostInfo,
constructors::id::GPUDeviceLostInfo,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUDeviceLostInfo>::Depth,
prototypes::id::GPUDeviceLostInfo,
true,
0,
"GPUDeviceLostInfo",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUDeviceLostInfoPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUDeviceLostInfo,
PrototypeTraits<prototypes::id::GPUDeviceLostInfo>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUDeviceLostInfo",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::DeviceLostInfo>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUDeviceLostInfo, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::DeviceLostInfo>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::DeviceLostInfo>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::DeviceLostInfo>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::DeviceLostInfo>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::DeviceLostInfo* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::DeviceLostInfo>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::DeviceLostInfo*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::DeviceLostInfo> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUDeviceLostInfo);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUDeviceLostInfo);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUDeviceLostInfo",
ShouldExpose<GPUDeviceLostInfo_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUDeviceLostInfo,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUDeviceLostInfo,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUDeviceLostInfo_Binding
namespace GPUError_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_message(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUError", "message", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Error*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetMessage(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetMessage(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo message_getterinfo = {
{ get_message },
{ prototypes::id::GPUError },
{ PrototypeTraits<prototypes::id::GPUError>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("message", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &message_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[1];
static PropertyInfo sNativeProperties_propertyInfos[1];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
1,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(1 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUError,
constructors::id::GPUError,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUError>::Depth,
prototypes::id::GPUError,
true,
0,
"GPUError",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUErrorPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUError,
PrototypeTraits<prototypes::id::GPUError>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUError);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUError);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUError",
ShouldExpose<GPUError_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUError,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JSObject*
GetProtoObject(JSContext* aCx)
{
return GetProtoObjectHandle(aCx);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUError,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUError_Binding
namespace GPUExternalTexture_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUExternalTexture", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::ExternalTexture*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUExternalTexture", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::ExternalTexture*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPUExternalTexture },
{ PrototypeTraits<prototypes::id::GPUExternalTexture>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPUExternalTexture },
{ PrototypeTraits<prototypes::id::GPUExternalTexture>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::ExternalTexture* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ExternalTexture>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::ExternalTexture>(self);
}
}
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[1];
static PropertyInfo sNativeProperties_propertyInfos[1];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
1,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(1 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUExternalTexture,
constructors::id::GPUExternalTexture,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUExternalTexture>::Depth,
prototypes::id::GPUExternalTexture,
true,
0,
"GPUExternalTexture",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUExternalTexturePrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUExternalTexture,
PrototypeTraits<prototypes::id::GPUExternalTexture>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUExternalTexture",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::ExternalTexture>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUExternalTexture, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::ExternalTexture>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::ExternalTexture>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::ExternalTexture>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::ExternalTexture>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::ExternalTexture* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::ExternalTexture>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::ExternalTexture*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::ExternalTexture> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUExternalTexture);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUExternalTexture);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUExternalTexture",
ShouldExpose<GPUExternalTexture_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUExternalTexture,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUExternalTexture,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUExternalTexture_Binding
namespace GPUInternalError_Binding {
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<GPUError_Binding::NativeType>::value,
"Can't inherit from an interface with a different ownership model.");
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::InternalError* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::InternalError>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::InternalError>(self);
}
}
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ nullptr, nullptr, &sNativePropertiesInited },
prototypes::id::GPUInternalError,
constructors::id::GPUInternalError,
&DefaultXrayExpandoObjectClass
};
static bool
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUInternalError", "constructor", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS::Rooted<JSObject*> obj(cx, &args.callee());
if (!args.isConstructing()) {
return ThrowConstructorWithoutNew(cx, "GPUInternalError");
}
JS::Rooted<JSObject*> desiredProto(cx);
if (!GetDesiredProto(cx, args,
prototypes::id::GPUInternalError,
CreateInterfaceObjects,
&desiredProto)) {
return false;
}
if (!args.requireAtLeast(cx, "GPUInternalError constructor", 1)) {
return false;
}
GlobalObject global(cx, obj);
if (global.Failed()) {
return false;
}
bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
Maybe<JSAutoRealm> ar;
if (objIsXray) {
// Since our object is an Xray, we can just CheckedUnwrapStatic:
// we know Xrays have no dynamic unwrap behavior.
obj = js::CheckedUnwrapStatic(obj);
if (!obj) {
return false;
}
ar.emplace(cx, obj);
if (!JS_WrapObject(cx, &desiredProto)) {
return false;
}
}
FastErrorResult rv;
auto result(StrongOrRawPtr<mozilla::webgpu::InternalError>(mozilla::webgpu::InternalError::Constructor(global, NonNullHelper(Constify(arg0)), rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUInternalError constructor"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
static_assert(!std::is_pointer_v<decltype(result)>,
"NewObject implies that we need to keep the object alive with a strong reference.");
if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ _constructor, &sNativePropertyHooks },
GPUError_Binding::GetConstructorObjectHandle,
PrototypeTraits<prototypes::id::GPUInternalError>::Depth,
prototypes::id::GPUInternalError,
true,
1,
"GPUInternalError",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUInternalErrorPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUInternalError,
PrototypeTraits<prototypes::id::GPUInternalError>::Depth,
&sNativePropertyHooks,
GPUError_Binding::GetProtoObject
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUInternalError",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::InternalError>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUError, prototypes::id::GPUInternalError, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::InternalError>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::InternalError>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::InternalError>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::InternalError>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::InternalError* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::InternalError>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::InternalError*>);
MOZ_ASSERT(static_cast<mozilla::webgpu::Error*>(aObject) ==
reinterpret_cast<mozilla::webgpu::Error*>(aObject),
"Multiple inheritance for mozilla::webgpu::Error is broken.");
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::InternalError> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUInternalError);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUInternalError);
JS::Handle<JSObject*> parentProto(GPUError_Binding::GetProtoObjectHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(GPUError_Binding::GetConstructorObjectHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 1, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
nullptr,
nullptr,
"GPUInternalError",
ShouldExpose<GPUInternalError_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUInternalError,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUInternalError,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUInternalError_Binding
namespace GPUMapMode_Binding {
MOZ_GLOBINIT static const ConstantSpec sConstants_specs[] = {
{ "READ", JS::NumberValue(1U) },
{ "WRITE", JS::NumberValue(2U) },
{ 0, JS::UndefinedValue() }
};
static const PrefableDisablers sConstants_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const ConstantSpec> sConstants[] = {
{ &sConstants_disablers0, &sConstants_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[2];
static PropertyInfo sNativeProperties_propertyInfos[2];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
false, 0,
false, 0,
false, 0,
true, 0 /* sConstants */,
-1,
2,
sNativeProperties_sortedPropertyIndices,
{
{ sConstants, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(2 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::_ID_Count,
constructors::id::GPUMapMode,
&DefaultXrayExpandoObjectClass
};
static const DOMIfaceAndProtoJSClass sNamespaceObjectClass = {
{
"GPUMapMode",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS,
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eNamespace,
prototypes::id::_ID_Count,
0,
&sNativePropertyHooks,
// This isn't strictly following the spec (see
// but should be ok for Xrays.
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!constructorProto) {
return;
}
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUMapMode);
dom::CreateNamespaceObject(aCx, aGlobal, constructorProto,
sNamespaceObjectClass,
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUMapMode",
ShouldExpose<GPUMapMode_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal));
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUMapMode,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUMapMode_Binding
namespace GPUOutOfMemoryError_Binding {
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<GPUError_Binding::NativeType>::value,
"Can't inherit from an interface with a different ownership model.");
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::OutOfMemoryError* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::OutOfMemoryError>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::OutOfMemoryError>(self);
}
}
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ nullptr, nullptr, &sNativePropertiesInited },
prototypes::id::GPUOutOfMemoryError,
constructors::id::GPUOutOfMemoryError,
&DefaultXrayExpandoObjectClass
};
static bool
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUOutOfMemoryError", "constructor", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS::Rooted<JSObject*> obj(cx, &args.callee());
if (!args.isConstructing()) {
return ThrowConstructorWithoutNew(cx, "GPUOutOfMemoryError");
}
JS::Rooted<JSObject*> desiredProto(cx);
if (!GetDesiredProto(cx, args,
prototypes::id::GPUOutOfMemoryError,
CreateInterfaceObjects,
&desiredProto)) {
return false;
}
if (!args.requireAtLeast(cx, "GPUOutOfMemoryError constructor", 1)) {
return false;
}
GlobalObject global(cx, obj);
if (global.Failed()) {
return false;
}
bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
Maybe<JSAutoRealm> ar;
if (objIsXray) {
// Since our object is an Xray, we can just CheckedUnwrapStatic:
// we know Xrays have no dynamic unwrap behavior.
obj = js::CheckedUnwrapStatic(obj);
if (!obj) {
return false;
}
ar.emplace(cx, obj);
if (!JS_WrapObject(cx, &desiredProto)) {
return false;
}
}
FastErrorResult rv;
auto result(StrongOrRawPtr<mozilla::webgpu::OutOfMemoryError>(mozilla::webgpu::OutOfMemoryError::Constructor(global, NonNullHelper(Constify(arg0)), rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUOutOfMemoryError constructor"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
static_assert(!std::is_pointer_v<decltype(result)>,
"NewObject implies that we need to keep the object alive with a strong reference.");
if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ _constructor, &sNativePropertyHooks },
GPUError_Binding::GetConstructorObjectHandle,
PrototypeTraits<prototypes::id::GPUOutOfMemoryError>::Depth,
prototypes::id::GPUOutOfMemoryError,
true,
1,
"GPUOutOfMemoryError",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUOutOfMemoryErrorPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUOutOfMemoryError,
PrototypeTraits<prototypes::id::GPUOutOfMemoryError>::Depth,
&sNativePropertyHooks,
GPUError_Binding::GetProtoObject
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUOutOfMemoryError",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::OutOfMemoryError>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUError, prototypes::id::GPUOutOfMemoryError, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::OutOfMemoryError>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::OutOfMemoryError>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::OutOfMemoryError>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::OutOfMemoryError>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::OutOfMemoryError* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::OutOfMemoryError>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::OutOfMemoryError*>);
MOZ_ASSERT(static_cast<mozilla::webgpu::Error*>(aObject) ==
reinterpret_cast<mozilla::webgpu::Error*>(aObject),
"Multiple inheritance for mozilla::webgpu::Error is broken.");
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::OutOfMemoryError> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUOutOfMemoryError);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUOutOfMemoryError);
JS::Handle<JSObject*> parentProto(GPUError_Binding::GetProtoObjectHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(GPUError_Binding::GetConstructorObjectHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 1, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
nullptr,
nullptr,
"GPUOutOfMemoryError",
ShouldExpose<GPUOutOfMemoryError_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUOutOfMemoryError,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUOutOfMemoryError,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUOutOfMemoryError_Binding
namespace GPUPipelineError_Binding {
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<DOMException_Binding::NativeType>::value,
"Can't inherit from an interface with a different ownership model.");
MOZ_CAN_RUN_SCRIPT static bool
get_reason(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUPipelineError", "reason", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::PipelineError*>(void_self);
GPUPipelineErrorReason result(MOZ_KnownLive(self)->Reason());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo reason_getterinfo = {
{ get_reason },
{ prototypes::id::GPUPipelineError },
{ PrototypeTraits<prototypes::id::GPUPipelineError>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::PipelineError* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::PipelineError>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::PipelineError>(self);
}
}
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("reason", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &reason_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[1];
static PropertyInfo sNativeProperties_propertyInfos[1];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
1,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(1 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUPipelineError,
constructors::id::GPUPipelineError,
&DefaultXrayExpandoObjectClass
};
static bool
_constructor(JSContext* cx_, unsigned argc, JS::Value* vp)
{
BindingCallContext cx(cx_, "GPUPipelineError constructor");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUPipelineError", "constructor", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS::Rooted<JSObject*> obj(cx, &args.callee());
if (!args.isConstructing()) {
return ThrowConstructorWithoutNew(cx, "GPUPipelineError");
}
JS::Rooted<JSObject*> desiredProto(cx);
if (!GetDesiredProto(cx, args,
prototypes::id::GPUPipelineError,
CreateInterfaceObjects,
&desiredProto)) {
return false;
}
if (!args.requireAtLeast(cx, "GPUPipelineError constructor", 2)) {
return false;
}
GlobalObject global(cx, obj);
if (global.Failed()) {
return false;
}
bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
binding_detail::FakeString<char16_t> arg0;
if (args.hasDefined(0)) {
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
} else {
arg0.AssignLiteral(u"");
}
binding_detail::FastGPUPipelineErrorInit arg1;
if (!arg1.Init(cx, args[1], "Argument 2", false)) {
return false;
}
Maybe<JSAutoRealm> ar;
if (objIsXray) {
// Since our object is an Xray, we can just CheckedUnwrapStatic:
// we know Xrays have no dynamic unwrap behavior.
obj = js::CheckedUnwrapStatic(obj);
if (!obj) {
return false;
}
ar.emplace(cx, obj);
if (!JS_WrapObject(cx, &desiredProto)) {
return false;
}
}
auto result(StrongOrRawPtr<mozilla::webgpu::PipelineError>(mozilla::webgpu::PipelineError::Constructor(global, NonNullHelper(Constify(arg0)), Constify(arg1))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
static_assert(!std::is_pointer_v<decltype(result)>,
"NewObject implies that we need to keep the object alive with a strong reference.");
if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ _constructor, &sNativePropertyHooks },
DOMException_Binding::GetConstructorObjectHandle,
PrototypeTraits<prototypes::id::GPUPipelineError>::Depth,
prototypes::id::GPUPipelineError,
true,
2,
"GPUPipelineError",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUPipelineErrorPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUPipelineError,
PrototypeTraits<prototypes::id::GPUPipelineError>::Depth,
&sNativePropertyHooks,
DOMException_Binding::GetProtoObject
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUPipelineError",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::PipelineError>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::DOMException, prototypes::id::GPUPipelineError, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::PipelineError>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::PipelineError>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::PipelineError>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::PipelineError>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::PipelineError* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::PipelineError>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::PipelineError*>);
MOZ_ASSERT(static_cast<mozilla::dom::DOMException*>(aObject) ==
reinterpret_cast<mozilla::dom::DOMException*>(aObject),
"Multiple inheritance for mozilla::dom::DOMException is broken.");
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::PipelineError> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUPipelineError);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUPipelineError);
JS::Handle<JSObject*> parentProto(DOMException_Binding::GetProtoObjectHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(DOMException_Binding::GetConstructorObjectHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 2, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUPipelineError",
ShouldExpose<GPUPipelineError_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUPipelineError,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUPipelineError,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUPipelineError_Binding
namespace GPUPipelineLayout_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUPipelineLayout", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::PipelineLayout*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUPipelineLayout", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::PipelineLayout*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPUPipelineLayout },
{ PrototypeTraits<prototypes::id::GPUPipelineLayout>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPUPipelineLayout },
{ PrototypeTraits<prototypes::id::GPUPipelineLayout>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::PipelineLayout* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::PipelineLayout>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::PipelineLayout>(self);
}
}
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[1];
static PropertyInfo sNativeProperties_propertyInfos[1];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
1,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(1 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUPipelineLayout,
constructors::id::GPUPipelineLayout,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUPipelineLayout>::Depth,
prototypes::id::GPUPipelineLayout,
true,
0,
"GPUPipelineLayout",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUPipelineLayoutPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUPipelineLayout,
PrototypeTraits<prototypes::id::GPUPipelineLayout>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUPipelineLayout",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::PipelineLayout>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUPipelineLayout, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::PipelineLayout>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::PipelineLayout>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::PipelineLayout>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::PipelineLayout>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::PipelineLayout* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::PipelineLayout>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::PipelineLayout*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::PipelineLayout> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUPipelineLayout);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUPipelineLayout);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUPipelineLayout",
ShouldExpose<GPUPipelineLayout_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUPipelineLayout,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUPipelineLayout,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUPipelineLayout_Binding
namespace GPUQuerySet_Binding {
MOZ_CAN_RUN_SCRIPT static bool
destroy(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUQuerySet", "destroy", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::QuerySet*>(void_self);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Destroy())>, "Should be returning void here");
MOZ_KnownLive(self)->Destroy();
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo destroy_methodinfo = {
{ (JSJitGetterOp)destroy },
{ prototypes::id::GPUQuerySet },
{ PrototypeTraits<prototypes::id::GPUQuerySet>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_type(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUQuerySet", "type", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::QuerySet*>(void_self);
GPUQueryType result(MOZ_KnownLive(self)->Type());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo type_getterinfo = {
{ get_type },
{ prototypes::id::GPUQuerySet },
{ PrototypeTraits<prototypes::id::GPUQuerySet>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_count(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUQuerySet", "count", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::QuerySet*>(void_self);
uint32_t result(MOZ_KnownLive(self)->Count());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo count_getterinfo = {
{ get_count },
{ prototypes::id::GPUQuerySet },
{ PrototypeTraits<prototypes::id::GPUQuerySet>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUQuerySet", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::QuerySet*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUQuerySet", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::QuerySet*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPUQuerySet },
{ PrototypeTraits<prototypes::id::GPUQuerySet>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPUQuerySet },
{ PrototypeTraits<prototypes::id::GPUQuerySet>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::QuerySet* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::QuerySet>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::QuerySet>(self);
}
}
MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("destroy", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&destroy_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &sMethods_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("type", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &type_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("count", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &count_getterinfo, nullptr, nullptr),
JS_PS_END,
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_specs[0] },
{ nullptr, &sAttributes_specs[3] },
{ nullptr, nullptr }
};
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[4];
static PropertyInfo sNativeProperties_propertyInfos[4];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
4,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[1] }
}
};
static_assert(4 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUQuerySet,
constructors::id::GPUQuerySet,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUQuerySet>::Depth,
prototypes::id::GPUQuerySet,
true,
0,
"GPUQuerySet",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUQuerySetPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUQuerySet,
PrototypeTraits<prototypes::id::GPUQuerySet>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUQuerySet",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::QuerySet>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUQuerySet, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::QuerySet>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::QuerySet>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::QuerySet>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::QuerySet>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::QuerySet* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::QuerySet>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::QuerySet*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::QuerySet> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUQuerySet);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUQuerySet);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUQuerySet",
ShouldExpose<GPUQuerySet_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUQuerySet,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUQuerySet,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUQuerySet_Binding
namespace GPUQueue_Binding {
MOZ_CAN_RUN_SCRIPT static bool
submit(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUQueue.submit");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUQueue", "submit", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Queue*>(void_self);
if (!args.requireAtLeast(cx, "GPUQueue.submit", 1)) {
return false;
}
binding_detail::AutoSequence<OwningNonNull<mozilla::webgpu::CommandBuffer>> arg0;
if (args[0].isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 1", "sequence");
return false;
}
binding_detail::AutoSequence<OwningNonNull<mozilla::webgpu::CommandBuffer>> &arr = arg0;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
OwningNonNull<mozilla::webgpu::CommandBuffer>* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
OwningNonNull<mozilla::webgpu::CommandBuffer>& slot = *slotPtr;
if (temp.isObject()) {
static_assert(IsRefcounted<mozilla::webgpu::CommandBuffer>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUCommandBuffer, mozilla::webgpu::CommandBuffer>(&temp, slot, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Element of argument 1", "GPUCommandBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of argument 1");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 1", "sequence");
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Submit(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->Submit(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo submit_methodinfo = {
{ (JSJitGetterOp)submit },
{ prototypes::id::GPUQueue },
{ PrototypeTraits<prototypes::id::GPUQueue>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
onSubmittedWorkDone(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUQueue", "onSubmittedWorkDone", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Queue*>(void_self);
FastErrorResult rv;
auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->OnSubmittedWorkDone(rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUQueue.onSubmittedWorkDone"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
onSubmittedWorkDone_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
bool ok = onSubmittedWorkDone(cx, obj, void_self, args);
if (ok) {
return true;
}
return ConvertExceptionToPromise(cx, args.rval());
}
static const JSJitInfo onSubmittedWorkDone_methodinfo = {
{ (JSJitGetterOp)onSubmittedWorkDone_promiseWrapper },
{ prototypes::id::GPUQueue },
{ PrototypeTraits<prototypes::id::GPUQueue>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
writeBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUQueue.writeBuffer");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUQueue", "writeBuffer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Queue*>(void_self);
if (!args.requireAtLeast(cx, "GPUQueue.writeBuffer", 3)) {
return false;
}
NonNull<mozilla::webgpu::Buffer> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
uint64_t arg1;
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
return false;
}
MaybeSharedArrayBufferOrMaybeSharedArrayBufferView arg2;
if (!arg2.Init(cx, args[2], "Argument 3", false)) {
return false;
}
uint64_t arg3;
if (args.hasDefined(3)) {
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
return false;
}
} else {
arg3 = 0ULL;
}
Optional<uint64_t> arg4;
if (args.hasDefined(4)) {
arg4.Construct();
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[4], "Argument 5", &arg4.Value())) {
return false;
}
}
FastErrorResult rv;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->WriteBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, Constify(arg2), arg3, Constify(arg4), rv))>, "Should be returning void here");
MOZ_KnownLive(self)->WriteBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, Constify(arg2), arg3, Constify(arg4), rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUQueue.writeBuffer"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo writeBuffer_methodinfo = {
{ (JSJitGetterOp)writeBuffer },
{ prototypes::id::GPUQueue },
{ PrototypeTraits<prototypes::id::GPUQueue>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
writeTexture(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUQueue.writeTexture");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUQueue", "writeTexture", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Queue*>(void_self);
if (!args.requireAtLeast(cx, "GPUQueue.writeTexture", 4)) {
return false;
}
binding_detail::FastGPUTexelCopyTextureInfo arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
MaybeSharedArrayBufferOrMaybeSharedArrayBufferView arg1;
if (!arg1.Init(cx, args[1], "Argument 2", false)) {
return false;
}
binding_detail::FastGPUTexelCopyBufferLayout arg2;
if (!arg2.Init(cx, args[2], "Argument 3", false)) {
return false;
}
RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict arg3;
if (!arg3.Init(cx, args[3], "Argument 4", false)) {
return false;
}
FastErrorResult rv;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->WriteTexture(Constify(arg0), Constify(arg1), Constify(arg2), Constify(arg3), rv))>, "Should be returning void here");
MOZ_KnownLive(self)->WriteTexture(Constify(arg0), Constify(arg1), Constify(arg2), Constify(arg3), rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUQueue.writeTexture"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo writeTexture_methodinfo = {
{ (JSJitGetterOp)writeTexture },
{ prototypes::id::GPUQueue },
{ PrototypeTraits<prototypes::id::GPUQueue>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
copyExternalImageToTexture(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUQueue.copyExternalImageToTexture");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUQueue", "copyExternalImageToTexture", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Queue*>(void_self);
if (!args.requireAtLeast(cx, "GPUQueue.copyExternalImageToTexture", 3)) {
return false;
}
binding_detail::FastGPUCopyExternalImageSourceInfo arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
binding_detail::FastGPUCopyExternalImageDestInfo arg1;
if (!arg1.Init(cx, args[1], "Argument 2", false)) {
return false;
}
RangeEnforcedUnsignedLongSequenceOrGPUExtent3DDict arg2;
if (!arg2.Init(cx, args[2], "Argument 3", false)) {
return false;
}
FastErrorResult rv;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->CopyExternalImageToTexture(Constify(arg0), Constify(arg1), Constify(arg2), rv))>, "Should be returning void here");
MOZ_KnownLive(self)->CopyExternalImageToTexture(Constify(arg0), Constify(arg1), Constify(arg2), rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUQueue.copyExternalImageToTexture"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo copyExternalImageToTexture_methodinfo = {
{ (JSJitGetterOp)copyExternalImageToTexture },
{ prototypes::id::GPUQueue },
{ PrototypeTraits<prototypes::id::GPUQueue>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUQueue", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Queue*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUQueue", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Queue*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPUQueue },
{ PrototypeTraits<prototypes::id::GPUQueue>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPUQueue },
{ PrototypeTraits<prototypes::id::GPUQueue>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::Queue* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Queue>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::Queue>(self);
}
}
MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("submit", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&submit_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("onSubmittedWorkDone", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&onSubmittedWorkDone_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("writeBuffer", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&writeBuffer_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("writeTexture", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&writeTexture_methodinfo), 4, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("copyExternalImageToTexture", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&copyExternalImageToTexture_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &sMethods_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[6];
static PropertyInfo sNativeProperties_propertyInfos[6];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
6,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[5] }
}
};
static_assert(6 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUQueue,
constructors::id::GPUQueue,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUQueue>::Depth,
prototypes::id::GPUQueue,
true,
0,
"GPUQueue",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUQueuePrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUQueue,
PrototypeTraits<prototypes::id::GPUQueue>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUQueue",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::Queue>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUQueue, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::Queue>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::Queue>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::Queue>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::Queue>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::Queue* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::Queue>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::Queue*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::Queue> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUQueue);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUQueue);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUQueue",
ShouldExpose<GPUQueue_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUQueue,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUQueue,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUQueue_Binding
namespace GPURenderBundle_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderBundle", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderBundle*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderBundle", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderBundle*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPURenderBundle },
{ PrototypeTraits<prototypes::id::GPURenderBundle>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPURenderBundle },
{ PrototypeTraits<prototypes::id::GPURenderBundle>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::RenderBundle* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderBundle>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::RenderBundle>(self);
}
}
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[1];
static PropertyInfo sNativeProperties_propertyInfos[1];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
1,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(1 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPURenderBundle,
constructors::id::GPURenderBundle,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPURenderBundle>::Depth,
prototypes::id::GPURenderBundle,
true,
0,
"GPURenderBundle",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPURenderBundlePrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPURenderBundle,
PrototypeTraits<prototypes::id::GPURenderBundle>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPURenderBundle",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::RenderBundle>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPURenderBundle, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::RenderBundle>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::RenderBundle>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::RenderBundle>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::RenderBundle>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::RenderBundle* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::RenderBundle>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::RenderBundle*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::RenderBundle> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPURenderBundle);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPURenderBundle);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPURenderBundle",
ShouldExpose<GPURenderBundle_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPURenderBundle,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPURenderBundle,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPURenderBundle_Binding
namespace GPURenderBundleEncoder_Binding {
MOZ_CAN_RUN_SCRIPT static bool
finish(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderBundleEncoder.finish");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderBundleEncoder", "finish", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
binding_detail::FastGPURenderBundleDescriptor arg0;
if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
return false;
}
auto result(StrongOrRawPtr<mozilla::webgpu::RenderBundle>(MOZ_KnownLive(self)->Finish(Constify(arg0))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo finish_methodinfo = {
{ (JSJitGetterOp)finish },
{ prototypes::id::GPURenderBundleEncoder },
{ PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
setBindGroup(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderBundleEncoder.setBindGroup");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderBundleEncoder", "setBindGroup", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
unsigned argcount = std::min(args.length(), 5u);
switch (argcount) {
case 2: {
[[fallthrough]];
}
case 3: {
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
mozilla::webgpu::BindGroup* arg1;
if (args[1].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBindGroup, mozilla::webgpu::BindGroup>(args[1], arg1, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "GPUBindGroup");
return false;
}
}
} else if (args[1].isNullOrUndefined()) {
arg1 = nullptr;
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
return false;
}
binding_detail::AutoSequence<uint32_t> arg2;
if (args.hasDefined(2)) {
if (args[2].isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(args[2], JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 3", "sequence");
return false;
}
binding_detail::AutoSequence<uint32_t> &arr = arg2;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
uint32_t& slot = *slotPtr;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp, "Element of argument 3", &slot)) {
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 3", "sequence");
return false;
}
} else {
/* arg2 array is already empty; nothing to do */
}
FastErrorResult rv;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), rv))>, "Should be returning void here");
MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPURenderBundleEncoder.setBindGroup"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
break;
}
case 5: {
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
mozilla::webgpu::BindGroup* arg1;
if (args[1].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBindGroup, mozilla::webgpu::BindGroup>(args[1], arg1, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "GPUBindGroup");
return false;
}
}
} else if (args[1].isNullOrUndefined()) {
arg1 = nullptr;
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
return false;
}
RootedSpiderMonkeyInterface<Uint32Array> arg2(cx);
if (args[2].isObject()) {
if (!arg2.Init(&args[2].toObject())) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 3", "Uint32Array");
return false;
}
if (JS::IsLargeArrayBufferView(arg2.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("Argument 3");
return false;
}
if (JS::IsResizableArrayBufferView(arg2.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("Argument 3");
return false;
}
if (JS::IsImmutableArrayBufferView(arg2.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_IMMUTABLE>("Argument 3");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 3");
return false;
}
uint64_t arg3;
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
return false;
}
uint32_t arg4;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[4], "Argument 5", &arg4)) {
return false;
}
FastErrorResult rv;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), arg3, arg4, rv))>, "Should be returning void here");
MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), arg3, arg4, rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPURenderBundleEncoder.setBindGroup"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
break;
}
default: {
// Using nsPrintfCString here would require including that
// header. Let's not worry about it.
nsAutoCString argCountStr;
argCountStr.AppendPrintf("%u", args.length());
return cx.ThrowErrorMessage<MSG_INVALID_OVERLOAD_ARGCOUNT>(argCountStr.get());
}
}
MOZ_CRASH("We have an always-returning default case");
return false;
}
static const JSJitInfo setBindGroup_methodinfo = {
{ (JSJitGetterOp)setBindGroup },
{ prototypes::id::GPURenderBundleEncoder },
{ PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
pushDebugGroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderBundleEncoder", "pushDebugGroup", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.pushDebugGroup", 1)) {
return false;
}
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->PushDebugGroup(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->PushDebugGroup(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo pushDebugGroup_methodinfo = {
{ (JSJitGetterOp)pushDebugGroup },
{ prototypes::id::GPURenderBundleEncoder },
{ PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
popDebugGroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderBundleEncoder", "popDebugGroup", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->PopDebugGroup())>, "Should be returning void here");
MOZ_KnownLive(self)->PopDebugGroup();
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo popDebugGroup_methodinfo = {
{ (JSJitGetterOp)popDebugGroup },
{ prototypes::id::GPURenderBundleEncoder },
{ PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
insertDebugMarker(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderBundleEncoder", "insertDebugMarker", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.insertDebugMarker", 1)) {
return false;
}
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->InsertDebugMarker(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->InsertDebugMarker(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo insertDebugMarker_methodinfo = {
{ (JSJitGetterOp)insertDebugMarker },
{ prototypes::id::GPURenderBundleEncoder },
{ PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderBundleEncoder", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderBundleEncoder", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPURenderBundleEncoder },
{ PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPURenderBundleEncoder },
{ PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
setPipeline(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderBundleEncoder.setPipeline");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderBundleEncoder", "setPipeline", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.setPipeline", 1)) {
return false;
}
NonNull<mozilla::webgpu::RenderPipeline> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPURenderPipeline, mozilla::webgpu::RenderPipeline>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPURenderPipeline");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetPipeline(MOZ_KnownLive(NonNullHelper(arg0))))>, "Should be returning void here");
MOZ_KnownLive(self)->SetPipeline(MOZ_KnownLive(NonNullHelper(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo setPipeline_methodinfo = {
{ (JSJitGetterOp)setPipeline },
{ prototypes::id::GPURenderBundleEncoder },
{ PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
setIndexBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderBundleEncoder.setIndexBuffer");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderBundleEncoder", "setIndexBuffer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.setIndexBuffer", 2)) {
return false;
}
NonNull<mozilla::webgpu::Buffer> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
GPUIndexFormat arg1;
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, args[1],
binding_detail::EnumStrings<GPUIndexFormat>::Values,
"GPUIndexFormat", "argument 2",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
arg1 = static_cast<GPUIndexFormat>(index);
}
uint64_t arg2;
if (args.hasDefined(2)) {
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
return false;
}
} else {
arg2 = 0ULL;
}
Optional<uint64_t> arg3;
if (args.hasDefined(3)) {
arg3.Construct();
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3.Value())) {
return false;
}
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetIndexBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, arg2, Constify(arg3)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetIndexBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, arg2, Constify(arg3));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo setIndexBuffer_methodinfo = {
{ (JSJitGetterOp)setIndexBuffer },
{ prototypes::id::GPURenderBundleEncoder },
{ PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
setVertexBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderBundleEncoder.setVertexBuffer");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderBundleEncoder", "setVertexBuffer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.setVertexBuffer", 2)) {
return false;
}
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
NonNull<mozilla::webgpu::Buffer> arg1;
if (args[1].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[1], arg1, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
return false;
}
uint64_t arg2;
if (args.hasDefined(2)) {
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
return false;
}
} else {
arg2 = 0ULL;
}
Optional<uint64_t> arg3;
if (args.hasDefined(3)) {
arg3.Construct();
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3.Value())) {
return false;
}
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetVertexBuffer(arg0, MOZ_KnownLive(NonNullHelper(arg1)), arg2, Constify(arg3)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetVertexBuffer(arg0, MOZ_KnownLive(NonNullHelper(arg1)), arg2, Constify(arg3));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo setVertexBuffer_methodinfo = {
{ (JSJitGetterOp)setVertexBuffer },
{ prototypes::id::GPURenderBundleEncoder },
{ PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
draw(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderBundleEncoder.draw");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderBundleEncoder", "draw", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.draw", 1)) {
return false;
}
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
uint32_t arg1;
if (args.hasDefined(1)) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
return false;
}
} else {
arg1 = 1U;
}
uint32_t arg2;
if (args.hasDefined(2)) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
return false;
}
} else {
arg2 = 0U;
}
uint32_t arg3;
if (args.hasDefined(3)) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
return false;
}
} else {
arg3 = 0U;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Draw(arg0, arg1, arg2, arg3))>, "Should be returning void here");
MOZ_KnownLive(self)->Draw(arg0, arg1, arg2, arg3);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo draw_methodinfo = {
{ (JSJitGetterOp)draw },
{ prototypes::id::GPURenderBundleEncoder },
{ PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
drawIndexed(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderBundleEncoder.drawIndexed");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderBundleEncoder", "drawIndexed", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.drawIndexed", 1)) {
return false;
}
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
uint32_t arg1;
if (args.hasDefined(1)) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
return false;
}
} else {
arg1 = 1U;
}
uint32_t arg2;
if (args.hasDefined(2)) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
return false;
}
} else {
arg2 = 0U;
}
int32_t arg3;
if (args.hasDefined(3)) {
if (!ValueToPrimitive<int32_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
return false;
}
} else {
arg3 = 0;
}
uint32_t arg4;
if (args.hasDefined(4)) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[4], "Argument 5", &arg4)) {
return false;
}
} else {
arg4 = 0U;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->DrawIndexed(arg0, arg1, arg2, arg3, arg4))>, "Should be returning void here");
MOZ_KnownLive(self)->DrawIndexed(arg0, arg1, arg2, arg3, arg4);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo drawIndexed_methodinfo = {
{ (JSJitGetterOp)drawIndexed },
{ prototypes::id::GPURenderBundleEncoder },
{ PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
drawIndirect(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderBundleEncoder.drawIndirect");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderBundleEncoder", "drawIndirect", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.drawIndirect", 2)) {
return false;
}
NonNull<mozilla::webgpu::Buffer> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
uint64_t arg1;
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->DrawIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1))>, "Should be returning void here");
MOZ_KnownLive(self)->DrawIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo drawIndirect_methodinfo = {
{ (JSJitGetterOp)drawIndirect },
{ prototypes::id::GPURenderBundleEncoder },
{ PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
drawIndexedIndirect(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderBundleEncoder.drawIndexedIndirect");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderBundleEncoder", "drawIndexedIndirect", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderBundleEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderBundleEncoder.drawIndexedIndirect", 2)) {
return false;
}
NonNull<mozilla::webgpu::Buffer> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
uint64_t arg1;
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->DrawIndexedIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1))>, "Should be returning void here");
MOZ_KnownLive(self)->DrawIndexedIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo drawIndexedIndirect_methodinfo = {
{ (JSJitGetterOp)drawIndexedIndirect },
{ prototypes::id::GPURenderBundleEncoder },
{ PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::RenderBundleEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderBundleEncoder>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::RenderBundleEncoder>(self);
}
}
MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("finish", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&finish_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FS_END,
JS_FNSPEC("setBindGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setBindGroup_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("pushDebugGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&pushDebugGroup_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("popDebugGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&popDebugGroup_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("insertDebugMarker", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&insertDebugMarker_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("setPipeline", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setPipeline_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("setIndexBuffer", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setIndexBuffer_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("setVertexBuffer", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setVertexBuffer_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("draw", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&draw_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("drawIndexed", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&drawIndexed_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("drawIndirect", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&drawIndirect_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("drawIndexedIndirect", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&drawIndexedIndirect_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &sMethods_specs[0] },
{ nullptr, &sMethods_specs[2] },
{ nullptr, nullptr }
};
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(11 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[13];
static PropertyInfo sNativeProperties_propertyInfos[13];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
13,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[12] }
}
};
static_assert(13 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPURenderBundleEncoder,
constructors::id::GPURenderBundleEncoder,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth,
prototypes::id::GPURenderBundleEncoder,
true,
0,
"GPURenderBundleEncoder",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPURenderBundleEncoderPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPURenderBundleEncoder,
PrototypeTraits<prototypes::id::GPURenderBundleEncoder>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPURenderBundleEncoder",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::RenderBundleEncoder>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPURenderBundleEncoder, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::RenderBundleEncoder>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::RenderBundleEncoder>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::RenderBundleEncoder>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::RenderBundleEncoder>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::RenderBundleEncoder* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::RenderBundleEncoder>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::RenderBundleEncoder*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::RenderBundleEncoder> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPURenderBundleEncoder);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPURenderBundleEncoder);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPURenderBundleEncoder",
ShouldExpose<GPURenderBundleEncoder_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPURenderBundleEncoder,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPURenderBundleEncoder,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPURenderBundleEncoder_Binding
namespace GPURenderPassEncoder_Binding {
MOZ_CAN_RUN_SCRIPT static bool
setViewport(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderPassEncoder.setViewport");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "setViewport", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderPassEncoder.setViewport", 6)) {
return false;
}
float arg0;
if (!ValueToPrimitive<float, eDefault>(cx, args[0], "Argument 1", &arg0)) {
return false;
} else if (!std::isfinite(arg0)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Argument 1");
return false;
}
float arg1;
if (!ValueToPrimitive<float, eDefault>(cx, args[1], "Argument 2", &arg1)) {
return false;
} else if (!std::isfinite(arg1)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Argument 2");
return false;
}
float arg2;
if (!ValueToPrimitive<float, eDefault>(cx, args[2], "Argument 3", &arg2)) {
return false;
} else if (!std::isfinite(arg2)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Argument 3");
return false;
}
float arg3;
if (!ValueToPrimitive<float, eDefault>(cx, args[3], "Argument 4", &arg3)) {
return false;
} else if (!std::isfinite(arg3)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Argument 4");
return false;
}
float arg4;
if (!ValueToPrimitive<float, eDefault>(cx, args[4], "Argument 5", &arg4)) {
return false;
} else if (!std::isfinite(arg4)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Argument 5");
return false;
}
float arg5;
if (!ValueToPrimitive<float, eDefault>(cx, args[5], "Argument 6", &arg5)) {
return false;
} else if (!std::isfinite(arg5)) {
cx.ThrowErrorMessage<MSG_NOT_FINITE>("Argument 6");
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetViewport(arg0, arg1, arg2, arg3, arg4, arg5))>, "Should be returning void here");
MOZ_KnownLive(self)->SetViewport(arg0, arg1, arg2, arg3, arg4, arg5);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo setViewport_methodinfo = {
{ (JSJitGetterOp)setViewport },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
setScissorRect(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderPassEncoder.setScissorRect");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "setScissorRect", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderPassEncoder.setScissorRect", 4)) {
return false;
}
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
uint32_t arg1;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
return false;
}
uint32_t arg2;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
return false;
}
uint32_t arg3;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetScissorRect(arg0, arg1, arg2, arg3))>, "Should be returning void here");
MOZ_KnownLive(self)->SetScissorRect(arg0, arg1, arg2, arg3);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo setScissorRect_methodinfo = {
{ (JSJitGetterOp)setScissorRect },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
setBlendConstant(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderPassEncoder.setBlendConstant");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "setBlendConstant", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderPassEncoder.setBlendConstant", 1)) {
return false;
}
DoubleSequenceOrGPUColorDict arg0;
if (!arg0.Init(cx, args[0], "Argument 1", false)) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetBlendConstant(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetBlendConstant(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo setBlendConstant_methodinfo = {
{ (JSJitGetterOp)setBlendConstant },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
setStencilReference(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderPassEncoder.setStencilReference");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "setStencilReference", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderPassEncoder.setStencilReference", 1)) {
return false;
}
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetStencilReference(arg0))>, "Should be returning void here");
MOZ_KnownLive(self)->SetStencilReference(arg0);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo setStencilReference_methodinfo = {
{ (JSJitGetterOp)setStencilReference },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
beginOcclusionQuery(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderPassEncoder.beginOcclusionQuery");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "beginOcclusionQuery", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderPassEncoder.beginOcclusionQuery", 1)) {
return false;
}
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->BeginOcclusionQuery(arg0))>, "Should be returning void here");
MOZ_KnownLive(self)->BeginOcclusionQuery(arg0);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo beginOcclusionQuery_methodinfo = {
{ (JSJitGetterOp)beginOcclusionQuery },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
endOcclusionQuery(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "endOcclusionQuery", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->EndOcclusionQuery())>, "Should be returning void here");
MOZ_KnownLive(self)->EndOcclusionQuery();
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo endOcclusionQuery_methodinfo = {
{ (JSJitGetterOp)endOcclusionQuery },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
executeBundles(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderPassEncoder.executeBundles");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "executeBundles", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderPassEncoder.executeBundles", 1)) {
return false;
}
binding_detail::AutoSequence<OwningNonNull<mozilla::webgpu::RenderBundle>> arg0;
if (args[0].isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 1", "sequence");
return false;
}
binding_detail::AutoSequence<OwningNonNull<mozilla::webgpu::RenderBundle>> &arr = arg0;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
OwningNonNull<mozilla::webgpu::RenderBundle>* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
OwningNonNull<mozilla::webgpu::RenderBundle>& slot = *slotPtr;
if (temp.isObject()) {
static_assert(IsRefcounted<mozilla::webgpu::RenderBundle>::value, "We can only store refcounted classes.");
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPURenderBundle, mozilla::webgpu::RenderBundle>(&temp, slot, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Element of argument 1", "GPURenderBundle");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Element of argument 1");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 1", "sequence");
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->ExecuteBundles(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->ExecuteBundles(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo executeBundles_methodinfo = {
{ (JSJitGetterOp)executeBundles },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
end(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "end", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->End())>, "Should be returning void here");
MOZ_KnownLive(self)->End();
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo end_methodinfo = {
{ (JSJitGetterOp)end },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
setBindGroup(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderPassEncoder.setBindGroup");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "setBindGroup", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
unsigned argcount = std::min(args.length(), 5u);
switch (argcount) {
case 2: {
[[fallthrough]];
}
case 3: {
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
mozilla::webgpu::BindGroup* arg1;
if (args[1].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBindGroup, mozilla::webgpu::BindGroup>(args[1], arg1, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "GPUBindGroup");
return false;
}
}
} else if (args[1].isNullOrUndefined()) {
arg1 = nullptr;
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
return false;
}
binding_detail::AutoSequence<uint32_t> arg2;
if (args.hasDefined(2)) {
if (args[2].isObject()) {
JS::ForOfIterator iter(cx);
if (!iter.init(args[2], JS::ForOfIterator::AllowNonIterable)) {
return false;
}
if (!iter.valueIsIterable()) {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 3", "sequence");
return false;
}
binding_detail::AutoSequence<uint32_t> &arr = arg2;
JS::Rooted<JS::Value> temp(cx);
while (true) {
bool done;
if (!iter.next(&temp, &done)) {
return false;
}
if (done) {
break;
}
uint32_t* slotPtr = arr.AppendElement(mozilla::fallible);
if (!slotPtr) {
JS_ReportOutOfMemory(cx);
return false;
}
uint32_t& slot = *slotPtr;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp, "Element of argument 3", &slot)) {
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_CONVERSION_ERROR>("Argument 3", "sequence");
return false;
}
} else {
/* arg2 array is already empty; nothing to do */
}
FastErrorResult rv;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), rv))>, "Should be returning void here");
MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPURenderPassEncoder.setBindGroup"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
break;
}
case 5: {
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
mozilla::webgpu::BindGroup* arg1;
if (args[1].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBindGroup, mozilla::webgpu::BindGroup>(args[1], arg1, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "GPUBindGroup");
return false;
}
}
} else if (args[1].isNullOrUndefined()) {
arg1 = nullptr;
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
return false;
}
RootedSpiderMonkeyInterface<Uint32Array> arg2(cx);
if (args[2].isObject()) {
if (!arg2.Init(&args[2].toObject())) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 3", "Uint32Array");
return false;
}
if (JS::IsLargeArrayBufferView(arg2.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_LARGE>("Argument 3");
return false;
}
if (JS::IsResizableArrayBufferView(arg2.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_RESIZABLE>("Argument 3");
return false;
}
if (JS::IsImmutableArrayBufferView(arg2.Obj())) {
cx.ThrowErrorMessage<MSG_TYPEDARRAY_IS_IMMUTABLE>("Argument 3");
return false;
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 3");
return false;
}
uint64_t arg3;
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
return false;
}
uint32_t arg4;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[4], "Argument 5", &arg4)) {
return false;
}
FastErrorResult rv;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), arg3, arg4, rv))>, "Should be returning void here");
MOZ_KnownLive(self)->SetBindGroup(arg0, MOZ_KnownLive(Constify(arg1)), Constify(arg2), arg3, arg4, rv);
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPURenderPassEncoder.setBindGroup"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
break;
}
default: {
// Using nsPrintfCString here would require including that
// header. Let's not worry about it.
nsAutoCString argCountStr;
argCountStr.AppendPrintf("%u", args.length());
return cx.ThrowErrorMessage<MSG_INVALID_OVERLOAD_ARGCOUNT>(argCountStr.get());
}
}
MOZ_CRASH("We have an always-returning default case");
return false;
}
static const JSJitInfo setBindGroup_methodinfo = {
{ (JSJitGetterOp)setBindGroup },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
pushDebugGroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "pushDebugGroup", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderPassEncoder.pushDebugGroup", 1)) {
return false;
}
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->PushDebugGroup(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->PushDebugGroup(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo pushDebugGroup_methodinfo = {
{ (JSJitGetterOp)pushDebugGroup },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
popDebugGroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "popDebugGroup", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->PopDebugGroup())>, "Should be returning void here");
MOZ_KnownLive(self)->PopDebugGroup();
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo popDebugGroup_methodinfo = {
{ (JSJitGetterOp)popDebugGroup },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
insertDebugMarker(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "insertDebugMarker", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderPassEncoder.insertDebugMarker", 1)) {
return false;
}
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->InsertDebugMarker(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->InsertDebugMarker(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo insertDebugMarker_methodinfo = {
{ (JSJitGetterOp)insertDebugMarker },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
setPipeline(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderPassEncoder.setPipeline");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "setPipeline", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderPassEncoder.setPipeline", 1)) {
return false;
}
NonNull<mozilla::webgpu::RenderPipeline> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPURenderPipeline, mozilla::webgpu::RenderPipeline>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPURenderPipeline");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetPipeline(MOZ_KnownLive(NonNullHelper(arg0))))>, "Should be returning void here");
MOZ_KnownLive(self)->SetPipeline(MOZ_KnownLive(NonNullHelper(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo setPipeline_methodinfo = {
{ (JSJitGetterOp)setPipeline },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
setIndexBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderPassEncoder.setIndexBuffer");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "setIndexBuffer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderPassEncoder.setIndexBuffer", 2)) {
return false;
}
NonNull<mozilla::webgpu::Buffer> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
GPUIndexFormat arg1;
{
int index;
if (!binding_detail::FindEnumStringIndex<true>(cx, args[1],
binding_detail::EnumStrings<GPUIndexFormat>::Values,
"GPUIndexFormat", "argument 2",
&index)) {
return false;
}
MOZ_ASSERT(index >= 0);
arg1 = static_cast<GPUIndexFormat>(index);
}
uint64_t arg2;
if (args.hasDefined(2)) {
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
return false;
}
} else {
arg2 = 0ULL;
}
Optional<uint64_t> arg3;
if (args.hasDefined(3)) {
arg3.Construct();
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3.Value())) {
return false;
}
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetIndexBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, arg2, Constify(arg3)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetIndexBuffer(MOZ_KnownLive(NonNullHelper(arg0)), arg1, arg2, Constify(arg3));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo setIndexBuffer_methodinfo = {
{ (JSJitGetterOp)setIndexBuffer },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
setVertexBuffer(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderPassEncoder.setVertexBuffer");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "setVertexBuffer", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderPassEncoder.setVertexBuffer", 2)) {
return false;
}
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
NonNull<mozilla::webgpu::Buffer> arg1;
if (args[1].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[1], arg1, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 2", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 2");
return false;
}
uint64_t arg2;
if (args.hasDefined(2)) {
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
return false;
}
} else {
arg2 = 0ULL;
}
Optional<uint64_t> arg3;
if (args.hasDefined(3)) {
arg3.Construct();
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3.Value())) {
return false;
}
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetVertexBuffer(arg0, MOZ_KnownLive(NonNullHelper(arg1)), arg2, Constify(arg3)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetVertexBuffer(arg0, MOZ_KnownLive(NonNullHelper(arg1)), arg2, Constify(arg3));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo setVertexBuffer_methodinfo = {
{ (JSJitGetterOp)setVertexBuffer },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
draw(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderPassEncoder.draw");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "draw", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderPassEncoder.draw", 1)) {
return false;
}
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
uint32_t arg1;
if (args.hasDefined(1)) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
return false;
}
} else {
arg1 = 1U;
}
uint32_t arg2;
if (args.hasDefined(2)) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
return false;
}
} else {
arg2 = 0U;
}
uint32_t arg3;
if (args.hasDefined(3)) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
return false;
}
} else {
arg3 = 0U;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Draw(arg0, arg1, arg2, arg3))>, "Should be returning void here");
MOZ_KnownLive(self)->Draw(arg0, arg1, arg2, arg3);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo draw_methodinfo = {
{ (JSJitGetterOp)draw },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
drawIndexed(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderPassEncoder.drawIndexed");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "drawIndexed", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderPassEncoder.drawIndexed", 1)) {
return false;
}
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
uint32_t arg1;
if (args.hasDefined(1)) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
return false;
}
} else {
arg1 = 1U;
}
uint32_t arg2;
if (args.hasDefined(2)) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[2], "Argument 3", &arg2)) {
return false;
}
} else {
arg2 = 0U;
}
int32_t arg3;
if (args.hasDefined(3)) {
if (!ValueToPrimitive<int32_t, eEnforceRange>(cx, args[3], "Argument 4", &arg3)) {
return false;
}
} else {
arg3 = 0;
}
uint32_t arg4;
if (args.hasDefined(4)) {
if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, args[4], "Argument 5", &arg4)) {
return false;
}
} else {
arg4 = 0U;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->DrawIndexed(arg0, arg1, arg2, arg3, arg4))>, "Should be returning void here");
MOZ_KnownLive(self)->DrawIndexed(arg0, arg1, arg2, arg3, arg4);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo drawIndexed_methodinfo = {
{ (JSJitGetterOp)drawIndexed },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
drawIndirect(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderPassEncoder.drawIndirect");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "drawIndirect", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderPassEncoder.drawIndirect", 2)) {
return false;
}
NonNull<mozilla::webgpu::Buffer> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
uint64_t arg1;
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->DrawIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1))>, "Should be returning void here");
MOZ_KnownLive(self)->DrawIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo drawIndirect_methodinfo = {
{ (JSJitGetterOp)drawIndirect },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
drawIndexedIndirect(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPURenderPassEncoder.drawIndexedIndirect");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPassEncoder", "drawIndexedIndirect", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPassEncoder*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderPassEncoder.drawIndexedIndirect", 2)) {
return false;
}
NonNull<mozilla::webgpu::Buffer> arg0;
if (args[0].isObject()) {
{
// Our JSContext should be in the right global to do unwrapping in.
nsresult rv = UnwrapObject<prototypes::id::GPUBuffer, mozilla::webgpu::Buffer>(args[0], arg0, cx);
if (NS_FAILED(rv)) {
cx.ThrowErrorMessage<MSG_DOES_NOT_IMPLEMENT_INTERFACE>("Argument 1", "GPUBuffer");
return false;
}
}
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
uint64_t arg1;
if (!ValueToPrimitive<uint64_t, eEnforceRange>(cx, args[1], "Argument 2", &arg1)) {
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->DrawIndexedIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1))>, "Should be returning void here");
MOZ_KnownLive(self)->DrawIndexedIndirect(MOZ_KnownLive(NonNullHelper(arg0)), arg1);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo drawIndexedIndirect_methodinfo = {
{ (JSJitGetterOp)drawIndexedIndirect },
{ prototypes::id::GPURenderPassEncoder },
{ PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::RenderPassEncoder* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderPassEncoder>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::RenderPassEncoder>(self);
}
}
MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("setViewport", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setViewport_methodinfo), 6, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("setScissorRect", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setScissorRect_methodinfo), 4, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("setBlendConstant", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setBlendConstant_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("setStencilReference", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setStencilReference_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("beginOcclusionQuery", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&beginOcclusionQuery_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("endOcclusionQuery", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&endOcclusionQuery_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("executeBundles", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&executeBundles_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("end", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&end_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FS_END,
JS_FNSPEC("setBindGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setBindGroup_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("pushDebugGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&pushDebugGroup_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("popDebugGroup", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&popDebugGroup_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("insertDebugMarker", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&insertDebugMarker_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("setPipeline", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setPipeline_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("setIndexBuffer", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setIndexBuffer_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("setVertexBuffer", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setVertexBuffer_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("draw", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&draw_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("drawIndexed", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&drawIndexed_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("drawIndirect", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&drawIndirect_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("drawIndexedIndirect", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&drawIndexedIndirect_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &sMethods_specs[0] },
{ nullptr, &sMethods_specs[9] },
{ nullptr, nullptr }
};
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(11 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[20];
static PropertyInfo sNativeProperties_propertyInfos[20];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
20,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[19] }
}
};
static_assert(20 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPURenderPassEncoder,
constructors::id::GPURenderPassEncoder,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth,
prototypes::id::GPURenderPassEncoder,
true,
0,
"GPURenderPassEncoder",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPURenderPassEncoderPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPURenderPassEncoder,
PrototypeTraits<prototypes::id::GPURenderPassEncoder>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPURenderPassEncoder",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::RenderPassEncoder>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPURenderPassEncoder, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::RenderPassEncoder>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::RenderPassEncoder>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::RenderPassEncoder>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::RenderPassEncoder>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::RenderPassEncoder* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::RenderPassEncoder>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::RenderPassEncoder*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::RenderPassEncoder> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPURenderPassEncoder);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPURenderPassEncoder);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPURenderPassEncoder",
ShouldExpose<GPURenderPassEncoder_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPURenderPassEncoder,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPURenderPassEncoder,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPURenderPassEncoder_Binding
namespace GPURenderPipeline_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPipeline", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPipeline*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPipeline", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPipeline*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPURenderPipeline },
{ PrototypeTraits<prototypes::id::GPURenderPipeline>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPURenderPipeline },
{ PrototypeTraits<prototypes::id::GPURenderPipeline>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
getBindGroupLayout(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPURenderPipeline", "getBindGroupLayout", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::RenderPipeline*>(void_self);
if (!args.requireAtLeast(cx, "GPURenderPipeline.getBindGroupLayout", 1)) {
return false;
}
uint32_t arg0;
if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[0], "Argument 1", &arg0)) {
return false;
}
auto result(StrongOrRawPtr<mozilla::webgpu::BindGroupLayout>(MOZ_KnownLive(self)->GetBindGroupLayout(arg0)));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo getBindGroupLayout_methodinfo = {
{ (JSJitGetterOp)getBindGroupLayout },
{ prototypes::id::GPURenderPipeline },
{ PrototypeTraits<prototypes::id::GPURenderPipeline>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::RenderPipeline* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::RenderPipeline>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::RenderPipeline>(self);
}
}
MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("getBindGroupLayout", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getBindGroupLayout_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ nullptr, &sMethods_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[2];
static PropertyInfo sNativeProperties_propertyInfos[2];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
2,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[1] }
}
};
static_assert(2 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPURenderPipeline,
constructors::id::GPURenderPipeline,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPURenderPipeline>::Depth,
prototypes::id::GPURenderPipeline,
true,
0,
"GPURenderPipeline",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPURenderPipelinePrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPURenderPipeline,
PrototypeTraits<prototypes::id::GPURenderPipeline>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPURenderPipeline",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::RenderPipeline>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPURenderPipeline, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::RenderPipeline>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::RenderPipeline>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::RenderPipeline>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::RenderPipeline>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::RenderPipeline* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::RenderPipeline>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::RenderPipeline*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::RenderPipeline> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPURenderPipeline);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPURenderPipeline);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPURenderPipeline",
ShouldExpose<GPURenderPipeline_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPURenderPipeline,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPURenderPipeline,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPURenderPipeline_Binding
namespace GPUSampler_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSampler", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Sampler*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSampler", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Sampler*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPUSampler },
{ PrototypeTraits<prototypes::id::GPUSampler>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPUSampler },
{ PrototypeTraits<prototypes::id::GPUSampler>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::Sampler* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Sampler>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::Sampler>(self);
}
}
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[1];
static PropertyInfo sNativeProperties_propertyInfos[1];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
1,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(1 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUSampler,
constructors::id::GPUSampler,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUSampler>::Depth,
prototypes::id::GPUSampler,
true,
0,
"GPUSampler",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUSamplerPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUSampler,
PrototypeTraits<prototypes::id::GPUSampler>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUSampler",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::Sampler>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUSampler, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::Sampler>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::Sampler>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::Sampler>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::Sampler>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::Sampler* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::Sampler>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::Sampler*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::Sampler> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUSampler);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUSampler);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUSampler",
ShouldExpose<GPUSampler_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUSampler,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUSampler,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUSampler_Binding
namespace GPUShaderModule_Binding {
MOZ_CAN_RUN_SCRIPT static bool
getCompilationInfo(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUShaderModule", "getCompilationInfo", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::ShaderModule*>(void_self);
FastErrorResult rv;
auto result(StrongOrRawPtr<Promise>(MOZ_KnownLive(self)->GetCompilationInfo(rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUShaderModule.getCompilationInfo"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
getCompilationInfo_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
bool ok = getCompilationInfo(cx, obj, void_self, args);
if (ok) {
return true;
}
return ConvertExceptionToPromise(cx, args.rval());
}
static const JSJitInfo getCompilationInfo_methodinfo = {
{ (JSJitGetterOp)getCompilationInfo_promiseWrapper },
{ prototypes::id::GPUShaderModule },
{ PrototypeTraits<prototypes::id::GPUShaderModule>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUShaderModule", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::ShaderModule*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUShaderModule", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::ShaderModule*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPUShaderModule },
{ PrototypeTraits<prototypes::id::GPUShaderModule>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPUShaderModule },
{ PrototypeTraits<prototypes::id::GPUShaderModule>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::ShaderModule* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ShaderModule>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::ShaderModule>(self);
}
}
MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("getCompilationInfo", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&getCompilationInfo_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &sMethods_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[2];
static PropertyInfo sNativeProperties_propertyInfos[2];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
2,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[1] }
}
};
static_assert(2 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUShaderModule,
constructors::id::GPUShaderModule,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUShaderModule>::Depth,
prototypes::id::GPUShaderModule,
true,
0,
"GPUShaderModule",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUShaderModulePrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUShaderModule,
PrototypeTraits<prototypes::id::GPUShaderModule>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUShaderModule",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::ShaderModule>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUShaderModule, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::ShaderModule>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::ShaderModule>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::ShaderModule>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::ShaderModule>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::ShaderModule* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::ShaderModule>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::ShaderModule*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::ShaderModule> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUShaderModule);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUShaderModule);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUShaderModule",
ShouldExpose<GPUShaderModule_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUShaderModule,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUShaderModule,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUShaderModule_Binding
namespace GPUShaderStage_Binding {
MOZ_GLOBINIT static const ConstantSpec sConstants_specs[] = {
{ "VERTEX", JS::NumberValue(1U) },
{ "FRAGMENT", JS::NumberValue(2U) },
{ "COMPUTE", JS::NumberValue(4U) },
{ 0, JS::UndefinedValue() }
};
static const PrefableDisablers sConstants_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const ConstantSpec> sConstants[] = {
{ &sConstants_disablers0, &sConstants_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[3];
static PropertyInfo sNativeProperties_propertyInfos[3];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
false, 0,
false, 0,
false, 0,
true, 0 /* sConstants */,
-1,
3,
sNativeProperties_sortedPropertyIndices,
{
{ sConstants, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(3 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::_ID_Count,
constructors::id::GPUShaderStage,
&DefaultXrayExpandoObjectClass
};
static const DOMIfaceAndProtoJSClass sNamespaceObjectClass = {
{
"GPUShaderStage",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS,
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eNamespace,
prototypes::id::_ID_Count,
0,
&sNativePropertyHooks,
// This isn't strictly following the spec (see
// but should be ok for Xrays.
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!constructorProto) {
return;
}
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUShaderStage);
dom::CreateNamespaceObject(aCx, aGlobal, constructorProto,
sNamespaceObjectClass,
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUShaderStage",
ShouldExpose<GPUShaderStage_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal));
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUShaderStage,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUShaderStage_Binding
namespace GPUSupportedFeatures_Binding {
namespace SetlikeHelpers {
void
Clear(mozilla::webgpu::SupportedFeatures* self, ErrorResult& aRv)
{
MOZ_ASSERT(self);
AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
// It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
// all we want is to wrap into _some_ scope and then unwrap to find
// the reflector, and wrapping has no side-effects.
JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible);
if (!scope) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
JSAutoRealm tempRealm(cx, scope);
JS::Rooted<JS::Value> v(cx);
if(!ToJSValue(cx, self, &v)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
// This is a reflector, but due to trying to name things
// similarly across method generators, it's called obj here.
JS::Rooted<JSObject*> obj(cx);
obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
JSAutoRealm reflectorRealm(cx, obj);
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
if (created) {
PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
}
if (!JS::SetClear(cx, backingObj)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
}
bool
Delete(mozilla::webgpu::SupportedFeatures* self, const nsAString& aKey, ErrorResult& aRv)
{
MOZ_ASSERT(self);
AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
// It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
// all we want is to wrap into _some_ scope and then unwrap to find
// the reflector, and wrapping has no side-effects.
JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible);
if (!scope) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
JSAutoRealm tempRealm(cx, scope);
JS::Rooted<JS::Value> v(cx);
if(!ToJSValue(cx, self, &v)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
// This is a reflector, but due to trying to name things
// similarly across method generators, it's called obj here.
JS::Rooted<JSObject*> obj(cx);
obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
JSAutoRealm reflectorRealm(cx, obj);
JS::RootedVector<JS::Value> argv(cx);
if (!argv.resize(1)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
do {
if (!xpc::NonVoidStringToJsval(cx, aKey, argv[0])) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
break;
} while (false);
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
if (created) {
PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
}
bool retVal;
if (!JS::SetDelete(cx, backingObj, argv[0], &retVal)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
return retVal;
}
bool
Has(mozilla::webgpu::SupportedFeatures* self, const nsAString& aKey, ErrorResult& aRv)
{
MOZ_ASSERT(self);
AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
// It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
// all we want is to wrap into _some_ scope and then unwrap to find
// the reflector, and wrapping has no side-effects.
JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible);
if (!scope) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
JSAutoRealm tempRealm(cx, scope);
JS::Rooted<JS::Value> v(cx);
if(!ToJSValue(cx, self, &v)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
// This is a reflector, but due to trying to name things
// similarly across method generators, it's called obj here.
JS::Rooted<JSObject*> obj(cx);
obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
JSAutoRealm reflectorRealm(cx, obj);
JS::RootedVector<JS::Value> argv(cx);
if (!argv.resize(1)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
do {
if (!xpc::NonVoidStringToJsval(cx, aKey, argv[0])) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
break;
} while (false);
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
if (created) {
PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
}
bool retVal;
if (!JS::SetHas(cx, backingObj, argv[0], &retVal)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
return retVal;
}
void
Add(mozilla::webgpu::SupportedFeatures* self, const nsAString& aKey, ErrorResult& aRv)
{
MOZ_ASSERT(self);
AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
// It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
// all we want is to wrap into _some_ scope and then unwrap to find
// the reflector, and wrapping has no side-effects.
JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible);
if (!scope) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
JSAutoRealm tempRealm(cx, scope);
JS::Rooted<JS::Value> v(cx);
if(!ToJSValue(cx, self, &v)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
// This is a reflector, but due to trying to name things
// similarly across method generators, it's called obj here.
JS::Rooted<JSObject*> obj(cx);
obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
JSAutoRealm reflectorRealm(cx, obj);
JS::RootedVector<JS::Value> argv(cx);
if (!argv.resize(1)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
do {
if (!xpc::NonVoidStringToJsval(cx, aKey, argv[0])) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
break;
} while (false);
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
if (created) {
PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
}
if (!JS::SetAdd(cx, backingObj, argv[0])) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
}
} // namespace SetlikeHelpers
MOZ_CAN_RUN_SCRIPT static bool
get_size(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedFeatures", "size", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedFeatures*>(void_self);
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
return false;
}
if (created) {
PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
}
uint32_t result = JS::SetSize(cx, backingObj);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo size_getterinfo = {
{ get_size },
{ prototypes::id::GPUSupportedFeatures },
{ PrototypeTraits<prototypes::id::GPUSupportedFeatures>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
entries(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedFeatures", "entries", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedFeatures*>(void_self);
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
return false;
}
if (created) {
PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
}
// TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
// after bug 1023984 is fixed.
if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
return false;
}
JS::Rooted<JSObject*> result(cx);
JS::Rooted<JS::Value> v(cx);
if (!JS::SetEntries(cx, backingObj, &v)) {
return false;
}
result = &v.toObject();
JS::ExposeObjectToActiveJS(result);
args.rval().setObject(*result);
if (!MaybeWrapObjectValue(cx, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo::ArgType entries_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
static const JSTypedMethodJitInfo entries_methodinfo = {
{
{ (JSJitGetterOp)entries },
{ prototypes::id::GPUSupportedFeatures },
{ PrototypeTraits<prototypes::id::GPUSupportedFeatures>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
true, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
},
entries_methodinfo_argTypes
};
MOZ_CAN_RUN_SCRIPT static bool
keys(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedFeatures", "keys", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedFeatures*>(void_self);
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
return false;
}
if (created) {
PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
}
// TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
// after bug 1023984 is fixed.
if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
return false;
}
JS::Rooted<JSObject*> result(cx);
JS::Rooted<JS::Value> v(cx);
if (!JS::SetKeys(cx, backingObj, &v)) {
return false;
}
result = &v.toObject();
JS::ExposeObjectToActiveJS(result);
args.rval().setObject(*result);
if (!MaybeWrapObjectValue(cx, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo::ArgType keys_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
static const JSTypedMethodJitInfo keys_methodinfo = {
{
{ (JSJitGetterOp)keys },
{ prototypes::id::GPUSupportedFeatures },
{ PrototypeTraits<prototypes::id::GPUSupportedFeatures>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
true, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
},
keys_methodinfo_argTypes
};
MOZ_CAN_RUN_SCRIPT static bool
values(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedFeatures", "values", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedFeatures*>(void_self);
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
return false;
}
if (created) {
PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
}
// TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
// after bug 1023984 is fixed.
if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
return false;
}
JS::Rooted<JSObject*> result(cx);
JS::Rooted<JS::Value> v(cx);
if (!JS::SetValues(cx, backingObj, &v)) {
return false;
}
result = &v.toObject();
JS::ExposeObjectToActiveJS(result);
args.rval().setObject(*result);
if (!MaybeWrapObjectValue(cx, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo::ArgType values_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
static const JSTypedMethodJitInfo values_methodinfo = {
{
{ (JSJitGetterOp)values },
{ prototypes::id::GPUSupportedFeatures },
{ PrototypeTraits<prototypes::id::GPUSupportedFeatures>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
true, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
},
values_methodinfo_argTypes
};
MOZ_CAN_RUN_SCRIPT static bool
forEach(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUSupportedFeatures.forEach");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedFeatures", "forEach", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedFeatures*>(void_self);
JS::Rooted<JSObject*> arg0(cx);
if (args.get(0).isObject()) {
arg0 = &args.get(0).toObject();
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
JS::Rooted<JS::Value> arg1(cx);
if (args.hasDefined(1)) {
arg1 = args.get(1);
} else {
arg1 = JS::UndefinedValue();
}
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
return false;
}
if (created) {
PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
}
// Create a wrapper function.
JSFunction* func = js::NewFunctionWithReserved(cx, ForEachHandler, 3, 0, nullptr);
if (!func) {
return false;
}
JS::Rooted<JSObject*> funcObj(cx, JS_GetFunctionObject(func));
JS::Rooted<JS::Value> funcVal(cx, JS::ObjectValue(*funcObj));
js::SetFunctionNativeReserved(funcObj, FOREACH_CALLBACK_SLOT,
JS::ObjectValue(*arg0));
js::SetFunctionNativeReserved(funcObj, FOREACH_MAPLIKEORSETLIKEOBJ_SLOT,
JS::ObjectValue(*obj));
if (!JS::SetForEach(cx, backingObj, funcVal, arg1)) {
return false;
}
args.rval().setUndefined();
return true;
}
static const JSJitInfo forEach_methodinfo = {
{ (JSJitGetterOp)forEach },
{ prototypes::id::GPUSupportedFeatures },
{ PrototypeTraits<prototypes::id::GPUSupportedFeatures>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
has(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedFeatures", "has", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedFeatures*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
return false;
}
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
return false;
}
if (created) {
PreserveWrapper<mozilla::webgpu::SupportedFeatures>(self);
}
JS::Rooted<JS::Value> arg0Val(cx);
if (!ToJSValue(cx, arg0, &arg0Val)) {
return false;
}
bool result;
if (!JS::SetHas(cx, backingObj, arg0Val, &result)) {
return false;
}
args.rval().setBoolean(result);
return true;
}
static const JSJitInfo::ArgType has_methodinfo_argTypes[] = { JSJitInfo::String, JSJitInfo::ArgTypeListEnd };
static const JSTypedMethodJitInfo has_methodinfo = {
{
{ (JSJitGetterOp)has },
{ prototypes::id::GPUSupportedFeatures },
{ PrototypeTraits<prototypes::id::GPUSupportedFeatures>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
true, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
},
has_methodinfo_argTypes
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::SupportedFeatures* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::SupportedFeatures>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::SupportedFeatures>(self);
}
}
MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("entries", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&entries_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("keys", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&keys_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("values", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&values_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("forEach", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&forEach_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("has", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&has_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ nullptr, &sMethods_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("size", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &size_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[6];
static PropertyInfo sNativeProperties_propertyInfos[6];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
2,
6,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[5] }
}
};
static_assert(2 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.iteratorAliasMethodIndex) - 1),
"We have an iterator alias index that is oversized");
static_assert(6 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
// This may allocate too many slots, because we only really need
// slots for our non-interface-typed members that we cache. But
// allocating slots only for those would make the slot index
// computations much more complicated, so let's do this the simple
// way for now.
DEFINE_XRAY_EXPANDO_CLASS_WITH_OPS(static, sXrayExpandoObjectClass, 1,
&xpc::XrayExpandoObjectClassOps);
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUSupportedFeatures,
constructors::id::GPUSupportedFeatures,
&sXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUSupportedFeatures>::Depth,
prototypes::id::GPUSupportedFeatures,
true,
0,
"GPUSupportedFeatures",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUSupportedFeaturesPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUSupportedFeatures,
PrototypeTraits<prototypes::id::GPUSupportedFeatures>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUSupportedFeatures",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::SupportedFeatures>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUSupportedFeatures, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::SupportedFeatures>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::SupportedFeatures>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::SupportedFeatures>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::SupportedFeatures>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(2 >= 2,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::SupportedFeatures* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::SupportedFeatures>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::SupportedFeatures*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::SupportedFeatures> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUSupportedFeatures);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUSupportedFeatures);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUSupportedFeatures",
ShouldExpose<GPUSupportedFeatures_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
JS::AssertObjectIsNotGray(*protoCache);
JS::Handle<JSObject*> proto = JS::Handle<JSObject*>::fromMarkedLocation(protoCache->unsafeAddress());
if (!proto) {
*protoCache = nullptr;
if (interfaceCache) {
*interfaceCache = nullptr;
}
return;
}
// Set up aliases on the interface prototype object we just created.
JS::Rooted<JS::Value> aliasedVal(aCx);
if (!JS_GetProperty(aCx, proto, "values", &aliasedVal)) {
*protoCache = nullptr;
if (interfaceCache) {
*interfaceCache = nullptr;
}
return;
}
JS::Rooted<jsid> iteratorId(aCx, JS::GetWellKnownSymbolKey(aCx, JS::SymbolCode::iterator));
if (!JS_DefinePropertyById(aCx, proto, iteratorId, aliasedVal, 0)) {
*protoCache = nullptr;
if (interfaceCache) {
*interfaceCache = nullptr;
}
return;
}
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUSupportedFeatures,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUSupportedFeatures,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUSupportedFeatures_Binding
namespace GPUSupportedLimits_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_maxTextureDimension1D(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxTextureDimension1D", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxTextureDimension1D());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxTextureDimension1D_getterinfo = {
{ get_maxTextureDimension1D },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxTextureDimension2D(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxTextureDimension2D", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxTextureDimension2D());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxTextureDimension2D_getterinfo = {
{ get_maxTextureDimension2D },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxTextureDimension3D(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxTextureDimension3D", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxTextureDimension3D());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxTextureDimension3D_getterinfo = {
{ get_maxTextureDimension3D },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxTextureArrayLayers(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxTextureArrayLayers", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxTextureArrayLayers());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxTextureArrayLayers_getterinfo = {
{ get_maxTextureArrayLayers },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxBindGroups(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxBindGroups", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxBindGroups());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxBindGroups_getterinfo = {
{ get_maxBindGroups },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxBindGroupsPlusVertexBuffers(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxBindGroupsPlusVertexBuffers", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxBindGroupsPlusVertexBuffers());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxBindGroupsPlusVertexBuffers_getterinfo = {
{ get_maxBindGroupsPlusVertexBuffers },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxBindingsPerBindGroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxBindingsPerBindGroup", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxBindingsPerBindGroup());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxBindingsPerBindGroup_getterinfo = {
{ get_maxBindingsPerBindGroup },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxDynamicUniformBuffersPerPipelineLayout(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxDynamicUniformBuffersPerPipelineLayout", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxDynamicUniformBuffersPerPipelineLayout());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxDynamicUniformBuffersPerPipelineLayout_getterinfo = {
{ get_maxDynamicUniformBuffersPerPipelineLayout },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxDynamicStorageBuffersPerPipelineLayout(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxDynamicStorageBuffersPerPipelineLayout", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxDynamicStorageBuffersPerPipelineLayout());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxDynamicStorageBuffersPerPipelineLayout_getterinfo = {
{ get_maxDynamicStorageBuffersPerPipelineLayout },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxSampledTexturesPerShaderStage(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxSampledTexturesPerShaderStage", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxSampledTexturesPerShaderStage());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxSampledTexturesPerShaderStage_getterinfo = {
{ get_maxSampledTexturesPerShaderStage },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxSamplersPerShaderStage(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxSamplersPerShaderStage", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxSamplersPerShaderStage());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxSamplersPerShaderStage_getterinfo = {
{ get_maxSamplersPerShaderStage },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxStorageBuffersPerShaderStage(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxStorageBuffersPerShaderStage", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxStorageBuffersPerShaderStage());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxStorageBuffersPerShaderStage_getterinfo = {
{ get_maxStorageBuffersPerShaderStage },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxStorageTexturesPerShaderStage(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxStorageTexturesPerShaderStage", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxStorageTexturesPerShaderStage());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxStorageTexturesPerShaderStage_getterinfo = {
{ get_maxStorageTexturesPerShaderStage },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxUniformBuffersPerShaderStage(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxUniformBuffersPerShaderStage", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxUniformBuffersPerShaderStage());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxUniformBuffersPerShaderStage_getterinfo = {
{ get_maxUniformBuffersPerShaderStage },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxUniformBufferBindingSize(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxUniformBufferBindingSize", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint64_t result(MOZ_KnownLive(self)->MaxUniformBufferBindingSize());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().set(JS_NumberValue(double(result)));
return true;
}
static const JSJitInfo maxUniformBufferBindingSize_getterinfo = {
{ get_maxUniformBufferBindingSize },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxStorageBufferBindingSize(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxStorageBufferBindingSize", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint64_t result(MOZ_KnownLive(self)->MaxStorageBufferBindingSize());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().set(JS_NumberValue(double(result)));
return true;
}
static const JSJitInfo maxStorageBufferBindingSize_getterinfo = {
{ get_maxStorageBufferBindingSize },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_minUniformBufferOffsetAlignment(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "minUniformBufferOffsetAlignment", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MinUniformBufferOffsetAlignment());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo minUniformBufferOffsetAlignment_getterinfo = {
{ get_minUniformBufferOffsetAlignment },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_minStorageBufferOffsetAlignment(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "minStorageBufferOffsetAlignment", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MinStorageBufferOffsetAlignment());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo minStorageBufferOffsetAlignment_getterinfo = {
{ get_minStorageBufferOffsetAlignment },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxVertexBuffers(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxVertexBuffers", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxVertexBuffers());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxVertexBuffers_getterinfo = {
{ get_maxVertexBuffers },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxBufferSize(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxBufferSize", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint64_t result(MOZ_KnownLive(self)->MaxBufferSize());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().set(JS_NumberValue(double(result)));
return true;
}
static const JSJitInfo maxBufferSize_getterinfo = {
{ get_maxBufferSize },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxVertexAttributes(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxVertexAttributes", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxVertexAttributes());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxVertexAttributes_getterinfo = {
{ get_maxVertexAttributes },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxVertexBufferArrayStride(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxVertexBufferArrayStride", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxVertexBufferArrayStride());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxVertexBufferArrayStride_getterinfo = {
{ get_maxVertexBufferArrayStride },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxInterStageShaderVariables(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxInterStageShaderVariables", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxInterStageShaderVariables());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxInterStageShaderVariables_getterinfo = {
{ get_maxInterStageShaderVariables },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxColorAttachments(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxColorAttachments", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxColorAttachments());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxColorAttachments_getterinfo = {
{ get_maxColorAttachments },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxColorAttachmentBytesPerSample(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxColorAttachmentBytesPerSample", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxColorAttachmentBytesPerSample());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxColorAttachmentBytesPerSample_getterinfo = {
{ get_maxColorAttachmentBytesPerSample },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxComputeWorkgroupStorageSize(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxComputeWorkgroupStorageSize", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxComputeWorkgroupStorageSize());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxComputeWorkgroupStorageSize_getterinfo = {
{ get_maxComputeWorkgroupStorageSize },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxComputeInvocationsPerWorkgroup(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxComputeInvocationsPerWorkgroup", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxComputeInvocationsPerWorkgroup());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxComputeInvocationsPerWorkgroup_getterinfo = {
{ get_maxComputeInvocationsPerWorkgroup },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxComputeWorkgroupSizeX(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxComputeWorkgroupSizeX", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxComputeWorkgroupSizeX());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxComputeWorkgroupSizeX_getterinfo = {
{ get_maxComputeWorkgroupSizeX },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxComputeWorkgroupSizeY(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxComputeWorkgroupSizeY", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxComputeWorkgroupSizeY());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxComputeWorkgroupSizeY_getterinfo = {
{ get_maxComputeWorkgroupSizeY },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxComputeWorkgroupSizeZ(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxComputeWorkgroupSizeZ", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxComputeWorkgroupSizeZ());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxComputeWorkgroupSizeZ_getterinfo = {
{ get_maxComputeWorkgroupSizeZ },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_maxComputeWorkgroupsPerDimension(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUSupportedLimits", "maxComputeWorkgroupsPerDimension", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::SupportedLimits*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MaxComputeWorkgroupsPerDimension());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo maxComputeWorkgroupsPerDimension_getterinfo = {
{ get_maxComputeWorkgroupsPerDimension },
{ prototypes::id::GPUSupportedLimits },
{ PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::SupportedLimits* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::SupportedLimits>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::SupportedLimits>(self);
}
}
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("maxTextureDimension1D", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxTextureDimension1D_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxTextureDimension2D", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxTextureDimension2D_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxTextureDimension3D", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxTextureDimension3D_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxTextureArrayLayers", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxTextureArrayLayers_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxBindGroups", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxBindGroups_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxBindGroupsPlusVertexBuffers", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxBindGroupsPlusVertexBuffers_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxBindingsPerBindGroup", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxBindingsPerBindGroup_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxDynamicUniformBuffersPerPipelineLayout", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxDynamicUniformBuffersPerPipelineLayout_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxDynamicStorageBuffersPerPipelineLayout", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxDynamicStorageBuffersPerPipelineLayout_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxSampledTexturesPerShaderStage", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxSampledTexturesPerShaderStage_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxSamplersPerShaderStage", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxSamplersPerShaderStage_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxStorageBuffersPerShaderStage", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxStorageBuffersPerShaderStage_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxStorageTexturesPerShaderStage", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxStorageTexturesPerShaderStage_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxUniformBuffersPerShaderStage", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxUniformBuffersPerShaderStage_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxUniformBufferBindingSize", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxUniformBufferBindingSize_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxStorageBufferBindingSize", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxStorageBufferBindingSize_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("minUniformBufferOffsetAlignment", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &minUniformBufferOffsetAlignment_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("minStorageBufferOffsetAlignment", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &minStorageBufferOffsetAlignment_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxVertexBuffers", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxVertexBuffers_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxBufferSize", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxBufferSize_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxVertexAttributes", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxVertexAttributes_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxVertexBufferArrayStride", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxVertexBufferArrayStride_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxInterStageShaderVariables", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxInterStageShaderVariables_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxColorAttachments", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxColorAttachments_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxColorAttachmentBytesPerSample", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxColorAttachmentBytesPerSample_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxComputeWorkgroupStorageSize", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxComputeWorkgroupStorageSize_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxComputeInvocationsPerWorkgroup", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxComputeInvocationsPerWorkgroup_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxComputeWorkgroupSizeX", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxComputeWorkgroupSizeX_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxComputeWorkgroupSizeY", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxComputeWorkgroupSizeY_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxComputeWorkgroupSizeZ", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxComputeWorkgroupSizeZ_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("maxComputeWorkgroupsPerDimension", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &maxComputeWorkgroupsPerDimension_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(31 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[31];
static PropertyInfo sNativeProperties_propertyInfos[31];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
31,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(31 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUSupportedLimits,
constructors::id::GPUSupportedLimits,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth,
prototypes::id::GPUSupportedLimits,
true,
0,
"GPUSupportedLimits",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUSupportedLimitsPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUSupportedLimits,
PrototypeTraits<prototypes::id::GPUSupportedLimits>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUSupportedLimits",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::SupportedLimits>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUSupportedLimits, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::SupportedLimits>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::SupportedLimits>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::SupportedLimits>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::SupportedLimits>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::SupportedLimits* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::SupportedLimits>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::SupportedLimits*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::SupportedLimits> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUSupportedLimits);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUSupportedLimits);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUSupportedLimits",
ShouldExpose<GPUSupportedLimits_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUSupportedLimits,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUSupportedLimits,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUSupportedLimits_Binding
namespace GPUTexture_Binding {
MOZ_CAN_RUN_SCRIPT static bool
createView(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "GPUTexture.createView");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUTexture", "createView", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
binding_detail::FastGPUTextureViewDescriptor arg0;
if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1", false)) {
return false;
}
auto result(StrongOrRawPtr<mozilla::webgpu::TextureView>(MOZ_KnownLive(self)->CreateView(Constify(arg0))));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const JSJitInfo createView_methodinfo = {
{ (JSJitGetterOp)createView },
{ prototypes::id::GPUTexture },
{ PrototypeTraits<prototypes::id::GPUTexture>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
destroy(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUTexture", "destroy", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->Destroy())>, "Should be returning void here");
MOZ_KnownLive(self)->Destroy();
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setUndefined();
return true;
}
static const JSJitInfo destroy_methodinfo = {
{ (JSJitGetterOp)destroy },
{ prototypes::id::GPUTexture },
{ PrototypeTraits<prototypes::id::GPUTexture>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_width(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUTexture", "width", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
uint32_t result(MOZ_KnownLive(self)->Width());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo width_getterinfo = {
{ get_width },
{ prototypes::id::GPUTexture },
{ PrototypeTraits<prototypes::id::GPUTexture>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_height(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUTexture", "height", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
uint32_t result(MOZ_KnownLive(self)->Height());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo height_getterinfo = {
{ get_height },
{ prototypes::id::GPUTexture },
{ PrototypeTraits<prototypes::id::GPUTexture>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_depthOrArrayLayers(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUTexture", "depthOrArrayLayers", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
uint32_t result(MOZ_KnownLive(self)->DepthOrArrayLayers());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo depthOrArrayLayers_getterinfo = {
{ get_depthOrArrayLayers },
{ prototypes::id::GPUTexture },
{ PrototypeTraits<prototypes::id::GPUTexture>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_mipLevelCount(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUTexture", "mipLevelCount", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
uint32_t result(MOZ_KnownLive(self)->MipLevelCount());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo mipLevelCount_getterinfo = {
{ get_mipLevelCount },
{ prototypes::id::GPUTexture },
{ PrototypeTraits<prototypes::id::GPUTexture>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_sampleCount(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUTexture", "sampleCount", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
uint32_t result(MOZ_KnownLive(self)->SampleCount());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo sampleCount_getterinfo = {
{ get_sampleCount },
{ prototypes::id::GPUTexture },
{ PrototypeTraits<prototypes::id::GPUTexture>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_dimension(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUTexture", "dimension", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
GPUTextureDimension result(MOZ_KnownLive(self)->Dimension());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo dimension_getterinfo = {
{ get_dimension },
{ prototypes::id::GPUTexture },
{ PrototypeTraits<prototypes::id::GPUTexture>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_format(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUTexture", "format", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
GPUTextureFormat result(MOZ_KnownLive(self)->Format());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!ToJSValue(cx, result, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo format_getterinfo = {
{ get_format },
{ prototypes::id::GPUTexture },
{ PrototypeTraits<prototypes::id::GPUTexture>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_usage(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUTexture", "usage", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
uint32_t result(MOZ_KnownLive(self)->Usage());
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo usage_getterinfo = {
{ get_usage },
{ prototypes::id::GPUTexture },
{ PrototypeTraits<prototypes::id::GPUTexture>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUTexture", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUTexture", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::Texture*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPUTexture },
{ PrototypeTraits<prototypes::id::GPUTexture>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPUTexture },
{ PrototypeTraits<prototypes::id::GPUTexture>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::Texture* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::Texture>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::Texture>(self);
}
}
MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("createView", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&createView_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("destroy", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&destroy_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const PrefableDisablers sMethods_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ &sMethods_disablers0, &sMethods_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("width", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &width_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("height", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &height_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("depthOrArrayLayers", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &depthOrArrayLayers_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("mipLevelCount", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &mipLevelCount_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("sampleCount", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &sampleCount_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("dimension", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &dimension_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("format", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &format_getterinfo, nullptr, nullptr),
JSPropertySpec::nativeAccessors("usage", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &usage_getterinfo, nullptr, nullptr),
JS_PS_END,
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const PrefableDisablers sAttributes_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ &sAttributes_disablers0, &sAttributes_specs[0] },
{ nullptr, &sAttributes_specs[9] },
{ nullptr, nullptr }
};
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(8 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[11];
static PropertyInfo sNativeProperties_propertyInfos[11];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
11,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[2] }
}
};
static_assert(11 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUTexture,
constructors::id::GPUTexture,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUTexture>::Depth,
prototypes::id::GPUTexture,
true,
0,
"GPUTexture",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUTexturePrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUTexture,
PrototypeTraits<prototypes::id::GPUTexture>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUTexture",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::Texture>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUTexture, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::Texture>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::Texture>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::Texture>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::Texture>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::Texture* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::Texture>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::Texture*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::Texture> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUTexture);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUTexture);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUTexture",
ShouldExpose<GPUTexture_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUTexture,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUTexture,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUTexture_Binding
namespace GPUTextureUsage_Binding {
MOZ_GLOBINIT static const ConstantSpec sConstants_specs[] = {
{ "COPY_SRC", JS::NumberValue(1U) },
{ "COPY_DST", JS::NumberValue(2U) },
{ "TEXTURE_BINDING", JS::NumberValue(4U) },
{ "STORAGE_BINDING", JS::NumberValue(8U) },
{ "RENDER_ATTACHMENT", JS::NumberValue(16U) },
{ 0, JS::UndefinedValue() }
};
static const PrefableDisablers sConstants_disablers0 = {
WebIDLPrefIndex::NoPref, 0, true, OriginTrial(0), nullptr
};
static const Prefable<const ConstantSpec> sConstants[] = {
{ &sConstants_disablers0, &sConstants_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[5];
static PropertyInfo sNativeProperties_propertyInfos[5];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
false, 0,
false, 0,
false, 0,
true, 0 /* sConstants */,
-1,
5,
sNativeProperties_sortedPropertyIndices,
{
{ sConstants, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(5 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::_ID_Count,
constructors::id::GPUTextureUsage,
&DefaultXrayExpandoObjectClass
};
static const DOMIfaceAndProtoJSClass sNamespaceObjectClass = {
{
"GPUTextureUsage",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS,
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eNamespace,
prototypes::id::_ID_Count,
0,
&sNativePropertyHooks,
// This isn't strictly following the spec (see
// but should be ok for Xrays.
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmObjectPrototype(aCx));
if (!constructorProto) {
return;
}
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUTextureUsage);
dom::CreateNamespaceObject(aCx, aGlobal, constructorProto,
sNamespaceObjectClass,
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUTextureUsage",
ShouldExpose<GPUTextureUsage_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal));
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUTextureUsage,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUTextureUsage_Binding
namespace GPUTextureView_Binding {
MOZ_CAN_RUN_SCRIPT static bool
get_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUTextureView", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::TextureView*>(void_self);
DOMString result;
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->GetLabel(result))>, "Should be returning void here");
MOZ_KnownLive(self)->GetLabel(result);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
return false;
}
return true;
}
MOZ_CAN_RUN_SCRIPT static bool
set_label(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitSetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUTextureView", "label", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_SETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::TextureView*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
if (!NormalizeUSVString(arg0)) {
JS_ReportOutOfMemory(cx);
return false;
}
// NOTE: This assert does NOT call the function.
static_assert(std::is_void_v<decltype(MOZ_KnownLive(self)->SetLabel(Constify(arg0)))>, "Should be returning void here");
MOZ_KnownLive(self)->SetLabel(Constify(arg0));
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return true;
}
static const JSJitInfo label_getterinfo = {
{ get_label },
{ prototypes::id::GPUTextureView },
{ PrototypeTraits<prototypes::id::GPUTextureView>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static const JSJitInfo label_setterinfo = {
{ (JSJitGetterOp)set_label },
{ prototypes::id::GPUTextureView },
{ PrototypeTraits<prototypes::id::GPUTextureView>::Depth },
JSJitInfo::Setter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::TextureView* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::TextureView>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::TextureView>(self);
}
}
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("label", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &label_getterinfo, GenericSetter<NormalThisPolicy>, &label_setterinfo),
JS_PS_END
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[1];
static PropertyInfo sNativeProperties_propertyInfos[1];
static const NativePropertiesN<1> sNativeProperties = {
false, 0,
false, 0,
false, 0,
true, 0 /* sAttributes */,
false, 0,
false, 0,
false, 0,
-1,
1,
sNativeProperties_sortedPropertyIndices,
{
{ sAttributes, &sNativeProperties_propertyInfos[0] }
}
};
static_assert(1 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::GPUTextureView,
constructors::id::GPUTextureView,
&DefaultXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::GPUTextureView>::Depth,
prototypes::id::GPUTextureView,
true,
0,
"GPUTextureView",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUTextureViewPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUTextureView,
PrototypeTraits<prototypes::id::GPUTextureView>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUTextureView",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::TextureView>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUTextureView, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::TextureView>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::TextureView>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::TextureView>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::TextureView>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::TextureView* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::TextureView>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::TextureView*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::TextureView> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUTextureView);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUTextureView);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"GPUTextureView",
ShouldExpose<GPUTextureView_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUTextureView,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUTextureView,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUTextureView_Binding
namespace GPUValidationError_Binding {
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<GPUError_Binding::NativeType>::value,
"Can't inherit from an interface with a different ownership model.");
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::ValidationError* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::ValidationError>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::ValidationError>(self);
}
}
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ nullptr, nullptr, &sNativePropertiesInited },
prototypes::id::GPUValidationError,
constructors::id::GPUValidationError,
&DefaultXrayExpandoObjectClass
};
static bool
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"GPUValidationError", "constructor", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS::Rooted<JSObject*> obj(cx, &args.callee());
if (!args.isConstructing()) {
return ThrowConstructorWithoutNew(cx, "GPUValidationError");
}
JS::Rooted<JSObject*> desiredProto(cx);
if (!GetDesiredProto(cx, args,
prototypes::id::GPUValidationError,
CreateInterfaceObjects,
&desiredProto)) {
return false;
}
if (!args.requireAtLeast(cx, "GPUValidationError constructor", 1)) {
return false;
}
GlobalObject global(cx, obj);
if (global.Failed()) {
return false;
}
bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
return false;
}
Maybe<JSAutoRealm> ar;
if (objIsXray) {
// Since our object is an Xray, we can just CheckedUnwrapStatic:
// we know Xrays have no dynamic unwrap behavior.
obj = js::CheckedUnwrapStatic(obj);
if (!obj) {
return false;
}
ar.emplace(cx, obj);
if (!JS_WrapObject(cx, &desiredProto)) {
return false;
}
}
FastErrorResult rv;
auto result(StrongOrRawPtr<mozilla::webgpu::ValidationError>(mozilla::webgpu::ValidationError::Constructor(global, NonNullHelper(Constify(arg0)), rv)));
if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx, "GPUValidationError constructor"))) {
return false;
}
MOZ_ASSERT(!JS_IsExceptionPending(cx));
static_assert(!std::is_pointer_v<decltype(result)>,
"NewObject implies that we need to keep the object alive with a strong reference.");
if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
MOZ_ASSERT(JS_IsExceptionPending(cx));
return false;
}
return true;
}
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ _constructor, &sNativePropertyHooks },
GPUError_Binding::GetConstructorObjectHandle,
PrototypeTraits<prototypes::id::GPUValidationError>::Depth,
prototypes::id::GPUValidationError,
true,
1,
"GPUValidationError",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"GPUValidationErrorPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::GPUValidationError,
PrototypeTraits<prototypes::id::GPUValidationError>::Depth,
&sNativePropertyHooks,
GPUError_Binding::GetProtoObject
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "GPUValidationError",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::ValidationError>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::GPUError, prototypes::id::GPUValidationError, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::ValidationError>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::ValidationError>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::ValidationError>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::ValidationError>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(1 >= 1,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::ValidationError* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::ValidationError>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::ValidationError*>);
MOZ_ASSERT(static_cast<mozilla::webgpu::Error*>(aObject) ==
reinterpret_cast<mozilla::webgpu::Error*>(aObject),
"Multiple inheritance for mozilla::webgpu::Error is broken.");
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::ValidationError> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GPUValidationError);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GPUValidationError);
JS::Handle<JSObject*> parentProto(GPUError_Binding::GetProtoObjectHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(GPUError_Binding::GetConstructorObjectHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 1, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
nullptr,
nullptr,
"GPUValidationError",
ShouldExpose<GPUValidationError_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::GPUValidationError,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::GPUValidationError,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace GPUValidationError_Binding
namespace WGSLLanguageFeatures_Binding {
namespace SetlikeHelpers {
void
Clear(mozilla::webgpu::WGSLLanguageFeatures* self, ErrorResult& aRv)
{
MOZ_ASSERT(self);
AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
// It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
// all we want is to wrap into _some_ scope and then unwrap to find
// the reflector, and wrapping has no side-effects.
JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible);
if (!scope) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
JSAutoRealm tempRealm(cx, scope);
JS::Rooted<JS::Value> v(cx);
if(!ToJSValue(cx, self, &v)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
// This is a reflector, but due to trying to name things
// similarly across method generators, it's called obj here.
JS::Rooted<JSObject*> obj(cx);
obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
JSAutoRealm reflectorRealm(cx, obj);
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
if (created) {
PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
}
if (!JS::SetClear(cx, backingObj)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
}
bool
Delete(mozilla::webgpu::WGSLLanguageFeatures* self, const nsAString& aKey, ErrorResult& aRv)
{
MOZ_ASSERT(self);
AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
// It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
// all we want is to wrap into _some_ scope and then unwrap to find
// the reflector, and wrapping has no side-effects.
JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible);
if (!scope) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
JSAutoRealm tempRealm(cx, scope);
JS::Rooted<JS::Value> v(cx);
if(!ToJSValue(cx, self, &v)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
// This is a reflector, but due to trying to name things
// similarly across method generators, it's called obj here.
JS::Rooted<JSObject*> obj(cx);
obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
JSAutoRealm reflectorRealm(cx, obj);
JS::RootedVector<JS::Value> argv(cx);
if (!argv.resize(1)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
do {
if (!xpc::NonVoidStringToJsval(cx, aKey, argv[0])) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
break;
} while (false);
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
if (created) {
PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
}
bool retVal;
if (!JS::SetDelete(cx, backingObj, argv[0], &retVal)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
return retVal;
}
bool
Has(mozilla::webgpu::WGSLLanguageFeatures* self, const nsAString& aKey, ErrorResult& aRv)
{
MOZ_ASSERT(self);
AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
// It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
// all we want is to wrap into _some_ scope and then unwrap to find
// the reflector, and wrapping has no side-effects.
JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible);
if (!scope) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
JSAutoRealm tempRealm(cx, scope);
JS::Rooted<JS::Value> v(cx);
if(!ToJSValue(cx, self, &v)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
// This is a reflector, but due to trying to name things
// similarly across method generators, it's called obj here.
JS::Rooted<JSObject*> obj(cx);
obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
JSAutoRealm reflectorRealm(cx, obj);
JS::RootedVector<JS::Value> argv(cx);
if (!argv.resize(1)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
do {
if (!xpc::NonVoidStringToJsval(cx, aKey, argv[0])) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
break;
} while (false);
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
if (created) {
PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
}
bool retVal;
if (!JS::SetHas(cx, backingObj, argv[0], &retVal)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return bool(0);
}
return retVal;
}
void
Add(mozilla::webgpu::WGSLLanguageFeatures* self, const nsAString& aKey, ErrorResult& aRv)
{
MOZ_ASSERT(self);
AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
// It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
// all we want is to wrap into _some_ scope and then unwrap to find
// the reflector, and wrapping has no side-effects.
JSObject* scope = UnprivilegedJunkScopeOrWorkerGlobal(fallible);
if (!scope) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
JSAutoRealm tempRealm(cx, scope);
JS::Rooted<JS::Value> v(cx);
if(!ToJSValue(cx, self, &v)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
// This is a reflector, but due to trying to name things
// similarly across method generators, it's called obj here.
JS::Rooted<JSObject*> obj(cx);
obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
JSAutoRealm reflectorRealm(cx, obj);
JS::RootedVector<JS::Value> argv(cx);
if (!argv.resize(1)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
do {
if (!xpc::NonVoidStringToJsval(cx, aKey, argv[0])) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
break;
} while (false);
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
if (created) {
PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
}
if (!JS::SetAdd(cx, backingObj, argv[0])) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return;
}
}
} // namespace SetlikeHelpers
MOZ_CAN_RUN_SCRIPT static bool
get_size(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, JSJitGetterCallArgs args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"WGSLLanguageFeatures", "size", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_GETTER) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::WGSLLanguageFeatures*>(void_self);
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
return false;
}
if (created) {
PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
}
uint32_t result = JS::SetSize(cx, backingObj);
MOZ_ASSERT(!JS_IsExceptionPending(cx));
args.rval().setNumber(result);
return true;
}
static const JSJitInfo size_getterinfo = {
{ get_size },
{ prototypes::id::WGSLLanguageFeatures },
{ PrototypeTraits<prototypes::id::WGSLLanguageFeatures>::Depth },
JSJitInfo::Getter,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
true, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
entries(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"WGSLLanguageFeatures", "entries", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::WGSLLanguageFeatures*>(void_self);
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
return false;
}
if (created) {
PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
}
// TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
// after bug 1023984 is fixed.
if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
return false;
}
JS::Rooted<JSObject*> result(cx);
JS::Rooted<JS::Value> v(cx);
if (!JS::SetEntries(cx, backingObj, &v)) {
return false;
}
result = &v.toObject();
JS::ExposeObjectToActiveJS(result);
args.rval().setObject(*result);
if (!MaybeWrapObjectValue(cx, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo::ArgType entries_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
static const JSTypedMethodJitInfo entries_methodinfo = {
{
{ (JSJitGetterOp)entries },
{ prototypes::id::WGSLLanguageFeatures },
{ PrototypeTraits<prototypes::id::WGSLLanguageFeatures>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
true, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
},
entries_methodinfo_argTypes
};
MOZ_CAN_RUN_SCRIPT static bool
keys(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"WGSLLanguageFeatures", "keys", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::WGSLLanguageFeatures*>(void_self);
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
return false;
}
if (created) {
PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
}
// TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
// after bug 1023984 is fixed.
if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
return false;
}
JS::Rooted<JSObject*> result(cx);
JS::Rooted<JS::Value> v(cx);
if (!JS::SetKeys(cx, backingObj, &v)) {
return false;
}
result = &v.toObject();
JS::ExposeObjectToActiveJS(result);
args.rval().setObject(*result);
if (!MaybeWrapObjectValue(cx, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo::ArgType keys_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
static const JSTypedMethodJitInfo keys_methodinfo = {
{
{ (JSJitGetterOp)keys },
{ prototypes::id::WGSLLanguageFeatures },
{ PrototypeTraits<prototypes::id::WGSLLanguageFeatures>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
true, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
},
keys_methodinfo_argTypes
};
MOZ_CAN_RUN_SCRIPT static bool
values(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"WGSLLanguageFeatures", "values", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::WGSLLanguageFeatures*>(void_self);
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
return false;
}
if (created) {
PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
}
// TODO (Bug 1173651): Xrays currently cannot wrap iterators. Change
// after bug 1023984 is fixed.
if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
JS_ReportErrorASCII(cx, "Xray wrapping of iterators not supported.");
return false;
}
JS::Rooted<JSObject*> result(cx);
JS::Rooted<JS::Value> v(cx);
if (!JS::SetValues(cx, backingObj, &v)) {
return false;
}
result = &v.toObject();
JS::ExposeObjectToActiveJS(result);
args.rval().setObject(*result);
if (!MaybeWrapObjectValue(cx, args.rval())) {
return false;
}
return true;
}
static const JSJitInfo::ArgType values_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
static const JSTypedMethodJitInfo values_methodinfo = {
{
{ (JSJitGetterOp)values },
{ prototypes::id::WGSLLanguageFeatures },
{ PrototypeTraits<prototypes::id::WGSLLanguageFeatures>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
true, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
},
values_methodinfo_argTypes
};
MOZ_CAN_RUN_SCRIPT static bool
forEach(JSContext* cx_, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
BindingCallContext cx(cx_, "WGSLLanguageFeatures.forEach");
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"WGSLLanguageFeatures", "forEach", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::WGSLLanguageFeatures*>(void_self);
JS::Rooted<JSObject*> arg0(cx);
if (args.get(0).isObject()) {
arg0 = &args.get(0).toObject();
} else {
cx.ThrowErrorMessage<MSG_NOT_OBJECT>("Argument 1");
return false;
}
JS::Rooted<JS::Value> arg1(cx);
if (args.hasDefined(1)) {
arg1 = args.get(1);
} else {
arg1 = JS::UndefinedValue();
}
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
return false;
}
if (created) {
PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
}
// Create a wrapper function.
JSFunction* func = js::NewFunctionWithReserved(cx, ForEachHandler, 3, 0, nullptr);
if (!func) {
return false;
}
JS::Rooted<JSObject*> funcObj(cx, JS_GetFunctionObject(func));
JS::Rooted<JS::Value> funcVal(cx, JS::ObjectValue(*funcObj));
js::SetFunctionNativeReserved(funcObj, FOREACH_CALLBACK_SLOT,
JS::ObjectValue(*arg0));
js::SetFunctionNativeReserved(funcObj, FOREACH_MAPLIKEORSETLIKEOBJ_SLOT,
JS::ObjectValue(*obj));
if (!JS::SetForEach(cx, backingObj, funcVal, arg1)) {
return false;
}
args.rval().setUndefined();
return true;
}
static const JSJitInfo forEach_methodinfo = {
{ (JSJitGetterOp)forEach },
{ prototypes::id::WGSLLanguageFeatures },
{ PrototypeTraits<prototypes::id::WGSLLanguageFeatures>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
false, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
};
MOZ_CAN_RUN_SCRIPT static bool
has(JSContext* cx, JS::Handle<JSObject*> obj, void* void_self, const JSJitMethodCallArgs& args)
{
AUTO_PROFILER_LABEL_DYNAMIC_FAST(
"WGSLLanguageFeatures", "has", DOM, cx,
uint32_t(js::ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD) |
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
auto* self = static_cast<mozilla::webgpu::WGSLLanguageFeatures*>(void_self);
binding_detail::FakeString<char16_t> arg0;
if (!ConvertJSValueToString(cx, args.get(0), eStringify, eStringify, arg0)) {
return false;
}
JS::Rooted<JSObject*> backingObj(cx);
bool created = false;
if (!GetSetlikeBackingObject(cx, obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), &backingObj, &created)) {
return false;
}
if (created) {
PreserveWrapper<mozilla::webgpu::WGSLLanguageFeatures>(self);
}
JS::Rooted<JS::Value> arg0Val(cx);
if (!ToJSValue(cx, arg0, &arg0Val)) {
return false;
}
bool result;
if (!JS::SetHas(cx, backingObj, arg0Val, &result)) {
return false;
}
args.rval().setBoolean(result);
return true;
}
static const JSJitInfo::ArgType has_methodinfo_argTypes[] = { JSJitInfo::String, JSJitInfo::ArgTypeListEnd };
static const JSTypedMethodJitInfo has_methodinfo = {
{
{ (JSJitGetterOp)has },
{ prototypes::id::WGSLLanguageFeatures },
{ PrototypeTraits<prototypes::id::WGSLLanguageFeatures>::Depth },
JSJitInfo::Method,
JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
false, /* isInfallible. False in setters. */
false, /* isMovable. Not relevant for setters. */
false, /* isEliminatable. Not relevant for setters. */
false, /* isAlwaysInSlot. Only relevant for getters. */
false, /* isLazilyCachedInSlot. Only relevant for getters. */
true, /* isTypedMethod. Only relevant for methods. */
0 /* Reserved slot index, if we're stored in a slot, else 0. */
},
has_methodinfo_argTypes
};
static void
_finalize(JS::GCContext* gcx, JSObject* obj)
{
mozilla::webgpu::WGSLLanguageFeatures* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::webgpu::WGSLLanguageFeatures>(obj);
if (self) {
JS::SetReservedSlot(obj, DOM_OBJECT_SLOT, JS::UndefinedValue());
ClearWrapper(self, self, obj);
if (size_t mallocBytes = BindingJSObjectMallocBytes(self)) {
JS::RemoveAssociatedMemory(obj, mallocBytes,
JS::MemoryUse::DOMBinding);
}
AddForDeferredFinalization<mozilla::webgpu::WGSLLanguageFeatures>(self);
}
}
MOZ_GLOBINIT static const JSFunctionSpec sMethods_specs[] = {
JS_FNSPEC("entries", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&entries_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("keys", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&keys_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("values", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&values_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("forEach", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&forEach_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FNSPEC("has", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&has_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
JS_FS_END
};
static const Prefable<const JSFunctionSpec> sMethods[] = {
{ nullptr, &sMethods_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
MOZ_GLOBINIT static const JSPropertySpec sAttributes_specs[] = {
JSPropertySpec::nativeAccessors("size", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &size_getterinfo, nullptr, nullptr),
JS_PS_END
};
static const Prefable<const JSPropertySpec> sAttributes[] = {
{ nullptr, &sAttributes_specs[0] },
{ nullptr, nullptr }
};
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
"We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
"We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
static uint16_t sNativeProperties_sortedPropertyIndices[6];
static PropertyInfo sNativeProperties_propertyInfos[6];
static const NativePropertiesN<2> sNativeProperties = {
false, 0,
false, 0,
true, 0 /* sMethods */,
true, 1 /* sAttributes */,
false, 0,
false, 0,
false, 0,
2,
6,
sNativeProperties_sortedPropertyIndices,
{
{ sMethods, &sNativeProperties_propertyInfos[0] },
{ sAttributes, &sNativeProperties_propertyInfos[5] }
}
};
static_assert(2 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.iteratorAliasMethodIndex) - 1),
"We have an iterator alias index that is oversized");
static_assert(6 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount)),
"We have a property info count that is oversized");
// This may allocate too many slots, because we only really need
// slots for our non-interface-typed members that we cache. But
// allocating slots only for those would make the slot index
// computations much more complicated, so let's do this the simple
// way for now.
DEFINE_XRAY_EXPANDO_CLASS_WITH_OPS(static, sXrayExpandoObjectClass, 1,
&xpc::XrayExpandoObjectClassOps);
bool sNativePropertiesInited = false;
const NativePropertyHooks sNativePropertyHooks = {
nullptr,
{ sNativeProperties.Upcast(), nullptr, &sNativePropertiesInited },
prototypes::id::WGSLLanguageFeatures,
constructors::id::WGSLLanguageFeatures,
&sXrayExpandoObjectClass
};
static const DOMInterfaceInfo sInterfaceObjectInfo = {
{ ThrowingConstructor, &sNativePropertyHooks },
JS::GetRealmFunctionPrototypeHandle,
PrototypeTraits<prototypes::id::WGSLLanguageFeatures>::Depth,
prototypes::id::WGSLLanguageFeatures,
true,
0,
"WGSLLanguageFeatures",
};
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
{
"WGSLLanguageFeaturesPrototype",
JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
JS_NULL_CLASS_OPS,
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
},
eInterfacePrototype,
prototypes::id::WGSLLanguageFeatures,
PrototypeTraits<prototypes::id::WGSLLanguageFeatures>::Depth,
&sNativePropertyHooks,
JS::GetRealmObjectPrototype
};
bool
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
{
return mozilla::webgpu::Instance::PrefEnabled(aCx, aObj) &&
mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx);
static const JSClassOps sClassOps = {
nullptr, /* addProperty */
nullptr, /* delProperty */
nullptr, /* enumerate */
nullptr, /* newEnumerate */
nullptr, /* resolve */
nullptr, /* mayResolve */
_finalize, /* finalize */
nullptr, /* call */
nullptr, /* construct */
nullptr, /* trace */
};
static const DOMJSClass sClass = {
{ "WGSLLanguageFeatures",
JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_PRESERVES_WRAPPER,
&sClassOps,
JS_NULL_CLASS_SPEC,
&NativeTypeHelpers<mozilla::webgpu::WGSLLanguageFeatures>::sClassExtension,
JS_NULL_OBJECT_OPS
},
{ prototypes::id::WGSLLanguageFeatures, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
std::is_base_of_v<nsISupports, mozilla::webgpu::WGSLLanguageFeatures>,
&sNativePropertyHooks,
FindAssociatedGlobalForNative<mozilla::webgpu::WGSLLanguageFeatures>::Get,
GetProtoObjectHandle,
GetCCParticipant<mozilla::webgpu::WGSLLanguageFeatures>::Get(),
nullptr,
NativeTypeHelpers<mozilla::webgpu::WGSLLanguageFeatures>::GetWrapperCache
};
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
"Must have the right minimal number of reserved slots.");
static_assert(2 >= 2,
"Must have enough reserved slots.");
bool
Wrap(JSContext* aCx, mozilla::webgpu::WGSLLanguageFeatures* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
{
static_assert(!std::is_base_of_v<NonRefcountedDOMObject, mozilla::webgpu::WGSLLanguageFeatures>,
"Shouldn't have wrappercached things that are not refcounted.");
static_assert(std::is_same_v<decltype(aObject), mozilla::webgpu::WGSLLanguageFeatures*>);
MOZ_ASSERT(ToSupportsIsCorrect(aObject));
MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
MOZ_ASSERT(!aCache->GetWrapper(),
"You should probably not be using Wrap() directly; use "
"GetOrCreateDOMReflector instead");
MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
"nsISupports must be on our primary inheritance chain");
// If the wrapper cache contains a dead reflector then finalize that
// now, ensuring that the finalizer for the old reflector always
// runs before the new reflector is created and attached. This
// avoids the awkward situation where there are multiple reflector
// objects that contain pointers to the same native.
if (JSObject* oldReflector = aCache->GetWrapperMaybeDead()) {
_finalize(nullptr /* unused */, oldReflector);
MOZ_ASSERT(!aCache->GetWrapperMaybeDead());
}
JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
if (!global) {
return false;
}
MOZ_ASSERT(JS_IsGlobalObject(global));
JS::AssertObjectIsNotGray(global);
// That might have ended up wrapping us already, due to the wonders
// of XBL. Check for that, and bail out as needed.
aReflector.set(aCache->GetWrapper());
if (aReflector) {
#ifdef DEBUG
AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
#endif // DEBUG
return true;
}
JSAutoRealm ar(aCx, global);
JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
if (!canonicalProto) {
return false;
}
JS::Rooted<JSObject*> proto(aCx);
if (aGivenProto) {
proto = aGivenProto;
// Unfortunately, while aGivenProto was in the compartment of aCx
// coming in, we changed compartments to that of "parent" so may need
// to wrap the proto here.
if (js::GetContextCompartment(aCx) != JS::GetCompartment(proto)) {
if (!JS_WrapObject(aCx, &proto)) {
return false;
}
}
} else {
proto = canonicalProto;
}
BindingJSObjectCreator<mozilla::webgpu::WGSLLanguageFeatures> creator(aCx);
creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
if (!aReflector) {
return false;
}
aCache->SetWrapper(aReflector);
creator.InitializationSucceeded();
MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
aCache->GetWrapperPreserveColor() == aReflector);
// If proto != canonicalProto, we have to preserve our wrapper;
// otherwise we won't be able to properly recreate it later, since
// we won't know what proto to use. Note that we don't check
// aGivenProto here, since it's entirely possible (and even
// somewhat common) to have a non-null aGivenProto which is the
// same as canonicalProto.
if (proto != canonicalProto) {
PreserveWrapper(aObject);
}
return true;
}
void
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, DefineInterfaceProperty aDefineOnGlobal)
{
JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::WGSLLanguageFeatures);
JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::WGSLLanguageFeatures);
JS::Handle<JSObject*> parentProto(JS::GetRealmObjectPrototypeHandle(aCx));
if (!parentProto) {
return;
}
JS::Handle<JSObject*> constructorProto(JS::GetRealmFunctionPrototypeHandle(aCx));
if (!constructorProto) {
return;
}
dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
&sPrototypeClass, protoCache,
constructorProto, &sInterfaceObjectInfo, 0, false, Span<const LegacyFactoryFunction, 0>{},
interfaceCache,
sNativeProperties.Upcast(),
nullptr,
"WGSLLanguageFeatures",
ShouldExpose<WGSLLanguageFeatures_Binding::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal),
nullptr,
false,
nullptr);
JS::AssertObjectIsNotGray(*protoCache);
JS::Handle<JSObject*> proto = JS::Handle<JSObject*>::fromMarkedLocation(protoCache->unsafeAddress());
if (!proto) {
*protoCache = nullptr;
if (interfaceCache) {
*interfaceCache = nullptr;
}
return;
}
// Set up aliases on the interface prototype object we just created.
JS::Rooted<JS::Value> aliasedVal(aCx);
if (!JS_GetProperty(aCx, proto, "values", &aliasedVal)) {
*protoCache = nullptr;
if (interfaceCache) {
*interfaceCache = nullptr;
}
return;
}
JS::Rooted<jsid> iteratorId(aCx, JS::GetWellKnownSymbolKey(aCx, JS::SymbolCode::iterator));
if (!JS_DefinePropertyById(aCx, proto, iteratorId, aliasedVal, 0)) {
*protoCache = nullptr;
if (interfaceCache) {
*interfaceCache = nullptr;
}
return;
}
}
static JS::Handle<JSObject*>
GetProtoObjectHandle(JSContext* aCx)
{
/* Get the interface prototype object for this class. This will create the
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::WGSLLanguageFeatures,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
JS::Handle<JSObject*>
GetConstructorObjectHandle(JSContext* aCx)
{
/* Get the interface object for this class. This will create the object as
needed. */
return GetPerInterfaceObjectHandle(aCx, constructors::id::WGSLLanguageFeatures,
&CreateInterfaceObjects,
DefineInterfaceProperty::CheckExposure);
}
} // namespace WGSLLanguageFeatures_Binding
} // namespace dom
} // namespace mozilla