@Retention(value=RUNTIME) @Target(value=TYPE) @Repeatable(value=ExportLibrary.Repeat.class) public @interface ExportLibrary
value specifies the library class that is exported. If there are abstract methods specified by a
library then those messages need to be implemented. A receiver may export multiple libraries at
the same time, by specifying multiple export annotations. Subclasses of the receiver type inherit
all exported messages and may also be exported again. In this case the subclass overrides the
base class export.
@ExportLibrary(ArrayLibrary.class)
static final class BufferArray {
private int length;
private int[] buffer;
BufferArray(int length) {
this.length = length;
this.buffer = new int[length];
}
@ExportMessage
boolean isArray() {
return true;
}
@ExportMessage
int read(int index) {
return buffer[index];
}
}
specialization then the export
must be specified as class. In this case the simple name of the message is resolved by using the
class name and turning the first character lower-case. So for an exported class named
Read the message read would be used. It is not allowed to use a method
export and a class export for the same message at the same time. Multiple ExportMessage
annotations may be used for the same method or class to export them for multiple messages. In
this case the message name needs to be specified explicitly and the
target signatures need to match for all exported messages.
@ExportLibrary(value = ArrayLibrary.class)
static final class SequenceArray {
final int start;
final int stride;
final int length;
SequenceArray(int start, int stride, int length) {
this.start = start;
this.stride = stride;
this.length = length;
}
@ExportMessage
boolean isArray() {
return true;
}
@ExportMessage
static class Read {
@Specialization(guards = {"seq.stride == cachedStride",
"seq.start == cachedStart"}, limit = "1")
static int doSequenceCached(SequenceArray seq, int index,
@Cached("seq.start") int cachedStart,
@Cached("seq.stride") int cachedStride) {
return cachedStart + cachedStride * index;
}
@Specialization(replaces = "doSequenceCached")
static int doSequence(SequenceArray seq, int index) {
return doSequenceCached(seq, index, seq.start, seq.stride);
}
}
}
default exports or types that support dynamic dispatch the export may declare an explicit receiver type.GenerateLibrary,
CachedLibrary| Modifier and Type | Required Element and Description |
|---|---|
Class<? extends Library> |
value
The library class that specifies the messages that are exported.
|
| Modifier and Type | Optional Element and Description |
|---|---|
Class<?> |
receiverType
The explicit receiver type to use if specified.
|
public abstract Class<?> receiverType
default exports or types that are
dynamically dispatched. If specified, all exported methods
need to be declared statically with the receiver type argument as first parameter.
@ExportLibrary(value = ArrayLibrary.class, receiverType = Integer.class)
static final class ScalarIntegerArray {
@ExportMessage
static boolean isArray(Integer receiver) {
return true;
}
@ExportMessage
int read(Integer receiver, int index) {
if (index == 0) {
return receiver;
} else {
throw new ArrayIndexOutOfBoundsException(index);
}
}
}