public final class EncapsulatingNodeReference extends Object
CompilerDirectives.TruffleBoundary
. To correctly
produce exception stack traces it is necessary to remember the node that transitioned to the
uncached case. Uncached calls to CallTarget
will automatically use the value of the
encapsulating node. Truffle DSL produces such transitions automatically if Truffle libraries are
used and they transition to uncached.
Usage example for pushing and restoring the current node to the stack.
EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent(); Node encapsulatingNode = encapsulating.set(currentNode); try { // follow uncached path } finally { encapsulating.set(encapsulatingNode); }
The current encapsulating node can also be useful when constructing guest exceptions in slow-paths and the location of the error needs to be found out reliably. Usage example:
final class LanguageException extends AbstractTruffleException { private LanguageException(Node locationNode) { super(locationNode); } static LanguageException create(Node locationNode) { CompilerAsserts.partialEvaluationConstant(locationNode); if (locationNode == null || !locationNode.isAdoptable()) { return new LanguageException(EncapsulatingNodeReference.getCurrent().get()); } else { return new LanguageException(locationNode); } } // ... }Note that
Node.isAdoptable()
is a way to find out whether a node was used in an uncached
scenario or not.Modifier and Type | Method and Description |
---|---|
Node |
get()
Returns the current encapsulating node for the current thread.
|
static EncapsulatingNodeReference |
getCurrent()
Returns the encapsulating node reference of the
current
thread. |
Node |
set(Node node)
Sets the current encapsulating node for the current thread and returns its previous value.
|
public Node set(Node node)
null
. The set node must be adoptable
and be adopted by a RootNode
otherwise an AssertionError
is
thrown. This method must only be used from the thread it was requested
for. This method is safe to be called from compiled code paths.public Node get()
null
. If the returned node is non-null then it is guaranteed to be
adoptable
and adopted by a RootNode
. This method must only
be used from the thread it was requested
for. This method is safe to be
called from compiled code paths.public static EncapsulatingNodeReference getCurrent()
current
thread. The returned value is never null
. This method is safe to be called from
compiled code paths.