public static final class TruffleInstrument.Env extends Object
Modifier and Type | Method and Description |
---|---|
long |
calculateContextHeapSize(TruffleContext truffleContext,
long stopAtBytes,
AtomicBoolean cancelled)
Returns heap memory size retained by a polyglot context.
|
Thread |
createSystemThread(Runnable runnable)
Creates a new thread designed to process instrument tasks in the background.
|
Thread |
createSystemThread(Runnable runnable,
ThreadGroup threadGroup)
Creates a new thread designed to process instrument tasks in the background.
|
OutputStream |
err()
Standard error writer for
Engine this
instrument is being executed in. |
TruffleContext |
getEnteredContext()
Returns the entered
TruffleContext or null when no context is entered. |
Instrumenter |
getInstrumenter()
Returns the instrumenter which lets you instrument guest language ASTs.
|
Map<String,InstrumentInfo> |
getInstruments()
Returns a map
instrument id to instrument info of all instruments that are installed in the environment. |
LanguageInfo |
getLanguageInfo(Class<? extends TruffleLanguage<?>> languageClass)
Returns the
language info for a given language class if available. |
Map<String,LanguageInfo> |
getLanguages()
Returns a map
language id to language
info of all languages that are installed in the environment. |
Object |
getLanguageView(LanguageInfo language,
Object value)
Wraps the provided value to provide language specific information for primitive and
foreign values.
|
TruffleLogger |
getLogger(Class<?> forClass)
Find or create an engine bound logger for an instrument.
|
TruffleLogger |
getLogger(String loggerName)
Find or create an engine bound logger for an instrument.
|
OptionValues |
getOptions()
Returns the context independent option values for the options described in
TruffleInstrument.getOptionDescriptors() . |
OptionValues |
getOptions(TruffleContext context)
Returns the context specific option values for the options described in
TruffleInstrument.getContextOptionDescriptors() and
TruffleInstrument.getOptionDescriptors() . |
Object |
getPolyglotBindings()
Returns the polyglot scope - symbols explicitly exported by languages.
|
SandboxPolicy |
getSandboxPolicy()
Returns the engine's
SandboxPolicy . |
Object |
getScope(LanguageInfo language)
Provides top scope object of the language, if any.
|
TruffleFile |
getTruffleFile(TruffleContext context,
String path)
Returns a
TruffleFile for given path and context . |
TruffleFile |
getTruffleFile(TruffleContext context,
URI uri)
|
InputStream |
in()
Input associated with
Engine this instrument is being executed in. |
boolean |
isEngineRoot(RootNode root)
Returns
true if the given root node is considered an engine evaluation root
for the current execution context. |
<S> S |
lookup(InstrumentInfo instrument,
Class<S> type)
Returns an additional service provided by this instrument, specified by type.
|
<S> S |
lookup(LanguageInfo language,
Class<S> type)
Queries a
language implementation for a special service. |
OutputStream |
out()
Standard output writer for
Engine this
instrument is being executed in. |
CallTarget |
parse(Source source,
String... argumentNames)
Evaluates source of (potentially different) language using the current context.The names
of arguments are parameters for the resulting {#link CallTarget} that allow the
source to reference the actual parameters passed to
CallTarget.call(java.lang.Object...) . |
ExecutableNode |
parseInline(Source source,
Node node,
MaterializedFrame frame)
Parses source snippet of the node's language at the provided node location.
|
void |
registerService(Object service)
Registers additional service.
|
void |
setAsynchronousStackDepth(int depth)
Request for languages to provide stack frames of scheduled asynchronous execution.
|
MessageEndpoint |
startServer(URI uri,
MessageEndpoint server)
Start a server at the provided URI via the
MessageTransport service. |
Future<Void> |
submitThreadLocal(TruffleContext context,
Thread[] threads,
ThreadLocalAction action)
Submits a thread local action to be performed at the next guest language safepoint on a
provided set of threads, once for each thread.
|
public Instrumenter getInstrumenter()
Instrumenter
public InputStream in()
Engine
this instrument
is being executed in.null
public OutputStream out()
Engine
this
instrument
is being executed in.null
public OutputStream err()
Engine
this
instrument
is being executed in.null
public MessageEndpoint startServer(URI uri, MessageEndpoint server) throws IOException, MessageTransport.VetoException
MessageTransport
service. Before an
instrument creates a server endpoint for a message protocol, it needs to check the result
of this method. When a virtual message transport is available, it blocks until a client
connects and MessageEndpoint
representing the peer endpoint is returned. Those
endpoints need to be used instead of a direct creation of a server socket. If no virtual
message transport is available at that URI, null
is returned and the
instrument needs to set up the server itself.
When MessageTransport.VetoException
is thrown, the server
creation needs to be abandoned.
This method can be called concurrently from multiple threads. However, the
MessageEndpoint
ought to be called on one thread at a time, unless you're sure
that the particular implementation can handle concurrent calls. The same holds true for
the returned endpoint, it's called synchronously.
uri
- the URI of the server endpointserver
- the handler of messages at the server sideMessageEndpoint
call back representing the client
side, or null
when no virtual transport is availableMessageTransport.VetoException
- if creation of a server at that URI is not allowedIOException
public void registerService(Object service)
initialization of the instrument
. These services are made available to users via
Instrument.lookup(java.lang.Class<T>)
query method.
This method can only be called from
TruffleInstrument.onCreate(com.oracle.truffle.api.instrumentation.TruffleInstrument.Env)
method -
then the services are collected and cannot be changed anymore.service
- a service to be returned from associated
Instrument.lookup(java.lang.Class<T>)
IllegalStateException
- if the method is called later than from
TruffleInstrument.onCreate(com.oracle.truffle.api.instrumentation.TruffleInstrument.Env)
methodpublic <S> S lookup(LanguageInfo language, Class<S> type)
language implementation
for a special service. The
services can be provided by the language by directly implementing them when subclassing
TruffleLanguage
. The truffle language needs to be entered on the current Thread
otherwise an AssertionError
is thrown.S
- the requested typelanguage
- identification of the language to querytype
- the class of the requested typenull
if none is foundpublic <S> S lookup(InstrumentInfo instrument, Class<S> type)
IllegalArgumentException
is thrown if a service is
looked up from the current instrument.S
- the requested typeinstrument
- identification of the instrument to querytype
- the class of the requested typenull
if none is foundpublic Map<String,LanguageInfo> getLanguages()
language id
to language
info
of all languages that are installed in the environment.public Map<String,InstrumentInfo> getInstruments()
instrument id
to instrument info
of all instruments that are installed in the environment.public OptionValues getOptions()
TruffleInstrument.getOptionDescriptors()
. The returned options are never
null
.to return the context specific options for this
instrument.
public OptionValues getOptions(TruffleContext context)
TruffleInstrument.getContextOptionDescriptors()
and
TruffleInstrument.getOptionDescriptors()
. Instrument context options can be
different for each TruffleContext, whereas regular options cannot.to get the context independent options set for this instrument
public CallTarget parse(Source source, String... argumentNames) throws IOException
source
to reference the actual parameters passed to
CallTarget.call(java.lang.Object...)
.source
- the source to evaluateargumentNames
- the names of CallTarget.call(java.lang.Object...)
arguments
that can be referenced from the sourceIOException
- if the parsing or evaluation fails for some reasonSecurityException
public ExecutableNode parseInline(Source source, Node node, MaterializedFrame frame)
ExecutableNode
that accepts frames valid at the
provided node location, or null
when inline parsing is not supported by the
language.source
- a source snippet to parse at the provided node locationnode
- a context location where the source is parsed at, must not be
null
frame
- a frame location where the source is parsed at, can be null
null
public TruffleFile getTruffleFile(TruffleContext context, String path)
TruffleFile
for given path and context
.context
- the TruffleContext
, or null
to use a current entered
context.path
- the absolute or relative path to create TruffleFile
forTruffleFile
public TruffleFile getTruffleFile(TruffleContext context, URI uri)
context
- the TruffleContext
, or null
to use a current entered
context.uri
- the URI
to create TruffleFile
forTruffleFile
public TruffleContext getEnteredContext()
TruffleContext
or null
when no context is entered.public boolean isEngineRoot(RootNode root)
true
if the given root node is considered an engine evaluation root
for the current execution context. Multiple such root nodes can appear on stack frames
returned by
TruffleRuntime.iterateFrames(com.oracle.truffle.api.frame.FrameInstanceVisitor)
.
A debugger implementation might use this information to hide stack frames of other
engines.root
- the root node to checktrue
if engine root else false
public void setAsynchronousStackDepth(int depth)
depth
asynchronous stack frames are asked for. When multiple
instruments call this method, the languages get a maximum depth of these calls and may
therefore provide longer asynchronous stacks than requested. Also, languages may provide
asynchronous stacks if it's of no performance penalty, or if requested by other options.
Asynchronous stacks can then be accessed via
TruffleStackTrace.getAsynchronousStackTrace(CallTarget, Frame)
.depth
- the requested stack depth, 0 means no asynchronous stack frames are
required.TruffleStackTrace.getAsynchronousStackTrace(CallTarget, Frame)
public LanguageInfo getLanguageInfo(Class<? extends TruffleLanguage<?>> languageClass)
language info
for a given language class if available.
Language classes are typically obtained by invoking the
InteropLibrary.getLanguage(Object)
message. Throws an
IllegalArgumentException
if the provided language is not registered. Note that
languages may be returned that are not contained in TruffleInstrument.Env.getLanguages()
. For example,
values originating from the embedder like Java classes or polyglot proxies
.languageClass
- the language class to convertIllegalArgumentException
- if the language class is not valid.public Object getLanguageView(LanguageInfo language, Object value)
language
.
display
string
for primitive and foreign values.
metaobject
primitive or foreign values.
language
- the language to provide the view forvalue
- the value to language specific information for.TruffleLanguage.getLanguageView(Object, Object)
public Object getPolyglotBindings()
public Object getScope(LanguageInfo language)
interop scope
object
, or null
.language
- a languagenull
if the language does not support such conceptTruffleLanguage.getScope(Object)
public TruffleLogger getLogger(String loggerName)
If a logger with given name already exists it's returned, otherwise a new logger is created.
Unlike loggers created by
TruffleLogger.getLogger
loggers created by this method are bound to engine, there may be
more logger instances having the same name but each bound to different engine instance.
Instruments should never store the returned logger into a static fields. A new logger
must be always created in
onCreate
method.
loggerName
- the the name of a TruffleLogger
, if a loggerName
is
null or empty a root logger for language or instrument is returnedTruffleLogger
public TruffleLogger getLogger(Class<?> forClass)
If a logger for the class already exists it's returned, otherwise a new logger is created.
Unlike loggers created by
TruffleLogger.getLogger
loggers created by this method are bound to engine, there may be
more logger instances having the same name but each bound to different engine instance.
Instruments should never store the returned logger into a static fields. A new logger
must be always created in
onCreate
method.
forClass
- the Class
to create a logger forTruffleLogger
NullPointerException
- if forClass
is nullpublic long calculateContextHeapSize(TruffleContext truffleContext, long stopAtBytes, AtomicBoolean cancelled)
truffleContext
- specifies the polyglot context for which retained size is
calculated.stopAtBytes
- when the calculated size exceeds stopAtBytes, calculation is stopped
and only size calculated up to that point is returned, i.e., if the retained
size is greater than stopAtBytes, a value greater than stopAtBytes will be
returned, not the total retained size which might be much greater.cancelled
- when cancelled returns true, calculation is cancelled and
CancellationException
is thrown. The message of
the exception specifies the number of bytes calculated up to that point.UnsupportedOperationException
- in case heap size calculation is not supported on
current runtime.CancellationException
- in case the heap size calculation is
cancelled based on the cancelled parameter. The message of the exception
specifies the number of bytes calculated up to that point.public Future<Void> submitThreadLocal(TruffleContext context, Thread[] threads, ThreadLocalAction action)
null
then the thread local action will be performed on all alive threads. The submitted
actions are processed in the same order as they are submitted in. The action can be
synchronous or asynchronous, side-effecting or non-sideeffecting. Please see
ThreadLocalAction
for details.
It is ensured that a thread local action will get processed as long as the thread stays
active for this context. If a thread becomes inactive before the action can get processed
then the action will not be performed for this thread. If a thread becomes active while
the action is being processed then the action will be performed for that thread as long
as the thread filter includes the thread or null
was passed. Already started
synchronous actions will block on activation of a new thread. If the synchronous action
was not yet started on any thread, then the synchronous action will also be performed for
the newly activated thread.
The method returns a Future
instance that allows to wait for the thread local
action to complete or to cancel a currently performed event.
Example Usage:
Env env; // supplied by TruffleInstrument TruffleContext context; // supplied by ContextsListener env.submitThreadLocal(context, null, new ThreadLocalAction(true, true) { @Override protected void perform(Access access) { // perform action } });
By default thread-local actions are executed once per configured thread and do not repeat
themselves. If a ThreadLocalAction is configured to be
recurring
then the
action will automatically be rescheduled in the same configuration until it is
cancelled
. For recurring actions, an invocation of
Future.get()
will only wait for the first action to to be performed.
Future.isDone()
will return true
only if the action was canceled.
Canceling a recurring action will result in the current event being canceled and no
further events being submitted. Using recurring events should be preferred over
submitting the event again for the current thread while performing the thread-local
action as recurring events are also resubmitted in case all threads leave and later
reenter.
If the thread local action future needs to be waited on and this might be prone to
deadlocks the
blocking API
can be used to allow other thread local actions to be processed while the
current thread is waiting. The returned Future.get()
method can be used as
TruffleSafepoint.Interruptible
. If the supplied context is already closed, the method returns a
completed Future
.
context
- the context in which the action should be performed. Non null
.threads
- the threads to execute the action on. null
for all threadsaction
- the action to perform on that thread.ThreadLocalAction
,
TruffleSafepoint
public Thread createSystemThread(Runnable runnable)
TruffleInstrument.Env.createSystemThread(Runnable, ThreadGroup)
for a detailed description of the
parameters.TruffleInstrument.Env.createSystemThread(Runnable, ThreadGroup)
public Thread createSystemThread(Runnable runnable, ThreadGroup threadGroup)
IllegalStateException
is thrown.
Creating or terminating a system thread does not notify languages or
ThreadsListener
s. Creating a system thread does not cause a transition to
multi-threaded access.
It is recommended to set an
uncaught exception handler
for the created thread. For example the thread can throw an
uncaught exception if the engine is closed before the thread is started.
The instrument that created and started the thread is responsible to stop and join it
during the onDispose
, otherwise an
IllegalStateException
is thrown. It's not safe to use the
ExecutorService.awaitTermination(long, java.util.concurrent.TimeUnit)
to detect
Thread termination as the system thread may be cancelled before executing the executor
worker.
A typical implementation looks like:
class SystemThreadInstrument extendsTruffleInstrument
{ private volatileThread
systemThread; private volatile boolean cancelled; private finalBlockingQueue
<Runnable
> tasks = newLinkedBlockingQueue
<>(); @Override
protected void onCreate(Env env) { // Create and start a Thread for the asynchronous task. // Remember the Thread reference to stop and join it in // the finalizeContext systemThread = env.createSystemThread(() -> { while (!cancelled) { try {Runnable
task = tasks.poll(Integer
.MAX_VALUE, SECONDS); if (task != null) { task.run(); } } catch (InterruptedException
ie) { // pass to cancelled check } } }); systemThread.start(); } @Override
protected void onDispose(Env env) { // Stop and join system thread. cancelled = true; systemThread.interrupt(); boolean interrupted = false; boolean terminated = false; while (!terminated) { try { systemThread.join(); terminated = true; } catch (InterruptedException
ie) { interrupted = true; } } if (interrupted) {Thread
.currentThread().interrupt(); } } }
runnable
- the runnable to run on this thread.threadGroup
- the thread group, passed on to the underlying Thread
.IllegalStateException
- if the engine is already closed.TruffleInstrument.Env.createSystemThread(Runnable)
public SandboxPolicy getSandboxPolicy()
SandboxPolicy
. An instrument can use the returned sandbox
policy to make instrument-specific verifications that the sandbox requirements are met.
These verifications should be made as early as possible in the
TruffleInstrument.onCreate(Env)
method.SandboxPolicy
,
TruffleInstrument.onCreate(Env)