From 75c55b45c064d6af7780b7a7f93cc1ceba8061e8 Mon Sep 17 00:00:00 2001 From: Alexey Illarionov Date: Sat, 10 Feb 2024 05:13:30 +0300 Subject: [PATCH] Fix functionTypes indexes of imported functions (#240) --- .../com/dylibso/chicory/runtime/Machine.java | 28 ++++------- .../com/dylibso/chicory/runtime/Module.java | 2 +- .../dylibso/chicory/runtime/ModuleTest.java | 44 ++++++++++++++++++ .../resources/compiled/mixed-imports.wat.wasm | Bin 0 -> 140 bytes .../src/test/resources/wat/mixed-imports.wat | 35 ++++++++++++++ 5 files changed, 89 insertions(+), 20 deletions(-) create mode 100644 wasm-corpus/src/test/resources/compiled/mixed-imports.wat.wasm create mode 100644 wasm-corpus/src/test/resources/wat/mixed-imports.wat diff --git a/runtime/src/main/java/com/dylibso/chicory/runtime/Machine.java b/runtime/src/main/java/com/dylibso/chicory/runtime/Machine.java index 9c5757fc9..be7d380af 100644 --- a/runtime/src/main/java/com/dylibso/chicory/runtime/Machine.java +++ b/runtime/src/main/java/com/dylibso/chicory/runtime/Machine.java @@ -61,28 +61,18 @@ public static Value[] call( eval(stack, instance, callStack); } else { callStack.push(new StackFrame(instance, funcId, args, List.of())); - var imprt = instance.imports().index()[funcId]; + var imprt = instance.imports().function(funcId); if (imprt == null) { throw new ChicoryException("Missing host import, number: " + funcId); } - - switch (imprt.type()) { - case FUNCTION: - var hostFunc = ((HostFunction) imprt).handle(); - var results = hostFunc.apply(instance, args); - // a host function can return null or an array of ints - // which we will push onto the stack - if (results != null) { - for (var result : results) { - stack.push(result); - } - } - break; - case GLOBAL: - stack.push(((HostGlobal) imprt).value()); - break; - default: - throw new ChicoryException("Not implemented"); + var hostFunc = imprt.handle(); + var results = hostFunc.apply(instance, args); + // a host function can return null or an array of ints + // which we will push onto the stack + if (results != null) { + for (var result : results) { + stack.push(result); + } } } diff --git a/runtime/src/main/java/com/dylibso/chicory/runtime/Module.java b/runtime/src/main/java/com/dylibso/chicory/runtime/Module.java index 77da77feb..13b315dca 100644 --- a/runtime/src/main/java/com/dylibso/chicory/runtime/Module.java +++ b/runtime/src/main/java/com/dylibso/chicory/runtime/Module.java @@ -154,7 +154,7 @@ public Instance instantiate(HostImports hostImports) { case FUNCTION: { var type = ((FunctionImport) imprt).typeIndex(); - functionTypes[importId] = type; + functionTypes[funcIdx] = type; // The global function id increases on this table // function ids are assigned on imports first imports[importId++] = imprt; diff --git a/runtime/src/test/java/com/dylibso/chicory/runtime/ModuleTest.java b/runtime/src/test/java/com/dylibso/chicory/runtime/ModuleTest.java index ebaee5507..ddb0e2b5e 100644 --- a/runtime/src/test/java/com/dylibso/chicory/runtime/ModuleTest.java +++ b/runtime/src/test/java/com/dylibso/chicory/runtime/ModuleTest.java @@ -5,10 +5,12 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import com.dylibso.chicory.runtime.exceptions.WASMMachineException; +import com.dylibso.chicory.wasm.types.MemoryLimits; import com.dylibso.chicory.wasm.types.Value; import com.dylibso.chicory.wasm.types.ValueType; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; import org.junit.jupiter.api.Test; public class ModuleTest { @@ -248,4 +250,46 @@ public void shouldRunKitchenSink() { // var run = instance.getExport("run"); // assertEquals(-25438, run.apply(Value.i32(100)).asInt()); // } + + @Test + public void shouldRunMixedImports() { + var cbrtFunc = + new HostFunction( + (Instance instance, Value... args) -> { + var x = args[0].asInt(); + var cbrt = Math.cbrt(x); + return new Value[] {Value.fromDouble(cbrt)}; + }, + "env", + "cbrt", + List.of(ValueType.I32), + List.of(ValueType.F64)); + var logResult = new AtomicReference(null); + var logFunc = + new HostFunction( + (Instance instance, Value... args) -> { + var logLevel = args[0].asInt(); + var value = (int) args[1].asDouble(); + logResult.set(logLevel + ": " + value); + return null; + }, + "env", + "log", + List.of(ValueType.I32, ValueType.F64), + List.of()); + var memory = new HostMemory("env", "memory", new Memory(new MemoryLimits(1))); + + var module = Module.builder("compiled/mixed-imports.wat.wasm").build(); + var hostImports = + new HostImports( + new HostFunction[] {cbrtFunc, logFunc}, + new HostGlobal[0], + memory, + new HostTable[0]); + var instance = module.instantiate(hostImports); + + var run = instance.export("main"); + run.apply(); + assertEquals("1: 164", logResult.get()); + } } diff --git a/wasm-corpus/src/test/resources/compiled/mixed-imports.wat.wasm b/wasm-corpus/src/test/resources/compiled/mixed-imports.wat.wasm new file mode 100644 index 0000000000000000000000000000000000000000..1493d8514940b3887446cbf5b053e9273bc4f0ff GIT binary patch literal 140 zcmW-ay$ZrG9K`Scp#?KEqiznJ9DM={zC^cFDI%CgswhIBK8o~7n|KFzznc#2!xI47 zEF6s#9mNzpMmUZc0j@;4{