Bug 1838694: fix(webgpu): impl. correct GPUError types r=jgilbert,webgpu-reviewers,webidl,peterv

Differential Revision: https://phabricator.services.mozilla.com/D181690
This commit is contained in:
Erich Gubler 2023-07-06 20:50:52 +00:00
parent fdd9df03d3
commit 260a0b100c
16 changed files with 203 additions and 68 deletions

View file

@ -1440,6 +1440,12 @@ DOMInterfaces = {
'GPUDeviceLostInfo': {
'nativeType': 'mozilla::webgpu::DeviceLostInfo',
},
'GPUError': {
'nativeType': 'mozilla::webgpu::Error',
},
'GPUInternalError': {
'nativeType': 'mozilla::webgpu::InternalError',
},
'GPUOutOfMemoryError': {
'nativeType': 'mozilla::webgpu::OutOfMemoryError',
},

View file

@ -514,6 +514,10 @@ let interfaceNamesInGlobalScope = [
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "GPUDeviceLostInfo", nightly: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "GPUError", nightly: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "GPUInternalError", nightly: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "GPUMapMode", nightly: true },
// IMPORTANT: Do not change this list without review from a DOM peer!
{ name: "GPUOutOfMemoryError", nightly: true },

View file

@ -8,6 +8,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/Logging.h"
#include "mozilla/RefPtr.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/WebGPUBinding.h"
#include "Device.h"
@ -18,6 +19,7 @@
#include "Buffer.h"
#include "ComputePipeline.h"
#include "DeviceLostInfo.h"
#include "InternalError.h"
#include "OutOfMemoryError.h"
#include "PipelineLayout.h"
#include "Queue.h"
@ -358,7 +360,7 @@ already_AddRefed<dom::Promise> Device::PopErrorScope(ErrorResult& aRv) {
errorPromise->Then(
GetCurrentSerialEventTarget(), __func__,
[self = RefPtr{this}, promise](const PopErrorScopeResult& aResult) {
dom::OwningGPUOutOfMemoryErrorOrGPUValidationError error;
RefPtr<Error> error;
switch (aResult.resultType) {
case PopErrorScopeResultType::NoError:
@ -377,21 +379,18 @@ already_AddRefed<dom::Promise> Device::PopErrorScope(ErrorResult& aRv) {
return;
case PopErrorScopeResultType::OutOfMemory:
error.SetAsGPUOutOfMemoryError() = new OutOfMemoryError(self);
error =
new OutOfMemoryError(self->GetParentObject(), aResult.message);
break;
case PopErrorScopeResultType::ValidationError:
error.SetAsGPUValidationError() =
error =
new ValidationError(self->GetParentObject(), aResult.message);
break;
case PopErrorScopeResultType::InternalError:
MOZ_CRASH("TODO");
/*
error.SetAsGPUInternalError() = new InternalError(
self->GetParentObject(), aResult.message);
error = new InternalError(self->GetParentObject(), aResult.message);
break;
*/
}
promise->MaybeResolve(std::move(error));
},

20
dom/webgpu/Error.cpp Normal file
View file

@ -0,0 +1,20 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Error.h"
namespace mozilla::webgpu {
GPU_IMPL_CYCLE_COLLECTION(Error, mGlobal)
Error::Error(nsIGlobalObject* const aGlobal, const nsACString& aMessage)
: mGlobal(aGlobal) {
CopyUTF8toUTF16(aMessage, mMessage);
}
Error::Error(nsIGlobalObject* const aGlobal, const nsAString& aMessage)
: mGlobal(aGlobal), mMessage(aMessage) {}
} // namespace mozilla::webgpu

46
dom/webgpu/Error.h Normal file
View file

@ -0,0 +1,46 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GPU_Error_H_
#define GPU_Error_H_
#include "js/Value.h"
#include "mozilla/WeakPtr.h"
#include "nsIGlobalObject.h"
#include "nsString.h"
#include "ObjectModel.h"
namespace mozilla {
class ErrorResult;
namespace dom {
class GlobalObject;
} // namespace dom
namespace webgpu {
class Error : public nsWrapperCache, public SupportsWeakPtr {
protected:
nsCOMPtr<nsIGlobalObject> mGlobal;
nsString mMessage;
public:
GPU_DECL_CYCLE_COLLECTION(Error)
Error(nsIGlobalObject* const aGlobal, const nsAString& aMessage);
Error(nsIGlobalObject* const aGlobal, const nsACString& aMessage);
protected:
virtual ~Error() = default;
virtual void Cleanup() {}
public:
void GetMessage(nsAString& aMessage) const { aMessage = mMessage; }
nsIGlobalObject* GetParentObject() const { return mGlobal; }
virtual JSObject* WrapObject(JSContext*, JS::Handle<JSObject*>) = 0;
};
} // namespace webgpu
} // namespace mozilla
#endif // GPU_Error_H_

View file

@ -0,0 +1,21 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "InternalError.h"
#include "mozilla/dom/WebGPUBinding.h"
namespace mozilla::webgpu {
GPU_IMPL_JS_WRAP(InternalError)
already_AddRefed<InternalError> InternalError::Constructor(
const dom::GlobalObject& aGlobal, const nsAString& aString,
ErrorResult& aRv) {
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
MOZ_RELEASE_ASSERT(global);
return MakeAndAddRef<InternalError>(global, aString);
}
} // namespace mozilla::webgpu

View file

@ -0,0 +1,40 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GPU_InternalError_H_
#define GPU_InternalError_H_
#include "Error.h"
namespace mozilla {
class ErrorResult;
namespace dom {
class GlobalObject;
} // namespace dom
namespace webgpu {
class InternalError final : public Error {
public:
GPU_DECL_JS_WRAP(InternalError)
InternalError(nsIGlobalObject* const aGlobal, const nsAString& aMessage)
: Error(aGlobal, aMessage) {}
InternalError(nsIGlobalObject* const aGlobal, const nsACString& aMessage)
: Error(aGlobal, aMessage) {}
private:
~InternalError() override = default;
public:
static already_AddRefed<InternalError> Constructor(
const dom::GlobalObject& aGlobal, const nsAString& aString,
ErrorResult& aRv);
};
} // namespace webgpu
} // namespace mozilla
#endif // GPU_InternalError_H_

View file

@ -12,6 +12,7 @@
#include "CommandEncoder.h"
#include "Instance.h"
#include "Texture.h"
#include "nsIGlobalObject.h"
namespace mozilla::webgpu {

View file

@ -4,14 +4,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "OutOfMemoryError.h"
#include "Device.h"
#include "mozilla/dom/WebGPUBinding.h"
namespace mozilla::webgpu {
GPU_IMPL_CYCLE_COLLECTION(OutOfMemoryError, mParent)
GPU_IMPL_JS_WRAP(OutOfMemoryError)
OutOfMemoryError::~OutOfMemoryError() = default;
already_AddRefed<OutOfMemoryError> OutOfMemoryError::Constructor(
const dom::GlobalObject& aGlobal, const nsAString& aString,
ErrorResult& aRv) {
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
MOZ_RELEASE_ASSERT(global);
return MakeAndAddRef<OutOfMemoryError>(global, aString);
}
} // namespace mozilla::webgpu

View file

@ -6,27 +6,32 @@
#ifndef GPU_OutOfMemoryError_H_
#define GPU_OutOfMemoryError_H_
#include "nsWrapperCache.h"
#include "ObjectModel.h"
#include "Error.h"
namespace mozilla {
class ErrorResult;
namespace dom {
class GlobalObject;
} // namespace dom
namespace webgpu {
class Device;
class OutOfMemoryError final : public nsWrapperCache, public ChildOf<Device> {
class OutOfMemoryError final : public Error {
public:
GPU_DECL_CYCLE_COLLECTION(OutOfMemoryError)
GPU_DECL_JS_WRAP(OutOfMemoryError)
explicit OutOfMemoryError(const RefPtr<Device>& aParent)
: ChildOf<Device>(aParent) {}
OutOfMemoryError(nsIGlobalObject* const aGlobal, const nsAString& aMessage)
: Error(aGlobal, aMessage) {}
OutOfMemoryError(nsIGlobalObject* const aGlobal, const nsACString& aMessage)
: Error(aGlobal, aMessage) {}
private:
virtual ~OutOfMemoryError();
void Cleanup() {}
~OutOfMemoryError() override = default;
public:
static already_AddRefed<OutOfMemoryError> Constructor(
const dom::GlobalObject& aGlobal, const nsAString& aString,
ErrorResult& aRv);
};
} // namespace webgpu

View file

@ -5,36 +5,16 @@
#include "ValidationError.h"
#include "mozilla/dom/WebGPUBinding.h"
#include "mozilla/ErrorResult.h"
#include "nsIGlobalObject.h"
#include "nsReadableUtils.h"
namespace mozilla::webgpu {
GPU_IMPL_CYCLE_COLLECTION(ValidationError, mGlobal)
GPU_IMPL_JS_WRAP(ValidationError)
ValidationError::ValidationError(nsIGlobalObject* aGlobal,
const nsACString& aMessage)
: mGlobal(aGlobal) {
CopyUTF8toUTF16(aMessage, mMessage);
}
ValidationError::ValidationError(nsIGlobalObject* aGlobal,
const nsAString& aMessage)
: mGlobal(aGlobal), mMessage(aMessage) {}
ValidationError::~ValidationError() = default;
already_AddRefed<ValidationError> ValidationError::Constructor(
const dom::GlobalObject& aGlobal, const nsAString& aString,
ErrorResult& aRv) {
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
if (!global) {
aRv.ThrowInvalidStateError("aGlobal is not nsIGlobalObject");
return nullptr;
}
MOZ_RELEASE_ASSERT(global);
return MakeAndAddRef<ValidationError>(global, aString);
}

View file

@ -6,39 +6,32 @@
#ifndef GPU_ValidationError_H_
#define GPU_ValidationError_H_
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsWrapperCache.h"
#include "ObjectModel.h"
#include "Error.h"
namespace mozilla {
class ErrorResult;
namespace dom {
class GlobalObject;
} // namespace dom
namespace webgpu {
class ValidationError final : public nsWrapperCache {
nsCOMPtr<nsIGlobalObject> mGlobal;
nsString mMessage;
class ValidationError final : public Error {
public:
GPU_DECL_CYCLE_COLLECTION(ValidationError)
GPU_DECL_JS_WRAP(ValidationError)
ValidationError(nsIGlobalObject* aGlobal, const nsACString& aMessage);
ValidationError(nsIGlobalObject* aGlobal, const nsAString& aMessage);
ValidationError(nsIGlobalObject* const aGlobal, const nsAString& aMessage)
: Error(aGlobal, aMessage) {}
ValidationError(nsIGlobalObject* const aGlobal, const nsACString& aMessage)
: Error(aGlobal, aMessage) {}
private:
virtual ~ValidationError();
void Cleanup() {}
~ValidationError() override = default;
public:
static already_AddRefed<ValidationError> Constructor(
const dom::GlobalObject& aGlobal, const nsAString& aString,
ErrorResult& aRv);
void GetMessage(nsAString& aMessage) const { aMessage = mMessage; }
nsIGlobalObject* GetParentObject() const { return mGlobal; }
};
} // namespace webgpu

View file

@ -1105,8 +1105,7 @@ ipc::IPCResult WebGPUChild::RecvUncapturedError(const Maybe<RawId> aDeviceId,
JsWarning(device->GetOwnerGlobal(), aMessage);
dom::GPUUncapturedErrorEventInit init;
init.mError.SetAsGPUValidationError() =
new ValidationError(device->GetParentObject(), aMessage);
init.mError = new ValidationError(device->GetParentObject(), aMessage);
RefPtr<mozilla::dom::GPUUncapturedErrorEvent> event =
dom::GPUUncapturedErrorEvent::Constructor(
device, u"uncapturederror"_ns, init);

View file

@ -1149,9 +1149,9 @@ ipc::IPCResult WebGPUParent::RecvDevicePopErrorScope(
case dom::GPUErrorFilter::Out_of_memory:
ret.resultType = PopErrorScopeResultType::OutOfMemory;
break;
// case dom::GPUErrorFilter::Internal:
// ret.resultType = PopErrorScopeResultType::InternalError;
// break;
case dom::GPUErrorFilter::Internal:
ret.resultType = PopErrorScopeResultType::InternalError;
break;
case dom::GPUErrorFilter::EndGuard_:
MOZ_CRASH("Bad GPUErrorFilter");
}

View file

@ -28,7 +28,9 @@ h_and_cpp = [
"ComputePipeline",
"Device",
"DeviceLostInfo",
"Error",
"Instance",
"InternalError",
"ObjectModel",
"OutOfMemoryError",
"PipelineLayout",

View file

@ -1182,23 +1182,38 @@ partial interface GPUDevice {
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
interface GPUOutOfMemoryError {
//constructor();
interface GPUError {
readonly attribute DOMString message;
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
interface GPUValidationError {
interface GPUValidationError
: GPUError {
[Throws]
constructor(DOMString message);
readonly attribute DOMString message;
};
typedef (GPUOutOfMemoryError or GPUValidationError) GPUError;
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
interface GPUOutOfMemoryError
: GPUError {
[Throws]
constructor(DOMString message);
};
[Pref="dom.webgpu.enabled",
Exposed=(Window /* ,DedicatedWorker */), SecureContext]
interface GPUInternalError
: GPUError {
[Throws]
constructor(DOMString message);
};
enum GPUErrorFilter {
"validation",
"out-of-memory",
"validation"
"internal",
};
typedef [EnforceRange] unsigned long GPUBufferDynamicOffset;