The community edition of the Truffle runtime providing execution engine and optimization support for dynamic programming languages built with the Truffle framework
—
Language interoperability framework that enables seamless interaction between different programming languages in GraalVM through the InteropLibrary protocol and polyglot bindings.
Core interoperability protocol that provides language-neutral operations for reading, writing, executing, and type checking of foreign objects.
/**
* Library for interoperating with foreign objects from different languages
* Main protocol for cross-language object interaction
*/
@ExportLibrary(value = InteropLibrary.class, delegateTo = "delegate")
public abstract class InteropLibrary extends Library {
/** Returns the singleton interop library for uncached usage */
public static InteropLibrary getUncached();
/** Returns a cached interop library instance for the given object */
public static InteropLibrary getUncached(Object receiver);
// === Object Identity and Null Checks ===
/** Checks if the object represents null */
public boolean isNull(Object receiver);
/** Checks if the object is identical to another object */
public boolean isIdentical(Object receiver, Object other, InteropLibrary otherInterop);
/** Returns the identity hash code */
public int identityHashCode(Object receiver);
// === Boolean Operations ===
/** Checks if the object represents a boolean value */
public boolean isBoolean(Object receiver);
/** Returns the boolean value */
public boolean asBoolean(Object receiver) throws UnsupportedMessageException;
// === String Operations ===
/** Checks if the object represents a string */
public boolean isString(Object receiver);
/** Returns the string value */
public String asString(Object receiver) throws UnsupportedMessageException;
// === Number Operations ===
/** Checks if the object represents a number */
public boolean isNumber(Object receiver);
/** Checks if the number fits in a specific type */
public boolean fitsInByte(Object receiver);
public boolean fitsInShort(Object receiver);
public boolean fitsInInt(Object receiver);
public boolean fitsInLong(Object receiver);
public boolean fitsInFloat(Object receiver);
public boolean fitsInDouble(Object receiver);
/** Converts the number to a specific type */
public byte asByte(Object receiver) throws UnsupportedMessageException;
public short asShort(Object receiver) throws UnsupportedMessageException;
public int asInt(Object receiver) throws UnsupportedMessageException;
public long asLong(Object receiver) throws UnsupportedMessageException;
public float asFloat(Object receiver) throws UnsupportedMessageException;
public double asDouble(Object receiver) throws UnsupportedMessageException;
// === Array Operations ===
/** Checks if the object has array elements */
public boolean hasArrayElements(Object receiver);
/** Returns the size of the array */
public long getArraySize(Object receiver) throws UnsupportedMessageException;
/** Checks if an array index is readable */
public boolean isArrayElementReadable(Object receiver, long index);
/** Reads an array element */
public Object readArrayElement(Object receiver, long index)
throws UnsupportedMessageException, InvalidArrayIndexException;
/** Checks if an array index is writable */
public boolean isArrayElementWritable(Object receiver, long index);
/** Writes an array element */
public void writeArrayElement(Object receiver, long index, Object value)
throws UnsupportedMessageException, InvalidArrayIndexException, UnsupportedTypeException;
// === Member Operations ===
/** Checks if the object has members (properties) */
public boolean hasMembers(Object receiver);
/** Returns the list of member keys */
public Object getMembers(Object receiver, boolean includeInternal) throws UnsupportedMessageException;
/** Checks if a member is readable */
public boolean isMemberReadable(Object receiver, String member);
/** Reads a member value */
public Object readMember(Object receiver, String member)
throws UnsupportedMessageException, UnknownIdentifierException;
/** Checks if a member is writable */
public boolean isMemberWritable(Object receiver, String member);
/** Writes a member value */
public void writeMember(Object receiver, String member, Object value)
throws UnsupportedMessageException, UnknownIdentifierException, UnsupportedTypeException;
/** Checks if a member is removable */
public boolean isMemberRemovable(Object receiver, String member);
/** Removes a member */
public void removeMember(Object receiver, String member)
throws UnsupportedMessageException, UnknownIdentifierException;
// === Execution Operations ===
/** Checks if the object is executable */
public boolean isExecutable(Object receiver);
/** Executes the object as a function */
public Object execute(Object receiver, Object... arguments)
throws UnsupportedMessageException, ArityException, UnsupportedTypeException;
/** Checks if the object is instantiable */
public boolean isInstantiable(Object receiver);
/** Instantiates the object as a constructor */
public Object instantiate(Object receiver, Object... arguments)
throws UnsupportedMessageException, ArityException, UnsupportedTypeException;
}Usage Examples:
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
public Object interopExample(Object foreignObject) {
InteropLibrary interop = InteropLibrary.getUncached(foreignObject);
try {
// Check and read properties
if (interop.hasMembers(foreignObject)) {
Object members = interop.getMembers(foreignObject, false);
if (interop.isMemberReadable(foreignObject, "name")) {
Object name = interop.readMember(foreignObject, "name");
if (interop.isString(name)) {
return interop.asString(name);
}
}
}
// Check and call as function
if (interop.isExecutable(foreignObject)) {
return interop.execute(foreignObject, "arg1", 42);
}
// Array access
if (interop.hasArrayElements(foreignObject)) {
long size = interop.getArraySize(foreignObject);
if (size > 0 && interop.isArrayElementReadable(foreignObject, 0)) {
return interop.readArrayElement(foreignObject, 0);
}
}
} catch (UnsupportedMessageException | InvalidArrayIndexException | UnknownIdentifierException e) {
// Handle interop errors
return null;
}
return foreignObject;
}Marker interface that identifies objects as Truffle interoperability objects.
/**
* Marker interface for objects that participate in Truffle interoperability
* Objects implementing this interface can be passed between languages
*/
public interface TruffleObject {
// Marker interface - no methods
}Specialized exceptions for interoperability error conditions.
/**
* Exception thrown when an interop message is not supported
*/
public final class UnsupportedMessageException extends InteropException {
/** Creates exception for unsupported message */
public static UnsupportedMessageException create();
}
/**
* Exception thrown when array index is invalid
*/
public final class InvalidArrayIndexException extends InteropException {
/** Creates exception for invalid array index */
public static InvalidArrayIndexException create(long invalidIndex);
/** Returns the invalid index */
public long getInvalidIndex();
}
/**
* Exception thrown when identifier is unknown
*/
public final class UnknownIdentifierException extends InteropException {
/** Creates exception for unknown identifier */
public static UnknownIdentifierException create(String unknownIdentifier);
/** Returns the unknown identifier */
public String getUnknownIdentifier();
}
/**
* Exception thrown when type is not supported for operation
*/
public final class UnsupportedTypeException extends InteropException {
/** Creates exception for unsupported type */
public static UnsupportedTypeException create(Object[] suppliedValues);
/** Creates exception for unsupported type with message */
public static UnsupportedTypeException create(Object[] suppliedValues, String hint);
/** Returns the supplied values that caused the error */
public Object[] getSuppliedValues();
}
/**
* Exception thrown when wrong number of arguments provided
*/
public final class ArityException extends InteropException {
/** Creates exception for wrong arity */
public static ArityException create(int expectedMinArity, int expectedMaxArity, int actualArity);
/** Returns the expected minimum arity */
public int getExpectedMinArity();
/** Returns the expected maximum arity */
public int getExpectedMaxArity();
/** Returns the actual arity provided */
public int getActualArity();
}System for optimizing interop message dispatch through specialized nodes.
/**
* Base class for interop message resolution
*/
public abstract class Message {
/** Returns the message name */
public abstract String getSimpleName();
/** Creates a message node for this message */
public abstract InteropNode createNode();
// Predefined message constants
public static final Message IS_NULL = createMessage("IS_NULL");
public static final Message IS_EXECUTABLE = createMessage("IS_EXECUTABLE");
public static final Message EXECUTE = createMessage("EXECUTE");
public static final Message READ = createMessage("READ");
public static final Message WRITE = createMessage("WRITE");
// ... additional message constants
}
/**
* Specialized node for executing interop messages
*/
public abstract class InteropNode extends Node {
/** Executes the interop message */
public abstract Object execute(Object receiver, Object[] arguments);
/** Creates a node for the given message */
public static InteropNode create(Message message);
}public abstract class InteropException extends Exception {
/** Base class for all interop-related exceptions */
}
public interface Library {
/** Base interface for all Truffle library protocols */
/** Accepts a visitor for library introspection */
public boolean accepts(Object receiver);
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExportLibrary {
/** Annotation for exporting library implementations */
Class<? extends Library> value();
String delegateTo() default "";
int priority() default 0;
}Usage Examples:
// Implementing interop for custom objects
@ExportLibrary(InteropLibrary.class)
public class MyLanguageObject implements TruffleObject {
private final Map<String, Object> members = new HashMap<>();
@ExportMessage
public boolean hasMembers() {
return true;
}
@ExportMessage
public Object getMembers(boolean includeInternal) {
return new KeysArray(members.keySet().toArray(new String[0]));
}
@ExportMessage
public boolean isMemberReadable(String member) {
return members.containsKey(member);
}
@ExportMessage
public Object readMember(String member) throws UnknownIdentifierException {
if (!members.containsKey(member)) {
throw UnknownIdentifierException.create(member);
}
return members.get(member);
}
@ExportMessage
public boolean isMemberWritable(String member) {
return true;
}
@ExportMessage
public void writeMember(String member, Object value) {
members.put(member, value);
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-graalvm-truffle--truffle-runtime