Class TruffleInstrument.Env

java.lang.Object
com.oracle.truffle.api.instrumentation.TruffleInstrument.Env
Enclosing class:
TruffleInstrument

public static final class TruffleInstrument.Env extends Object
Access to instrumentation services as well as input, output, and error streams.
Since:
0.12
  • Method Details

    • getInstrumenter

      public Instrumenter getInstrumenter()
      Returns the instrumenter which lets you instrument guest language ASTs.
      Since:
      0.12
      See Also:
    • in

      public InputStream in()
      Input associated with Engine this instrument is being executed in.
      Returns:
      reader, never null
      Since:
      0.12
    • out

      public OutputStream out()
      Standard output writer for Engine this instrument is being executed in.
      Returns:
      writer, never null
      Since:
      0.12
    • err

      public OutputStream err()
      Standard error writer for Engine this instrument is being executed in.
      Returns:
      writer, never null
      Since:
      0.12
    • startServer

      Start a server at the provided URI via the 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.

      Parameters:
      uri - the URI of the server endpoint
      server - the handler of messages at the server side
      Returns:
      an implementation of MessageEndpoint call back representing the client side, or null when no virtual transport is available
      Throws:
      MessageTransport.VetoException - if creation of a server at that URI is not allowed
      IOException
      Since:
      19.0
    • registerService

      public void registerService(Object service)
      Registers additional service. This method can be called multiple time, but only during 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.
      Parameters:
      service - a service to be returned from associated Instrument.lookup(java.lang.Class<T>)
      Throws:
      IllegalStateException - if the method is called later than from TruffleInstrument.onCreate(com.oracle.truffle.api.instrumentation.TruffleInstrument.Env) method
      Since:
      0.12
    • lookup

      public <S> S lookup(LanguageInfo language, Class<S> type)
      Queries a 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.
      Type Parameters:
      S - the requested type
      Parameters:
      language - identification of the language to query
      type - the class of the requested type
      Returns:
      the registered service or null if none is found
      Since:
      0.26
    • lookup

      public <S> S lookup(InstrumentInfo instrument, Class<S> type)
      Returns an additional service provided by this instrument, specified by type. If an instrument is not enabled, it will be enabled automatically by requesting a supported service. If the instrument does not provide a service for a given type it will not be enabled automatically. An IllegalArgumentException is thrown if a service is looked up from the current instrument.
      Type Parameters:
      S - the requested type
      Parameters:
      instrument - identification of the instrument to query
      type - the class of the requested type
      Returns:
      the registered service or null if none is found
      Since:
      0.26
    • getLanguages

      public Map<String,LanguageInfo> getLanguages()
      Returns a map language id to language info of all languages that are installed in the environment.
      Since:
      0.26
    • getInstruments

      public Map<String,InstrumentInfo> getInstruments()
      Returns a map instrument id to instrument info of all instruments that are installed in the environment.
      Since:
      0.26
    • getOptions

      public OptionValues getOptions()
      Returns the context independent option values for the options described in TruffleInstrument.getOptionDescriptors(). The returned options are never null.
      Since:
      0.27
      See Also:
    • getOptions

      public OptionValues getOptions(TruffleContext context)
      Returns the context specific option values for the options described in TruffleInstrument.getContextOptionDescriptors() and TruffleInstrument.getOptionDescriptors(). Instrument context options can be different for each TruffleContext, whereas regular options cannot.
      Since:
      20.3
      See Also:
    • parse

      public CallTarget parse(Source source, String... argumentNames) throws IOException
      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...).
      Parameters:
      source - the source to evaluate
      argumentNames - the names of CallTarget.call(java.lang.Object...) arguments that can be referenced from the source
      Returns:
      the call target representing the parsed result
      Throws:
      IOException - if the parsing or evaluation fails for some reason
      SecurityException
      Since:
      0.12
    • parseInline

      public ExecutableNode parseInline(Source source, Node node, MaterializedFrame frame)
      Parses source snippet of the node's language at the provided node location. The result is an AST fragment represented by ExecutableNode that accepts frames valid at the provided node location, or null when inline parsing is not supported by the language.
      Parameters:
      source - a source snippet to parse at the provided node location
      node - 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
      Returns:
      the executable fragment representing the parsed result, or null
      Since:
      0.31
    • getTruffleFile

      @Deprecated public TruffleFile getTruffleFile(String path)
      Deprecated.
      Returns a TruffleFile for given path. This must be called on a context thread only.
      Parameters:
      path - the absolute or relative path to create TruffleFile for
      Returns:
      TruffleFile
      Since:
      19.0
    • getTruffleFile

      @Deprecated public TruffleFile getTruffleFile(URI uri)
      Deprecated.
      Returns a TruffleFile for given URI. This must be called on a context thread only.
      Parameters:
      uri - the URI to create TruffleFile for
      Returns:
      TruffleFile
      Since:
      19.0
    • getTruffleFile

      public TruffleFile getTruffleFile(TruffleContext context, String path)
      Returns a TruffleFile for given path and context.
      Parameters:
      context - the TruffleContext, or null to use a current entered context.
      path - the absolute or relative path to create TruffleFile for
      Returns:
      TruffleFile
      Throws:
      UnsupportedOperationException - when the FileSystem supports only URI
      IllegalArgumentException - if the path string cannot be converted to a Path
      Since:
      23.0
    • getTruffleFile

      public TruffleFile getTruffleFile(TruffleContext context, URI uri)
      Returns a TruffleFile for given URI and context.
      Parameters:
      context - the TruffleContext, or null to use a current entered context.
      uri - the URI to create TruffleFile for
      Returns:
      TruffleFile
      Throws:
      UnsupportedOperationException - when URI scheme is not supported
      IllegalArgumentException - if preconditions on the uri do not hold.
      FileSystemNotFoundException - is the file system, identified by the uri, does not exist and cannot be created automatically
      Since:
      23.0
    • getEnteredContext

      public TruffleContext getEnteredContext()
      Returns the entered TruffleContext or null when no context is entered.
      Since:
      20.3
    • isEngineRoot

      public boolean isEngineRoot(RootNode root)
      Returns 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.
      Parameters:
      root - the root node to check
      Returns:
      true if engine root else false
      Since:
      0.17
    • setAsynchronousStackDepth

      public void setAsynchronousStackDepth(int depth)
      Request for languages to provide stack frames of scheduled asynchronous execution. Languages might not provide asynchronous stack frames by default for performance reasons. At most 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).

      Parameters:
      depth - the requested stack depth, 0 means no asynchronous stack frames are required.
      Since:
      20.1.0
      See Also:
    • getLanguageInfo

      public LanguageInfo getLanguageInfo(Class<? extends TruffleLanguage<?>> languageClass)
      Returns the 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 getLanguages(). For example, values originating from the embedder like Java classes or polyglot proxies.
      Parameters:
      languageClass - the language class to convert
      Returns:
      the associated language info
      Throws:
      IllegalArgumentException - if the language class is not valid.
      Since:
      20.1
    • getLanguageView

      public Object getLanguageView(LanguageInfo language, Object value)
      Wraps the provided value to provide language specific information for primitive and foreign values. A typical implementation of a given language for this method does the following:
      • Return the current language as their associated language.
      • Provide a language specific display string for primitive and foreign values.
      • Return a language specific metaobject primitive or foreign values.
      • Add members to the object that would implicitly be available for all objects. For example, any JavaScript object is expected to have a prototype member. Foreign objects, even if they do not have such a member, are interpreted as if they have.
      Parameters:
      language - the language to provide the view for
      value - the value to language specific information for.
      Since:
      20.1
      See Also:
    • getPolyglotBindings

      public Object getPolyglotBindings()
      Returns the polyglot scope - symbols explicitly exported by languages. The polyglot bindings of the current entered context are returned.
      Returns:
      an interop object having the symbol names as properties
      Since:
      20.1
    • getScope

      public Object getScope(LanguageInfo language)
      Provides top scope object of the language, if any. Uses the current context to find the language scope associated with. The returned object is an interop scope object, or null.
      Parameters:
      language - a language
      Returns:
      the top scope, or null if the language does not support such concept
      Since:
      20.3
      See Also:
    • getInternalResource

      public TruffleFile getInternalResource(Class<? extends InternalResource> resource) throws IOException
      Returns the TruffleFile representing the target directory of an internal resource. The internal resource is guaranteed to be fully InternalResource.unpackFiles(InternalResource.Env, Path) unpacked} before this method returns. When this method is called for the first time and the resource is not cached than the resource will be unpacked. Unpacking an internal resource can be an expensive operation, but the implementation makes sure that unpacked internal resources are cached.

      The returned TruffleFile will only grant read-only access to the target directory, but access is provided even if IO access is disabled.

      On a HotSpot VM the internal resource is typically cached in the user directory, so unpacking would be repeated once per operating system user. When the language was compiled using native-image internal resources are unpacked at native-image compile time and stored relative to the native-image.

      The caller thread must be entered in a context.

      Parameters:
      resource - the resource class to load
      Throws:
      IllegalArgumentException - if resource is not associated with this instrument
      IOException - in case of IO error
      Since:
      23.1
    • getInternalResource

      public TruffleFile getInternalResource(String resourceId) throws IOException
      Returns the TruffleFile representing the target directory of an internal resource. Unlike the getInternalResource(Class), this method can be used for optional resources whose classes may not exist at runtime. In this case the optional resource must be unpacked at build time, see Engine.copyResources(Path, String...). If the resource with the specified resourceId is not associated to this instrument, the function returns null.
      Parameters:
      resourceId - unique id of the resource to be loaded
      Returns:
      internal resource directory or null if resource with the resourceId is not associated with this instrument
      Throws:
      IOException - in case of IO error
      Since:
      23.1
      See Also:
    • getLogger

      public TruffleLogger getLogger(String loggerName)
      Find or create an engine bound logger for an instrument. When a logging is required from a thread which entered a context the context's logging handler and options are used. Otherwise the engine's logging handler and options are used.

      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.

      Parameters:
      loggerName - the the name of a TruffleLogger, if a loggerName is null or empty a root logger for language or instrument is returned
      Returns:
      a TruffleLogger
      Since:
      19.0
    • getLogger

      public TruffleLogger getLogger(Class<?> forClass)
      Find or create an engine bound logger for an instrument. The engine bound loggers can be used by threads executing without any current context. When a logging is required from a thread which entered a context the context's logging handler and options are used. Otherwise the engine's logging handler and options are used.

      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.

      Parameters:
      forClass - the Class to create a logger for
      Returns:
      a TruffleLogger
      Throws:
      NullPointerException - if forClass is null
      Since:
      19.0
    • isSameFrame

      public boolean isSameFrame(RootNode root, Frame frame1, Frame frame2)
      Tests if two frames are the same. This method is mainly used by instruments in case of yield of the execution and later resume. Frame comparison is used to match the particular yielded and resumed execution. The frames must correspond to the root.
      Since:
      24.0
    • calculateContextHeapSize

      public long calculateContextHeapSize(TruffleContext truffleContext, long stopAtBytes, AtomicBoolean cancelled)
      Returns heap memory size retained by a polyglot context.
      Parameters:
      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.
      Returns:
      calculated heap memory size retained by the specified polyglot context, or a value greater than stopAtBytes if the calculated size is greater than stopAtBytes.
      Throws:
      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.
      Since:
      21.1
    • submitThreadLocal

      public 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. If the threads array is 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.

      Parameters:
      context - the context in which the action should be performed. Non null .
      threads - the threads to execute the action on. null for all threads
      action - the action to perform on that thread.
      Since:
      21.1
      See Also:
    • createSystemThread

      public Thread createSystemThread(Runnable runnable)
      Creates a new thread designed to process instrument tasks in the background. See createSystemThread(Runnable, ThreadGroup) for a detailed description of the parameters.
      Since:
      22.3
      See Also:
    • createSystemThread

      public Thread createSystemThread(Runnable runnable, ThreadGroup threadGroup)
      Creates a new thread designed to process instrument tasks in the background. The created thread cannot enter the context, if it tries an IllegalStateException is thrown. Creating or terminating a system thread does not notify languages or ThreadsListeners. 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 extends TruffleInstrument {
      
          private volatile Thread systemThread;
          private volatile boolean cancelled;
          private final BlockingQueue<Runnable> tasks = new LinkedBlockingQueue<>();
      
          @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();
              }
          }
      }
      
      Parameters:
      runnable - the runnable to run on this thread.
      threadGroup - the thread group, passed on to the underlying Thread.
      Throws:
      IllegalStateException - if the engine is already closed.
      Since:
      22.3
      See Also:
    • getSandboxPolicy

      public SandboxPolicy getSandboxPolicy()
      Returns the engine's 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.
      Since:
      23.0
      See Also: