Dawn.node: Make cts inheritance test pass
We can't make GPUDevice (C++) inherit from EventTarget (JS)
but we can set the prototype chain so that
`someGPUDevice instanceof EventTarget` returns true.
Bug: 419128706
Change-Id: Ief3541041b801cdf6d3d9df3227e0395aab0d084
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/245854
Commit-Queue: Gregg Tavares <gman@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/node/ManualConstructors.cpp b/src/dawn/node/ManualConstructors.cpp
index 9bfd9f7..8cd2494 100644
--- a/src/dawn/node/ManualConstructors.cpp
+++ b/src/dawn/node/ManualConstructors.cpp
@@ -54,6 +54,9 @@
Napi::Object global = env.Global();
DOMException_ctor = Napi::Persistent(global.Get("DOMException").As<Napi::Function>());
+ // Lookup the EventTarget class
+ EventTarget_ctor = Napi::Persistent(global.Get("EventTarget").As<Napi::Function>());
+
// Define GPUUncapturedErrorEvent as a JavaScript object because it
// must inherit from Event otherwise it can not be passed to an EventTarget
// and this is apparently impossible in Napi if it's a C++ based object.
diff --git a/src/dawn/node/ManualConstructors.h b/src/dawn/node/ManualConstructors.h
index b7641b4..2f58858 100644
--- a/src/dawn/node/ManualConstructors.h
+++ b/src/dawn/node/ManualConstructors.h
@@ -39,6 +39,7 @@
Napi::FunctionReference GPUUncapturedErrorEvent_ctor;
Napi::FunctionReference GPUPipelineError_ctor;
Napi::FunctionReference DOMException_ctor;
+ Napi::FunctionReference EventTarget_ctor;
};
} // namespace wgpu::interop
diff --git a/src/dawn/node/interop/Browser.idl b/src/dawn/node/interop/Browser.idl
index 886b3f6..89803c1 100644
--- a/src/dawn/node/interop/Browser.idl
+++ b/src/dawn/node/interop/Browser.idl
@@ -49,7 +49,7 @@
typedef(EventListenerInterface or EventListenerCallback) EventListener;
typedef EventListenerCallback? EventHandler;
-[LegacyNoInterfaceObject] interface EventTarget {
+[LegacyNoInterfaceObject] [ManualImplementation] interface EventTarget {
undefined addEventListener(DOMString type, EventListener? callback, optional (AddEventListenerOptions or boolean) options);
undefined removeEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options);
boolean dispatchEvent(Event event);
diff --git a/src/dawn/node/interop/WebGPU.cpp.tmpl b/src/dawn/node/interop/WebGPU.cpp.tmpl
index d65fab2..d14cd6e 100644
--- a/src/dawn/node/interop/WebGPU.cpp.tmpl
+++ b/src/dawn/node/interop/WebGPU.cpp.tmpl
@@ -70,10 +70,7 @@
{{ range $ := .Declarations}}
{{- if IsDictionary $}}{{template "Dictionary" $}}
-{{- else if IsInterface $}}
-{{- if not (HasAnnotation $ "ManualImplementation")}}
- {{template "Interface" $}}
-{{- end}}
+{{- else if IsInterface $}}{{template "Interface" $}}
{{- else if IsEnum $}}{{template "Enum" $}}
{{- end}}
{{- end}}
@@ -425,6 +422,7 @@
{{- define "Interface"}}
{{$.Name}}::{{$.Name}}() = default;
+{{- if not (HasAnnotation $ "ManualImplementation")}}
{{$.Name}}* {{$.Name}}::Unwrap(Napi::Object object) {
auto* wrappers = Wrappers::For(object.Env());
if (!object.InstanceOf(wrappers->{{$.Name}}_ctor.Value())) {
@@ -453,6 +451,7 @@
return Interface<{{$.Name}}>(object);
}
+{{- end}}
{{$.Name}}::~{{$.Name}}() = default;
{{ end}}
diff --git a/src/dawn/node/interop/WebGPU.h.tmpl b/src/dawn/node/interop/WebGPU.h.tmpl
index e6dfbb5..e177489 100644
--- a/src/dawn/node/interop/WebGPU.h.tmpl
+++ b/src/dawn/node/interop/WebGPU.h.tmpl
@@ -140,6 +140,7 @@
// interface {{$.Name}}
class {{$.Name}} {{- if $.Inherits }} : public virtual {{$.Inherits}}{{end}} {
public:
+{{- if not (HasAnnotation $ "ManualImplementation")}}
static Interface<{{$.Name}}> Bind(Napi::Env, std::unique_ptr<{{$.Name}}>&&);
static {{$.Name}}* Unwrap(Napi::Object);
@@ -147,7 +148,7 @@
static inline Interface<{{$.Name}}> Create(Napi::Env env, ARGS&& ... args) {
return Bind(env, std::make_unique<T>(std::forward<ARGS>(args)...));
}
-
+{{- end}}
virtual ~{{$.Name}}() {{- if $.Inherits }} override{{end}};
{{$.Name}}();
{{- if $s := SetlikeOf $}}
diff --git a/src/dawn/node/test.mjs b/src/dawn/node/test.mjs
index 1c72cba..3694720d 100644
--- a/src/dawn/node/test.mjs
+++ b/src/dawn/node/test.mjs
@@ -12,6 +12,14 @@
const dawnNodePath = join(__dirname, '..', '..', '..', 'out', 'active', 'dawn.node');
const { create, globals } = require(dawnNodePath);
+// Save these before they might get replaced by the following assignment
+const globalsBeforeGlobalAssignment = {
+ DOMException,
+ EventTarget,
+ Error,
+ Event,
+};
+
Object.assign(globalThis, globals);
const assert = {
@@ -48,6 +56,14 @@
await new Promise(r => setTimeout(r, 1000));
})
+ await describe('global tests', async () => {
+ // Check that these globals were not replaced when we added dawn.node's globals
+ assert.ok(() => globalsBeforeGlobalAssignment.EventTarget === EventTarget);
+ assert.ok(() => globalsBeforeGlobalAssignment.Event === Event);
+ assert.ok(() => globalsBeforeGlobalAssignment.Error === Error);
+ assert.ok(() => globalsBeforeGlobalAssignment.DOMException === DOMException);
+ });
+
await describe('device tests', async () => {
await it('basic device tests', () => {