- GraalVM for JDK 23 (最新)
- GraalVM for JDK 24 (早期アクセス)
- GraalVM for JDK 21
- GraalVM for JDK 17
- アーカイブ
- 開発ビルド
相互運用性
GraalVM は JavaScript、Python、Ruby、R を含むその他の多くのプログラミング言語をサポートしています。GraalVM の lli
の実装は LLVM ビットコードを実行するように設計されていますが、他の GraalVM がサポートする任意の言語からコードを実行できるプログラミング言語相互運用性用の API も用意しています。
JavaScript などの動的言語では、通常はオブジェクト メンバーに名前でアクセスします。通常、名前は LLVM ビットコードでは維持されないため、デバッグ情報が有効な状態でコンパイルする必要があります (GraalVM に搭載されている LLVM ツールチェーンはデバッグ情報を自動的に有効にします)。
以下の例では、他のプログラミング言語と相互運用するための API を使用する方法を示します。
cpart.c というファイルにポイント用の C 構造体を定義し、割り当て関数を実装します
// cpart.c
#include <graalvm/llvm/polyglot.h>
#include <stdlib.h>
#include <stdio.h>
struct Point {
double x;
double y;
};
POLYGLOT_DECLARE_STRUCT(Point)
void *allocNativePoint() {
struct Point *ret = malloc(sizeof(*ret));
return polyglot_from_Point(ret);
}
void *allocNativePointArray(int length) {
struct Point *ret = calloc(length, sizeof(*ret));
return polyglot_from_Point_array(ret, length);
}
void freeNativePoint(struct Point *p) {
free(p);
}
void printPoint(struct Point *p) {
printf("Point<%f,%f>\n", p->x, p->y);
}
LLVM_TOOLCHAIN
が GraalVM LLVM ツールチェーン (lli --print-toolchain-path
) に解決していることを確認し、cpart.c をコンパイルします (graalvm-llvm ライブラリはサンプルで使用される多言語の API 関数を定義します)
$LLVM_TOOLCHAIN/clang -shared cpart.c -lgraalvm-llvm -o cpart.so
その後、jspart.js ファイルにこの C/C++ コードからアクセスできます
// Load and parse the LLVM bitcode into GraalVM
var cpart = Polyglot.evalFile("llvm" ,"cpart.so");
// Allocate a light-weight C struct
var point = cpart.allocNativePoint();
// Access it as if it was a JS object
point.x = 5;
point.y = 7;
// Pass it back to a native function
cpart.printPoint(point);
// Allocate an array of structs
var pointArray = cpart.allocNativePointArray(15);
// Access this array like it was a JS array
for (var i = 0; i < pointArray.length; i++) {
var p = pointArray[i];
p.x = i;
p.y = 2*i;
}
cpart.printPoint(pointArray[3]);
// Additionally, pass a JS object to a native function
cpart.printPoint({x: 17, y: 42});
// Free the unmanaged data objects
cpart.freeNativePoint(point);
cpart.freeNativePoint(pointArray);
最後に、この JavaScript ファイルを実行します
js --polyglot jspart.js
Point<5.000000,7.000000>
Point<3.000000,6.000000>
Point<17.000000,42.000000>
多言語 C API #
C から多言語値に直接アクセスするための下位レベルの API 関数もあります。詳細については、多言語プログラミングリファレンスと polyglot.h
のコメントを参照してください。
例えば、このプログラムは C から Java 配列を割り当ててアクセスします
#include <stdio.h>
#include <graalvm/llvm/polyglot.h>
int main() {
void *arrayType = polyglot_java_type("int[]");
void *array = polyglot_new_instance(arrayType, 4);
polyglot_set_array_element(array, 2, 24);
int element = polyglot_as_i32(polyglot_get_array_element(array, 2));
printf("%d\n", element);
return element;
}
それを LLVM ビットコードにコンパイルします
$LLVM_TOOLCHAIN/clang polyglot.c -lgraalvm-llvm -o polyglot
次に実行します
lli polyglot
24
Java への組み込み #
LLVM ビットコードを Java ホストアプリケーションに埋め込むことができます。
例えば、前の例を実行するための LLVM ビットコードを埋め込む Polyglot.java
という Java クラスを作成します
import java.io.*;
import org.graalvm.polyglot.*;
class Polyglot {
public static void main(String[] args) throws IOException {
Context polyglot = Context.newBuilder().
allowAllAccess(true).build();
File file = new File("polyglot");
Source source = Source.newBuilder("llvm", file).build();
Value cpart = polyglot.eval(source);
cpart.execute();
}
}
コンパイルして実行します
javac Polyglot.java
java Polyglot
24
詳細については、言語の埋め込みリファレンスを参照してください。