GraalWasm

GraalWasmは、オープン・ソースのWebAssemblyランタイムです。これは、WebAssemblyプログラムをバイナリ形式で実行し、JavaアプリケーションにWebAssemblyモジュールを埋め込んで利用するために使用できます。GraalWasmは、アクティブな開発中であり、多数のWebAssembly拡張機能をトラッキングしています。

Javaに埋め込まれたWebAssemblyの実行

コンパイルされたWebAssemblyバイナリ・コードには、GraalVM SDKポリグロットAPIを使用してプログラムでアクセスできます。これにより、WebAssemblyをユーザー・アプリケーションに埋め込むことができます。

次の例では、C関数をWebAssemblyにコンパイルし、Javaアプリケーションに埋め込んで実行する方法を示します。デモを実行するには、次が必要です:

デモ・パート

  1. floyd.cという名前のファイルに次のCプログラムを入れます:
     #include <stdio.h>
    
     void floyd() {
         int number = 1;
         int rows = 10;
         for (int i = 1; i <= rows; i++) {
             for (int j = 1; j <= i; j++) {
                 printf("%d ", number);
                 ++number;
             }
             printf(".\n");
         }
     }
    
     int main() {
         floyd();
         return 0;
     }
    

    floydは、個別の関数として定義されており、エクスポートできることに注意してください。

  2. 最新のEmscriptenコンパイラのフロントエンドを使用してCコードをコンパイルします:
     emcc --no-entry -s EXPORTED_FUNCTIONS=_floyd -o floyd.wasm floyd.c
    

    エクスポートされた関数の先頭には、_を付ける必要があります。Javaコードなどでその関数を参照する場合、エクスポートされた名前にアンダースコアを含めることはできません。

    現在の作業ディレクトリにスタンドアロン・ファイルのfloyd.wasmが生成されます。

  3. 依存関係を追加します。GraalVM SDKポリグロットAPIは、デフォルトでは使用できませんが、JavaプロジェクトにMaven依存関係として簡単に追加できます。GraalWasmアーティファクトは、Javaモジュールまたはクラスパスにも存在する必要があります。プロジェクト構成ファイル(Mavenの場合はpom.xml)に次の依存関係セットを追加します。

    • GraalVMポリグロット・ランタイムを有効にするには:
        <dependency>
            <groupId>org.graalvm.polyglot</groupId>
            <artifactId>polyglot</artifactId> 
            <version>${graalvm.polyglot.version}</version>
        </dependency>
      
    • Wasmを有効にするには:
        <dependency>
            <groupId>org.graalvm.polyglot</groupId>
            <artifactId>wasm</artifactId> 
            <version>${graalvm.polyglot.version}</version>
            <type>pom</type>
        </dependency>
      
  4. これで、次のようにこのWebAssembly関数をJavaアプリケーションに埋め込むことができます:

     import org.graalvm.polyglot.*;
     import org.graalvm.polyglot.io.ByteSequence;
    
     // Load the WebAssembly contents into a byte array
     byte[] binary = Files.readAllBytes(Path.of("path", "to", "wasm", "file", "floyd.wasm"));
    
     // Setup context
     Context.Builder contextBuilder = Context.newBuilder("wasm").option("wasm.Builtins", "wasi_snapshot_preview1");
     Source.Builder sourceBuilder = Source.newBuilder("wasm", ByteSequence.create(binary), "example");
     Source source = sourceBuilder.build();
     Context context = contextBuilder.build();
    
     // Evaluate the WebAssembly module
     context.eval(source);
    
     // Execute the floyd function
     context.getBindings("wasm").getMember("example").getMember("_initialize").executeVoid();
     Value mainFunction =context.getBindings("wasm").getMember("example").getMember("floyd");
     mainFunction.execute();
     context.close();
    
  5. 通常どおりMavenでこのJavaアプリケーションをコンパイルして実行します。