The community edition of the Truffle runtime providing execution engine and optimization support for dynamic programming languages built with the Truffle framework
—
Execution frame system providing efficient storage and access to method arguments, local variables, and temporary values during AST interpretation.
Base interface for accessing execution context including arguments and local variables.
/**
* Base interface for execution frames containing arguments and local variables
* Provides access to the execution context of a method or function
*/
public interface Frame {
/** Returns the frame descriptor defining the frame layout */
FrameDescriptor getFrameDescriptor();
/** Returns the arguments passed to this frame */
Object[] getArguments();
/** Materializes this frame for persistence beyond the call stack */
MaterializedFrame materialize();
// === Object Slot Access ===
/** Gets the value from an object slot */
Object getObject(FrameSlot slot) throws FrameSlotTypeException;
/** Sets the value in an object slot */
void setObject(FrameSlot slot, Object value);
/** Gets object value by identifier */
Object getObject(Object identifier) throws FrameSlotTypeException;
/** Sets object value by identifier */
void setObject(Object identifier, Object value);
// === Primitive Slot Access ===
/** Gets a byte value from a slot */
byte getByte(FrameSlot slot) throws FrameSlotTypeException;
/** Sets a byte value in a slot */
void setByte(FrameSlot slot, byte value);
/** Gets an int value from a slot */
int getInt(FrameSlot slot) throws FrameSlotTypeException;
/** Sets an int value in a slot */
void setInt(FrameSlot slot, int value);
/** Gets a long value from a slot */
long getLong(FrameSlot slot) throws FrameSlotTypeException;
/** Sets a long value in a slot */
void setLong(FrameSlot slot, long value);
/** Gets a float value from a slot */
float getFloat(FrameSlot slot) throws FrameSlotTypeException;
/** Sets a float value in a slot */
void setFloat(FrameSlot slot, float value);
/** Gets a double value from a slot */
double getDouble(FrameSlot slot) throws FrameSlotTypeException;
/** Sets a double value in a slot */
void setDouble(FrameSlot slot, double value);
/** Gets a boolean value from a slot */
boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException;
/** Sets a boolean value in a slot */
void setBoolean(FrameSlot slot, boolean value);
// === Auxiliary Slot Access ===
/** Gets auxiliary data from a slot */
Object getAuxiliarySlot(FrameSlot slot);
/** Sets auxiliary data in a slot */
void setAuxiliarySlot(FrameSlot slot, Object value);
// === Slot Management ===
/** Checks if a slot is of object type */
boolean isObject(FrameSlot slot);
/** Checks if a slot is of byte type */
boolean isByte(FrameSlot slot);
/** Checks if a slot is of int type */
boolean isInt(FrameSlot slot);
/** Checks if a slot is of long type */
boolean isLong(FrameSlot slot);
/** Checks if a slot is of float type */
boolean isFloat(FrameSlot slot);
/** Checks if a slot is of double type */
boolean isDouble(FrameSlot slot);
/** Checks if a slot is of boolean type */
boolean isBoolean(FrameSlot slot);
/** Gets the value from a slot without type checking */
Object getValue(FrameSlot slot);
/** Clears the value in a slot */
void clear(FrameSlot slot);
}Optimized frame implementation for efficient execution on the call stack.
/**
* Optimized frame for efficient execution
* Lives on the call stack and provides fast access to frame data
*/
public interface VirtualFrame extends Frame {
/**
* Materializes this virtual frame into a persistent materialized frame
* The materialized frame can be stored beyond the current call
*/
MaterializedFrame materialize();
/**
* Checks if this frame has been materialized
* Materialization affects performance characteristics
*/
boolean isMaterialized();
}Persistent frame that can be stored and accessed beyond the current call stack.
/**
* Persistent frame that can exist beyond the call stack
* Used for closures, continuations, and debugging
*/
public interface MaterializedFrame extends Frame {
// Inherits all Frame methods
// No additional methods - marker interface for persistent frames
}Template defining the layout and structure of frames, including slot definitions and metadata.
/**
* Descriptor defining the structure and layout of execution frames
* Specifies available slots and their properties
*/
public abstract class FrameDescriptor implements Cloneable {
/** Creates a new frame descriptor */
public static FrameDescriptor create();
/** Creates a frame descriptor with a default value */
public static FrameDescriptor create(Object defaultValue);
/** Adds a new frame slot with the given identifier */
public abstract FrameSlot addFrameSlot(Object identifier);
/** Adds a new frame slot with identifier and kind */
public abstract FrameSlot addFrameSlot(Object identifier, FrameSlotKind kind);
/** Adds a new frame slot with identifier, info, and kind */
public abstract FrameSlot addFrameSlot(Object identifier, Object info, FrameSlotKind kind);
/** Finds a frame slot by identifier */
public abstract FrameSlot findFrameSlot(Object identifier);
/** Finds or adds a frame slot */
public abstract FrameSlot findOrAddFrameSlot(Object identifier);
/** Finds or adds a frame slot with kind */
public abstract FrameSlot findOrAddFrameSlot(Object identifier, FrameSlotKind kind);
/** Finds or adds a frame slot with info and kind */
public abstract FrameSlot findOrAddFrameSlot(Object identifier, Object info, FrameSlotKind kind);
/** Returns all frame slots */
public abstract List<? extends FrameSlot> getSlots();
/** Returns the number of slots */
public abstract int getSize();
/** Returns the default value for uninitialized slots */
public abstract Object getDefaultValue();
/** Creates a shallow copy of this descriptor */
public abstract FrameDescriptor shallowCopy();
/** Creates a deep copy of this descriptor */
public FrameDescriptor copy();
}Individual slot within a frame for storing local variables and temporary values.
/**
* Individual slot within a frame for storing values
* Represents a local variable or temporary storage location
*/
public abstract class FrameSlot implements Cloneable {
/** Returns the slot identifier */
public abstract Object getIdentifier();
/** Returns additional slot information */
public abstract Object getInfo();
/** Sets additional slot information */
public abstract void setInfo(Object info);
/** Returns the slot kind (optimization hint) */
public abstract FrameSlotKind getKind();
/** Sets the slot kind */
public abstract void setKind(FrameSlotKind kind);
/** Returns the slot index in the frame */
public abstract int getIndex();
/** Checks if this slot equals another slot */
public final boolean equals(Object obj);
/** Returns hash code for this slot */
public final int hashCode();
/** Returns string representation */
public final String toString();
}Type hint enumeration for optimizing frame slot storage.
/**
* Type hint for frame slots to enable storage optimizations
*/
public enum FrameSlotKind {
/** Object reference storage */
Object,
/** Long integer storage */
Long,
/** Integer storage */
Int,
/** Double precision floating point storage */
Double,
/** Single precision floating point storage */
Float,
/** Boolean storage */
Boolean,
/** Byte storage */
Byte,
/** Illegal/uninitialized storage */
Illegal;
/** Tag value for this kind */
public final byte tag;
}Utilities for working with frames and handling frame-related errors.
/**
* Exception thrown when accessing a frame slot with wrong type
*/
public final class FrameSlotTypeException extends SlowPathException {
/** Creates exception for wrong slot type access */
public FrameSlotTypeException();
/** Creates exception with custom message */
public FrameSlotTypeException(String message);
}
/**
* Utility methods for working with frames
*/
public final class FrameUtil {
/** Gets object value with type checking */
public static Object getObjectSafe(Frame frame, FrameSlot slot);
/** Gets int value with type checking */
public static int getIntSafe(Frame frame, FrameSlot slot);
/** Gets long value with type checking */
public static long getLongSafe(Frame frame, FrameSlot slot);
/** Gets double value with type checking */
public static double getDoubleSafe(Frame frame, FrameSlot slot);
/** Gets float value with type checking */
public static float getFloatSafe(Frame frame, FrameSlot slot);
/** Gets boolean value with type checking */
public static boolean getBooleanSafe(Frame frame, FrameSlot slot);
/** Gets byte value with type checking */
public static byte getByteSafe(Frame frame, FrameSlot slot);
}Usage Examples:
import com.oracle.truffle.api.frame.*;
public class MyLanguageLocalVariableNode extends MyLanguageExpressionNode {
private final FrameSlot slot;
public MyLanguageLocalVariableNode(FrameSlot slot) {
this.slot = slot;
}
@Override
public Object execute(VirtualFrame frame) {
try {
// Try to read as the expected type first
if (frame.isInt(slot)) {
return frame.getInt(slot);
} else if (frame.isDouble(slot)) {
return frame.getDouble(slot);
} else if (frame.isBoolean(slot)) {
return frame.getBoolean(slot);
} else {
return frame.getObject(slot);
}
} catch (FrameSlotTypeException e) {
// Fall back to object access
return frame.getValue(slot);
}
}
}
public class MyLanguageAssignmentNode extends MyLanguageStatementNode {
@Child private MyLanguageExpressionNode valueNode;
private final FrameSlot slot;
public MyLanguageAssignmentNode(FrameSlot slot, MyLanguageExpressionNode valueNode) {
this.slot = slot;
this.valueNode = valueNode;
}
@Override
public Object execute(VirtualFrame frame) {
Object value = valueNode.execute(frame);
// Optimize storage based on value type
if (value instanceof Integer) {
slot.setKind(FrameSlotKind.Int);
frame.setInt(slot, (Integer) value);
} else if (value instanceof Double) {
slot.setKind(FrameSlotKind.Double);
frame.setDouble(slot, (Double) value);
} else if (value instanceof Boolean) {
slot.setKind(FrameSlotKind.Boolean);
frame.setBoolean(slot, (Boolean) value);
} else {
slot.setKind(FrameSlotKind.Object);
frame.setObject(slot, value);
}
return value;
}
}
// Creating a frame descriptor for a function
public class MyLanguageFunctionParser {
public RootNode parseFunction(String name, List<String> parameters, Node body) {
FrameDescriptor.Builder builder = FrameDescriptor.newBuilder();
// Add slots for parameters
List<FrameSlot> parameterSlots = new ArrayList<>();
for (String param : parameters) {
FrameSlot slot = builder.addSlot(FrameSlotKind.Illegal, param, null);
parameterSlots.add(slot);
}
FrameDescriptor frameDescriptor = builder.build();
return new MyLanguageFunctionRootNode(
getCurrentLanguageInfo(),
frameDescriptor,
body,
name,
parameterSlots
);
}
}public abstract class SlowPathException extends Exception {
/** Base class for exceptions that should not affect compilation */
protected SlowPathException() {
super();
}
protected SlowPathException(String message) {
super(message);
}
}
public final class FrameDescriptor.Builder {
/** Builder for creating frame descriptors */
/** Adds a slot with the given kind and identifier */
public FrameSlot addSlot(FrameSlotKind kind, Object identifier, Object info);
/** Builds the frame descriptor */
public FrameDescriptor build();
}Install with Tessl CLI
npx tessl i tessl/maven-org-graalvm-truffle--truffle-runtime