Skip to main content

script_webgpu/
gpuerror.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use std::marker::PhantomData;
6
7use dom_struct::dom_struct;
8use js::context::JSContext;
9use js::rust::HandleObject;
10use malloc_size_of_derive::MallocSizeOf;
11use script_bindings::DomTypes;
12use script_bindings::codegen::GenericBindings::WebGPUBinding::{
13    GPUErrorFilter, GPUErrorMethods, GPUErrorWrap,
14};
15use script_bindings::domstring::TracedDOMString;
16use script_bindings::reflector::{Reflector, reflect_dom_object_with_proto_and_wrap};
17use webgpu_traits::{Error, ErrorFilter};
18
19use crate::JSTraceable;
20use crate::dom::bindings::root::DomRoot;
21use crate::dom::bindings::str::DOMString;
22use crate::gpuconvert::WebGPUConvert;
23use crate::gpuinternalerror::GPUInternalError;
24use crate::gpuoutofmemoryerror::GPUOutOfMemoryError;
25use crate::gpuvalidationerror::GPUValidationError;
26use crate::traits::Equivalence;
27
28#[dom_struct]
29pub struct GPUError<D: DomTypes> {
30    reflector_: Reflector,
31    message: TracedDOMString,
32    #[no_trace = "PhantomData does not exist"]
33    phantom: PhantomData<D>,
34}
35
36impl<D> GPUError<D>
37where
38    D: Equivalence,
39{
40    pub(crate) fn new_inherited(message: DOMString) -> Self {
41        Self {
42            reflector_: Reflector::new(),
43            message: message.traced(),
44            phantom: PhantomData,
45        }
46    }
47
48    #[expect(dead_code)]
49    pub(crate) fn new(
50        cx: &mut JSContext,
51        global: &D::GlobalScope,
52        message: DOMString,
53    ) -> DomRoot<Self> {
54        Self::new_with_proto(cx, global, None, message)
55    }
56
57    pub(crate) fn new_with_proto(
58        cx: &mut JSContext,
59        global: &D::GlobalScope,
60        proto: Option<HandleObject>,
61        message: DOMString,
62    ) -> DomRoot<Self> {
63        reflect_dom_object_with_proto_and_wrap::<D, _, _>(
64            cx,
65            Box::new(GPUError::new_inherited(message)),
66            global,
67            proto,
68            GPUErrorWrap::<D>,
69        )
70    }
71
72    pub fn from_error(cx: &mut JSContext, global: &D::GlobalScope, error: Error) -> DomRoot<Self> {
73        match error {
74            Error::Validation(msg) => DomRoot::upcast(GPUValidationError::<D>::new_with_proto(
75                cx,
76                global,
77                None,
78                msg.into(),
79            )),
80            Error::OutOfMemory(msg) => DomRoot::upcast(GPUOutOfMemoryError::<D>::new_with_proto(
81                cx,
82                global,
83                None,
84                msg.into(),
85            )),
86            Error::Internal(msg) => DomRoot::upcast(GPUInternalError::<D>::new_with_proto(
87                cx,
88                global,
89                None,
90                msg.into(),
91            )),
92        }
93    }
94}
95
96impl<D: Equivalence> GPUErrorMethods<D> for GPUError<D> {
97    /// <https://gpuweb.github.io/gpuweb/#dom-gpuerror-message>
98    fn Message(&self) -> DOMString {
99        self.message.clone().root()
100    }
101}
102
103impl WebGPUConvert<GPUErrorFilter> for ErrorFilter {
104    fn convert(self) -> GPUErrorFilter {
105        match self {
106            ErrorFilter::Validation => GPUErrorFilter::Validation,
107            ErrorFilter::OutOfMemory => GPUErrorFilter::Out_of_memory,
108            ErrorFilter::Internal => GPUErrorFilter::Internal,
109        }
110    }
111}
112
113pub(crate) trait AsWebGpu {
114    fn as_webgpu(&self) -> ErrorFilter;
115}
116
117impl AsWebGpu for GPUErrorFilter {
118    fn as_webgpu(&self) -> ErrorFilter {
119        match self {
120            GPUErrorFilter::Validation => ErrorFilter::Validation,
121            GPUErrorFilter::Out_of_memory => ErrorFilter::OutOfMemory,
122            GPUErrorFilter::Internal => ErrorFilter::Internal,
123        }
124    }
125}