From 1d47146f43976013481efba3fa77b6e83c6eb262 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 4 Oct 2024 10:02:06 +0200 Subject: [PATCH] wasm gc: support JS functions with varargs --- .../org/teavm/backend/wasm/wasm-gc-runtime.js | 12 +++++++++++- jso/impl/src/main/java/org/teavm/jso/impl/JS.java | 15 +++++++++++++++ .../java/org/teavm/jso/impl/JSClassProcessor.java | 3 ++- .../test/java/org/teavm/jso/test/CallTest.java | 2 +- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/core/src/main/resources/org/teavm/backend/wasm/wasm-gc-runtime.js b/core/src/main/resources/org/teavm/backend/wasm/wasm-gc-runtime.js index 5434dcd23..1570bf2aa 100644 --- a/core/src/main/resources/org/teavm/backend/wasm/wasm-gc-runtime.js +++ b/core/src/main/resources/org/teavm/backend/wasm/wasm-gc-runtime.js @@ -296,7 +296,16 @@ TeaVM.wasm = function() { } else { return 0; } - } + }, + apply: (instance, method, args) => { + if (instance === null) { + let fn = getGlobalName(method); + return fn(...args); + } else { + return instance[method](...args); + } + }, + concatArray: (a, b) => a.concat(b) }; for (let name of ["wrapByte", "wrapShort", "wrapChar", "wrapInt", "wrapFloat", "wrapDouble", "unwrapByte", "unwrapShort", "unwrapChar", "unwrapInt", "unwrapFloat", "unwrapDouble"]) { @@ -308,6 +317,7 @@ TeaVM.wasm = function() { imports.teavmJso["callMethod" + i] = (instance, method, ...args) => instance !== null ? instance[method](...args) : getGlobalName(method)(...args); imports.teavmJso["construct" + i] = (constructor, ...args) => new constructor(...args); + imports.teavmJso["arrayOf" + i] = (...args) => args } } diff --git a/jso/impl/src/main/java/org/teavm/jso/impl/JS.java b/jso/impl/src/main/java/org/teavm/jso/impl/JS.java index 6fe6051f1..d4e561381 100644 --- a/jso/impl/src/main/java/org/teavm/jso/impl/JS.java +++ b/jso/impl/src/main/java/org/teavm/jso/impl/JS.java @@ -39,6 +39,7 @@ public final class JS { @InjectedBy(JSNativeInjector.class) @NoSideEffects + @Import(name = "concatArray", module = "teavmJso") public static native JSObject concatArray(JSObject a, JSObject b); @InjectedBy(JSNativeInjector.class) @@ -562,76 +563,90 @@ public final class JS { JSObject l, JSObject m); @InjectedBy(JSNativeInjector.class) + @Import(name = "apply", module = "teavmJso") public static native JSObject apply(JSObject instance, JSObject method, JSArray v); @InjectedBy(JSNativeInjector.class) @PluggableDependency(JSNativeInjector.class) @NoSideEffects + @Import(name = "arrayOf1", module = "teavmJso") public static native JSObject arrayOf(JSObject a); @InjectedBy(JSNativeInjector.class) @PluggableDependency(JSNativeInjector.class) @NoSideEffects + @Import(name = "arrayOf2", module = "teavmJso") public static native JSObject arrayOf(JSObject a, JSObject b); @InjectedBy(JSNativeInjector.class) @PluggableDependency(JSNativeInjector.class) @NoSideEffects + @Import(name = "arrayOf3", module = "teavmJso") public static native JSObject arrayOf(JSObject a, JSObject b, JSObject c); @InjectedBy(JSNativeInjector.class) @PluggableDependency(JSNativeInjector.class) @NoSideEffects + @Import(name = "arrayOf4", module = "teavmJso") public static native JSObject arrayOf(JSObject a, JSObject b, JSObject c, JSObject d); @InjectedBy(JSNativeInjector.class) @PluggableDependency(JSNativeInjector.class) @NoSideEffects + @Import(name = "arrayOf5", module = "teavmJso") public static native JSObject arrayOf(JSObject a, JSObject b, JSObject c, JSObject d, JSObject e); @InjectedBy(JSNativeInjector.class) @PluggableDependency(JSNativeInjector.class) @NoSideEffects + @Import(name = "arrayOf6", module = "teavmJso") public static native JSObject arrayOf(JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f); @InjectedBy(JSNativeInjector.class) @PluggableDependency(JSNativeInjector.class) @NoSideEffects + @Import(name = "arrayOf7", module = "teavmJso") public static native JSObject arrayOf(JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f, JSObject g); @InjectedBy(JSNativeInjector.class) @PluggableDependency(JSNativeInjector.class) @NoSideEffects + @Import(name = "arrayOf8", module = "teavmJso") public static native JSObject arrayOf(JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f, JSObject g, JSObject h); @InjectedBy(JSNativeInjector.class) @PluggableDependency(JSNativeInjector.class) + @Import(name = "arrayOf9", module = "teavmJso") public static native JSObject arrayOf(JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f, JSObject g, JSObject h, JSObject i); @InjectedBy(JSNativeInjector.class) @PluggableDependency(JSNativeInjector.class) @NoSideEffects + @Import(name = "arrayOf10", module = "teavmJso") public static native JSObject arrayOf(JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f, JSObject g, JSObject h, JSObject i, JSObject j); @InjectedBy(JSNativeInjector.class) @PluggableDependency(JSNativeInjector.class) @NoSideEffects + @Import(name = "arrayOf11", module = "teavmJso") public static native JSObject arrayOf(JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f, JSObject g, JSObject h, JSObject i, JSObject j, JSObject k); @InjectedBy(JSNativeInjector.class) @PluggableDependency(JSNativeInjector.class) @NoSideEffects + @Import(name = "arrayOf12", module = "teavmJso") public static native JSObject arrayOf(JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f, JSObject g, JSObject h, JSObject i, JSObject j, JSObject k, JSObject l); @InjectedBy(JSNativeInjector.class) @PluggableDependency(JSNativeInjector.class) @NoSideEffects + @Import(name = "arrayOf13", module = "teavmJso") public static native JSObject arrayOf(JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f, JSObject g, JSObject h, JSObject i, JSObject j, JSObject k, JSObject l, JSObject m); diff --git a/jso/impl/src/main/java/org/teavm/jso/impl/JSClassProcessor.java b/jso/impl/src/main/java/org/teavm/jso/impl/JSClassProcessor.java index 906e54ba2..fe76d4405 100644 --- a/jso/impl/src/main/java/org/teavm/jso/impl/JSClassProcessor.java +++ b/jso/impl/src/main/java/org/teavm/jso/impl/JSClassProcessor.java @@ -1088,7 +1088,8 @@ class JSClassProcessor { var arg = invoke.getArguments().get(i); var byRef = byRefParams[i]; if (vararg && i == invoke.getArguments().size() - 1 - && typeHelper.isSupportedByRefType(method.parameterType(i))) { + && typeHelper.isSupportedByRefType(method.parameterType(i)) + && !wasmGC) { byRef = true; } arg = marshaller.wrapArgument(callLocation, arg, diff --git a/tests/src/test/java/org/teavm/jso/test/CallTest.java b/tests/src/test/java/org/teavm/jso/test/CallTest.java index 40f0419fc..d86622cb2 100644 --- a/tests/src/test/java/org/teavm/jso/test/CallTest.java +++ b/tests/src/test/java/org/teavm/jso/test/CallTest.java @@ -31,7 +31,7 @@ import org.testng.annotations.Test; @RunWith(TeaVMTestRunner.class) @SkipJVM -@OnlyPlatform(TestPlatform.JAVASCRIPT) +@OnlyPlatform({TestPlatform.JAVASCRIPT, TestPlatform.WEBASSEMBLY_GC}) @EachTestCompiledSeparately public class CallTest { @Test