Class BytecodeFrame
BytecodeFrame is intended for use cases where the frame escapes or outlives the root node
invocation. Prefer using a built-in operation or LocalAccessor to access the frame
whenever possible.
BytecodeFrame should be used instead of TruffleStackTraceElement or
FrameInstance to access frame data because the frame captured in these abstractions is
not always the actual frame used in execution (e.g., it may be different for a resumed
continuation).
There are a few ways to capture the frame:
BytecodeNode.createCopiedFrame(int, Frame)captures a copy.BytecodeNode.createMaterializedFrame(int, MaterializedFrame)captures the original frame.get(FrameInstance, FrameAccess)captures a frame from aFrameInstance. It captures the original frame ifFrameInstance.FrameAccess.READ_WRITEorFrameInstance.FrameAccess.MATERIALIZEis requested. Otherwise, it captures either the original frame or a copy.get(TruffleStackTraceElement)captures a frame from aTruffleStackTraceElement. It captures either the original frame or a copy.getNonVirtual(FrameInstance)captures the original frame from aFrameInstance, if it is non-virtual.getNonVirtual(TruffleStackTraceElement)captures the original frame from aTruffleStackTraceElement, if it is non-virtual and available in the stack trace.
Note: if the interpreter uses block scoping, local
offsets are location-dependent and physical frame slots may be reused for different locals as
execution proceeds. After execution continues, a captured frame may therefore expose values
belonging to a different lexical scope. Any non-copied BytecodeFrame is consequently
only valid until the interpreter continues execution. The frame must not be used
after this point; doing so can cause undefined behaviour. If you need to access the frame after
execution continues, you should capture a copy or explicitly copy() the captured
bytecode frame. This restriction also applies to frames created by methods like
get(TruffleStackTraceElement), which do not specify whether they capture
the original frame or a copy.
- Since:
- 25.1
-
Method Summary
Modifier and TypeMethodDescriptioncopy()Returns a copy of this frame.static BytecodeFrameget(FrameInstance frameInstance, FrameInstance.FrameAccess access) Creates a bytecode frame from the given frame instance.static BytecodeFrameget(TruffleStackTraceElement element) Creates a bytecode frame from the given stack trace element.getArgument(int argumentIndex) Returns the value of the argument at the given index.intReturns the number of arguments in the captured frame.intReturns the bytecode index associated with the captured frame.Returns the bytecode node associated with the captured frame.Returns theinfoobject associated with the frame's descriptor.intReturns the number of live locals in the captured frame.Object[]Returns the names associated with the live locals, if provided.getLocalValue(int localOffset) Returns the value of the local at the given offset.Returns the bytecode location associated with the captured frame.static BytecodeFramegetNonVirtual(FrameInstance frameInstance) Attempts to create a bytecode frame from the given frame instance.static BytecodeFramegetNonVirtual(TruffleStackTraceElement element) Attempts to create a bytecode frame from the given stack trace element.static BytecodeFramegetTop(FrameInstance.FrameAccess access, Node topLocation, int topBytecodeIndex) Returns the current top stack activation as abytecode frame.static <T> TiterateBytecodeFrames(Function<BytecodeFrame, T> visitor, FrameInstance.FrameAccess access, Node topLocation, int topBytecodeIndex, int skipBytecodeFrames) Iterates the current stack asbytecode frames, starting with the current top activation.voidsetArgument(int argumentIndex, Object value) Updates the value of the local at the given offset.voidsetLocalValue(int localOffset, Object value) Updates the value of the local at the given offset.
-
Method Details
-
copy
Returns a copy of this frame. This method can be used to snapshot the current state of a bytecode frame, in case it may be modified or become invalid in the future.- Returns:
- a copy of this frame that is always valid and will not observe updates
- Since:
- 25.1
-
getLocation
Returns the bytecode location associated with the captured frame. This location is only valid until the bytecode interpreter resumes execution.- Since:
- 25.1
-
getBytecodeNode
Returns the bytecode node associated with the captured frame.- Since:
- 25.1
-
getBytecodeIndex
public int getBytecodeIndex()Returns the bytecode index associated with the captured frame.- Since:
- 25.1
-
getLocalCount
public int getLocalCount()Returns the number of live locals in the captured frame.- Since:
- 25.1
-
getLocalValue
Returns the value of the local at the given offset. The offset should be in the range[0, getLocalCount()).- Since:
- 25.1
-
setLocalValue
Updates the value of the local at the given offset. The offset should be in the range[0, getLocalCount()).This method will throw an
AssertionErrorif the captured frame does not support writes.- Since:
- 25.1
-
getLocalNames
Returns the names associated with the live locals, if provided.- Since:
- 25.1
-
getArgumentCount
public int getArgumentCount()Returns the number of arguments in the captured frame.- Since:
- 25.1
-
getArgument
Returns the value of the argument at the given index. The offset should be between 0 andgetArgumentCount().- Since:
- 25.1
-
setArgument
Updates the value of the local at the given offset. The offset should be between 0 andgetArgumentCount().- Since:
- 25.1
-
getFrameDescriptorInfo
-
get
Creates a bytecode frame from the given frame instance.- Parameters:
frameInstance- the frame instanceaccess- the access mode to use when capturing the frame- Returns:
- a bytecode frame, or null if the frame instance is missing location info.
- Since:
- 25.1
-
getNonVirtual
Attempts to create a bytecode frame from the given frame instance. Returns null if the corresponding frame is virtual. The frame can be read from, written to, and escaped.This method can be used to probe for a frame that can safely escape without forcing materialization. For example, if a language needs to capture local variables from a stack frame, it's often more efficient to use an existing non-virtual frame rather than create a copy of all variables.
- Parameters:
frameInstance- the frame instance- Returns:
- a bytecode frame or null if the frame is virtual or if the frame instance is missing location info.
- Since:
- 25.1
-
get
Creates a bytecode frame from the given stack trace element.This method will return null unless the interpreter specifies
GenerateBytecode.captureFramesForTrace(), which indicates whether frames should be captured.- Parameters:
element- the stack trace element- Returns:
- a bytecode frame, or null if the frame was not captured or the stack trace element is missing location information.
- Throws:
IllegalArgumentException- if the element has an invalid bytecode index.- Since:
- 25.1
-
getNonVirtual
Attempts to create a bytecode frame from the given stack trace element. Returns null if the corresponding frame is virtual. The frame can be read from, written to, and escaped.This method can be used to probe for a frame that can safely escape without forcing materialization. For example, if a language needs to capture local variables from a stack frame, it's often more efficient to use an existing non-virtual frame rather than create a copy of all variables.
- Parameters:
element- the stack trace element- Returns:
- a bytecode frame or null if the frame is virtual/unavailable or if the frame instance is missing location info.
- Throws:
IllegalArgumentException- if the element has an invalid bytecode index.- Since:
- 25.1
-
getTop
public static BytecodeFrame getTop(FrameInstance.FrameAccess access, Node topLocation, int topBytecodeIndex) Returns the current top stack activation as abytecode frame.The top frame's location is derived using
topLocationandtopBytecodeIndex. IftopBytecodeIndexis-1, the bytecode index is resolved fromtopLocationand the resolved topFrame.- Parameters:
access- the access mode used when resolving the top frametopLocation- a node in the current top bytecode activationtopBytecodeIndex- the bytecode index of the current top bytecode activation, or-1to resolve it fromtopLocationand the resolved frame- Returns:
- the current top bytecode frame
- Throws:
IllegalArgumentException- iftopLocationandtopBytecodeIndexdo not identify a valid location for the top frame, or if the top frame is not a bytecode frame.- Since:
- 25.1
-
iterateBytecodeFrames
public static <T> T iterateBytecodeFrames(Function<BytecodeFrame, T> visitor, FrameInstance.FrameAccess access, Node topLocation, int topBytecodeIndex, int skipBytecodeFrames) Iterates the current stack asbytecode frames, starting with the current top activation.This method uses
TruffleRuntime.iterateFrames(FrameInstanceVisitor)to perform a stack walk, constructing eachBytecodeFrameinstance from an underlyingFrameInstance. Frame instances that do not correspond to bytecode frames are ignored.The visitor is invoked for each available bytecode frame until it returns a non-
nullvalue, which is then returned from this method. If the visitor always returnsnull, this method returnsnull.The stack walk begins with the current (top) activation. The top frame's location is derived using
topLocationandtopBytecodeIndex. These parameters are necessary because theFrameInstancefor the top activation does not necessarily provide location information.If
skipBytecodeFrames > 0, the top frame is skipped andtopLocationandtopBytecodeIndexare ignored. Otherwise,topLocationmust identify a node in the current top bytecode activation, andtopBytecodeIndexmust be a valid bytecode index or-1. WhentopBytecodeIndexis-1, the bytecode index of the top frame is computed usingtopLocationand the resolved topFrame.- Parameters:
visitor- the visitor applied to each bytecode frameaccess- the access mode used when resolving frames from runtime stack framestopLocation- a node in the current top bytecode activation; ignored ifskipBytecodeFrames > 0topBytecodeIndex- the bytecode index of the current top bytecode activation, or-1to resolve it fromtopLocationand the resolved frame; ignored ifskipBytecodeFrames > 0skipBytecodeFrames- the number of bytecode frames to skip before invoking the visitor- Returns:
- the first non-
nullvalue returned byvisitor, ornullif no visited frame produces one - Throws:
IllegalArgumentException- if the top frame is not skipped andtopLocationandtopBytecodeIndexdo not identify a valid location for the top frame, or if the top frame is not a bytecode frame.- Since:
- 25.1
-