Class TruffleContext
- All Implemented Interfaces:
AutoCloseable
A context
consists of a language
context
instance for each installed language
. The current
language context is created
eagerly and can be
accessed using a context reference
after the context was
entered
.
The configuration for each language context is inherited from its parent/creator context. In
addition to that config
parameters can be passed to new
language context instance of the current language. The configuration of other installed languages
cannot be modified. To run guest language code in a context, the context needs to be first
entered
and then left
. The context should be
closed
when it is no longer needed. If the context is not closed explicitly,
then it is automatically closed together with the parent context.
Example usage:
final class MyNode extends Node {
void executeInContext(Env env) {
MyContext outerLangContext = getContext(this);
TruffleContext innerContext = env.newInnerContextBuilder().
initializeCreatorContext(true).build();
Object p = innerContext.enter(this);
try {
/*
* Here the this node cannot be passed otherwise an
* invalid sharing error would occur.
*/
MyContext innerLangContext = getContext(null);
assert outerLangContext != innerLangContext;
} finally {
innerContext.leave(this, p);
}
assert outerLangContext == getContext(this);
innerContext.close();
}
}
private static ContextReference<MyContext> REFERENCE
= ContextReference.create(MyLanguage.class);
private static MyContext getContext(Node node) {
return REFERENCE.get(node);
}
- Since:
- 0.27
-
Nested Class Summary
Modifier and TypeClassDescriptionfinal class
Builder class to create newTruffleContext
instances. -
Method Summary
Modifier and TypeMethodDescriptionvoid
close()
Closes this context and disposes its resources.void
closeCancelled
(Node closeLocation, String message) Force closes the context as cancelled and stops all the execution on all active threads using a specialThreadDeath
cancel exception.void
closeExited
(Node exitLocation, int exitCode) Initiates force close of the context as exited -hard exit
.void
closeResourceExhausted
(Node location, String message) Force closes the context due to resource exhaustion.Enters this context and returns an object representing the previous context.boolean
evalInternal
(Node node, Source source) Evaluates a source in an inner context and returns the result.evalPublic
(Node node, Source source) The same asevalInternal(Node, Source)
, but only public languages are accessible.Get a parent context of this context, if any.int
hashCode()
boolean
initializeInternal
(Node node, String languageId) Forces initialization of an internal or public language.boolean
initializePublic
(Node node, String languageId) The same asinitializeInternal(Node, String)
, but only public languages are accessible.boolean
isActive()
Returnstrue
if the context is currently active on the current thread, elsefalse
.boolean
Returnstrue
if the context is being cancelled elsefalse
.boolean
isClosed()
Returnstrue
if the context was closed elsefalse
.boolean
Checks whether the context is entered on the current thread and the context is the currently active context on this thread.boolean
Returnstrue
if the context is being hard-exited elsefalse
.void
Leaves this context and sets the previous context as the new current context.<T,
R> R leaveAndEnter
(Node node, TruffleSafepoint.Interrupter interrupter, TruffleSafepoint.InterruptibleFunction<T, R> interruptible, T object) Leaves this context, runs the passed interruptible function and reenters the context.<T> T
leaveAndEnter
(Node node, Supplier<T> runWhileOutsideContext) Deprecated.pause()
Pause execution on all threads for this context.void
Resume previously paused execution on all threads for this context.
-
Method Details
-
equals
-
hashCode
public int hashCode() -
getParent
Get a parent context of this context, if any. This provides the hierarchy of inner contexts.- Returns:
- a parent context, or
null
if there is no parent - Since:
- 0.30
-
enter
Enters this context and returns an object representing the previous context. Calls to enter must be followed by a call toleave(Node, Object)
in a finally block and the previous context must be passed as an argument. It is allowed to enter a context multiple times from the same thread. If the context is currently not entered by any thread then it is allowed be entered by an arbitrary thread. Entering the context from two or more different threads at the same time is possible, unless one of the loaded languages denies access to the thread, in which case anIllegalStateException
is thrown.If the current thread was not previously entered in any context, the enter function returns
null
. If the return value is notnull
, the result of the enter function is unspecified and must only be passed toleave(Node, Object)
. The result value must not be stored permanently.An adopted node may be passed to allow perform optimizations on the fast-path. If a
null
node is passed then entering a context will result in aboundary
call in compiled code. If the provided node is not adopted anIllegalArgumentException
is thrown.Entering a language context is designed for compilation and is most efficient if the
context
instance is compilation final.Example usage:
TruffleContextSnippets.MyNode.executeInContext(com.oracle.truffle.api.TruffleLanguage.Env)
- Since:
- 20.3
- See Also:
-
initializeInternal
Forces initialization of an internal or public language. If the context is not an inner context and e.g. accessed usingTruffleLanguage.Env.getContext()
anIllegalStateException
is thrown. In such a caseTruffleLanguage.Env.initializeLanguage(LanguageInfo)
should be used instead to initialize contexts.No context or the parent creator context must be entered to initialize languages in a
TruffleContext
otherwise anIllegalStateException
will be thrown.- Parameters:
node
- a partial evaluation constant node context used to optimize this operation. Can benull
if not available.languageId
- the id of the language to initialize- Returns:
true
if the language was initialized, elsefalse
, e.g. if the language as already initialized.- Throws:
IllegalStateException
- if an invalid context is entered or the context is already closed.IllegalArgumentException
- if the given language of the source cannot be accessed.- Since:
- 22.3
-
initializePublic
The same asinitializeInternal(Node, String)
, but only public languages are accessible.- Parameters:
node
- a partial evaluation constant node context used to optimize this operation. Can benull
if not available.languageId
- the id of the language to initialize- Returns:
true
if the language was initialized, elsefalse
, e.g. if the language as already initialized.- Throws:
IllegalStateException
- if an invalid context is entered or the context is already closed.IllegalArgumentException
- if the given language of the source cannot be accessed.- Since:
- 22.3
-
evalInternal
Evaluates a source in an inner context and returns the result. If the context is not an inner context and e.g. accessed usingTruffleLanguage.Env.getContext()
anIllegalStateException
is thrown. In such a caseTruffleLanguage.Env.parseInternal(Source, String...)
should be used instead to evaluate sources.No context or the parent creator context must be entered to evaluate sources in a
TruffleContext
otherwise anIllegalStateException
will be thrown. In order to ensure that all values are accessed from their respective contexts only, any non-primitive value returned by the evaluation will be wrapped and enter this context for each interop message sent. Parameters to interop messages will enter and leave the parent context when they are accessed. If the result is a primitive value, then the value is directly returned.This method has access to all public and internal languages the creator context has access to. This corresponds to the set of languages returned by
TruffleLanguage.Env.getInternalLanguages()
. If a language cannot be accessed then anIllegalArgumentException
is thrown. If a language is not yet initialized in the inner context, it will get automatically initialized.This method is designed to be used in compiled code paths. This method may be used from multiple threads at the same time. The result of this method must not be cached, instead the
Source
object should be cached.- Parameters:
node
- a partial evaluation constant node context used to optimize this operation. Can benull
if not available.source
- the source to evaluate- Throws:
IllegalArgumentException
- if the given language of the source cannot be accessed.IllegalStateException
- if an invalid context is entered or the context is already closed.- Since:
- 21.3
-
evalPublic
The same asevalInternal(Node, Source)
, but only public languages are accessible.- Parameters:
node
- a partial evaluation constant node context used to optimize this operation. Can benull
if not available.source
- the source to evaluate- Throws:
IllegalArgumentException
- if the given language of the source cannot be accessed.IllegalStateException
- if an invalid context is entered or the context is already closed.- Since:
- 21.3
-
isEntered
public boolean isEntered()Checks whether the context is entered on the current thread and the context is the currently active context on this thread. There can be multiple contextsactive
on a single thread, but this method only returnstrue
if it is the top-most context. This method is thread-safe and may be used from multiple threads.- Returns:
true
if the context is active,false
otherwise- Since:
- 20.0
-
isActive
public boolean isActive()Returnstrue
if the context is currently active on the current thread, elsefalse
. Checks whether the context has been previously entered by this thread withenter(Node)
and hasn't been left yet withleave(Node, java.lang.Object)
methods. Multiple contexts can be active on a single thread. SeeisEntered()
for checking whether it is the top-most entered context. This method is thread-safe and may be used from multiple threads.- Since:
- 20.3
-
isClosed
public boolean isClosed()Returnstrue
if the context was closed elsefalse
. A context may be closed ifclose()
,closeCancelled(Node, String)
, orcloseExited(Node, int)
was called previously.- Since:
- 20.3
-
isCancelling
public boolean isCancelling()Returnstrue
if the context is being cancelled elsefalse
. A context may be in the process of cancelling ifcloseCancelled(Node, String)
was called previously.- Since:
- 21.1
-
isExiting
public boolean isExiting()Returnstrue
if the context is being hard-exited elsefalse
. A context may be in the process of exit ifcloseExited(Node, int)
was called previously.- Since:
- 22.0
-
pause
Pause execution on all threads for this context. This call does not wait for the threads to be actually paused. Instead, a future is returned that can be used to wait for the execution to be paused. The future is completed when all active threads are paused. New threads entered after this point are paused immediately after entering untilresume(Future)
is called.- Returns:
- a future that can be used to wait for the execution to be paused. Also, the future is
used to resume execution by passing it to the
resume(Future)
method. - Since:
- 21.2
-
resume
Resume previously paused execution on all threads for this context. The execution will not resume ifpause()
was called multiple times and for some of the other calls resume was not called yet.- Parameters:
pauseFuture
- pause future returned by a previous call topause()
.- Throws:
IllegalArgumentException
- in case the passed pause future was not obtained by a previous call topause()
on this context.- Since:
- 21.2
-
leave
Leaves this context and sets the previous context as the new current context.An adopted node may be passed to allow perform optimizations on the fast-path. If a
null
node is passed then entering a context will result in aboundary
call in compiled code. If the node is not adopted anIllegalArgumentException
is thrown.Leaving a language context is designed for compilation and is most efficient if the
context
instance is compilation final.- Parameters:
prev
- the previous context returned byenter(Node)
- Since:
- 20.3
- See Also:
-
leaveAndEnter
Deprecated.Leaves this context, runs the passed supplier and reenters the context. This is useful when the current thread must wait for another thread (and does not need to access the context to do so) and triggering multithreading is not desired, for instance when implementing coroutines with threads. The supplier cannot access the context and must not run any guest language code or invoke interoperability messages.The supplier will typically notify another thread that it can now enter the context without triggering multithreading and then wait for some thread to leave the context before exiting the supplier and reentering the context (again to avoid triggering multithreading).
An adopted node may be passed to allow perform optimizations on the fast-path. If a
null
node is passed then entering a context will result in aboundary
call in compiled code. If the provided node is not adopted anIllegalArgumentException
is thrown.Entering a language context is designed for compilation and is most efficient if the
context
instance is compilation final.- Parameters:
node
- an adopted node ornull
runWhileOutsideContext
- the supplier to run while having left this context- Since:
- 21.1
-
leaveAndEnter
public <T,R> R leaveAndEnter(Node node, TruffleSafepoint.Interrupter interrupter, TruffleSafepoint.InterruptibleFunction<T, R> interruptible, T object) Leaves this context, runs the passed interruptible function and reenters the context. This is useful when the current thread must wait for another thread (and does not need to access the context to do so) and triggering multithreading is not desired, for instance when implementing coroutines with threads. The function cannot access the context and must not run any guest language code or invoke interoperability messages.The function will typically notify another thread that it can now enter the context without triggering multithreading and then wait for some thread to leave the context before exiting the function and reentering the context (again to avoid triggering multithreading).
An adopted node may be passed to allow performing optimizations on the fast-path.
- Parameters:
node
- an adopted node ornull
interrupter
- an interrupter used to interrupt the interruptible function when, e.g., the context is cancelled. The interrupter is also used toreset
the interrupted state when the context is reentered.interruptible
- the interruptible function to run while having left this context. This function is run at most once.- Returns:
- return value of the interruptible, or
null
if the interruptibe throws anInterruptedException
without the context being cancelled or exited. - Since:
- 23.1
-
close
public void close()Closes this context and disposes its resources. Closes this context and disposes its resources. A context cannot be closed if it is currentlyentered
or active by any thread. If a closed context is attempted to be accessed or entered, then anIllegalStateException
is thrown. If the context is not closed explicitly, then it is automatically closed together with the parent context. If an attempt to close a context was successful then consecutive calls to close have no effect.- Specified by:
close
in interfaceAutoCloseable
- Throws:
UnsupportedOperationException
- if the close operation is not supported on this contextIllegalStateException
- if the context isactive
.- Since:
- 0.27
- See Also:
-
closeCancelled
Force closes the context as cancelled and stops all the execution on all active threads using a specialThreadDeath
cancel exception. If this context is not currentlyentered
on the current thread then this method waits until the close operation is complete andisClosed()
returnstrue
, else it throws the cancelled exception upon its completion of this method. If an attempt to close a context was successful then consecutive calls to close have no effect.The throwing of the special
ThreadDeath
cancel exception also applies to any guest code run duringTruffleLanguage.finalizeContext(Object)
which means thatTruffleLanguage.finalizeContext(Object)
cannot run guest code during the cancel operation.If forced and this context currently
entered
on the current thread and no other context is entered on the current thread then this method directly throws aThreadDeath
error instead of completing to indicate that the current thread should be stopped. The thrownThreadDeath
must not be caught by the guest language and freely propagated to the guest application to cancel the execution on the current thread. Please note that this means that the guest language's finally blocks must not be executed.If a context is
active
on the current thread, but notentered
, then anIllegalStateException
is thrown, as parent contexts that are active on the current thread cannot be cancelled.- Parameters:
closeLocation
- the node where the close occurred. If the context is currently entered on the thread, then this node will be used as location, for the exception thrown. If the context is not entered, then the closeLocation parameter will be ignored.message
- exception text for humans provided to the embedder and tools that observe the cancellation.- Throws:
UnsupportedOperationException
- if the close operation is not supported on this contextIllegalStateException
- if the context isactive
but notentered
on the current thread.- Since:
- 20.3
- See Also:
-
closeExited
Initiates force close of the context as exited -hard exit
. Requires the context to be entered on the current thread. Languages are first notified by callingTruffleLanguage.exitContext(Object, TruffleLanguage.ExitMode, int)
and then the closing of the context is initiated. Execution on all active threads including the current thread is stopped by throwing a specialThreadDeath
exit exception. This method does not wait for the execution on other threads to be stopped, it throws theThreadDeath
exception as soon as possible. To exit threads reliably, guest languages need to ensure that theThreadDeath
is always immediately rethrown and guest language exception handlers and finally blocks are not run.The throwing of the special
ThreadDeath
exit exception also applies to any guest code run duringTruffleLanguage.finalizeContext(Object)
which means thatTruffleLanguage.finalizeContext(Object)
cannot run guest code during hard exit.The exit code can be specified only once and the first call to this method also executes the
exit notifications
on the same thread. Further calls to this method will ensure that the following guest code on the calling thread is not executed by throwing theThreadDeath
exit exception, and the exit location is used as the stopping point of the thread, but the passed exit code is ignored and exit notifications are not run.In case the context is in one of the following states
- the context is being closed and the finalization stage has already begun
(
TruffleLanguage.finalizeContext(Object)
is being executed for all language contexts). - the context is already closed
- the context threads are being unwound as a part of the cancelling process
- the context threads are being unwound as a part of the hard exit process that comes after exit notifications
- Parameters:
exitLocation
- the node where the exit occurred.exitCode
- exitCode provided to the embedder and tools that observe the exit.- Throws:
IllegalStateException
- if the context is notentered
on the current thread.- Since:
- 22.0
- See Also:
- the context is being closed and the finalization stage has already begun
(
-
closeResourceExhausted
Force closes the context due to resource exhaustion. This method is equivalent to callingcloseCancelled(location, message)
except in addition the thrownPolyglotException
returnstrue
forPolyglotException.isResourceExhausted()
.- Since:
- 20.3
- See Also:
-
leaveAndEnter(Node, Interrupter, InterruptibleFunction, Object)
instead.