graal icon indicating copy to clipboard operation
graal copied to clipboard

Graalvm Embedding WebAssembly to Java

Open burakakca opened this issue 2 years ago • 6 comments

OpenJDK 64-Bit Server VM (19.0.1+10-jvmci-22.3-b08) for linux-amd64 JRE (19.0.1+10-jvmci-22.3-b08), built on 2022-10-19T11:11:18Z by "buildslave" with gcc 11.2.0

Describe the issue Using this example

Embedding WebAssembly Programs

javac HelloWorld.java
native-image --language:wasm HelloWorld
Exception in thread "main" The module 'wasi_snapshot_preview1', referenced by the import 'fd_write' in the module 'main', does not exist.
        at org.graalvm.sdk/org.graalvm.polyglot.Value.getMember(Value.java:793)
        at HelloWorld.main(HelloWorld.java:19)

Code snippet or code repository that reproduces the issue

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import org.graalvm.polyglot.*;
import org.graalvm.polyglot.io.ByteSequence;

public class HelloWorld {
  public static void main(String[] args) throws IOException {
    System.out.println("Hello, World!");

    byte[] binary = Files.readAllBytes(Paths.get("floyd.wasm"));
        Context.Builder contextBuilder = Context.newBuilder("wasm");
        Source.Builder sourceBuilder = Source.newBuilder("wasm", ByteSequence.create(binary), "floyd");
        Source source = sourceBuilder.build();
        Context context = contextBuilder.build();

        context.eval(source);

        Value mainFunction = context.getBindings("wasm").getMember("main").getMember("_start");
        mainFunction.executeVoid();
  }
}

burakakca avatar Dec 06 '22 08:12 burakakca

Hi, Thank you for reaching out about this. The provided example (floyd.wasm) requires built-in modules that the Emscripten toolchain needs. Therefore, to run it using GraalVM's wasm, you'll need to use wasm --Builtins=wasi_snapshot_preview1 floyd.wasm.

Since you are calling wasm from within Java, you need to add contextBuilder.option("wasm.Builtins", "wasi_snapshot_preview1") to your context builder for it to work. here is how the java class should be:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import org.graalvm.polyglot.*;
import org.graalvm.polyglot.io.ByteSequence;

public class HelloWorld {
  public static void main(String[] args) throws IOException {
    System.out.println("Hello, World!");

    byte[] binary = Files.readAllBytes(Paths.get("floyd.wasm"));
        Context.Builder contextBuilder = Context.newBuilder("wasm");
        contextBuilder.option("wasm.Builtins", "wasi_snapshot_preview1");
        Source.Builder sourceBuilder = Source.newBuilder("wasm", ByteSequence.create(binary), "floyd");

        Source source = sourceBuilder.build();
        Context context = contextBuilder.build();

        context.eval(source);

        Value mainFunction = context.getBindings("wasm").getMember("main").getMember("_start");
        mainFunction.executeVoid();
  }
}

oubidar-Abderrahim avatar Dec 12 '22 14:12 oubidar-Abderrahim

It works now but with a few errors.


./helloworld 
Hello, World!
1 .
2 3 .
4 5 6 .
7 8 9 10 .
11 12 13 14 15 .
16 17 18 19 20 21 .
22 23 24 25 26 27 28 .
29 30 31 32 33 34 35 36 .
37 38 39 40 41 42 43 44 45 .
46 47 48 49 50 51 52 53 54 55 .
Exception in thread "main" Program exited with status code 0.
        at <wasm> wasm-function:__wasi_proc_exit(Unknown)
        at <wasm> wasm-function:10(Unknown)
        at <wasm> wasm-function:9(Unknown)
        at <wasm> _start(Unknown)
        at org.graalvm.sdk/org.graalvm.polyglot.Value.executeVoid(Value.java:900)
        at HelloWorld.main(HelloWorld.java:22)

burakakca avatar Dec 12 '22 15:12 burakakca

How to use C#, Rust, and Go wasm in that code?

burakakca avatar Dec 13 '22 07:12 burakakca

the line contextBuilder.option("wasm.Builtins", "wasi_snapshot_preview1"); is missing in the docs: https://www.graalvm.org/latest/reference-manual/wasm/

and with graalvm 22.3.1 (Java version: 17.0.6, vendor: GraalVM Community, runtime: /shared2/graalvm/graalvm-ce-java17-22.3.1) the error that is output at the end is this:

1 .
2 3 .
4 5 6 .
7 8 9 10 .
11 12 13 14 15 .
16 17 18 19 20 21 .
22 23 24 25 26 27 28 .
29 30 31 32 33 34 35 36 .
37 38 39 40 41 42 43 44 45 .
46 47 48 49 50 51 52 53 54 55 .
[WARNING] 
org.graalvm.polyglot.PolyglotException: Program exited with status code 0.
    at <wasm>.wasm-function:__wasi_proc_exit (Unknown)
    at <wasm>.wasm-function:10 (Unknown)
    at <wasm>.wasm-function:9 (Unknown)
    at <wasm>._start (Unknown)
    at org.graalvm.polyglot.Value.execute (Value.java:878)
    at Floyd.main (Floyd.java:23)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:254)
    at java.lang.Thread.run (Thread.java:833)

maxant avatar May 07 '23 16:05 maxant

Tracked internally on GR 43131

oubidar-Abderrahim avatar Feb 07 '24 15:02 oubidar-Abderrahim

@burakakca, meanwhile the running WebAssembly embedded in Java example was improved. Please check it at the website https://www.graalvm.org/jdk23/reference-manual/wasm/.

olyagpl avatar Jun 07 '24 06:06 olyagpl