public abstract class InteropLibrary extends Library
The interop API differentiates between the source and the target language. The source language is
the language that implements/exports the message implementations. The implementations map types
of the source language to the interop protocol as it is specified by the protocol. For example,
language values that represent arrays or array like structures should implement the messages for
array based access
. This allows the target language to call the
protocol without knowledge of the concrete source language. The target language embeds the
interop protocol semantics as part of their existing language semantics. For example, language
operations that access array elements in the target language should call
array access
messages for interop values.
The interop protocol only allows interop values to be used as receivers, return values or parameters of messages. Allowed Java types of interop values are:
TruffleObject
: Any object that implements the TruffleObject
interface is
interpreted according to the interop messages it exports
. Truffle objects
are expected but not required to export interop library messages.
String
and Character
are interpreted as string
value.
Boolean
is interpreted as boolean
value.
Byte
, Short
, Integer
, Long
, Float
and Double
are interpreted as number
values.
null
is never a valid interop value. Instead, use a
TruffleObject
which implements InteropLibrary.isNull(Object)
message.
The following type combinations are mutually exclusive and cannot return true
for
the type check message of the same receiver value:
executable
instantiable
pointer
members
hash entries
array elements
buffer elements
language
associated metaobject
metaobject parents as array elements
declaring meta object
source location
identity
scope parent
executable name
exception message
exception cause
exception stack trace
iterator
If a date or time value has a timezone
then it is called aware
, otherwise naive
An aware time and date has sufficient knowledge of applicable algorithmic and political time adjustments, such as time zone and daylight saving time information, to locate itself relative to other aware objects. An aware object is used to represent a specific moment in time that is not open to interpretation.
A naive time and date does not contain enough information to unambiguously locate itself relative to other date/time objects. Whether a naive object represents Coordinated Universal Time (UTC), local time, or time in some other timezone is purely up to the program, just like it is up to the program whether a particular number represents metres, miles, or mass. Naive objects are easy to understand and to work with, at the cost of ignoring some aspects of reality.
Interop messages throw checked exceptions
to indicate error states. The
target language is supposed to always catch those exceptions and translate them into guest
language errors of the target language. Interop message contracts are verified only if assertions
(-ea) are enabled.
Reference documentation of Truffle Libraries.
Node.Child, Node.Children
Modifier | Constructor and Description |
---|---|
protected |
InteropLibrary() |
Modifier and Type | Method and Description |
---|---|
BigInteger |
asBigInteger(Object receiver)
Returns the receiver value as Java BigInteger if the number fits without loss of precision.
|
boolean |
asBoolean(Object receiver)
Returns the Java boolean value if the receiver represents a
boolean like value. |
byte |
asByte(Object receiver)
Returns the receiver value as Java byte primitive if the number fits without loss of
precision.
|
LocalDate |
asDate(Object receiver)
Returns the receiver as date if this object represents a
date . |
double |
asDouble(Object receiver)
Returns the receiver value as Java double primitive if the number fits without loss of
precision.
|
Duration |
asDuration(Object receiver)
Returns the receiver as duration if this object represents a
duration . |
float |
asFloat(Object receiver)
Returns the receiver value as Java float primitive if the number fits without loss of
precision.
|
Instant |
asInstant(Object receiver)
Returns the receiver as instant if this object represents an
instant . |
int |
asInt(Object receiver)
Returns the receiver value as Java int primitive if the number fits without loss of
precision.
|
long |
asLong(Object receiver)
Returns the receiver value as Java long primitive if the number fits without loss of
precision.
|
long |
asPointer(Object receiver)
Returns the pointer value as long value if the receiver represents a pointer like value.
|
protected boolean |
assertAdopted()
Utility for libraries to require adoption before cached versions of nodes can be executed.
|
short |
asShort(Object receiver)
Returns the receiver value as Java short primitive if the number fits without loss of
precision.
|
String |
asString(Object receiver)
Returns the Java string value if the receiver represents a
string
like value. |
LocalTime |
asTime(Object receiver)
Returns the receiver as time if this object represents a
time . |
ZoneId |
asTimeZone(Object receiver)
Returns the receiver as timestamp if this object represents a
timezone . |
TruffleString |
asTruffleString(Object receiver)
Returns the
TruffleString value if the receiver represents a string like value. |
Object |
execute(Object receiver,
Object... arguments)
Executes an executable value with the given arguments.
|
boolean |
fitsInBigInteger(Object receiver)
Returns
true if the receiver represents a number and its value fits
in a Java BigInteger without loss of precision, else false . |
boolean |
fitsInByte(Object receiver)
Returns
true if the receiver represents a number and its value fits
in a Java byte primitive without loss of precision, else false . |
boolean |
fitsInDouble(Object receiver)
Returns
true if the receiver represents a number and its value fits
in a Java double primitive without loss of precision, else false . |
boolean |
fitsInFloat(Object receiver)
Returns
true if the receiver represents a number and its value fits
in a Java float primitive without loss of precision, else false . |
boolean |
fitsInInt(Object receiver)
Returns
true if the receiver represents a number and its value fits
in a Java int primitive without loss of precision, else false . |
boolean |
fitsInLong(Object receiver)
Returns
true if the receiver represents a number and its value fits
in a Java long primitive without loss of precision, else false . |
boolean |
fitsInShort(Object receiver)
Returns
true if the receiver represents a number and its value fits
in a Java short primitive without loss of precision, else false . |
long |
getArraySize(Object receiver)
Returns the array size of the receiver.
|
long |
getBufferSize(Object receiver)
Returns the buffer size of the receiver, in bytes.
|
Object |
getDeclaringMetaObject(Object receiver)
Returns declaring meta object.
|
Object |
getExceptionCause(Object receiver)
Returns the internal cause of the receiver.
|
int |
getExceptionExitStatus(Object receiver)
Returns exception exit status of the receiver.
|
Object |
getExceptionMessage(Object receiver)
Returns exception message of the receiver.
|
Object |
getExceptionStackTrace(Object receiver)
Returns the exception stack trace of the receiver that is of type exception.
|
ExceptionType |
getExceptionType(Object receiver)
Returns
exception type of the receiver. |
Object |
getExecutableName(Object receiver)
Returns executable name of the receiver.
|
static LibraryFactory<InteropLibrary> |
getFactory()
Returns the library factory for the interop library.
|
Object |
getHashEntriesIterator(Object receiver)
Returns the hash entries iterator for the receiver.
|
Object |
getHashKeysIterator(Object receiver)
Returns the hash keys iterator for the receiver.
|
long |
getHashSize(Object receiver)
Returns the number of receiver entries.
|
Object |
getHashValuesIterator(Object receiver)
Returns the hash values iterator for the receiver.
|
Object |
getIterator(Object receiver)
Returns the iterator for the receiver.
|
Object |
getIteratorNextElement(Object receiver)
Returns the next element in the iteration.
|
Class<? extends TruffleLanguage<?>> |
getLanguage(Object receiver)
Returns the the original language of the receiver value.
|
Object |
getMembers(Object receiver)
Short-cut for
getMembers(receiver, false) . |
Object |
getMembers(Object receiver,
boolean includeInternal)
Returns an array of member name strings.
|
Object |
getMetaObject(Object receiver)
Returns the metaobject that is associated with this value.
|
Object |
getMetaParents(Object receiver)
Returns an array like
InteropLibrary.hasArrayElements(Object) of metaobjects that are direct
parents (super types) of this metaobject. |
Object |
getMetaQualifiedName(Object metaObject)
Returns the qualified name of a metaobject as
string . |
Object |
getMetaSimpleName(Object metaObject)
Returns the simple name of a metaobject as
string . |
Object |
getScopeParent(Object receiver)
Returns the parent scope object if it
has the parent . |
SourceSection |
getSourceLocation(Object receiver)
Returns the declared source location of the receiver value.
|
static InteropLibrary |
getUncached()
Returns the uncached automatically dispatched version of the interop library.
|
static InteropLibrary |
getUncached(Object v)
Returns the uncached manually dispatched version of the interop library.
|
boolean |
hasArrayElements(Object receiver)
Returns
true if the receiver may have array elements. |
boolean |
hasBufferElements(Object receiver)
Returns
true if the receiver may have buffer elements. |
boolean |
hasDeclaringMetaObject(Object receiver)
Returns
true if the receiver has a declaring meta object. |
boolean |
hasExceptionCause(Object receiver)
Returns
true if the receiver is an exception with an attached internal cause. |
boolean |
hasExceptionMessage(Object receiver)
Returns
true if the receiver is an exception that has an exception message. |
boolean |
hasExceptionStackTrace(Object receiver)
Returns
true if the receiver is an exception and has a stack trace. |
boolean |
hasExecutableName(Object receiver)
Returns
true if the receiver has an executable name. |
boolean |
hasHashEntries(Object receiver)
Returns
true if the receiver may have hash entries. |
boolean |
hasIdentity(Object receiver)
Returns
true if and only if the receiver specifies identity, else
false . |
boolean |
hasIterator(Object receiver)
Returns
true if the receiver provides an iterator. |
boolean |
hasIteratorNextElement(Object receiver)
Returns
true if the receiver is an iterator which has more elements, else
false . |
boolean |
hasLanguage(Object receiver)
Returns
true if the receiver originates from a language, else false
. |
boolean |
hasMemberReadSideEffects(Object receiver,
String member)
Returns
true if reading a member may cause a side-effect. |
boolean |
hasMembers(Object receiver)
Returns
true if the receiver may have members. |
boolean |
hasMemberWriteSideEffects(Object receiver,
String member)
Returns
true if writing a member may cause a side-effect, besides the write
operation of the member. |
boolean |
hasMetaObject(Object receiver)
Returns
true if the receiver value has a metaobject associated. |
boolean |
hasMetaParents(Object receiver)
Returns
true if the receiver value is a metaobject
which has parents (super types). |
boolean |
hasScopeParent(Object receiver)
Returns
true if this scope has an enclosing parent scope, else
false . |
boolean |
hasSourceLocation(Object receiver)
Returns
true if the receiver value has a declared source location attached, else
false . |
int |
identityHashCode(Object receiver)
Returns an identity hash code for the receiver if it has
identity . |
Object |
instantiate(Object receiver,
Object... arguments)
Instantiates the receiver value with the given arguments.
|
Object |
invokeMember(Object receiver,
String member,
Object... arguments)
Invokes a member for a given receiver and arguments.
|
boolean |
isArrayElementExisting(Object receiver,
long index)
Returns true if the array element is existing.
|
boolean |
isArrayElementInsertable(Object receiver,
long index)
Returns
true if a given array element index is not existing and
insertable . |
boolean |
isArrayElementModifiable(Object receiver,
long index)
Returns
true if a given array element index is existing and
writable . |
boolean |
isArrayElementReadable(Object receiver,
long index)
Returns
true if a given array element is readable . |
boolean |
isArrayElementRemovable(Object receiver,
long index)
Returns
true if a given array element index is existing and
removable . |
boolean |
isArrayElementWritable(Object receiver,
long index)
Returns true if the array element is
modifiable or insertable . |
boolean |
isBoolean(Object receiver)
Returns
true if the receiver represents a boolean like value, else
false . |
boolean |
isBufferWritable(Object receiver)
Returns
true if the receiver is a modifiable buffer. |
boolean |
isDate(Object receiver)
Returns
true if this object represents a date, else false . |
boolean |
isDuration(Object receiver)
Returns
true if this object represents a duration, else false . |
boolean |
isException(Object receiver)
Returns
true if the receiver value represents a throwable exception/error}. |
boolean |
isExceptionIncompleteSource(Object receiver)
Returns
true if receiver value represents an incomplete source exception. |
boolean |
isExecutable(Object receiver)
Returns
true if the receiver represents an executable value, else
false . |
boolean |
isHashEntryExisting(Object receiver,
Object key)
Returns
true if mapping for a given key is existing. |
boolean |
isHashEntryInsertable(Object receiver,
Object key)
Returns
true if mapping for the specified key does not exist and is
writable . |
boolean |
isHashEntryModifiable(Object receiver,
Object key)
Returns
true if mapping for the specified key exists and is
writable . |
boolean |
isHashEntryReadable(Object receiver,
Object key)
Returns
true if mapping for the specified key exists and is
readable . |
boolean |
isHashEntryRemovable(Object receiver,
Object key)
Returns
true if mapping for the specified key exists and is removable. |
boolean |
isHashEntryWritable(Object receiver,
Object key)
|
boolean |
isIdentical(Object receiver,
Object other,
InteropLibrary otherInterop)
Returns
true if two values represent the the identical value, else
false . |
protected TriState |
isIdenticalOrUndefined(Object receiver,
Object other)
|
boolean |
isInstant(Object receiver)
Returns
true if the receiver represents an instant. |
boolean |
isInstantiable(Object receiver)
Returns
true if the receiver represents an instantiable value, else
false . |
boolean |
isIterator(Object receiver)
Returns
true if the receiver represents an iterator. |
boolean |
isMemberExisting(Object receiver,
String member)
Returns true if the member is existing.
|
boolean |
isMemberInsertable(Object receiver,
String member)
Returns
true if a given member is not existing and
writable . |
boolean |
isMemberInternal(Object receiver,
String member)
Returns true if a member is internal.
|
boolean |
isMemberInvocable(Object receiver,
String member)
Returns
true if a given member is invocable. |
boolean |
isMemberModifiable(Object receiver,
String member)
Returns
true if a given member is existing and
writable . |
boolean |
isMemberReadable(Object receiver,
String member)
Returns
true if a given member is readable . |
boolean |
isMemberRemovable(Object receiver,
String member)
Returns
true if a given member is existing and removable. |
boolean |
isMemberWritable(Object receiver,
String member)
Returns true if the member is
modifiable or
insertable . |
boolean |
isMetaInstance(Object receiver,
Object instance)
Returns
true if the given instance is of the provided receiver metaobject, else
false . |
boolean |
isMetaObject(Object receiver)
Returns
true if the receiver value represents a metaobject. |
boolean |
isNull(Object receiver)
Returns
true if the receiver represents a null like value, else
false . |
boolean |
isNumber(Object receiver)
Returns
true if the receiver represents a number value, else
false . |
boolean |
isPointer(Object receiver)
Returns
true if the receiver value represents a native pointer. |
boolean |
isScope(Object receiver)
Returns
true if the value represents a scope object, else false . |
boolean |
isString(Object receiver)
Returns
true if the receiver represents a string value, else
false . |
boolean |
isTime(Object receiver)
Returns
true if this object represents a time, else false . |
boolean |
isTimeZone(Object receiver)
Returns
true if this object represents a timezone, else false . |
static boolean |
isValidProtocolValue(Object value)
Utility to check whether a value is a valid interop protocol value.
|
static boolean |
isValidValue(Object receiver)
Utility to check whether a value is a valid interop value.
|
Object |
readArrayElement(Object receiver,
long index)
Reads the value of an array element by index.
|
byte |
readBufferByte(Object receiver,
long byteOffset)
Reads the byte from the receiver object at the given byte offset from the start of the
buffer.
|
double |
readBufferDouble(Object receiver,
ByteOrder order,
long byteOffset)
Reads the double from the receiver object in the given byte order at the given byte offset
from the start of the buffer.
|
float |
readBufferFloat(Object receiver,
ByteOrder order,
long byteOffset)
Reads the float from the receiver object in the given byte order at the given byte offset
from the start of the buffer.
|
int |
readBufferInt(Object receiver,
ByteOrder order,
long byteOffset)
Reads the int from the receiver object in the given byte order at the given byte offset from
the start of the buffer.
|
long |
readBufferLong(Object receiver,
ByteOrder order,
long byteOffset)
Reads the long from the receiver object in the given byte order at the given byte offset from
the start of the buffer.
|
short |
readBufferShort(Object receiver,
ByteOrder order,
long byteOffset)
Reads the short from the receiver object in the given byte order at the given byte offset
from the start of the buffer.
|
Object |
readHashValue(Object receiver,
Object key)
Reads the value for the specified key.
|
Object |
readHashValueOrDefault(Object receiver,
Object key,
Object defaultValue)
Reads the value for the specified key or returns the
defaultValue when the mapping
for the specified key does not exist or is not readable. |
Object |
readMember(Object receiver,
String member)
Reads the value of a given member.
|
void |
removeArrayElement(Object receiver,
long index)
Remove an array element from the receiver object.
|
void |
removeHashEntry(Object receiver,
Object key)
Removes the mapping for a given key from the receiver.
|
void |
removeMember(Object receiver,
String member)
Removes a member from the receiver object.
|
RuntimeException |
throwException(Object receiver)
Throws the receiver object as an exception of the source language, as if it was thrown by the
source language itself.
|
Object |
toDisplayString(Object receiver)
Converts the receiver to a human readable
string of the language. |
Object |
toDisplayString(Object receiver,
boolean allowSideEffects)
Converts the receiver to a human readable
string . |
void |
toNative(Object receiver)
Attempts to transform a
receiver to a value that represents a raw
native pointer. |
void |
writeArrayElement(Object receiver,
long index,
Object value)
Writes the value of an array element by index.
|
void |
writeBufferByte(Object receiver,
long byteOffset,
byte value)
Writes the given byte from the receiver object at the given byte offset from the start of the
buffer.
|
void |
writeBufferDouble(Object receiver,
ByteOrder order,
long byteOffset,
double value)
Writes the given double from the receiver object in the given byte order at the given byte
offset from the start of the buffer.
|
void |
writeBufferFloat(Object receiver,
ByteOrder order,
long byteOffset,
float value)
Writes the given float from the receiver object in the given byte order at the given byte
offset from the start of the buffer.
|
void |
writeBufferInt(Object receiver,
ByteOrder order,
long byteOffset,
int value)
Writes the given int from the receiver object in the given byte order at the given byte
offset from the start of the buffer.
|
void |
writeBufferLong(Object receiver,
ByteOrder order,
long byteOffset,
long value)
Writes the given long from the receiver object in the given byte order at the given byte
offset from the start of the buffer.
|
void |
writeBufferShort(Object receiver,
ByteOrder order,
long byteOffset,
short value)
Writes the given short from the receiver object in the given byte order at the given byte
offset from the start of the buffer.
|
void |
writeHashEntry(Object receiver,
Object key,
Object value)
Associates the specified value with the specified key in the receiver.
|
void |
writeMember(Object receiver,
String member,
Object value)
Writes the value of a given member.
|
accept, adoptChildren, atomic, atomic, copy, deepCopy, getChildren, getCost, getDebugProperties, getDescription, getEncapsulatingSourceSection, getLock, getParent, getRootNode, getSourceSection, insert, insert, isAdoptable, isSafelyReplaceableBy, notifyInserted, onReplace, replace, replace, reportPolymorphicSpecialize, toString
public boolean isNull(Object receiver)
true
if the receiver represents a null
like value, else
false
. Most object oriented languages have one or many values representing null
values. Invoking this message does not cause any observable side-effects.public boolean isBoolean(Object receiver)
true
if the receiver represents a boolean
like value, else
false
. Invoking this message does not cause any observable side-effects.InteropLibrary.asBoolean(Object)
public boolean asBoolean(Object receiver) throws UnsupportedMessageException
boolean
like value.UnsupportedMessageException
- if and only if InteropLibrary.isBoolean(Object)
returns
false
for the same receiver.InteropLibrary.isBoolean(Object)
public boolean isExecutable(Object receiver)
true
if the receiver represents an executable
value, else
false
. Functions, methods or closures are common examples of executable values.
Invoking this message does not cause any observable side-effects. Note that receiver values
which are executable
might also be
instantiable
.InteropLibrary.execute(Object, Object...)
public Object execute(Object receiver, Object... arguments) throws UnsupportedTypeException, ArityException, UnsupportedMessageException
UnsupportedTypeException
- if one of the arguments is not compatible to the executable
signature. The exception is thrown on best effort basis, dynamic languages may
throw their own exceptions if the arguments are wrong.ArityException
- if the number of expected arguments does not match the number of
actual arguments.UnsupportedMessageException
- if and only if InteropLibrary.isExecutable(Object)
returns
false
for the same receiver.InteropLibrary.isExecutable(Object)
public boolean hasExecutableName(Object receiver)
true
if the receiver has an executable name. Invoking this message does not
cause any observable side-effects. Returns false
by default.InteropLibrary.getExecutableName(Object)
public Object getExecutableName(Object receiver) throws UnsupportedMessageException
UnsupportedMessageException
when the
receiver is has no executable name
. The return value is an
interop value that is guaranteed to return true
for InteropLibrary.isString(Object)
.UnsupportedMessageException
InteropLibrary.hasExecutableName(Object)
public boolean hasDeclaringMetaObject(Object receiver)
true
if the receiver has a declaring meta object. The declaring meta object
is the meta object of the executable or meta object that declares the receiver value.
Invoking this message does not cause any observable side-effects. Returns false
by
default.InteropLibrary.getDeclaringMetaObject(Object)
public Object getDeclaringMetaObject(Object receiver) throws UnsupportedMessageException
UnsupportedMessageException
when the receiver is
has no declaring meta object
. The return value is an
interop value that is guaranteed to return true
for
InteropLibrary.isMetaObject(Object)
.UnsupportedMessageException
InteropLibrary.hasDeclaringMetaObject(Object)
public boolean isInstantiable(Object receiver)
true
if the receiver represents an instantiable
value, else
false
. Contructors or metaobjects
are typical
examples of instantiable values. Invoking this message does not cause any observable
side-effects. Note that receiver values which are executable
might also be instantiable
.InteropLibrary.instantiate(Object, Object...)
,
InteropLibrary.isMetaObject(Object)
public Object instantiate(Object receiver, Object... arguments) throws UnsupportedTypeException, ArityException, UnsupportedMessageException
UnsupportedTypeException
- if one of the arguments is not compatible to the executable
signatureArityException
- if the number of expected arguments does not match the number of
actual arguments.UnsupportedMessageException
- if and only if InteropLibrary.isInstantiable(Object)
returns
false
for the same receiver.InteropLibrary.isExecutable(Object)
public boolean isString(Object receiver)
true
if the receiver represents a string
value, else
false
. Invoking this message does not cause any observable side-effects.InteropLibrary.asString(Object)
public String asString(Object receiver) throws UnsupportedMessageException
string
like value.UnsupportedMessageException
- if and only if InteropLibrary.isString(Object)
returns
false
for the same receiver.InteropLibrary.isString(Object)
public TruffleString asTruffleString(Object receiver) throws UnsupportedMessageException
TruffleString
value if the receiver represents a string
like value.UnsupportedMessageException
- if and only if InteropLibrary.isString(Object)
returns
false
for the same receiver.InteropLibrary.isString(Object)
public boolean isNumber(Object receiver)
true
if the receiver represents a number
value, else
false
. Invoking this message does not cause any observable side-effects.InteropLibrary.fitsInByte(Object)
,
InteropLibrary.fitsInShort(Object)
,
InteropLibrary.fitsInInt(Object)
,
InteropLibrary.fitsInLong(Object)
,
InteropLibrary.fitsInBigInteger(Object)
,
InteropLibrary.fitsInFloat(Object)
,
InteropLibrary.fitsInDouble(Object)
,
InteropLibrary.asByte(Object)
,
InteropLibrary.asShort(Object)
,
InteropLibrary.asInt(Object)
,
InteropLibrary.asLong(Object)
,
InteropLibrary.asBigInteger(Object)
,
InteropLibrary.asFloat(Object)
,
InteropLibrary.asDouble(Object)
public boolean fitsInByte(Object receiver)
true
if the receiver represents a number
and its value fits
in a Java byte primitive without loss of precision, else false
. Invoking this
message does not cause any observable side-effects.InteropLibrary.isNumber(Object)
,
InteropLibrary.asByte(Object)
public boolean fitsInShort(Object receiver)
true
if the receiver represents a number
and its value fits
in a Java short primitive without loss of precision, else false
. Invoking this
message does not cause any observable side-effects.InteropLibrary.isNumber(Object)
,
InteropLibrary.asShort(Object)
public boolean fitsInInt(Object receiver)
true
if the receiver represents a number
and its value fits
in a Java int primitive without loss of precision, else false
. Invoking this
message does not cause any observable side-effects.InteropLibrary.isNumber(Object)
,
InteropLibrary.asInt(Object)
public boolean fitsInLong(Object receiver)
true
if the receiver represents a number
and its value fits
in a Java long primitive without loss of precision, else false
. Invoking this
message does not cause any observable side-effects.InteropLibrary.isNumber(Object)
,
InteropLibrary.asLong(Object)
public boolean fitsInBigInteger(Object receiver)
true
if the receiver represents a number
and its value fits
in a Java BigInteger without loss of precision, else false
. Invoking this
message does not cause any observable side-effects.InteropLibrary.isNumber(Object)
,
InteropLibrary.asBigInteger(Object)
public boolean fitsInFloat(Object receiver)
true
if the receiver represents a number
and its value fits
in a Java float primitive without loss of precision, else false
. Invoking this
message does not cause any observable side-effects.InteropLibrary.isNumber(Object)
,
InteropLibrary.asFloat(Object)
public boolean fitsInDouble(Object receiver)
true
if the receiver represents a number
and its value fits
in a Java double primitive without loss of precision, else false
. Invoking this
message does not cause any observable side-effects.InteropLibrary.isNumber(Object)
,
InteropLibrary.asDouble(Object)
public byte asByte(Object receiver) throws UnsupportedMessageException
UnsupportedMessageException
- if and only if the receiver is not a
InteropLibrary.isNumber(Object)
or it does not fit without loss of precision.InteropLibrary.isNumber(Object)
,
InteropLibrary.fitsInByte(Object)
public short asShort(Object receiver) throws UnsupportedMessageException
UnsupportedMessageException
- if and only if the receiver is not a
InteropLibrary.isNumber(Object)
or it does not fit without loss of precision.InteropLibrary.isNumber(Object)
,
InteropLibrary.fitsInShort(Object)
public int asInt(Object receiver) throws UnsupportedMessageException
UnsupportedMessageException
- if and only if the receiver is not a
InteropLibrary.isNumber(Object)
or it does not fit without loss of precision.InteropLibrary.isNumber(Object)
,
InteropLibrary.fitsInInt(Object)
public long asLong(Object receiver) throws UnsupportedMessageException
UnsupportedMessageException
- if and only if the receiver is not a
InteropLibrary.isNumber(Object)
or it does not fit without loss of precision.InteropLibrary.isNumber(Object)
,
InteropLibrary.fitsInLong(Object)
public BigInteger asBigInteger(Object receiver) throws UnsupportedMessageException
UnsupportedMessageException
- if and only if the receiver is not a
InteropLibrary.isNumber(Object)
or it does not fit without loss of precision.InteropLibrary.isNumber(Object)
,
InteropLibrary.fitsInBigInteger(Object)
public float asFloat(Object receiver) throws UnsupportedMessageException
UnsupportedMessageException
- if and only if the receiver is not a
InteropLibrary.isNumber(Object)
or it does not fit without loss of precision.InteropLibrary.isNumber(Object)
,
InteropLibrary.fitsInFloat(Object)
public double asDouble(Object receiver) throws UnsupportedMessageException
UnsupportedMessageException
- if and only if the receiver is not a
InteropLibrary.isNumber(Object)
or it does not fit without loss of precision.InteropLibrary.isNumber(Object)
,
InteropLibrary.fitsInDouble(Object)
public boolean hasMembers(Object receiver)
true
if the receiver may have members. Therefore, at least one of
InteropLibrary.readMember(Object, String)
, InteropLibrary.writeMember(Object, String, Object)
,
InteropLibrary.removeMember(Object, String)
, InteropLibrary.invokeMember(Object, String, Object...)
must
not throw UnsupportedMessageException
. Members are structural elements of a class.
For example, a method or field is a member of a class. Invoking this message does not cause
any observable side-effects. Returns false
by default.InteropLibrary.getMembers(Object, boolean)
,
InteropLibrary.isMemberReadable(Object, String)
,
InteropLibrary.isMemberModifiable(Object, String)
,
InteropLibrary.isMemberInvocable(Object, String)
,
InteropLibrary.isMemberInsertable(Object, String)
,
InteropLibrary.isMemberRemovable(Object, String)
,
InteropLibrary.readMember(Object, String)
,
InteropLibrary.writeMember(Object, String, Object)
,
InteropLibrary.removeMember(Object, String)
,
InteropLibrary.invokeMember(Object, String, Object...)
public Object getMembers(Object receiver, boolean includeInternal) throws UnsupportedMessageException
true
for
InteropLibrary.hasArrayElements(Object)
and every array element must be of type
string
. The member elements may also provide additional information
like source location
in case of scope
variables, etc.
The order of member names needs to be:
true
then internal member names are returned
as well. Internal members are implementation specific and should not be exposed to guest
language application. An example of internal members are internal slots in ECMAScript.UnsupportedMessageException
- if and only if the receiver does not have any
members
.InteropLibrary.hasMembers(Object)
public final Object getMembers(Object receiver) throws UnsupportedMessageException
getMembers(receiver, false)
. Invoking this
message does not cause any observable side-effects.UnsupportedMessageException
- if and only if the receiver has no
members
.InteropLibrary.getMembers(Object, boolean)
public boolean isMemberReadable(Object receiver, String member)
true
if a given member is readable
.
This method may only return true
if InteropLibrary.hasMembers(Object)
returns
true
as well and InteropLibrary.isMemberInsertable(Object, String)
returns
false
. Invoking this message does not cause any observable side-effects. Returns
false
by default.InteropLibrary.readMember(Object, String)
public Object readMember(Object receiver, String member) throws UnsupportedMessageException, UnknownIdentifierException
In case of a method-like member, we recommend that languages return a bound method (or an
artificial receiver-method binding) to improve cross-language portability. In this case, the
member should be readable
and
invocable
and the result of reading the member
should be executable
and bound to the receiver.
This message must have not observable side-effects unless
InteropLibrary.hasMemberReadSideEffects(Object, String)
returns true
.
UnsupportedMessageException
- if when the receiver does not support reading at all. An
empty receiver with no readable members supports the read operation (even though
there is nothing to read), therefore it throws UnknownIdentifierException
for all arguments instead.UnknownIdentifierException
- if the given member cannot be read, e.g. because it is not
(or no longer) readable
such as when
the member with the given name does not exist or has been removed.InteropLibrary.hasMemberReadSideEffects(Object, String)
public boolean isMemberModifiable(Object receiver, String member)
true
if a given member is existing and
writable
. This method may only return
true
if InteropLibrary.hasMembers(Object)
returns true
as well and
InteropLibrary.isMemberInsertable(Object, String)
returns false
. Invoking this message
does not cause any observable side-effects. Returns false
by default.InteropLibrary.writeMember(Object, String, Object)
public boolean isMemberInsertable(Object receiver, String member)
true
if a given member is not existing and
writable
. This method may only return
true
if InteropLibrary.hasMembers(Object)
returns true
as well and
InteropLibrary.isMemberExisting(Object, String)
returns false
. Invoking this message
does not cause any observable side-effects. Returns false
by default.InteropLibrary.writeMember(Object, String, Object)
public void writeMember(Object receiver, String member, Object value) throws UnsupportedMessageException, UnknownIdentifierException, UnsupportedTypeException
modifiable
, or not existing and
insertable
.
This method must have no observable side-effects other than the changed member unless
side-effects
are allowed.UnsupportedMessageException
- when the receiver does not support writing at all, e.g.
when it is immutable.UnknownIdentifierException
- if the given member is not
modifiable
nor
insertable
.UnsupportedTypeException
- if the provided value type is not allowed to be written.InteropLibrary.hasMemberWriteSideEffects(Object, String)
public boolean isMemberRemovable(Object receiver, String member)
true
if a given member is existing and removable. This method may only
return true
if InteropLibrary.hasMembers(Object)
returns true
as well and
InteropLibrary.isMemberInsertable(Object, String)
returns false
. Invoking this message
does not cause any observable side-effects. Returns false
by default.InteropLibrary.removeMember(Object, String)
public void removeMember(Object receiver, String member) throws UnsupportedMessageException, UnknownIdentifierException
removable
.
This method does not have not observable side-effects other than the removed member.UnsupportedMessageException
- when the receiver does not support removing at all, e.g.
when it is immutable.UnknownIdentifierException
- if the given member is not
InteropLibrary.isMemberRemovable(Object, String)
removable}, e.g. the receiver does not
have a member with the given name.InteropLibrary.isMemberRemovable(Object, String)
public boolean isMemberInvocable(Object receiver, String member)
true
if a given member is invocable. This method may only return
true
if InteropLibrary.hasMembers(Object)
returns true
as well and
InteropLibrary.isMemberInsertable(Object, String)
returns false
. Invoking this message
does not cause any observable side-effects. Returns false
by default.InteropLibrary.invokeMember(Object, String, Object...)
public Object invokeMember(Object receiver, String member, Object... arguments) throws UnsupportedMessageException, ArityException, UnknownIdentifierException, UnsupportedTypeException
UnknownIdentifierException
- if the given member does not exist or is not
invocable
.UnsupportedTypeException
- if one of the arguments is not compatible to the executable
signature. The exception is thrown on best effort basis, dynamic languages may
throw their own exceptions if the arguments are wrong.ArityException
- if the number of expected arguments does not match the number of
actual arguments.UnsupportedMessageException
- when the receiver does not support invoking at all, e.g.
when storing executable members is not allowed.InteropLibrary.isMemberInvocable(Object, String)
public boolean isMemberInternal(Object receiver, String member)
InteropLibrary.getMembers(Object, boolean)
by default. Internal members are only relevant to guest
language implementations and tools, but not to guest applications or embedders. An example of
internal members are internal slots in ECMAScript. Invoking this message does not cause any
observable side-effects. Returns false
by default.InteropLibrary.getMembers(Object, boolean)
public final boolean isMemberWritable(Object receiver, String member)
modifiable
or
insertable
.public final boolean isMemberExisting(Object receiver, String member)
modifiable
,
readable
, removable
or invocable
.public boolean hasMemberReadSideEffects(Object receiver, String member)
true
if reading a member may cause a side-effect. Invoking this message
does not cause any observable side-effects. A member read does not cause any side-effects by
default.
For instance in JavaScript a property read may have side-effects if the property has a getter function.
InteropLibrary.readMember(Object, String)
public boolean hasMemberWriteSideEffects(Object receiver, String member)
true
if writing a member may cause a side-effect, besides the write
operation of the member. Invoking this message does not cause any observable side-effects. A
member write does not cause any side-effects by default.
For instance in JavaScript a property write may have side-effects if the property has a setter function.
InteropLibrary.writeMember(Object, String, Object)
public boolean hasHashEntries(Object receiver)
true
if the receiver may have hash entries. Therefore, at least one of
InteropLibrary.readHashValue(Object, Object)
, InteropLibrary.writeHashEntry(Object, Object, Object)
,
InteropLibrary.removeHashEntry(Object, Object)
must not throw UnsupportedMessageException
.
For example, the contents of a map data structure could be interpreted as hash elements.
Invoking this message does not cause any observable side-effects. Returns false
by
default.InteropLibrary.getHashEntriesIterator(Object)
,
InteropLibrary.getHashSize(Object)
,
InteropLibrary.isHashEntryReadable(Object, Object)
,
InteropLibrary.isHashEntryWritable(Object, Object)
,
InteropLibrary.isHashEntryInsertable(Object, Object)
,
InteropLibrary.isHashEntryRemovable(Object, Object)
,
InteropLibrary.readHashValue(Object, Object)
,
InteropLibrary.readHashValueOrDefault(Object, Object, Object)
,
InteropLibrary.writeHashEntry(Object, Object, Object)
,
InteropLibrary.removeHashEntry(Object, Object)
public long getHashSize(Object receiver) throws UnsupportedMessageException
UnsupportedMessageException
- if and only if InteropLibrary.hasHashEntries(Object)
returns
false
.public boolean isHashEntryReadable(Object receiver, Object key)
true
if mapping for the specified key exists and is
readable
. This method may only return true
if
InteropLibrary.hasHashEntries(Object)
returns true
as well and
InteropLibrary.isHashEntryInsertable(Object, Object)
returns false
. Invoking this message
does not cause any observable side-effects. Returns false
by default.InteropLibrary.readHashValue(Object, Object)
public Object readHashValue(Object receiver, Object key) throws UnsupportedMessageException, UnknownKeyException
UnsupportedMessageException
- if the receiver does not support reading at all. An empty
receiver with no readable hash entries supports the read operation (even though
there is nothing to read), therefore it throws UnknownKeyException
for
all arguments instead.UnknownKeyException
- if mapping for the specified key is not
readable
, e.g. when the hash does
not contain specified key.InteropLibrary.isHashEntryReadable(Object, Object)
,
InteropLibrary.readHashValueOrDefault(Object, Object, Object)
public Object readHashValueOrDefault(Object receiver, Object key, Object defaultValue) throws UnsupportedMessageException
defaultValue
when the mapping
for the specified key does not exist or is not readable.UnsupportedMessageException
- if the receiver does not support reading at all. An empty
receiver with no readable hash entries supports the read operation (even though
there is nothing to read), therefore it returns the defaultValue
for all
arguments instead.InteropLibrary.isHashEntryReadable(Object, Object)
,
InteropLibrary.readHashValue(Object, Object)
public boolean isHashEntryModifiable(Object receiver, Object key)
true
if mapping for the specified key exists and is
writable
. This method may only return
true
if InteropLibrary.hasHashEntries(Object)
returns true
as well and
InteropLibrary.isHashEntryInsertable(Object, Object)
returns false
. Invoking this message
does not cause any observable side-effects. Returns false
by default.InteropLibrary.writeHashEntry(Object, Object, Object)
public boolean isHashEntryInsertable(Object receiver, Object key)
true
if mapping for the specified key does not exist and is
writable
. This method may only return
true
if InteropLibrary.hasHashEntries(Object)
returns true
as well and
InteropLibrary.isHashEntryExisting(Object, Object)
returns false
. Invoking this message
does not cause any observable side-effects. Returns false
by default.InteropLibrary.writeHashEntry(Object, Object, Object)
public void writeHashEntry(Object receiver, Object key, Object value) throws UnsupportedMessageException, UnknownKeyException, UnsupportedTypeException
modifiable
, or not
existing and insertable
.UnsupportedMessageException
- when the receiver does not support writing at all, e.g.
when it is immutable.UnknownKeyException
- if mapping for the specified key is not
modifiable
nor
insertable
.UnsupportedTypeException
- if the provided key type or value type is not allowed to be
written.public boolean isHashEntryRemovable(Object receiver, Object key)
true
if mapping for the specified key exists and is removable. This method
may only return true
if InteropLibrary.hasHashEntries(Object)
returns true
as well
and InteropLibrary.isHashEntryInsertable(Object, Object)
returns false
. Invoking this
message does not cause any observable side-effects. Returns false
by default.InteropLibrary.removeHashEntry(Object, Object)
public void removeHashEntry(Object receiver, Object key) throws UnsupportedMessageException, UnknownKeyException
removable
.UnsupportedMessageException
- when the receiver does not support removing at all, e.g.
when it is immutable.UnknownKeyException
- if the given mapping is not
removable
, e.g. the receiver does
not have a mapping for given key.InteropLibrary.isHashEntryRemovable(Object, Object)
public boolean isHashEntryExisting(Object receiver, Object key)
true
if mapping for a given key is existing. The mapping is existing if it is
modifiable
,
readable
or
removable
.public Object getHashEntriesIterator(Object receiver) throws UnsupportedMessageException
iterator
of array
elements. The
first array element is a key, the second array element is an associated value. Array returned
by the iterator may be modifiable but detached from the hash, updating the array elements may
not update the hash. So even if array elements are
modifiable
always use
InteropLibrary.writeHashEntry(Object, Object, Object)
to update the hash mapping.UnsupportedMessageException
- if and only if InteropLibrary.hasHashEntries(Object)
returns
false
for the same receiver.public Object getHashKeysIterator(Object receiver) throws UnsupportedMessageException
iterator
.UnsupportedMessageException
- if and only if InteropLibrary.hasHashEntries(Object)
returns
false
for the same receiver.public Object getHashValuesIterator(Object receiver) throws UnsupportedMessageException
iterator
.UnsupportedMessageException
- if and only if InteropLibrary.hasHashEntries(Object)
returns
false
for the same receiver.public boolean hasArrayElements(Object receiver)
true
if the receiver may have array elements. Therefore, At least one of
InteropLibrary.readArrayElement(Object, long)
, InteropLibrary.writeArrayElement(Object, long, Object)
,
InteropLibrary.removeArrayElement(Object, long)
must not throw {#link
UnsupportedMessageException
. For example, the contents of an array or list
datastructure could be interpreted as array elements. Invoking this message does not cause
any observable side-effects. Returns false
by default.InteropLibrary.getArraySize(Object)
public Object readArrayElement(Object receiver, long index) throws UnsupportedMessageException, InvalidArrayIndexException
UnsupportedMessageException
- when the receiver does not support reading at all. An
empty receiver with no readable array elements supports the read operation (even
though there is nothing to read), therefore it throws
UnknownIdentifierException
for all arguments instead.InvalidArrayIndexException
- if the given index is not
readable
, e.g. when the index is
invalid or the index is out of bounds.public long getArraySize(Object receiver) throws UnsupportedMessageException
UnsupportedMessageException
- if and only if InteropLibrary.hasArrayElements(Object)
returns
false
.public boolean isArrayElementReadable(Object receiver, long index)
true
if a given array element is readable
. This method may only return true
if InteropLibrary.hasArrayElements(Object)
returns true
as well. Invoking this message does not cause any observable
side-effects. Returns false
by default.InteropLibrary.readArrayElement(Object, long)
public void writeArrayElement(Object receiver, long index, Object value) throws UnsupportedMessageException, UnsupportedTypeException, InvalidArrayIndexException
modifiable
, or not existing and
insertable
.
This method must have not observable side-effects other than the changed array element.UnsupportedMessageException
- when the receiver does not support writing at all, e.g.
when it is immutable.InvalidArrayIndexException
- if the given index is not
insertable
nor
modifiable
, e.g. when the index
is invalid or the index is out of bounds and the array does not support growing.UnsupportedTypeException
- if the provided value type is not allowed to be written.public void removeArrayElement(Object receiver, long index) throws UnsupportedMessageException, InvalidArrayIndexException
removable
. This method may only
return true
if InteropLibrary.hasArrayElements(Object)
returns true
as
well and InteropLibrary.isArrayElementInsertable(Object, long)
returns false
.
This method does not have observable side-effects other than the removed array element and
shift of remaining elements. If shifting is not supported then the array might allow only
removal of last element.UnsupportedMessageException
- when the receiver does not support removing at all, e.g.
when it is immutable.InvalidArrayIndexException
- if the given index is not
removable
, e.g. when the index is
invalid, the index is out of bounds, or the array does not support shifting of
remaining elements.InteropLibrary.isArrayElementRemovable(Object, long)
public boolean isArrayElementModifiable(Object receiver, long index)
true
if a given array element index is existing and
writable
. This method may only return
true
if InteropLibrary.hasArrayElements(Object)
returns true
as well and
InteropLibrary.isArrayElementInsertable(Object, long)
returns false
. Invoking this
message does not cause any observable side-effects. Returns false
by default.public boolean isArrayElementInsertable(Object receiver, long index)
true
if a given array element index is not existing and
insertable
. This method may only return
true
if InteropLibrary.hasArrayElements(Object)
returns true
as well and
InteropLibrary.isArrayElementExisting(Object, long)
} returns false
. Invoking this
message does not cause any observable side-effects. Returns false
by default.public boolean isArrayElementRemovable(Object receiver, long index)
true
if a given array element index is existing and
removable
. This method may only return
true
if InteropLibrary.hasArrayElements(Object)
returns true
as well and
InteropLibrary.isArrayElementInsertable(Object, long)
} returns false
. Invoking this
message does not cause any observable side-effects. Returns false
by default.InteropLibrary.removeArrayElement(Object, long)
public final boolean isArrayElementWritable(Object receiver, long index)
modifiable
or insertable
.public final boolean isArrayElementExisting(Object receiver, long index)
modifiable
,
readable
or
removable
.public boolean hasBufferElements(Object receiver)
true
if the receiver may have buffer elements.
If this message returns true
, then InteropLibrary.getBufferSize(Object)
,
InteropLibrary.readBufferByte(Object, long)
, InteropLibrary.readBufferShort(Object, ByteOrder, long)
,
InteropLibrary.readBufferInt(Object, ByteOrder, long)
,
InteropLibrary.readBufferLong(Object, ByteOrder, long)
,
InteropLibrary.readBufferFloat(Object, ByteOrder, long)
and
InteropLibrary.readBufferDouble(Object, ByteOrder, long)
must not throw
UnsupportedMessageException
.
Invoking this message does not cause any observable side-effects.
By default, it returns false
.
public boolean isBufferWritable(Object receiver) throws UnsupportedMessageException
true
if the receiver is a modifiable buffer.
If this message returns true
, then InteropLibrary.getBufferSize(Object)
,
InteropLibrary.writeBufferByte(Object, long, byte)
,
InteropLibrary.writeBufferShort(Object, ByteOrder, long, short)
,
InteropLibrary.writeBufferInt(Object, ByteOrder, long, int)
,
InteropLibrary.writeBufferLong(Object, ByteOrder, long, long)
,
InteropLibrary.writeBufferFloat(Object, ByteOrder, long, float)
and
InteropLibrary.writeBufferDouble(Object, ByteOrder, long, double)
must not throw
UnsupportedMessageException
.
Invoking this message does not cause any observable side-effects.
By default, it returns false
if InteropLibrary.hasBufferElements(Object)
return
true
, and throws UnsupportedMessageException
otherwise.
UnsupportedMessageException
- if and only if InteropLibrary.hasBufferElements(Object)
returns
false
public long getBufferSize(Object receiver) throws UnsupportedMessageException
Invoking this message does not cause any observable side-effects.
UnsupportedMessageException
- if and only if InteropLibrary.hasBufferElements(Object)
returns
false
public byte readBufferByte(Object receiver, long byteOffset) throws UnsupportedMessageException, InvalidBufferOffsetException
The access is not guaranteed to be atomic. Therefore, this message is not thread-safe.
Invoking this message does not cause any observable side-effects.
InvalidBufferOffsetException
- if and only if
byteOffset < 0 || byteOffset >=
InteropLibrary.getBufferSize(Object)
UnsupportedMessageException
- if and only if either InteropLibrary.hasBufferElements(Object)
returns false
returns false
public void writeBufferByte(Object receiver, long byteOffset, byte value) throws UnsupportedMessageException, InvalidBufferOffsetException
The access is not guaranteed to be atomic. Therefore, this message is not thread-safe.
InvalidBufferOffsetException
- if and only if
byteOffset < 0 || byteOffset >=
InteropLibrary.getBufferSize(Object)
UnsupportedMessageException
- if and only if either InteropLibrary.hasBufferElements(Object)
or InteropLibrary.isBufferWritable(java.lang.Object)
returns false
public short readBufferShort(Object receiver, ByteOrder order, long byteOffset) throws UnsupportedMessageException, InvalidBufferOffsetException
Unaligned accesses are supported.
The access is not guaranteed to be atomic. Therefore, this message is not thread-safe.
Invoking this message does not cause any observable side-effects.
InvalidBufferOffsetException
- if and only if
byteOffset < 0 || byteOffset >= InteropLibrary.getBufferSize(Object)
- 1
UnsupportedMessageException
- if and only if InteropLibrary.hasBufferElements(Object)
returns
false
public void writeBufferShort(Object receiver, ByteOrder order, long byteOffset, short value) throws UnsupportedMessageException, InvalidBufferOffsetException
Unaligned accesses are supported.
The access is not guaranteed to be atomic. Therefore, this message is not thread-safe.
InvalidBufferOffsetException
- if and only if
byteOffset < 0 || byteOffset >= InteropLibrary.getBufferSize(Object)
- 1
UnsupportedMessageException
- if and only if either InteropLibrary.hasBufferElements(Object)
or InteropLibrary.isBufferWritable(java.lang.Object)
returns false
public int readBufferInt(Object receiver, ByteOrder order, long byteOffset) throws UnsupportedMessageException, InvalidBufferOffsetException
Unaligned accesses are supported.
The access is not guaranteed to be atomic. Therefore, this message is not thread-safe.
Invoking this message does not cause any observable side-effects.
InvalidBufferOffsetException
- if and only if
byteOffset < 0 || byteOffset >= InteropLibrary.getBufferSize(Object)
- 3
UnsupportedMessageException
- if and only if InteropLibrary.hasBufferElements(Object)
returns
false
public void writeBufferInt(Object receiver, ByteOrder order, long byteOffset, int value) throws UnsupportedMessageException, InvalidBufferOffsetException
Unaligned accesses are supported.
The access is not guaranteed to be atomic. Therefore, this message is not thread-safe.
InvalidBufferOffsetException
- if and only if
byteOffset < 0 || byteOffset >= InteropLibrary.getBufferSize(Object)
- 3
UnsupportedMessageException
- if and only if either InteropLibrary.hasBufferElements(Object)
or InteropLibrary.isBufferWritable(java.lang.Object)
returns false
public long readBufferLong(Object receiver, ByteOrder order, long byteOffset) throws UnsupportedMessageException, InvalidBufferOffsetException
Unaligned accesses are supported.
The access is not guaranteed to be atomic. Therefore, this message is not thread-safe.
Invoking this message does not cause any observable side-effects.
InvalidBufferOffsetException
- if and only if
byteOffset < 0 || byteOffset >= InteropLibrary.getBufferSize(Object)
- 7
UnsupportedMessageException
- if and only if InteropLibrary.hasBufferElements(Object)
returns
false
public void writeBufferLong(Object receiver, ByteOrder order, long byteOffset, long value) throws UnsupportedMessageException, InvalidBufferOffsetException
Unaligned accesses are supported.
The access is not guaranteed to be atomic. Therefore, this message is not thread-safe.
InvalidBufferOffsetException
- if and only if
byteOffset < 0 || byteOffset >= InteropLibrary.getBufferSize(Object)
- 7
UnsupportedMessageException
- if and only if either InteropLibrary.hasBufferElements(Object)
or InteropLibrary.isBufferWritable(java.lang.Object)
returns false
public float readBufferFloat(Object receiver, ByteOrder order, long byteOffset) throws UnsupportedMessageException, InvalidBufferOffsetException
Unaligned accesses are supported.
The access is not guaranteed to be atomic. Therefore, this message is not thread-safe.
Invoking this message does not cause any observable side-effects.
InvalidBufferOffsetException
- if and only if
byteOffset < 0 || byteOffset >= InteropLibrary.getBufferSize(Object)
- 3
UnsupportedMessageException
- if and only if InteropLibrary.hasBufferElements(Object)
returns
false
public void writeBufferFloat(Object receiver, ByteOrder order, long byteOffset, float value) throws UnsupportedMessageException, InvalidBufferOffsetException
Unaligned accesses are supported.
The access is not guaranteed to be atomic. Therefore, this message is not thread-safe.
InvalidBufferOffsetException
- if and only if
byteOffset < 0 || byteOffset >= InteropLibrary.getBufferSize(Object)
- 3
UnsupportedMessageException
- if and only if either InteropLibrary.hasBufferElements(Object)
or InteropLibrary.isBufferWritable(java.lang.Object)
returns false
public double readBufferDouble(Object receiver, ByteOrder order, long byteOffset) throws UnsupportedMessageException, InvalidBufferOffsetException
Unaligned accesses are supported.
The access is not guaranteed to be atomic. Therefore, this message is not thread-safe.
Invoking this message does not cause any observable side-effects.
InvalidBufferOffsetException
- if and only if
byteOffset < 0 || byteOffset >= InteropLibrary.getBufferSize(Object)
- 7
UnsupportedMessageException
- if and only if InteropLibrary.hasBufferElements(Object)
returns
false
public void writeBufferDouble(Object receiver, ByteOrder order, long byteOffset, double value) throws UnsupportedMessageException, InvalidBufferOffsetException
Unaligned accesses are supported.
The access is not guaranteed to be atomic. Therefore, this message is not thread-safe.
InvalidBufferOffsetException
- if and only if
byteOffset < 0 || byteOffset >= InteropLibrary.getBufferSize(Object)
- 7
UnsupportedMessageException
- if and only if either InteropLibrary.hasBufferElements(Object)
or InteropLibrary.isBufferWritable(java.lang.Object)
returns false
public boolean isPointer(Object receiver)
true
if the receiver value represents a native pointer. Native pointers
are represented as 64 bit pointers. Invoking this message does not cause any observable
side-effects. Returns false
by default.
It is expected that objects should only return true
if the native pointer value
corresponding to this object already exists, and obtaining it is a cheap operation. If an
object can be transformed to a pointer representation, but this hasn't happened yet, the
object is expected to return false
with InteropLibrary.isPointer(Object)
, and wait for
the InteropLibrary.toNative(Object)
message to trigger the transformation.
InteropLibrary.asPointer(Object)
,
InteropLibrary.toNative(Object)
public long asPointer(Object receiver) throws UnsupportedMessageException
UnsupportedMessageException
- if and only if InteropLibrary.isPointer(Object)
returns
false
for the same receiver.InteropLibrary.isPointer(Object)
public void toNative(Object receiver)
receiver
to a value that represents a raw
native pointer. After a successful transformation, the provided receiver returns true for
InteropLibrary.isPointer(Object)
and can be unwrapped using the InteropLibrary.asPointer(Object)
message.
If transformation cannot be done InteropLibrary.isPointer(Object)
will keep returning false.InteropLibrary.isPointer(Object)
,
InteropLibrary.asPointer(Object)
public Instant asInstant(Object receiver) throws UnsupportedMessageException
instant
. If a value is an instant then it is also a date
,
time
and timezone
. Using this method may
be more efficient than reconstructing the timestamp from the date, time and timezone data.
Implementers should implement this method if they can provide a more efficient conversion to Instant than reconstructing it from date, time and timezone date. Implementers must ensure that the following Java code snippet always holds:
ZoneId zone = getTimeZone(receiver); LocalDate date = getDate(receiver); LocalTime time = getTime(receiver); assert ZonedDateTime.of(date, time, zone).toInstant().equals(getInstant(receiver));
UnsupportedMessageException
- if and only if InteropLibrary.isInstant(Object)
returns
false
.InteropLibrary.isDate(Object)
,
InteropLibrary.isTime(Object)
,
InteropLibrary.isTimeZone(Object)
public final boolean isInstant(Object receiver)
true
if the receiver represents an instant. If a value is an instant
then it is also a date
, time
and
timezone
.
This method is short-hand for:
isDate(v) &&isTime
(v) &&isTimeZone
(v)
InteropLibrary.isDate(Object)
,
InteropLibrary.isTime(Object)
,
InteropLibrary.isInstant(Object)
,
InteropLibrary.asInstant(Object)
public boolean isTimeZone(Object receiver)
true
if this object represents a timezone, else false
. The
interpretation of timezone objects may vary:
InteropLibrary.isDate(Object)
and InteropLibrary.isTime(Object)
return true
, then the
returned date or time information is aware of this timezone.
InteropLibrary.isDate(Object)
and InteropLibrary.isTime(Object)
returns false
, then
it represents just timezone information.
fixed
zone
only. If this rule is violated then an AssertionError
is thrown if assertions
are enabled.
If this method is implemented then also InteropLibrary.asTimeZone(Object)
must be implemented.
InteropLibrary.asTimeZone(Object)
,
InteropLibrary.asInstant(Object)
public ZoneId asTimeZone(Object receiver) throws UnsupportedMessageException
timezone
.UnsupportedMessageException
- if and only if InteropLibrary.isTimeZone(Object)
returns
false
.InteropLibrary.isTimeZone(Object)
public boolean isDate(Object receiver)
true
if this object represents a date, else false
. If the
receiver is also a timezone
then the date is aware, otherwise it
is naive.InteropLibrary.asDate(Object)
public LocalDate asDate(Object receiver) throws UnsupportedMessageException
date
. The
returned date is either aware if the receiver has a timezone
otherwise it is naive.UnsupportedMessageException
- if and only if InteropLibrary.isDate(Object)
returns
false
.InteropLibrary.isDate(Object)
public boolean isTime(Object receiver)
true
if this object represents a time, else false
. If the
receiver is also a timezone
then the time is aware, otherwise it
is naive.InteropLibrary.asTime(Object)
public LocalTime asTime(Object receiver) throws UnsupportedMessageException
time
. The
returned time is either aware if the receiver has a timezone
otherwise it is naive.UnsupportedMessageException
- if and only if InteropLibrary.isTime(Object)
returns
false
.InteropLibrary.isTime(Object)
public boolean isDuration(Object receiver)
true
if this object represents a duration, else false
.Duration
,
InteropLibrary.asDuration(Object)
public Duration asDuration(Object receiver) throws UnsupportedMessageException
duration
.UnsupportedMessageException
- if and only if InteropLibrary.isDuration(Object)
returns
false
.InteropLibrary.isDuration(Object)
public boolean isException(Object receiver)
true
if the receiver value represents a throwable exception/error}.
Invoking this message does not cause any observable side-effects. Returns false
by default.
Objects must only return true
if they support InteropLibrary.throwException(java.lang.Object)
as well.
If this method is implemented then also InteropLibrary.throwException(Object)
must be implemented.
The following simplified TryCatchNode
shows how the exceptions should be handled by
languages.
static final class TryCatchNode extends StatementNode { @Node
.Child privateBlockNode
block; @Node
.Child privateBlockNode
catchBlock; @Node
.Child privateBlockNode
finallyBlock; private finalBranchProfile
exceptionProfile; TryCatchNode(BlockNode
block,BlockNode
catchBlock,BlockNode
finallyBlock) { this.block = block; this.catchBlock = catchBlock; this.finallyBlock = finallyBlock; this.exceptionProfile =BranchProfile
.create(); } @Override
void executeVoid(VirtualFrame
frame) {RuntimeException
rethrowException = null; try { block.executeVoid(frame); } catch (AbstractTruffleException
ex) { exceptionProfile.enter(); try { if (catchBlock != null) { catchBlock.executeVoid(frame); // do not rethrow if handled rethrowException = null; } else { // rethrow if not handled rethrowException = ex; } } catch (AbstractTruffleException
e) { rethrowException = e; } } catch (ControlFlowException
cfe) { // run finally blocks for control flow rethrowException = cfe; } // Java finally blocks that execute nodes are not allowed for // compilation as code in finally blocks is duplicated // by the Java bytecode compiler. This can lead to // exponential code growth in worst cases. if (finallyBlock != null) { finallyBlock.executeVoid(frame); } if (rethrowException != null) { throw rethrowException; } } }
InteropLibrary.throwException(Object)
,
AbstractTruffleException
public RuntimeException throwException(Object receiver) throws UnsupportedMessageException
InteropLibrary.isException(Object)
must be implemented.
Any interop value can be an exception value and export InteropLibrary.throwException(Object)
. The
exception thrown by this message must extend
AbstractTruffleException
. In future versions this
contract will be enforced using an assertion.
For a sample TryCatchNode
implementation see isException
.
UnsupportedMessageException
- if and only if InteropLibrary.isException(Object)
returns
false
for the same receiver.InteropLibrary.isException(Object)
public ExceptionType getExceptionType(Object receiver) throws UnsupportedMessageException
exception type
of the receiver. Throws
UnsupportedMessageException
when the receiver is not an exception
.
For a sample TryCatchNode
implementation see isException
.
UnsupportedMessageException
InteropLibrary.isException(Object)
,
ExceptionType
public boolean isExceptionIncompleteSource(Object receiver) throws UnsupportedMessageException
true
if receiver value represents an incomplete source exception. Throws
UnsupportedMessageException
when the receiver is not an exception
or the exception is not a ExceptionType.PARSE_ERROR
.UnsupportedMessageException
InteropLibrary.isException(Object)
,
InteropLibrary.getExceptionType(Object)
public int getExceptionExitStatus(Object receiver) throws UnsupportedMessageException
UnsupportedMessageException
when the receiver is not an exception
of the
exit type
. See
Context Exit
for further information. A return value zero indicates that the execution of the application
was successful, a non-zero value that it failed. The individual interpretation of non-zero
values depends on the application.UnsupportedMessageException
InteropLibrary.isException(Object)
,
InteropLibrary.getExceptionType(Object)
,
ExceptionType
public boolean hasExceptionCause(Object receiver)
true
if the receiver is an exception with an attached internal cause.
Invoking this message does not cause any observable side-effects. Returns false
by
default.InteropLibrary.isException(Object)
,
InteropLibrary.getExceptionCause(Object)
public Object getExceptionCause(Object receiver) throws UnsupportedMessageException
UnsupportedMessageException
when
the receiver is not an exception
or has no internal cause. The
return value of this message is guaranteed to return true
for
InteropLibrary.isException(Object)
.UnsupportedMessageException
InteropLibrary.isException(Object)
,
InteropLibrary.hasExceptionCause(Object)
public boolean hasExceptionMessage(Object receiver)
true
if the receiver is an exception that has an exception message. Invoking
this message does not cause any observable side-effects. Returns false
by default.InteropLibrary.isException(Object)
,
InteropLibrary.getExceptionMessage(Object)
public Object getExceptionMessage(Object receiver) throws UnsupportedMessageException
UnsupportedMessageException
when
the receiver is not an exception
or has no exception message.
The return value of this message is guaranteed to return true
for
InteropLibrary.isString(Object)
.UnsupportedMessageException
InteropLibrary.isException(Object)
,
InteropLibrary.hasExceptionMessage(Object)
public boolean hasExceptionStackTrace(Object receiver)
true
if the receiver is an exception and has a stack trace. Invoking this
message does not cause any observable side-effects. Returns false
by default.InteropLibrary.isException(Object)
,
InteropLibrary.getExceptionStackTrace(Object)
public Object getExceptionStackTrace(Object receiver) throws UnsupportedMessageException
array
of objects with potentially
executable name
, declaring meta object
and source location
of the caller.
Throws UnsupportedMessageException
when the receiver is not an
exception
or has no stack trace. Invoking this message or
accessing the stack trace elements array must not cause any observable side-effects.
The default implementation of InteropLibrary.getExceptionStackTrace(Object)
calls
TruffleStackTrace.getStackTrace(Throwable)
on the underlying exception object and
TruffleStackTraceElement.getGuestObject()
to access an interop capable object of the
underlying stack trace element.
UnsupportedMessageException
InteropLibrary.isException(Object)
,
InteropLibrary.hasExceptionStackTrace(Object)
public boolean hasIterator(Object receiver)
true
if the receiver provides an iterator. For example, an array or a list
provide an iterator over their content. Invoking this message does not cause any observable
side-effects. By default returns true
for receivers that have
array elements
.InteropLibrary.getIterator(Object)
public Object getIterator(Object receiver) throws UnsupportedMessageException
iterator
. Invoking this message does not cause any observable
side-effects.UnsupportedMessageException
- if and only if InteropLibrary.hasIterator(Object)
returns
false
for the same receiver.public boolean isIterator(Object receiver)
true
if the receiver represents an iterator. Invoking this message does not
cause any observable side-effects. Returns false
by default.InteropLibrary.hasIterator(Object)
,
InteropLibrary.getIterator(Object)
public boolean hasIteratorNextElement(Object receiver) throws UnsupportedMessageException
true
if the receiver is an iterator which has more elements, else
false
. Multiple calls to the InteropLibrary.hasIteratorNextElement(Object)
might lead to
different results if the underlying data structure is modified.
The following example shows how the hasIteratorNextElement
message can be emulated in languages where iterators only have a next
method and throw an exception if there are no further elements.
@ExportLibrary(InteropLibrary.class) abstract class InteropIterator implements TruffleObject { @SuppressWarnings("serial") public static final class Stop extends AbstractTruffleException { } private static final Object STOP = new Object(); private Object next; protected InteropIterator() { } protected abstract Object next() throws Stop; @ExportMessage @SuppressWarnings("static-method") boolean isIterator() { return true; } @ExportMessage boolean hasIteratorNextElement() { fetchNext(); return next != STOP; } @ExportMessage Object getIteratorNextElement() throws StopIterationException { fetchNext(); Object res = next; if (res == STOP) { throw StopIterationException.create(); } else { next = null; } return res; } private void fetchNext() { if (next == null) { try { next = next(); } catch (Stop stop) { next = STOP; } } } }
UnsupportedMessageException
- if and only if InteropLibrary.isIterator(Object)
returns
false
for the same receiver.InteropLibrary.isIterator(Object)
,
InteropLibrary.getIteratorNextElement(Object)
public Object getIteratorNextElement(Object receiver) throws UnsupportedMessageException, StopIterationException
InteropLibrary.getIteratorNextElement(Object)
may throw the StopIterationException
despite
the InteropLibrary.hasIteratorNextElement(Object)
returned true
.UnsupportedMessageException
- if InteropLibrary.isIterator(Object)
returns false
for
the same receiver or when the underlying iterator element exists but is not
readable.StopIterationException
- if the iteration has no more elements. Even if the
StopIterationException
was thrown it might not be thrown again by a next
InteropLibrary.getIteratorNextElement(Object)
invocation on the same receiver due to a
modification of an underlying iterable.InteropLibrary.isIterator(Object)
,
InteropLibrary.hasIteratorNextElement(Object)
public boolean hasSourceLocation(Object receiver)
true
if the receiver value has a declared source location attached, else
false
. Returning a source location for a value is optional and typically impacts
the capabilities of tools like debuggers to jump to the declaration of a value.
Examples for values that may provide a source location:
Metaobjects
like classes or types.
executables
, like functions, closures or
promises.
This method must not cause any observable side-effects. If this method is implemented then
also InteropLibrary.getSourceLocation(Object)
must be implemented.
InteropLibrary.getSourceLocation(Object)
public SourceSection getSourceLocation(Object receiver) throws UnsupportedMessageException
UnsupportedMessageException
if the value does not have a declared source location.
See InteropLibrary.hasSourceLocation(Object)
for further details on potential interpretations.
Throws UnsupportedMessageException
by default.
This method must not cause any observable side-effects. If this method is implemented then
also InteropLibrary.hasSourceLocation(Object)
must be implemented.
UnsupportedMessageException
- if and only if InteropLibrary.hasSourceLocation(Object)
returns
false
for the same receiver.public boolean hasLanguage(Object receiver)
true
if the receiver originates from a language, else false
. Primitive values or other shared interop value representations that are not associated with
a language may return false
. Values that originate from a language should return
true
. Returns false
by default.
The associated language allows tools to identify the original language of a value. If an
instrument requests a
language view
then values that are already associated with a language will just return the
same value. Otherwise TruffleLanguage.getLanguageView(Object, Object)
will be invoked
on the language. The returned language may be also exposed to embedders in the future.
This method must not cause any observable side-effects. If this method is implemented then
also InteropLibrary.getLanguage(Object)
and InteropLibrary.toDisplayString(Object, boolean)
must be
implemented.
InteropLibrary.getLanguage(Object)
,
InteropLibrary.toDisplayString(Object)
public Class<? extends TruffleLanguage<?>> getLanguage(Object receiver) throws UnsupportedMessageException
registered
language class. For more
details see InteropLibrary.hasLanguage(Object)
.
This method must not cause any observable side-effects. If this method is implemented then
also InteropLibrary.hasLanguage(Object)
must be implemented.
UnsupportedMessageException
- if and only if InteropLibrary.hasLanguage(Object)
returns
false
for the same receiver.public boolean hasMetaObject(Object receiver)
true
if the receiver value has a metaobject associated. The metaobject
represents a description of the object, reveals its kind and its features. Some information
that a metaobject might define includes the base object's type, interface, class, methods,
attributes, etc. Should return false
when no metaobject is known for this type.
Returns false
by default.
An example, for Java objects the returned metaobject is the class
instance. In JavaScript this could be the function or class that is associated with the
object.
Metaobjects for primitive values or values of other languages may be provided using
language views
. While an object is
associated with a metaobject in one language, the metaobject might be a different when viewed
from another language.
This method must not cause any observable side-effects. If this method is implemented then
also InteropLibrary.getMetaObject(Object)
must be implemented.
InteropLibrary.getMetaObject(Object)
,
InteropLibrary.isMetaObject(Object)
public Object getMetaObject(Object receiver) throws UnsupportedMessageException
UnsupportedMessageException
by default.
The returned object must return true
for InteropLibrary.isMetaObject(Object)
and
provide implementations for InteropLibrary.getMetaSimpleName(Object)
,
InteropLibrary.getMetaQualifiedName(Object)
, and InteropLibrary.isMetaInstance(Object, Object)
. For all
values with metaobjects it must at hold that
isMetaInstance(getMetaObject(value), value) ==
true
.
This method must not cause any observable side-effects. If this method is implemented then
also InteropLibrary.hasMetaObject(Object)
must be implemented.
UnsupportedMessageException
- if and only if InteropLibrary.hasMetaObject(Object)
returns
false
for the same receiver.InteropLibrary.hasMetaObject(Object)
public Object toDisplayString(Object receiver, boolean allowSideEffects)
string
. Each language may
have special formating conventions - even primitive values may not follow the traditional
Java rules. The format of the returned string is intended to be interpreted by humans not
machines and should therefore not be relied upon by machines. By default the receiver class
name and its identity hash code
is used as string
representation.
String representations for primitive values or values of other languages may be provided
using language views
. It is common
that languages provide different string representations for primitive and foreign values. To
convert the result value to a Java string use InteropLibrary.asString(Object)
.
allowSideEffects
- whether side-effects are allowed in the production of the string.TruffleLanguage.getLanguageView(Object, Object)
public final Object toDisplayString(Object receiver)
string
of the language.
Short-cut for
toDisplayString(Object, true)
.InteropLibrary.toDisplayString(Object, boolean)
public boolean isMetaObject(Object receiver)
true
if the receiver value represents a metaobject. Metaobjects may be
values that naturally occur in a language or they may be returned by
InteropLibrary.getMetaObject(Object)
. A metaobject represents a description of the object, reveals
its kind and its features. If a receiver is a metaobject it is often also
instantiable
, but this is not a requirement.
Sample interpretations: In Java an instance of the type Class
is a metaobject.
In JavaScript any function instance is a metaobject. For example, the metaobject of a
JavaScript class is the associated constructor function.
This method must not cause any observable side-effects. If this method is implemented then
also InteropLibrary.getMetaQualifiedName(Object)
, InteropLibrary.getMetaSimpleName(Object)
and
InteropLibrary.isMetaInstance(Object, Object)
must be implemented as well.
public Object getMetaQualifiedName(Object metaObject) throws UnsupportedMessageException
string
.
Sample interpretations: The qualified name of a Java class includes the package name
and its class name. JavaScript does not have the notion of qualified name and therefore
returns the simple name
instead.
This method must not cause any observable side-effects. If this method is implemented then
also InteropLibrary.isMetaObject(Object)
must be implemented as well.
UnsupportedMessageException
- if and only if InteropLibrary.isMetaObject(Object)
returns
false
for the same receiver.public Object getMetaSimpleName(Object metaObject) throws UnsupportedMessageException
string
.
Sample interpretations: The simple name of a Java class is the class name.
This method must not cause any observable side-effects. If this method is implemented then
also InteropLibrary.isMetaObject(Object)
must be implemented as well.
UnsupportedMessageException
- if and only if InteropLibrary.isMetaObject(Object)
returns
false
for the same receiver.public boolean isMetaInstance(Object receiver, Object instance) throws UnsupportedMessageException
true
if the given instance is of the provided receiver metaobject, else
false
.
Sample interpretations: A Java object is an instance of its returned
class
.
This method must not cause any observable side-effects. If this method is implemented then
also InteropLibrary.isMetaObject(Object)
must be implemented as well.
instance
- the instance object to check.UnsupportedMessageException
- if and only if InteropLibrary.isMetaObject(Object)
returns
false
for the same receiver.public boolean hasMetaParents(Object receiver)
true
if the receiver value is a metaobject
which has parents (super types).
This method must not cause any observable side-effects. If this method is implemented then
also InteropLibrary.getMetaParents(Object)
must be implemented.
receiver
- a metaobjectInteropLibrary.getMetaParents(Object)
public Object getMetaParents(Object receiver) throws UnsupportedMessageException
InteropLibrary.hasArrayElements(Object)
of metaobjects that are direct
parents (super types) of this metaobject.
The returned object is an array
of objects that return
true
from InteropLibrary.isMetaObject(Object)
.
receiver
- a metaobjectUnsupportedMessageException
- if and only if InteropLibrary.hasMetaParents(Object)
returns
false
for the same receiver.InteropLibrary.hasMetaParents(Object)
protected TriState isIdenticalOrUndefined(Object receiver, Object other)
TRUE
if the receiver is or FALSE
if the
receiver is not identical to the other
value. Returns UNDEFINED
if the operation is not specified.
Sample interpretations:
==
operator.
Any implementation, with the exception of an implementation that returns
UNDEFINED
unconditionally, must guarantee the following
properties:
x
, lib.isIdenticalOrUndefined(x, x)
always returns TRUE
. This is necessary to ensure that the
InteropLibrary.hasIdentity(Object)
contract has reliable results.
x
and y
,
lib.isIdenticalOrUndefined(x, y)
returns TRUE
if and only if
lib.isIdenticalOrUndefined(y, x)
returns TRUE
.
x
, y
, and z
, if
lib.isIdenticalOrUndefined(x, y)
returns TRUE
and
lib.isIdenticalOrUndefined(y, z)
returns TRUE
, then
lib.isIdentical(x, z, zLib)
returns TRUE
.
x
and y
, multiple invocations of
lib.isIdenticalOrUndefined(x, y)
consistently returns the same value.
Note that the target language identical semantics typically does not map directly to interop
identical implementation. Instead target language identity is specified by the language
operation, may take multiple other rules into account and may only fallback to interop
identical for values without dedicated interop type. For example, in many languages
primitives like numbers or strings may be identical, in the target language sense, still
identity can only be exposed for objects and non-primitive values. Primitive values like
Integer
can never be interop identical to other boxed language integers as this would
violate the symmetric property.
Example receiver class MyObject which uses an explicit identity field to compute whether two values are identical.
static class MyObject { final Object identity; MyObject(Object identity) { this.identity = identity; } @ExportMessage static final class IsIdenticalOrUndefined { @Specialization static TriState doMyObject(MyObject receiver, MyObject other) { return receiver.identity == other.identity ? TriState.TRUE : TriState.FALSE; } @Fallback static TriState doOther(MyObject receiver, Object other) { return TriState.UNDEFINED; } } // ... }
This method must not cause any observable side-effects. If this method is implemented then
also InteropLibrary.identityHashCode(Object)
must be implemented.
other
- the other value to compare topublic boolean isIdentical(Object receiver, Object other, InteropLibrary otherInterop)
true
if two values represent the the identical value, else
false
. Two values are identical if and only if they have specified identity
semantics in the target language and refer to the identical instance.
By default, an interop value does not support identical comparisons, and will return
false
for any invocation of this method. Use InteropLibrary.hasIdentity(Object)
to
find out whether a receiver supports identity comparisons.
This method has the following properties:
x
,
lib.isIdentical(x, x, lib)
may return false
if the object does not support
identity, else true
. This method is reflexive if x
supports identity. A
value supports identity if lib.isIdentical(x, x, lib)
returns true
. The
method InteropLibrary.hasIdentity(Object)
may be used to document this intent explicitly.
x
and y
,
lib.isIdentical(x, y, yLib)
returns true
if and only if
lib.isIdentical(y, x, xLib)
returns true
.
x
, y
, and z
, if
lib.isIdentical(x, y, yLib)
returns true
and
lib.isIdentical(y, z, zLib)
returns true
, then
lib.isIdentical(x, z, zLib)
returns true
.
x
and y
, multiple invocations of
lib.isIdentical(x, y, yLib)
consistently returns true
or consistently return
false
.
Note that the target language identical semantics typically does not map directly to interop
identical implementation. Instead target language identity is specified by the language
operation, may take multiple other rules into account and may only fallback to interop
identical for values without dedicated interop type. For example, in many languages
primitives like numbers or strings may be identical, in the target language sense, still
identity can only be exposed for objects and non-primitive values. Primitive values like
Integer
can never be interop identical to other boxed language integers as this would
violate the symmetric property.
This method performs double dispatch by forwarding calls to
InteropLibrary.isIdenticalOrUndefined(Object, Object)
with receiver and other value first and then
with reversed parameters if the result was undefined
. This allows
the receiver and the other value to negotiate identity semantics. This method is supposed to
be exported only if the receiver represents a wrapper that forwards messages. In such a case
the isIdentical message should be forwarded to the delegate value. Otherwise, the
InteropLibrary.isIdenticalOrUndefined(Object, Object)
should be exported instead.
This method must not cause any observable side-effects.
Cached usage example:
abstract class IsIdenticalUsage extends Node { abstract boolean execute(Object left, Object right); @Specialization(limit = "3") public boolean isIdentical(Object left, Object right, @CachedLibrary("left") InteropLibrary leftInterop, @CachedLibrary("right") InteropLibrary rightInterop) { return leftInterop.isIdentical(left, right, rightInterop); } }
Uncached usage example:
@TruffleBoundary public static boolean isIdentical(Object left, Object right) { return InteropLibrary.getUncached(left).isIdentical(left, right, InteropLibrary.getUncached(right)); }For a full example please refer to the SLEqualNode of the SimpleLanguage example implementation.
public final boolean hasIdentity(Object receiver)
true
if and only if the receiver specifies identity, else
false
. This method is a short-cut for
this.isIdentical(receiver, receiver, this) != TriState.UNDEFINED
. This message
cannot be exported. To add identity support to the receiver export
InteropLibrary.isIdenticalOrUndefined(Object, Object)
instead.InteropLibrary.isIdenticalOrUndefined(Object, Object)
public int identityHashCode(Object receiver) throws UnsupportedMessageException
identity
. If the receiver has no identity then an UnsupportedMessageException
is
thrown. The identity hash code may be used by languages to store foreign values with identity
in an identity hash map.
InteropLibrary.isIdentical(Object, Object, InteropLibrary)
message, then calling the
identityHashCode method on each of the two objects must produce the same integer result.
InteropLibrary.isIdenticalOrUndefined(Object, Object)
must be implemented.UnsupportedMessageException
- if and only if InteropLibrary.hasIdentity(Object)
returns
false
for the same receiver.InteropLibrary.isIdenticalOrUndefined(Object, Object)
,
InteropLibrary.isIdentical(Object, Object, InteropLibrary)
public boolean isScope(Object receiver)
true
if the value represents a scope object, else false
.
The scope object contains variables as members
and has a
scope display name
. It needs to be
associated with a language
. The scope may return a
source location
that indicates the range of
the scope in the source code. The scope may have parent
scopes
.
The members
of a scope represent all visible flattened variables,
including all parent scopes, if any. The variables of the current scope must be listed first
in InteropLibrary.getMembers(Object)
. Variables of the parent scope
must be listed afterwards, even if they contain duplicates. This allows to
resolve which variables are redeclared in sub scopes.
Every member
may not be just a String literal, but a
string object
that provides also a
source location
of its declaration. When different
variables of the same name are in different scopes, they will be represented by different
member elements providing the same name
.
This method must not cause any observable side-effects. If this method is implemented then
also InteropLibrary.hasMembers(Object)
and InteropLibrary.toDisplayString(Object, boolean)
must be
implemented and InteropLibrary.hasSourceLocation(Object)
is recommended.
InteropLibrary.getLanguage(Object)
,
InteropLibrary.getMembers(Object)
,
InteropLibrary.hasScopeParent(Object)
public boolean hasScopeParent(Object receiver)
true
if this scope has an enclosing parent scope, else
false
.
This method must not cause any observable side-effects. If this method is implemented then
also InteropLibrary.isScope(Object)
and InteropLibrary.getScopeParent(Object)
must be implemented.
InteropLibrary.isScope(Object)
,
InteropLibrary.getScopeParent(Object)
public Object getScopeParent(Object receiver) throws UnsupportedMessageException
has the parent
. The
returned object must be a scope
and must provide a reduced list of
member
variables, omitting all variables that are local to the
current scope.
This method must not cause any observable side-effects. If this method is implemented then
also InteropLibrary.isScope(Object)
and InteropLibrary.getScopeParent(Object)
must be implemented.
UnsupportedMessageException
- if and only if InteropLibrary.hasScopeParent(Object)
returns
false
for the same receiver.InteropLibrary.isScope(Object)
,
InteropLibrary.hasScopeParent(Object)
public static LibraryFactory<InteropLibrary> getFactory()
ResolvedLibrary.resolve(InteropLibrary.class)
.LibraryFactory.resolve(Class)
public static InteropLibrary getUncached()
InteropLibrary.getFactory().getUncached()
.LibraryFactory.getUncached()
public static InteropLibrary getUncached(Object v)
InteropLibrary.getFactory().getUncached(v)
.LibraryFactory.getUncached(Object)
protected final boolean assertAdopted()
public static boolean isValidValue(Object receiver)
InteropLibrary
. This method will be extended with more checked types as
interop is extended with further allowed values.
It is not recommended to make assumptions about the types of interop values. It is
recommended to use instance methods in InteropLibrary
to check for interop types
instead. However, it can be useful to make such assumptions for performance reasons. To
verify that these assumptions continue to hold this method can be used.
public static boolean isValidProtocolValue(Object value)
interop value
or a value that might be returned or
passed as parameter by any of the methods in InteropLibrary
. This can be useful to
validate all values received or returned by a wrapper that uses ReflectionLibrary
to
delegate all interop protocol parameters and return values. This method will be extended with
more checked types as interop is extended with further allowed values.InteropLibrary.isValidValue(Object)