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;


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) {

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

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" ,"");

// 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

// 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;


// Additionally, pass a JS object to a native function
cpart.printPoint({x: 17, y: 42});

// Free the unmanaged data objects

Finally, run this JavaScript file:

js --polyglot jspart.js

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:

lli polyglot

Embedding in Java #

You can embed LLVM bitcode in a Java host application.

For example, write a Java class that embeds LLVM bitcode to run the previous example:

import org.graalvm.polyglot.*;

class Polyglot {
    public static void main(String[] args) throws IOException {
        Context polyglot = Context.newBuilder().
        File file = new File("polyglot");
        Source source = Source.newBuilder("llvm", file).build();
        Value cpart = polyglot.eval(source);

Compile it and run:

java Polyglot

See the Embedding Languages reference for more information.

Connect with us