A multi-language framework for executing dynamic languages that achieves high performance when combined with Graal.
—
The Truffle DSL provides annotation-driven code generation for creating optimized AST nodes with automatic specialization, caching, and fallback handling. It enables high-performance language implementations through compile-time optimization and runtime adaptation.
Core specialization system allowing nodes to optimize for specific types and conditions through generated code.
/**
* Marks a method as a specialization of a node operation
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface Specialization {
/**
* Guards that must be true for this specialization
* @return Array of guard expressions
*/
String[] guards() default {};
/**
* Assumptions that must be valid for this specialization
* @return Array of assumption expressions
*/
String[] assumptions() default {};
/**
* Limit for polymorphic inline caching
* @return Maximum number of cached instances
*/
String limit() default "";
/**
* Conditions for rewriting to this specialization
* @return Array of condition expressions
*/
String[] replaces() default {};
/**
* Whether this specialization contains a slow path
* @return true if contains slow path
*/
boolean insertBefore() default false;
}
/**
* Marks a fallback method for handling uncovered cases
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface Fallback {
}
/**
* Caches values for specializations
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.PARAMETER)
public @interface Cached {
/**
* Expression for computing cached value
* @return Cache expression
*/
String value() default "";
/**
* Limit for cache size
* @return Maximum cache entries
*/
String limit() default "3";
/**
* Whether to use weak references
* @return true for weak references
*/
boolean weak() default false;
/**
* Dimensions for multidimensional caching
* @return Cache dimensions
*/
String dimensions() default "1";
}
/**
* Binds expressions to local variables in specializations
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.PARAMETER)
public @interface Bind {
/**
* Expression to bind
* @return Binding expression
*/
String value();
}
/**
* Marks parameter as shared across specializations
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.PARAMETER)
public @interface Shared {
/**
* Shared parameter name
* @return Parameter name
*/
String value();
}Usage Example:
public abstract class AddNode extends BinaryNode {
@Specialization
protected int doInteger(int left, int right) {
return left + right;
}
@Specialization
protected long doLong(long left, long right) {
return left + right;
}
@Specialization
protected double doDouble(double left, double right) {
return left + right;
}
@Specialization(guards = "isString(left) || isString(right)")
protected String doString(Object left, Object right,
@Cached ToStringNode leftToString,
@Cached ToStringNode rightToString) {
return leftToString.execute(left) + rightToString.execute(right);
}
@Fallback
protected Object doGeneric(Object left, Object right) {
throw new UnsupportedOperationException("Cannot add " + left + " and " + right);
}
protected boolean isString(Object value) {
return value instanceof String;
}
}Annotations for controlling code generation and node factory creation.
/**
* Generates node factory for DSL node
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface GenerateNodeFactory {
}
/**
* Generates uncached version of node
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface GenerateUncached {
/**
* Whether to inherit from parent node
* @return true to inherit
*/
boolean inherit() default true;
}
/**
* Generates inlined version of node
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface GenerateInline {
/**
* Whether inlining is allowed
* @return true if allowed
*/
boolean value() default true;
/**
* Inline cache limit
* @return Cache limit
*/
String inlineByDefault() default "true";
}
/**
* Generates ahead-of-time compilation support
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface GenerateAOT {
/**
* Whether to exclude from AOT
* @return true to exclude
*/
boolean exclude() default false;
}
/**
* Controls node cost calculation
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface NodeInfo {
/**
* Node cost hint
* @return NodeCost value
*/
NodeCost cost() default NodeCost.MONOMORPHIC;
/**
* Short name for node
* @return Node name
*/
String shortName() default "";
/**
* Description of node functionality
* @return Node description
*/
String description() default "";
}Annotations for defining node hierarchies and relationships.
/**
* Declares a child node
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
@Repeatable(NodeChildren.class)
public @interface NodeChild {
/**
* Child node name
* @return Node name
*/
String value() default "";
/**
* Child node type
* @return Node class
*/
Class<? extends Node> type() default Node.class;
/**
* Whether child execution is implicit
* @return true if implicit
*/
boolean implicit() default false;
}
/**
* Container for multiple NodeChild annotations
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface NodeChildren {
/**
* Array of child node declarations
* @return NodeChild annotations
*/
NodeChild[] value();
}
/**
* Declares a node field
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
@Repeatable(NodeFields.class)
public @interface NodeField {
/**
* Field name
* @return Field name
*/
String name();
/**
* Field type
* @return Field class
*/
Class<?> type();
}
/**
* Container for multiple NodeField annotations
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface NodeFields {
/**
* Array of field declarations
* @return NodeField annotations
*/
NodeField[] value();
}
/**
* Marks parameter as executed child node result
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.PARAMETER)
public @interface Executed {
/**
* Child node name or index
* @return Child identifier
*/
String with() default "";
}Annotations and classes for defining type systems and type operations.
/**
* Defines a type system for DSL nodes
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface TypeSystem {
/**
* Types in the type system hierarchy
* @return Array of type classes
*/
Class<?>[] value();
}
/**
* Defines implicit cast between types
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface ImplicitCast {
}
/**
* Defines type cast operation
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface TypeCast {
/**
* Source type for cast
* @return Source type class
*/
Class<?> value();
}
/**
* Defines type check operation
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface TypeCheck {
/**
* Type to check
* @return Type class
*/
Class<?> value();
}
/**
* Creates type system from annotations
*/
public abstract class TypeSystemReference {
/**
* Get type system instance
* @return TypeSystem instance
*/
public abstract Object getType();
}Usage Example:
@TypeSystem({int.class, long.class, double.class, boolean.class, String.class, Object.class})
public abstract class MyTypeSystem {
@ImplicitCast
public static long castIntToLong(int value) {
return value;
}
@ImplicitCast
public static double castLongToDouble(long value) {
return value;
}
@TypeCheck(int.class)
public static boolean isInteger(Object value) {
return value instanceof Integer;
}
@TypeCast(int.class)
public static int asInteger(Object value) {
return (Integer) value;
}
}Annotations for integrating DSL nodes with Truffle libraries.
/**
* Caches library instances for efficient dispatch
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.PARAMETER)
public @interface CachedLibrary {
/**
* Expression for library receiver
* @return Receiver expression
*/
String value() default "";
/**
* Cache limit for library instances
* @return Maximum cache size
*/
String limit() default "3";
}Exception types for DSL runtime errors.
/**
* Exception thrown when no specialization matches
*/
public final class UnsupportedSpecializationException extends RuntimeException {
/**
* Create exception with node and values
* @param node Node that failed
* @param suppliedValues Values that caused failure
* @return New exception instance
*/
public static UnsupportedSpecializationException create(Node node, Object... suppliedValues);
/**
* Get node that failed
* @return Node instance
*/
public Node getNode();
/**
* Get supplied values
* @return Array of values
*/
public Object[] getSuppliedValues();
}
/**
* Exception for unexpected result types
*/
public final class UnexpectedResultException extends SlowPathException {
/**
* Create exception with unexpected result
* @param result Unexpected result value
*/
public UnexpectedResultException(Object result);
/**
* Get unexpected result
* @return Result value
*/
public Object getResult();
}Interfaces for generated node factories.
/**
* Factory interface for creating DSL nodes
* @param <T> Node type
*/
public interface NodeFactory<T extends Node> {
/**
* Get node class
* @return Node class
*/
Class<T> getNodeClass();
/**
* Get list of execution signatures
* @return List of signatures
*/
List<List<Class<?>>> getNodeSignatures();
/**
* Get list of children classes
* @return List of child types
*/
List<Class<? extends Node>> getExecutionSignature();
/**
* Create node instance
* @param children Child nodes
* @return Node instance
*/
T createNode(Object... children);
/**
* Get uncached node instance
* @return Uncached node
*/
T getUncachedInstance();
}
/**
* Interface for nodes that support inlining
*/
public interface InlineSupport {
/**
* Create inlined version of node
* @param state Inline state
* @return Inlined node
*/
Node createInlined(InlineTarget target);
/**
* Get inline cost
* @return Inlining cost estimate
*/
int getInlinedCost();
}
/**
* State object for inline operations
*/
public abstract class InlineTarget {
/**
* Get target class for inlining
* @return Target class
*/
public abstract Class<?> getTargetClass();
/**
* Get frame transfer mode
* @return Transfer mode
*/
public abstract FrameTransferMode getFrameTransferMode();
}
/**
* Frame transfer modes for inlining
*/
public enum FrameTransferMode {
NONE, COPY_ARGUMENTS, MATERIALIZE
}/**
* Configuration for DSL code generation
*/
public final class DSLOptions {
/**
* Default cache limit for specializations
*/
public static final int DEFAULT_CACHE_LIMIT = 3;
/**
* Default polymorphism limit
*/
public static final int DEFAULT_POLYMORPHISM_LIMIT = 5;
}
/**
* Metadata for generated specializations
*/
public abstract class SpecializationData {
/**
* Check if specialization is active
* @return true if active
*/
public abstract boolean isActive();
/**
* Get specialization method name
* @return Method name
*/
public abstract String getMethodName();
/**
* Get guard expressions
* @return Array of guard expressions
*/
public abstract String[] getGuards();
}Install with Tessl CLI
npx tessl i tessl/maven-org-graalvm-truffle--truffle-api