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
Nested ClassesModifier and TypeClassDescriptionfinal classBuilder class to create newTruffleContextinstances. -
Method Summary
Modifier and TypeMethodDescriptionvoidclose()Closes this context and disposes its resources.voidcloseCancelled(Node closeLocation, String message) Force closes the context as cancelled and stops all the execution on all active threads using a specialThreadDeathcancel exception.voidcloseExited(Node exitLocation, int exitCode) Initiates force close of the context as exited -hard exit.voidcloseResourceExhausted(Node location, String message) Force closes the context due to resource exhaustion.Enters this context and returns an object representing the previous context.booleanevalInternal(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.inthashCode()booleaninitializeInternal(Node node, String languageId) Forces initialization of an internal or public language.booleaninitializePublic(Node node, String languageId) The same asinitializeInternal(Node, String), but only public languages are accessible.booleanisActive()Returnstrueif the context is currently active on the current thread, elsefalse.booleanReturnstrueif the context is being cancelled elsefalse.booleanisClosed()Returnstrueif the context was closed elsefalse.booleanChecks whether the context is entered on the current thread and the context is the currently active context on this thread.booleanReturnstrueif the context is being hard-exited elsefalse.voidLeaves 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> TleaveAndEnter(Node node, Supplier<T> runWhileOutsideContext) Deprecated.pause()Pause execution on all threads for this context.voidResume previously paused execution on all threads for this context.
-
Method Details
-
equals
-
hashCode
-
getParent
Get a parent context of this context, if any. This provides the hierarchy of inner contexts.- Returns:
- a parent context, or
nullif 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 anIllegalStateExceptionis 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
nullnode is passed then entering a context will result in aboundarycall in compiled code. If the provided node is not adopted anIllegalArgumentExceptionis thrown.Entering a language context is designed for compilation and is most efficient if the
contextinstance 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()anIllegalStateExceptionis 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
TruffleContextotherwise anIllegalStateExceptionwill be thrown.- Parameters:
node- a partial evaluation constant node context used to optimize this operation. Can benullif not available.languageId- the id of the language to initialize- Returns:
trueif 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 benullif not available.languageId- the id of the language to initialize- Returns:
trueif 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()anIllegalStateExceptionis 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
TruffleContextotherwise anIllegalStateExceptionwill 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 anIllegalArgumentExceptionis 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
Sourceobject should be cached.- Parameters:
node- a partial evaluation constant node context used to optimize this operation. Can benullif 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 benullif 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 contextsactiveon a single thread, but this method only returnstrueif it is the top-most context. This method is thread-safe and may be used from multiple threads.- Returns:
trueif the context is active,falseotherwise- Since:
- 20.0
-
isActive
public boolean isActive()Returnstrueif 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()Returnstrueif 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()Returnstrueif 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()Returnstrueif 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
nullnode is passed then entering a context will result in aboundarycall in compiled code. If the node is not adopted anIllegalArgumentExceptionis thrown.Leaving a language context is designed for compilation and is most efficient if the
contextinstance 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
nullnode is passed then entering a context will result in aboundarycall in compiled code. If the provided node is not adopted anIllegalArgumentExceptionis thrown.Entering a language context is designed for compilation and is most efficient if the
contextinstance is compilation final.- Parameters:
node- an adopted node ornullrunWhileOutsideContext- 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 ornullinterrupter- an interrupter used to interrupt the interruptible function when, e.g., the context is cancelled. The interrupter is also used toresetthe 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
nullif the interruptibe throws anInterruptedExceptionwithout 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 currentlyenteredor active by any thread. If a closed context is attempted to be accessed or entered, then anIllegalStateExceptionis 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:
closein 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 specialThreadDeathcancel exception. If this context is not currentlyenteredon 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
ThreadDeathcancel 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
enteredon the current thread and no other context is entered on the current thread then this method directly throws aThreadDeatherror instead of completing to indicate that the current thread should be stopped. The thrownThreadDeathmust 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
activeon the current thread, but notentered, then anIllegalStateExceptionis 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 isactivebut notenteredon 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 specialThreadDeathexit exception. This method does not wait for the execution on other threads to be stopped, it throws theThreadDeathexception as soon as possible. To exit threads reliably, guest languages need to ensure that theThreadDeathis always immediately rethrown and guest language exception handlers and finally blocks are not run.The throwing of the special
ThreadDeathexit 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 notificationson the same thread. Further calls to this method will ensure that the following guest code on the calling thread is not executed by throwing theThreadDeathexit 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 notenteredon 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 thrownPolyglotExceptionreturnstrueforPolyglotException.isResourceExhausted().- Since:
- 20.3
- See Also:
-
leaveAndEnter(Node, Interrupter, InterruptibleFunction, Object)instead.