- GraalVM for JDK 23 (Latest)
- GraalVM for JDK 24 (Early Access)
- GraalVM for JDK 21
- GraalVM for JDK 17
- Archives
- Dev Build
Interoperability
GraalVM supports several other programming languages including JavaScript, Python, Ruby, and R.
While GraalVM’s implementation of lli
is designed to run LLVM bitcode, it also provides the API for programming language interoperability that lets you execute code from any other GraalVM-supported language.
Dynamic languages like JavaScript usually access object members by name. Since normally names are not preserved in LLVM bitcode, it must be compiled with debug information enabled (the LLVM toolchain shipped with GraalVM will automatically enable debugging information).
The following example demonstrates how you can use the API for interoperability with other programming languages.
Define a C struct for points and implement allocation functions in a file named cpart.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);
}
Make sure LLVM_TOOLCHAIN
resolves to the GraalVM LLVM toolchain (lli --print-toolchain-path
), and then compile cpart.c (the graalvm-llvm library defines the Polyglot API functions used in the example):
$LLVM_TOOLCHAIN/clang -shared cpart.c -lgraalvm-llvm -o cpart.so
You can then access this C/C++ code from other languages. For example, save this JavaScript code in the jspart.js file:
// 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);
Finally, run this JavaScript file:
js --polyglot jspart.js
Point<5.000000,7.000000>
Point<3.000000,6.000000>
Point<17.000000,42.000000>
Polyglot C API #
There are also lower level API functions for directly accessing polyglot values from C.
See the Polyglot Programming reference and the comments in polyglot.h
for more details.
For example, this program allocates and accesses a Java array from C:
#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;
}
Compile it to LLVM bitcode:
$LLVM_TOOLCHAIN/clang polyglot.c -lgraalvm-llvm -o polyglot
Then run it, using the --jvm
argument to run in the JVM mode, since there is a Java type used:
lli --jvm polyglot
24
Embedding in Java #
GraalVM can also be used to embed LLVM bitcode in Java host programs.
For example, write a Java class Polyglot.java
that embeds GraalVM to
run the previous example:
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();
}
}
Compile it and run:
javac Polyglot.java
java Polyglot
24
See the Embedding Languages reference for more information.