kawamuray / wasmtime-java

Java or JVM-language binding for Wasmtime
Apache License 2.0
128 stars 29 forks source link

Can't define method correctly #20

Closed xafero closed 3 years ago

xafero commented 3 years ago

In my WAT it's like this: (import "go" "debug" (func (;0;) (type 1)))

My Java code does this: var module = "go"; var func = WasmFunctions.wrap(_store, WasmValType.I32, i -> { System.out.println(i); }); var extern = Extern.fromFunc(func); _linker.define(module, "debug", extern);

My result is: Exception in thread "main" io.github.kawamuray.wasmtime.WasmtimeException: incompatible import type for go::debug at io.github.kawamuray.wasmtime.Linker.nativeModule(Native Method) at io.github.kawamuray.wasmtime.Linker.module(Linker.java:21)

If I don't define it: Exception in thread "main" io.github.kawamuray.wasmtime.WasmtimeException: unknown import: go::debug has not been defined at io.github.kawamuray.wasmtime.Linker.nativeModule(Native Method) at io.github.kawamuray.wasmtime.Linker.module(Linker.java:21)

How to solve?

kawamuray commented 3 years ago

Can you share the function signature declared in your WAT which is referred by (type 1)?

xafero commented 3 years ago

I'm not sure where to find it. Maybe: (type (;1;) (func (param i32))) ?

I'll attach my hello world example. main.wasm.zip

kawamuray commented 3 years ago

H-m. I've tried similar example as below, but it worked perfectly well. Could it possibly an issue of wasmtime itself? You may wanna confirm by writing simple rust code that directly uses wasmtime to execute your wat.

Also, providing your full java code might helps.

hello_test.wasm

(module
  (type (;0;) (func (param i32)))
  (type (;1;) (func))
  (import "go" "debug" (func $_ZN10hello_test5debug17hee89981947308813E (type 0)))
  (func $debug_entry (type 0) (param i32)
    local.get 0
    call $_ZN10hello_test5debug17hee89981947308813E
    return)
  (func $dummy (type 1))
  (func $__wasm_call_dtors (type 1)
    call $dummy
    call $dummy)
  (func $debug_entry.command_export (type 0) (param i32)
    local.get 0
    call $debug_entry
    call $__wasm_call_dtors)
  (table (;0;) 1 1 funcref)
  (memory (;0;) 16)
  (global (;0;) (mut i32) (i32.const 1048576))
  (global (;1;) i32 (i32.const 1048576))
  (global (;2;) i32 (i32.const 1048576))
  (export "memory" (memory 0))
  (export "__heap_base" (global 1))
  (export "__data_end" (global 2))
  (export "debug_entry" (func $debug_entry.command_export)))
public class HelloWorld {
    public static void main(String[] args) {
        try (Store<Void> store = Store.withoutData()) {
            try (Engine engine = store.engine();
                 Module module = Module.fromFile(engine, "./hello_test.wasm");
                 Func debugFunc = WasmFunctions.wrap(store, I32, n -> {
                     System.err.println("Debug: " + n);
                 });
                 Linker linker = new Linker(store.engine())) {
                linker.define("go", "debug", Extern.fromFunc(debugFunc));
                linker.module(store, "", module);
                try (Func f = linker.get(store, "", "debug_entry").get().func()) {
                    WasmFunctions.Consumer1<Integer> fn = WasmFunctions.consumer(store, f, I32);
                    fn.accept(123);
                }
            }
        }
    }
}
xafero commented 3 years ago

Initially, I used "new Instance" like in examples/src/main/java/examples/Gcd.java ... Now I'm using only the Linker without Instance, like in your example now or in examples/src/main/java/examples/MemoryInterop.java ...

And it works. 16 Go examples are running fine, so thanks for writing a Java wasmtime again.