WebAssemblyのGraalVM実装

GraalVMでは、WebAssemblyにコンパイルされたプログラムを実行できます。WebAssemblyコードをバイナリ形式で解釈してコンパイルしたり、他のプログラムに埋め込むことができます。WebAssemblyのサポートは、開発の初期段階にあります。

Wasmのインストール

このサポートはデフォルトでは使用できませんが、GraalVMアップデータ・ツールを使用してGraalVMに追加できます:

gu install wasm

前述のコマンドは、GitHubカタログからコンポーネントのコミュニティ・バージョンをインストールします。GraalVM Enterpriseユーザーの場合、手動によるコンポーネントのインストールが必要です。

その後、コンパイルされたWebAssemblyバイナリ・コードを実行できるwasmランチャが使用可能になります。

WebAssemblyプログラムの実行

GraalVM上のWebAssemblyにコンパイルする言語で記述されたプログラムを実行できます。たとえば、floyd.cという名前のファイルに次のCプログラムを入れます:

#include <stdio.h>

int main() {
  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");
  }
  return 0;
}

最新のEmscriptenコンパイラのフロントエンド・バージョンを使用してコンパイルします。現在の作業ディレクトリにスタンドアロンfloyd.wasmファイルが生成されます:

emcc -o floyd.wasm floyd.c

次に、コンパイルしたWebAssemblyバイナリをGraalVMで次のように実行できます:

wasm --Builtins=wasi_snapshot_preview1 floyd.wasm

この例では、フラグ--Builtinsは、Emscriptenツールチェーンに必要な組込みモジュールを指定します。

WebAssemblyプログラムの埋込み

コンパイルされたWebAssemblyバイナリ・コードには、GraalVMポリグロットAPIを使用してプログラムでアクセスできます。これにより、GraalVM WebAssemblyをユーザー・プログラムに埋め込むことができます。JavaアプリケーションからWebAssemblyコードをコールする方法の簡単な例を次に示します:

import org.graalvm.polyglot.*;
import org.graalvm.polyglot.io.ByteSequence;
//Load the WASM contents into a byte array
byte[] binary = readBytes("example.wasm");
Context.Builder contextBuilder = Context.newBuilder("wasm");
Source.Builder sourceBuilder = Source.newBuilder("wasm", ByteSequence.create(binary), "example");
Source source = sourceBuilder.build();
Context context = contextBuilder.build();

context.eval(source);

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

より多くのポリグロットの例は、「ポリグロット・プログラミング」のページを参照してください。