C - internal state of the language associated with every thread that is executing program
parsed by the
languagepublic abstract class TruffleLanguage<C> extends Object
TruffleLanguage.Registration in order to be discoverable by the Polyglot
API.
TruffleLanguage subclasses must provide a public default constructor.
TruffleLanguage.Registration annotation and the implementation's JAR file placed on the host Java Virtual
Machine's class path.
A newly created engine locates all available language implementations and creates a descriptor for each. The descriptor holds the language's registered metadata, but its execution environment is not initialized until the language is needed for code execution. That execution environment remains initialized for the lifetime of the engine and is isolated from the environment in any other engine instance.
Language global state can be shared between multiple context instances by saving them in a custom
field of the TruffleLanguage subclass. Languages may control sharing between multiple
contexts using its context policy. By default the context
policy is exclusive: each context has its own separate
TruffleLanguage instance.
If the context policy is more permissive then the implementation needs to manually ensure data
isolation between the contexts. This means that state associated with a context must not be
stored in a TruffleLanguage subclass. ASTs and assumptions can be shared across multiple contexts
if modifying them does not affect language semantics. Languages are strongly discouraged from
using static mutable state in their languages. Instead TruffleLanguage instances should
be used instead to store global state and their sharing should be configured using
context policy.
Whenever an engine is disposed then each initialized language context will be
disposed.
TruffleLanguage instances per polyglot context is configured by the context policy. By default an
exclusive language instance is created
for every polyglot context or
inner context. With policy
reuse, language instances will be reused after a language context was
disposed. With policy shared, a language will also be reused if active contexts are not yet disposed. Language
instances will only be shared or reused if they are
compatible. Language
implementations are encouraged to support the most permissive context policy possible. Please see
the individual policies for details on the implications on the language
implementation.
The following illustration shows the cardinalities of the individual components:
N: unbounded
P: N for exclusive, 1 for shared context policy
L: number of installed languages
I: number of installed instruments
- 1 : Host VM Processs
- N : Engine
- N : Context
- L : Language Context
- P * L : TruffleLanguage
- I : Instrument
- 1 : TruffleInstrument
parsing request is cached per language instance,
source, argument
names and environment options. The scope of the caching is influenced
by the context policy. Caching may be
disabled for certain sources. It is enabled for new sources by default.
context creation each language context is provided with
information about the environment environment . Language can optionally declare
configurable options in
TruffleLanguage.getOptionDescriptors().
polyglot
bindings. This bindings object is used to implement guest language export/import statements used
for language interoperation.
A language implementation can also import or export a global symbol by name. The scope may be accessed from multiple threads at the same time. Existing keys are overwritten.
Context, which should be designed in a generic way.
Language-specific entry points, for instance to emulate the command-line interface of an existing
implementation, should be handled externally.
created and managed by a language for
a context. All internally created threads need to be stopped when the context is
disposed.
allows it.
By default every context only allows access from one thread at the
same time. Therefore if the context is tried to be accessed from multiple threads at the same
time the access will fail. Languages that want to allow multi-threaded access to a context may
override TruffleLanguage.isThreadAccessAllowed(Thread, boolean) and return true also for
multi-threaded accesses. Initialization actions for multi-threaded access can be performed by
overriding TruffleLanguage.initializeMultiThreading(Object). Threads are
initialized and disposed before and after use with a context. Languages may create new threads if the environment allows it.
for embedding of Truffle languages in Java host applications.| Modifier and Type | Class and Description |
|---|---|
static class |
TruffleLanguage.ContextPolicy
Defines the supported policy for reusing
languages per context. |
static class |
TruffleLanguage.ContextReference<C>
Represents a reference to the current context to be stored in an AST.
|
static class |
TruffleLanguage.Env
Represents execution environment of the
TruffleLanguage. |
static class |
TruffleLanguage.InlineParsingRequest
Request for inline parsing.
|
static class |
TruffleLanguage.LanguageReference<L extends TruffleLanguage>
Represents a reference to the language to be stored in an AST.
|
static class |
TruffleLanguage.ParsingRequest
Request for parsing.
|
static interface |
TruffleLanguage.Provider
Used to register a
TruffleLanguage using a ServiceLoader. |
static interface |
TruffleLanguage.Registration
The annotation to use to register your language to the
Polyglot
API. |
| Modifier | Constructor and Description |
|---|---|
protected |
TruffleLanguage()
Constructor to be called by subclasses.
|
| Modifier and Type | Method and Description |
|---|---|
protected boolean |
areOptionsCompatible(org.graalvm.options.OptionValues firstOptions,
org.graalvm.options.OptionValues newOptions)
|
protected abstract C |
createContext(TruffleLanguage.Env env)
Creates internal representation of the executing context suitable for given environment.
|
protected void |
disposeContext(C context)
Disposes the context created by
TruffleLanguage.createContext(com.oracle.truffle.api.TruffleLanguage.Env). |
protected void |
disposeThread(C context,
Thread thread)
Invoked the last time code will be executed for this thread and context.
|
protected void |
finalizeContext(C context)
Performs language context finalization actions that are necessary before language contexts
are
disposed. |
protected Iterable<Scope> |
findLocalScopes(C context,
Node node,
Frame frame)
Find a hierarchy of local scopes enclosing the given
node. |
protected Iterable<Scope> |
findTopScopes(C context)
Find a hierarchy of top-most scopes of the language, if any.
|
protected int |
getAsynchronousStackDepth()
Get the depth of asynchronous stack.
|
protected static <C,T extends TruffleLanguage<C>> |
getCurrentContext(Class<T> languageClass)
Returns the current language context entered on the current thread.
|
protected static <T extends TruffleLanguage<?>> |
getCurrentLanguage(Class<T> languageClass)
Returns the current language instance for the current
thread. |
protected String |
getLanguageHome()
Returns the home location for this language.
|
protected Object |
getLanguageView(C context,
Object value)
Wraps the value to provide language-specific information for primitive and foreign values.
|
protected org.graalvm.options.OptionDescriptors |
getOptionDescriptors()
Returns a set of option descriptors that are supported by this language.
|
protected Object |
getScopedView(C context,
Node location,
Frame frame,
Object value)
Wraps the value to filter or add scoping specific information for values associated with the
current language and location in the code.
|
protected void |
initializeContext(C context)
Perform any complex initialization.
|
protected void |
initializeMultipleContexts()
Initializes this language instance for use with multiple contexts.
|
protected void |
initializeMultiThreading(C context)
Invoked before the context is accessed from multiple threads at the same time.
|
protected void |
initializeThread(C context,
Thread thread)
Invoked before a context is accessed from a new thread.
|
protected boolean |
isThreadAccessAllowed(Thread thread,
boolean singleThreaded)
Returns
true if code of this language is allowed to be executed on this thread. |
protected boolean |
isVisible(C context,
Object value)
Decides whether the result of evaluating an interactive source should be printed to stdout.
|
protected ExecutableNode |
parse(TruffleLanguage.InlineParsingRequest request)
Parses the
provided source snippet at the
provided location and generates its appropriate
AST representation. |
protected CallTarget |
parse(TruffleLanguage.ParsingRequest request)
Parses the
provided source and generates its appropriate
AST representation. |
protected boolean |
patchContext(C context,
TruffleLanguage.Env newEnv)
Notifies the language with pre-initialized context about
TruffleLanguage.Env change. |
protected TruffleLanguage()
protected boolean areOptionsCompatible(org.graalvm.options.OptionValues firstOptions,
org.graalvm.options.OptionValues newOptions)
true if the combination of two sets of options allow to
share or reuse the same language
instance, else false. If options are incompatible then a new language instance
will be created for a new context. The first language context created for a TruffleLanguage instance always has compatible options, therefore
TruffleLanguage.areOptionsCompatible(OptionValues, OptionValues) will not be invoked for it. The
default implementation returns true.
If the context policy of a language is set to exclusive
(default behavior) then TruffleLanguage.areOptionsCompatible(OptionValues, OptionValues) will never
be invoked as TruffleLanguage instances will not be shared for multiple contexts. For
the other context policies reuse and shared this method can be used to further restrict the reuse of language instances.
Compatibility influences parse caching because it uses the
language instance as a key.
Example usage of areOptionsCompatible if sharing of the language instances and parse caching should be restricted by the script version option:
class CompatibleLanguage extendsTruffleLanguage<TruffleLanguage.Env> { @Option(help = "", category =OptionCategory.USER) static finalOptionKey<String> ScriptVersion = newOptionKey<>("ECMA2017"); @Overrideprotected boolean areOptionsCompatible(OptionValuesfirstOptions,OptionValuesnewOptions) { return firstOptions.get(ScriptVersion). equals(newOptions.get(ScriptVersion)); } @OverrideprotectedOptionDescriptorsgetOptionDescriptors() { return new CompatibleLanguageOptionDescriptors(); } }
firstOptions - the options used to create the first context, never nullnewOptions - the options that will be used for the new context, never nullTruffleLanguage.ContextPolicy,
TruffleLanguage.parse(ParsingRequest)protected abstract C createContext(TruffleLanguage.Env env)
language is used by a new
Context, the system calls this method to let the
language prepare for execution. The returned execution
context is completely language specific; it is however expected it will contain reference to
here-in provided env and adjust itself according to parameters provided by the
env object.
The context created by this method is accessible using TruffleLanguage.getCurrentContext(Class). An
IllegalStateException is thrown if the context is tried to be accessed while the
createContext method is executed.
This method shouldn't perform any complex operations. The runtime system is just being
initialized and for example making
calls into
other languages and assuming your language is already initialized and others can see it
would be wrong - until you return from this method, the initialization isn't over. The same
is true for instrumentation, the instruments cannot receive any meta data about code executed
during context creation. Should there be a need to perform complex initialization, do it by
overriding the TruffleLanguage.initializeContext(java.lang.Object) method.
Additional services provided by the language must be
registered by this method otherwise
IllegalStateException is thrown.
May return null if the language does not need any per-context
state. Otherwise it should return a new object instance every time it is called.
env - the environment the language is supposed to operate innullprotected void initializeContext(C context) throws Exception
TruffleLanguage.createContext(com.oracle.truffle.api.TruffleLanguage.Env) factory method shouldn't
do any complex operations. Just create the instance of the context, let the runtime system
register it properly. Should there be a need to perform complex initialization, override this
method and let the runtime call it later to finish any post initialization
actions. Example:
class PostInitLanguage extendsTruffleLanguage<Context> { @OverrideprotectedContextcreateContext(TruffleLanguage.Envenv) { // "quickly" create the context return newContext(env); } @Overrideprotected void initializeContext(Contextcontext) throwsIOException{ // called "later" to finish the initialization // for example call into another languageSourcesource =Source.newBuilder("js", "function(x, y) x * y", "mul.js").build(); context.mul = context.env.parsePublic(source); } }
context - the context created by
TruffleLanguage.createContext(com.oracle.truffle.api.TruffleLanguage.Env)Exception - if something goes wrongprotected void finalizeContext(C context)
disposed. All installed languages must remain usable
after finalization. The finalization order can be influenced by specifying
language dependencies. By default internal
languages are finalized last, otherwise the default order is unspecified but deterministic.
While finalization code is run, other language contexts may become initialized. In such a case, the finalization order may be non-deterministic and/or not respect the order specified by language dependencies.
All threads created by a language must be stopped after
finalizeContext was called. The languages are responsible for fulfilling that contract,
otherwise an AssertionError is thrown. It is recommended to join all threads that
were disposed.
context - the context created by
TruffleLanguage.createContext(com.oracle.truffle.api.TruffleLanguage.Env)for specifying language dependencies.protected void initializeMultipleContexts()
context policy.
With the default context policy exclusive, this method will
never be invoked. This method will be called prior or after the first context was created for
this language. In case an explicit
engine was used to create a context, then this method will be invoked prior to the
creation of the first language context of a language. For inner
contexts, this method may be invoked prior to the first
inner context that is created, but after the
the first outer context was created. No guest language code must be invoked in this method.
This method is called at most once per language instance.
A language may use this method to invalidate assumptions that assume a single context only. For example, assumptions that are dependent on the language context data. It is required to invalidate any such assumptions that are used in the AST when this method is invoked.
TruffleLanguage.areOptionsCompatible(OptionValues, OptionValues),
TruffleLanguage.ContextPolicyprotected void disposeContext(C context)
TruffleLanguage.createContext(com.oracle.truffle.api.TruffleLanguage.Env). A dispose cleans up all
resources associated with a context. The context may become unusable after it was disposed.
It is not allowed to run guest language code while disposing a context. Finalization code
should be run in TruffleLanguage.finalizeContext(Object) instead. Finalization will be performed
prior to context disposal.
The disposal order can be influenced by specifying language dependencies. By default internal languages are disposed last, otherwise the
default order is unspecified but deterministic. During disposal no other language must be
accessed using the language environment.
context - the context created by
TruffleLanguage.createContext(com.oracle.truffle.api.TruffleLanguage.Env)to run finalization code for a context.,
to perform disposal actions when a thread is no longer
used.protected CallTarget parse(TruffleLanguage.ParsingRequest request) throws Exception
provided source and generates its appropriate
AST representation. The parsing should execute no user code, it should only create the
Node tree to represent the source. If the provided
source does not correspond naturally to a call target, the returned call
target should create and if necessary initialize the corresponding language entity and return
it.
The result of the parsing request is cached per language instance,
source and argument names. It is safe to assume that current language instance
and argument names will remain unchanged for a
parsed CallTarget. The scope of the caching is influenced by the
context policy and option
compatibility.
Caching may be disabled for sources. It is enabled for new sources
by default.
The argumentNames may contain symbolic names for actual parameters of the call to the
returned value. The result should be a call target with method
CallTarget.call(java.lang.Object...) that accepts as many arguments as were provided
via the TruffleLanguage.ParsingRequest.getArgumentNames() method.
Implement TruffleLanguage.parse(com.oracle.truffle.api.TruffleLanguage.InlineParsingRequest) to
parse source in a specific context location.
request - request for parsingNode tree representing
just parsed codeException - exception can be thrown when parsing goes wrong. Here-in thrown exception
is propagated to the user who called one of eval methods of
ContextTruffleLanguage.Registration.contextPolicy()protected ExecutableNode parse(TruffleLanguage.InlineParsingRequest request) throws Exception
provided source snippet at the
provided location and generates its appropriate
AST representation. The parsing should execute no user code, it should only create the
Node tree to represent the source.
The parsing should be performed in a context (specified by
TruffleLanguage.InlineParsingRequest.getLocation()). The result should be an AST fragment with method
ExecutableNode.execute(com.oracle.truffle.api.frame.VirtualFrame) that accepts frames
valid at the provided location.
When not implemented, null is returned by default.
protected org.graalvm.options.OptionDescriptors getOptionDescriptors()
environment when the context is
created. To construct option descriptors from a list then
OptionDescriptors.create(List) can be used. Languages must always return the same
option descriptors independent of the language instance or side-effects.For an example of declaring the option descriptor using an annotation.protected boolean patchContext(C context, TruffleLanguage.Env newEnv)
TruffleLanguage.Env change. See
Context for information how to enable the Context
pre-initialization.
During the pre-initialization (in the native compilation time) the
TruffleLanguage.createContext(com.oracle.truffle.api.TruffleLanguage.Env) and
TruffleLanguage.initializeContext(java.lang.Object) methods are called. In the image execution time,
the TruffleLanguage.patchContext(java.lang.Object, com.oracle.truffle.api.TruffleLanguage.Env) is
called on all languages whose contexts were created during the pre-initialization a
consequence of Context.create(java.lang.String...) invocation.
The contexts are patched in a topological order starting from dependent languages. If the
TruffleLanguage.patchContext(java.lang.Object, com.oracle.truffle.api.TruffleLanguage.Env) is
successful for all pre-initialized languages the pre-initialized context is used, otherwise a
new context is created.
Typical implementation looks like:
@Overrideprotected boolean patchContext(Contextcontext,TruffleLanguage.EnvnewEnv) { if (!optionsAllowPreInitializedContext(context, newEnv)) { // Incompatible options - cannot use pre-initialized context return false; } context.env = newEnv; context.args = newEnv.getApplicationArguments(); context.in = newEnv.in(); context.out = newEnv.out(); context.err = newEnv.err(); return true; } private boolean optionsAllowPreInitializedContext(Contextcontext,TruffleLanguage.EnvnewEnv) { // Verify that values of important options in the new Env do not differ // from values in the pre-initialized context finalStringnewVersionValue = newEnv.getOptions().get(version); returnObjects.equals(context.languageVersion, newVersionValue); }
context - the context created by
TruffleLanguage.createContext(com.oracle.truffle.api.TruffleLanguage.Env) during
pre-initializationnewEnv - the new environment replacing the environment used in pre-initialization phasefalse to prevent an usage of pre-initialized context by a language which is
not aware of context pre-initialization.protected boolean isThreadAccessAllowed(Thread thread, boolean singleThreaded)
true if code of this language is allowed to be executed on this thread.
The method returns false to deny execution on this thread. The default
implementation denies access to more than one thread at the same time. The
current thread may differ from the passed thread.
Example multi-threaded language implementation:
class MultiThreadedLanguage extendsTruffleLanguage<Context> { @OverrideprotectedContextcreateContext(TruffleLanguage.Envenv) { return newContext(env); } @Overrideprotected boolean isThreadAccessAllowed(Threadthread, boolean singleThreaded) { // allow access from any thread instead of just one return true; } @Overrideprotected void initializeMultiThreading(Contextcontext) { // perform actions when the context is switched to multi-threading context.singleThreaded.invalidate(); } @Overrideprotected void initializeThread(Contextcontext,Threadthread) { // perform initialization actions for threads } @Overrideprotected void disposeThread(Contextcontext,Threadthread) { // perform disposal actions for threads } }
thread - the thread that accesses the context for the first time.singleThreaded - true if the access is considered single-threaded,
false if more than one thread is active at the same time.protected void initializeMultiThreading(C context)
TruffleLanguage.isThreadAccessAllowed(Thread, boolean) is implemented to deny access from
multiple threads at the same time. All initialized languages must allow multi-threading for
this method to be invoked.
Example multi-threaded language implementation:
class MultiThreadedLanguage extendsTruffleLanguage<Context> { @OverrideprotectedContextcreateContext(TruffleLanguage.Envenv) { return newContext(env); } @Overrideprotected boolean isThreadAccessAllowed(Threadthread, boolean singleThreaded) { // allow access from any thread instead of just one return true; } @Overrideprotected void initializeMultiThreading(Contextcontext) { // perform actions when the context is switched to multi-threading context.singleThreaded.invalidate(); } @Overrideprotected void initializeThread(Contextcontext,Threadthread) { // perform initialization actions for threads } @Overrideprotected void disposeThread(Contextcontext,Threadthread) { // perform disposal actions for threads } }
context - the context that should be prepared for multi-threading.protected void initializeThread(C context, Thread thread)
initialized for the thread the context will be initialized
with. If the thread is stored in the context it must be referenced using
WeakReference to avoid leaking thread objects.
The current thread may differ from the initialized thread.
Example multi-threaded language implementation:
class MultiThreadedLanguage extendsTruffleLanguage<Context> { @OverrideprotectedContextcreateContext(TruffleLanguage.Envenv) { return newContext(env); } @Overrideprotected boolean isThreadAccessAllowed(Threadthread, boolean singleThreaded) { // allow access from any thread instead of just one return true; } @Overrideprotected void initializeMultiThreading(Contextcontext) { // perform actions when the context is switched to multi-threading context.singleThreaded.invalidate(); } @Overrideprotected void initializeThread(Contextcontext,Threadthread) { // perform initialization actions for threads } @Overrideprotected void disposeThread(Contextcontext,Threadthread) { // perform disposal actions for threads } }
context - the context that is enteredthread - the thread that accesses the context for the first time.protected void disposeThread(C context, Thread thread)
current
thread may differ from the disposed thread. Disposal of threads is only guaranteed for
threads that were created by guest languages, so called polyglot threads. Other threads, created by the embedder, may be collected by the garbage
collector before they can be disposed and may therefore not be disposed.For usage details.protected Iterable<Scope> findLocalScopes(C context, Node node, Frame frame)
node. Unless the node is in
a global scope, it is expected that there is at least one scope provided, that corresponds to
the enclosing function. The language might provide additional block scopes, closure scopes,
etc. Global top scopes are provided by TruffleLanguage.findTopScopes(java.lang.Object). The scope
hierarchy should correspond with the scope nesting, from the inner-most to the outer-most.
The scopes are expected to contain variables valid at the given node.
Scopes may depend on the information provided by the frame.
Lexical scopes are returned when frame argument is null.
When not overridden, the enclosing RootNode's scope with variables read from its
FrameDescriptor's FrameSlots is provided by default.
The
TruffleInstrument.Env.findLocalScopes(com.oracle.truffle.api.nodes.Node, com.oracle.truffle.api.frame.Frame)
provides result of this method to instruments.
context - the current context of the languagenode - a node to find the enclosing scopes for. The node, is inside a RootNode
associated with this language.frame - The current frame the node is in, or null for lexical access when
the program is not running, or is not suspended at the node's location.protected Iterable<Scope> findTopScopes(C context)
Math is equivalent of a lookup with the identifier 'Math' in the top-most scopes
of the language. Looking up the identifier 'Math' should have equivalent semantics as reading
with the key 'Math' from the variables object of one of the top-most scopes of the language.
In addition languages may optionally allow modification and insertion with the variables
object of the returned top-scopes.
Languages may want to specify multiple top-scopes. It is recommended to stay as close as possible to the set of top-scopes that as is described in the guest language specification, if available. For example, in JavaScript, there is a 'global environment' and a 'global object' scope. While the global environment scope contains class declarations and is not insertable, the global object scope is used to insert new global variable values and is therefore insertable.
TruffleInstrument.Env.findTopScopes(java.lang.String)
. They are used by debuggers to access the top-most scopes of the language.
polyglot API as context
bindings object. When members of the bindings object are
read then the first scope where the key exists is read. If a
member is modified in the bindings object, then the
value will be written to the first scope where the key exists. If a new member is added to
the bindings object then it is added to the first variables object where the key is
insertable. If a member is removed, it is only tried to be removed from the first scope of
where such a key exists. If member keys are requested from the
bindings object, then the variable object keys are returned sorted from first to last.
When not overridden then a single read-only scope named 'global' without any keys will be returned.
context - the current context of the languageprotected boolean isVisible(C context, Object value)
true claiming all values are visible.
This method affects behavior of
Context.eval(org.graalvm.polyglot.Source) - when evaluating an
interactive source the result of the evaluation is tested for
visibility and if the value is found
visible, it gets converted to string and printed to
standard output.
A language can control whether a value is or isn't printed by overriding this method and
returning false for some or all values. In such case it is up to the language
itself to use the TruffleLanguage.Env.out(), TruffleLanguage.Env.err() and TruffleLanguage.Env.in() streams of the
environment.
When evaluation is called with an interactive source of a
language that controls its interactive behavior, it is the responsibility of the language
itself to print the result to use the TruffleLanguage.Env.out(), TruffleLanguage.Env.err() and
TruffleLanguage.Env.in() streams of the environment.
context - the execution context for doing the conversionvalue - the value to check. Either primitive type or
TruffleObjecttrue if the language implements an interactive response to evaluation of
interactive sources.protected Object getLanguageView(C context, Object value)
interop type. For example, it is not
allowed to change the type from number to string. If the behavior of an existing trait is
modified then all writes on the mapper need to be forwarded to the underlying object, apart
from the virtual members. Writes to the virtual members should be persisted in the wrapper if
this is the behavior of the object type that is being mapped to.
Every language view wrapper must return the current language as their associated
language. An
AssertionError is thrown when a language view is requested if this contract is
violated.
Example modifications language view wrappers may perform:
display string
for primitive and foreign values.
metaobject for
primitive or foreign values.
The default implementation returns null. If null is returned then
the default language view will be used. The default language view wraps the value and returns
the current language as their associated language. With the default view wrapper all interop
library messages will be forwarded to the delegate value, except the messages for
metaobjects and
display strings
.
This following example shows a simplified language view. For a full implementation including an example of metaobjects can be found in the Truffle examples language "SimpleLanguage".
@ExportLibrary(value = InteropLibrary.class, delegateTo = "delegate")
final class ExampleLanguageView implements TruffleObject {
protected final Object delegate;
ExampleLanguageView(Object delegate) {
this.delegate = delegate;
}
@ExportMessage
boolean hasLanguage() {
return true;
}
@ExportMessage
Class<? extends TruffleLanguage<?>> getLanguage() {
return MyLanguage.class;
}
@ExportMessage
Object toDisplayString(boolean allowSideEffects,
@CachedLibrary("this.delegate") InteropLibrary dLib) {
try {
if (dLib.isString(this.delegate)) {
return dLib.asString(this.delegate);
} else if (dLib.isBoolean(this.delegate)) {
return dLib.asBoolean(this.delegate) ? "TRUE" : "FALSE";
} else if (dLib.fitsInLong(this.delegate)) {
return longToString(dLib.asLong(this.delegate));
} else {
// full list truncated for this language
return "Unsupported value";
}
} catch (UnsupportedMessageException e) {
CompilerDirectives.transferToInterpreter();
throw new AssertionError(e);
}
}
@TruffleBoundary
private static String longToString(long value) {
return String.valueOf(value);
}
@ExportMessage
boolean hasMetaObject(@CachedLibrary("this.delegate") InteropLibrary dLib) {
return dLib.isString(this.delegate)//
|| dLib.fitsInLong(this.delegate)//
|| dLib.isBoolean(this.delegate);
}
@ExportMessage
Object getMetaObject(@CachedLibrary("this.delegate") InteropLibrary dLib)
throws UnsupportedMessageException {
if (dLib.isString(this.delegate)) {
return MyMetaObject.PRIMITIVE_STRING;
} else if (dLib.isBoolean(this.delegate)) {
return MyMetaObject.PRIMITIVE_LONG;
} else if (dLib.fitsInLong(this.delegate)) {
return MyMetaObject.PRIMITIVE_BOOLEAN;
} else {
// no associable metaobject
throw UnsupportedMessageException.create();
}
}
}
context - the current context.value - the valueprotected Object getScopedView(C context, Node location, Frame frame, Object value)
This method is only invoked with values that are associated with the current
language. For
values without language the language view is
requested first before the scoped view is requested. If this method needs an implementation
then TruffleLanguage.getLanguageView(Object, Object) should be implemented as well.
Scoped views may be implemented in a very similar way to
language views. Please refer to the examples from
this method.
context - the current context.location - the current source location. Guaranteed to be a node from a RootNode
associated with this language. Never null.frame - the current active frame. Guaranteed to be a frame from a RootNode
associated with this language. Never null.value - the value to provide scope information for. Never null. Always
associated with this language.protected static <T extends TruffleLanguage<?>> T getCurrentLanguage(Class<T> languageClass)
thread. If a node is accessible then Node.lookupLanguageReference(Class) should be used instead.
Throws an IllegalStateException if the language is not yet initialized or not
executing on this thread. If invoked on the fast-path then languageClass must be
a compilation final value.T - the language typelanguageClass - the exact language class needs to be provided for the lookup.Node.lookupLanguageReference(Class),
CachedLanguageprotected static <C,T extends TruffleLanguage<C>> C getCurrentContext(Class<T> languageClass)
node is
accessible then Node.lookupContextReference(Class) should be used instead. An
IllegalStateException is thrown if the language is not yet initialized or not
executing on this thread. If invoked on the fast-path then languageClass must be
a compilation final value.C - the context typeT - the language typelanguageClass - the exact language class needs to be provided for the lookup.Node.lookupContextReference(Class),
CachedContextprotected final String getLanguageHome()
protected final int getAsynchronousStackDepth()
Override RootNode.findAsynchronousFrames(Frame) to provide the asynchronous stack
frames.
RootNode.findAsynchronousFrames(Frame)