mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 23:02:20 +00:00
Bug 1809567: Propagate promise creation failures in mozilla::webgpu::Device::CreateShaderModule. r=webgpu-reviewers,webidl,smaug,saschanaz,ErichDonGubler
If creation of the `CompilationInfo` promise fails in `mozilla::webgpu::Device::CreateShaderModule`, propagate the error properly, rather than leaving a local `ErrorResult` unhandled. Differential Revision: https://phabricator.services.mozilla.com/D197600
This commit is contained in:
parent
231b768e20
commit
5ad3692e95
@ -247,16 +247,17 @@ already_AddRefed<BindGroup> Device::CreateBindGroup(
|
||||
}
|
||||
|
||||
already_AddRefed<ShaderModule> Device::CreateShaderModule(
|
||||
JSContext* aCx, const dom::GPUShaderModuleDescriptor& aDesc) {
|
||||
JSContext* aCx, const dom::GPUShaderModuleDescriptor& aDesc,
|
||||
ErrorResult& aRv) {
|
||||
Unused << aCx;
|
||||
|
||||
if (!mBridge->CanSend()) {
|
||||
aRv.ThrowInvalidStateError("Connection to GPU process has shut down");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ErrorResult err;
|
||||
RefPtr<dom::Promise> promise = dom::Promise::Create(GetParentObject(), err);
|
||||
if (NS_WARN_IF(err.Failed())) {
|
||||
RefPtr<dom::Promise> promise = dom::Promise::Create(GetParentObject(), aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -165,7 +165,8 @@ class Device final : public DOMEventTargetHelper, public SupportsWeakPtr {
|
||||
const dom::GPUBindGroupDescriptor& aDesc);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT already_AddRefed<ShaderModule> CreateShaderModule(
|
||||
JSContext* aCx, const dom::GPUShaderModuleDescriptor& aDesc);
|
||||
JSContext* aCx, const dom::GPUShaderModuleDescriptor& aDesc,
|
||||
ErrorResult& aRv);
|
||||
already_AddRefed<ComputePipeline> CreateComputePipeline(
|
||||
const dom::GPUComputePipelineDescriptor& aDesc);
|
||||
already_AddRefed<RenderPipeline> CreateRenderPipeline(
|
||||
|
72
dom/webgpu/crashtests/1809567.html
Normal file
72
dom/webgpu/crashtests/1809567.html
Normal file
@ -0,0 +1,72 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<body>
|
||||
<script>
|
||||
// The bulk of the test is wrapped in an async function because
|
||||
// the WebGPU API returns promises of adapters and devices,
|
||||
// which we would like to conveniently await.
|
||||
async function orphan_webgpu_device() {
|
||||
// Create an iframe in the same origin as this code.
|
||||
let iframe = document.createElement('iframe');
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
// Define a function in that iframe that creates a WebGPU
|
||||
// `GPUDevice`.
|
||||
let script = iframe.contentDocument.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.text = `
|
||||
async function create_device() {
|
||||
// WebGPU is not yet available in beta or release.
|
||||
if (!navigator.gpu) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let adapter = await navigator.gpu.requestAdapter({ });
|
||||
// Not all GPUs are capable of supporting WebGPU.
|
||||
if (!adapter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return await adapter.requestDevice({ });
|
||||
}
|
||||
`;
|
||||
iframe.contentDocument.body.appendChild(script);
|
||||
|
||||
// Call that function to create a `GPUDevice` in the iframe.
|
||||
let device = await iframe.contentWindow.create_device();
|
||||
|
||||
// If we can't run WebGPU in this browser, then we can't reach the crash.
|
||||
if (device) {
|
||||
// Remove the iframe from our document. This closes its window.
|
||||
iframe.remove();
|
||||
|
||||
try {
|
||||
// When a Web API JavaScript object has had its parent window
|
||||
// closed, C++ implementations of its WebIDL methods become unable
|
||||
// to create JavaScript objects as usual: calling
|
||||
// `EventTarget::GetParentObject` returns `nullptr`.
|
||||
//
|
||||
// Since we removed `iframe` from this document, the following
|
||||
// call will fail trying to create a `Promise` of the module's
|
||||
// `GPUCompilationInfo`.
|
||||
device.createShaderModule({ code: '' });
|
||||
} catch (error) {
|
||||
// Eating errors indiscriminately wastes later developers' time.
|
||||
if (error.name != "NS_ERROR_UNEXPECTED") {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
orphan_webgpu_device()
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
})
|
||||
.finally(() => {
|
||||
// End the crashtest.
|
||||
document.documentElement.removeAttribute("class");
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
1
dom/webgpu/crashtests/crashtests.list
Normal file
1
dom/webgpu/crashtests/crashtests.list
Normal file
@ -0,0 +1 @@
|
||||
load 1809567.html
|
@ -157,6 +157,7 @@ interface GPUDevice : EventTarget {
|
||||
GPUPipelineLayout createPipelineLayout(GPUPipelineLayoutDescriptor descriptor);
|
||||
GPUBindGroup createBindGroup(GPUBindGroupDescriptor descriptor);
|
||||
|
||||
[Throws]
|
||||
GPUShaderModule createShaderModule(GPUShaderModuleDescriptor descriptor);
|
||||
GPUComputePipeline createComputePipeline(GPUComputePipelineDescriptor descriptor);
|
||||
GPURenderPipeline createRenderPipeline(GPURenderPipelineDescriptor descriptor);
|
||||
|
@ -33,6 +33,7 @@ include ../../dom/smil/crashtests/crashtests.list
|
||||
include ../../dom/streams/crashtests/crashtests.list
|
||||
include ../../dom/svg/crashtests/crashtests.list
|
||||
include ../../dom/vr/test/crashtests/crashtests.list
|
||||
include ../../dom/webgpu/crashtests/crashtests.list
|
||||
include ../../dom/workers/test/crashtests/crashtests.list
|
||||
include ../../dom/xhr/tests/crashtests/crashtests.list
|
||||
include ../../dom/xml/crashtests/crashtests.list
|
||||
|
Loading…
Reference in New Issue
Block a user