public final class TruffleContext extends Object implements 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 extendsNode{ void executeInContext(TruffleLanguage.Envenv) { MyContext outerLangContext = getContext();TruffleContextinnerContext = env.newContextBuilder().build();Objectp = innerContext.enter(this); try { MyContext innerLangContext = getContext(); assert outerLangContext != innerLangContext; } finally { innerContext.leave(this, p); } assert outerLangContext == getContext(); innerContext.close(); } } private staticTruffleLanguage.ContextReference<MyContext> REFERENCE =TruffleLanguage.ContextReference.create(MyLanguage.class); private static MyContext getContext() { return REFERENCE.get(null); }
| Modifier and Type | Class and Description |
|---|---|
class |
TruffleContext.Builder
Builder class to create new
TruffleContext instances. |
| Modifier and Type | Method and Description |
|---|---|
void |
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
ThreadDeath exception. |
void |
closeResourceExhausted(Node location,
String message)
Force closes the context due to resource exhaustion.
|
Object |
enter(Node node)
Enters this context and returns an object representing the previous context.
|
boolean |
equals(Object obj) |
Object |
evalInternal(Node node,
Source source)
Evaluates a source in an inner context and returns the result.
|
Object |
evalPublic(Node node,
Source source)
The same as
TruffleContext.evalInternal(Node, Source), but only public languages are accessible. |
TruffleContext |
getParent()
Get a parent context of this context, if any.
|
int |
hashCode() |
boolean |
isActive()
Returns
true if the context is currently active on the current thread, else
false. |
boolean |
isCancelling()
Returns
true if the context is being cancelled else false. |
boolean |
isClosed()
Returns
true if the context was closed else false. |
boolean |
isEntered()
Checks whether the context is entered on the current thread and the context is the currently
active context on this thread.
|
void |
leave(Node node,
Object prev)
Leaves this context and sets the previous context as the new current context.
|
<T> T |
leaveAndEnter(Node node,
Supplier<T> runWhileOutsideContext)
Leaves this context, runs the passed supplier and reenters the context.
|
Future<Void> |
pause()
Pause execution on all threads for this context.
|
void |
resume(Future<Void> pauseFuture)
Resume previously paused execution on all threads for this context.
|
public TruffleContext getParent()
null if there is no parentpublic Object enter(Node node)
TruffleContext.leave(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 an IllegalStateException is thrown.
If the current thread was not previously entered in any context, the enter function returns
null. If the return value is not null, the result of the enter function is
unspecified and must only be passed to TruffleContext.leave(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 a
boundary call in compiled code. If the provided node is not adopted
an IllegalArgumentException is thrown.
Entering a language context is designed for compilation and is most efficient if the
context instance is compilation final.
Example usage:
final class MyNode extendsNode{ void executeInContext(TruffleLanguage.Envenv) { MyContext outerLangContext = getContext();TruffleContextinnerContext = env.newContextBuilder().build();Objectp = innerContext.enter(this); try { MyContext innerLangContext = getContext(); assert outerLangContext != innerLangContext; } finally { innerContext.leave(this, p); } assert outerLangContext == getContext(); innerContext.close(); } } private staticTruffleLanguage.ContextReference<MyContext> REFERENCE =TruffleLanguage.ContextReference.create(MyLanguage.class); private static MyContext getContext() { return REFERENCE.get(null); }
TruffleContext.leave(Node, Object)public Object evalInternal(Node node, Source source)
TruffleLanguage.Env.getContext() an IllegalStateException is
thrown. In such a case TruffleLanguage.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 an IllegalStateException 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 an IllegalArgumentException 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.
node - a partial evaluation constant node context used to optimize this operation. Can
be null if not available.source - the source to evaluateIllegalArgumentException - if the given language of the source cannot be accessed.IllegalStateException - if an invalid context is entered or the context is already
closed.public Object evalPublic(Node node, Source source)
TruffleContext.evalInternal(Node, Source), but only public languages are accessible.node - a partial evaluation constant node context used to optimize this operation. Can
be null if not available.source - the source to evaluateIllegalArgumentException - if the given language of the source cannot be accessed.IllegalStateException - if an invalid context is entered or the context is already
closed.public boolean isEntered()
active on a
single thread, but this method only returns true if it is the top-most context.
This method is thread-safe and may be used from multiple threads.true if the context is active, false otherwisepublic boolean isActive()
true if the context is currently active on the current thread, else
false. Checks whether the context has been previously entered by this thread
with TruffleContext.enter(Node) and hasn't been left yet with
TruffleContext.leave(Node, java.lang.Object) methods. Multiple contexts can be active on a single
thread. See TruffleContext.isEntered() for checking whether it is the top-most entered context.
This method is thread-safe and may be used from multiple threads.public boolean isClosed()
true if the context was closed else false. A context may be
closed if TruffleContext.close() or TruffleContext.closeCancelled(Node, String) was called previously.public boolean isCancelling()
true if the context is being cancelled else false. A
context may be in the process of cancelling if TruffleContext.closeCancelled(Node, String) was
called previously.public Future<Void> pause()
TruffleContext.resume(Future) is called.TruffleContext.resume(Future)
method.public void resume(Future<Void> pauseFuture)
TruffleContext.pause() was called multiple times and for some of the other
calls resume was not called yet.pauseFuture - pause future returned by a previous call to
TruffleContext.pause().IllegalArgumentException - in case the passed pause future was not obtained by a
previous call to TruffleContext.pause() on this context.public void leave(Node node, Object prev)
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 a
boundary call in compiled code. If the node is not adopted an
IllegalArgumentException is thrown.
Leaving a language context is designed for compilation and is most efficient if the
context instance is compilation final.
prev - the previous context returned by TruffleContext.enter(Node)TruffleContext.enter(Node)public <T> T leaveAndEnter(Node node, Supplier<T> runWhileOutsideContext)
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 a
boundary call in compiled code. If the provided node is not adopted
an IllegalArgumentException is thrown.
Entering a language context is designed for compilation and is most efficient if the
context instance is compilation final.
node - an adopted node or nullrunWhileOutsideContext - the supplier to run while having left this contextpublic void close()
entered or
active by any thread. If a closed context is attempted to be accessed or entered, then an
IllegalStateException 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.close in interface AutoCloseableUnsupportedOperationException - if the close operation is not supported on this contextIllegalStateException - if the context is active.TruffleContext.closeCancelled(Node, String),
TruffleContext.closeResourceExhausted(Node, String)public void closeCancelled(Node closeLocation, String message)
ThreadDeath exception. If this context is not currently entered on the current thread then this method waits until the close operation is complete
and TruffleContext.isClosed() returns true, 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.
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 a
ThreadDeath error instead of completing to indicate that the current thread should be
stopped. The thrown ThreadDeath must not be caught by the guest language and freely
propagated to the guest application to cancel the execution on the current thread. If a
context is active on the current thread, but not entered, then an IllegalStateException is thrown, as parent contexts that are active
on the current thread cannot be cancelled.
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.UnsupportedOperationException - if the close operation is not supported on this contextIllegalStateException - if the context is active but not
entered on the current thread.TruffleContext.close(),
TruffleContext.closeResourceExhausted(Node, String)public void closeResourceExhausted(Node location, String message)
closeCancelled(location, message) except in addition
the thrown PolyglotException returns true for
PolyglotException.isResourceExhausted().PolyglotException.isResourceExhausted(),
TruffleContext.close(),
TruffleContext.closeCancelled(Node, String)