Trüffel-Tutorial-Folien (30-60p) Dies ist mein eigenes Übersetzungsprotokoll.
Wir garantieren keine Fehlübersetzungen oder Auslassungen.
Wenn es ein Problem gibt, löschen Sie es.
Jeder Schlüsseltyp und Wert kann verwendet werden
Der Schlüssel ist normalerweise vom Typ String
SL-Typ | Wert | Implementierung in Java?(Java Type in Implementation) |
---|---|---|
Number | Ganzzahl mit beliebiger Genauigkeit | Lang innerhalb von 64 Bit Bei Überlauf Java.lang.BigInteger |
Boolean | richtig oder falsch | boolean |
String | Unicode-Zeichenfolge | java.lang.String |
Function | Verweis auf Funktion | SLFunction |
Object | Schlüssel und Wert | DynamicObject |
Null | null | SLNull.SINGLETON |
Verwenden Sie für die Leistung so oft wie möglich primitive Typen
Verwenden Sie Java null nicht in Ihrer Gastsprache
Abkürzung
Abkürzung
Getting Started
Abkürzung
Es tut mir leid, dass ich weglasse
Class Node
Basisklasse des Trüffelknotens? (Basisklasse aller Trüffelbaumknoten)
NodeUtil bietet praktische Dienstprogrammmethoden.
public abstract class Node implements Cloneable {
public final Node getParent() { ... }
public final Iterable<Node> getChildren() { ... }
public final <T extends Node> T replace(T newNode) { ... }
public Node copy() { ... }
public SourceSection getSourceSection();
}
public final class SLIfNode extends SLStatementNode {
@Child private SLExpressionNode conditionNode;
@Child private SLStatementNode thenPartNode;
@Child private SLStatementNode elsePartNode;
public SLIfNode(SLExpressionNode conditionNode, SLStatementNode thenPartNode, SLStatementNode elsePartNode) {
this.conditionNode = conditionNode;
this.thenPartNode = thenPartNode;
this.elsePartNode = elsePartNode;
}
public void executeVoid(VirtualFrame frame) {
if (conditionNode.executeBoolean(frame)) {
thenPartNode.executeVoid(frame);
}else{
elsePartNode.executeVoid(frame);
}
}
}
Kommentieren Sie die Felder der untergeordneten Knoten mit @Child und machen Sie sie nicht endgültig.
public final class SLIfNode extends SLStatementNode {
@Child private SLExpressionNode conditionNode;
@Child private SLStatementNode thenPartNode;
@Child private SLStatementNode elsePartNode;
private final ConditionProfile condition = ConditionProfile.createCountingProfile();
public SLIfNode(SLExpressionNode conditionNode, SLStatementNode thenPartNode, SLStatementNode elsePartNode) {
this.conditionNode = conditionNode;
this.thenPartNode = thenPartNode;
this.elsePartNode = elsePartNode;
}
public void executeVoid(VirtualFrame frame) {
if (condition.profile(conditionNode.executeBoolean(frame))) {
thenPartNode.executeVoid(frame);
}else{
elsePartNode.executeVoid(frame);
}
}
}
Durch die Profilerstellung mit einem Interpreter kann der Compiler besseren Code generieren.
public final class SLBlockNode extends SLStatementNode {
@Children private final SLStatementNode[] bodyNodes;
public SLBlockNode(SLStatementNode[] bodyNodes) {
this.bodyNodes = bodyNodes;
}
@ExplodeLoop public void executeVoid(VirtualFrame frame) {
for (SLStatementNode statement : bodyNodes) {
statement.executeVoid(frame);
}
}
}
Felder, die mehrere Knoten darstellen, werden durch ein endgültiges Array mit @Children dargestellt.
Muss ich @ExplodeLoop hinzufügen, wenn ich untergeordnete Elemente wiederhole? (Die Iteration der Kinder muss mit @ExplodeLoop kommentiert werden.)
public final class SLReturnNode extends SLStatementNode {
@Child private SLExpressionNode valueNode;
...
public void executeVoid(VirtualFrame frame) {
throw new SLReturnException(valueNode.executeGeneric(frame));
}
}
public final class SLReturnException extends ControlFlowException {
private final Object result;
...
}
public final class SLFunctionBodyNode extends SLExpressionNode {
@Child private SLStatementNode bodyNode;
...
public Object executeGeneric(VirtualFrame frame) {
try {
bodyNode.executeVoid(frame);
}catch (SLReturnException ex){
return ex.getResult();
}
return SLNull.SINGLETON;
}
}
Spult die Ausnahme alle Stapelrahmen zurück? (Ausnahme wickelt alle Interpreter-Stack-Frames der Methode ab (Schleifen, Bedingungen, Blöcke, ...))
@NodeChildren({@NodeChild("leftNode"), @NodeChild("rightNode")})
public abstract class SLBinaryNode extends SLExpressionNode {
}
public abstract class SLAddNode extends SLBinaryNode {
@Specialization(rewriteOn = ArithmeticException.class)
protected final long add(long left, long right) {
return ExactMath.addExact(left, right);
}
@Specialization
protected final BigInteger add(BigInteger left, BigInteger right) {
return left.add(right);
}
@Specialization(guards = "isString(left, right)")
protected final String add(Object left, Object right) {
return left.toString() + right.toString();
}
protected final boolean isString(Object a, Object b) {
return a instanceof String || b instanceof String;
}
}
Die Reihenfolge der @ Specialization-Methoden ist wichtig. Das erste passende Element wird ausgewählt.
In allen anderen Spezialisierungen ist der Schutz implizit basierend auf der Methodensignatur.
Von der Factory-Methode generierter Code
@GeneratedBy(SLAddNode.class)
public final class SLAddNodeGen extends SLAddNode {
public static SLAddNode create(SLExpressionNode leftNode, SLExpressionNode rightNode) {
...
}
...
}
@GeneratedBy(methodName = "add(long, long)", value = SLAddNode.class)
private static final class Add0Node_ extends BaseNode_ {
@Override public long executeLong(VirtualFrame frameValue) throws UnexpectedResultException {
long leftNodeValue_;
try {
leftNodeValue_ = root.leftNode_.executeLong(frameValue);
}catch (UnexpectedResultException ex){
Object rightNodeValue = executeRightNode_(frameValue);
return SLTypesGen.expectLong(getNext().execute_(frameValue, ex.getResult(), rightNodeValue));
}
long rightNodeValue_;
try {
rightNodeValue_ = root.rightNode_.executeLong(frameValue);
}catch (UnexpectedResultException ex){
return SLTypesGen.expectLong(getNext().execute_(frameValue, leftNodeValue_, ex.getResult()));
}
try {
return root.add(leftNodeValue_, rightNodeValue_);
} catch (ArithmeticException ex) {
root.excludeAdd0_ = true;
return SLTypesGen.expectLong(remove("threw rewrite exception", frameValue, leftNodeValue_, rightNodeValue_));
}
}
@Override public Object execute(VirtualFrame frameValue) {
try {
return executeLong(frameValue);
} catch (UnexpectedResultException ex) {
return ex.getResult();
}
} //Der Originalartikel hat diese schließende Klammer nicht
}
@TypeSystem({long.class, BigInteger.class, boolean.class, String.class, SLFunction.class, SLNull.class})
public abstract class SLTypes {
@ImplicitCast
public BigInteger castBigInteger(long value) {
return BigInteger.valueOf(value);
}
}
@TypeSystemReference(SLTypes.class)
public abstract class SLExpressionNode extends SLStatementNode {
public abstract Object executeGeneric(VirtualFrame frame);
public long executeLong(VirtualFrame frame) throws UnexpectedResultException {
return SLTypesGen.SLTYPES.expectLong(executeGeneric(frame));
}
public boolean executeBoolean(VirtualFrame frame) ...
}
UnexpectedResultException
Abkürzung
--Ist die Funktion dem Prolog zugeordnet? (Im Funktionsprolog zugeordnet)
--Factory-Methode der TruffleRuntime-Klasse
public interface Frame {
FrameDescriptor getFrameDescriptor();
Object[] getArguments();
boolean isType(FrameSlot slot);
Type getType(FrameSlot slot) throws FrameSlotTypeException;
void setType(FrameSlot slot, Type value);
Object getValue(FrameSlot slot);
MaterializedFrame materialize();
}
Frames unterstützen alle primitiven Java-Typen und -Objekte.
SL String, SLFunction, SLNull werden als Objekt gespeichert.
Ordnen Sie keine Frames zu und implementieren Sie keine Frames.
@NodeChild("valueNode")
@NodeField(name = "slot", type = FrameSlot.class)
public abstract class SLWriteLocalVariableNode extends SLExpressionNode {
protected abstract FrameSlot getSlot();
@Specialization(guards = "isLongOrIllegal(frame)")
protected long writeLong(VirtualFrame frame, long value) {
getSlot().setKind(FrameSlotKind.Long);
frame.setLong(getSlot(), value);
return value;
}
protected boolean isLongOrIllegal(VirtualFrame frame) {
return getSlot().getKind() == FrameSlotKind.Long || getSlot().getKind() == FrameSlotKind.Illegal;
}
...
@Specialization(contains = {"writeLong", " writeBoolean"})
protected Object write(VirtualFrame frame, Object value) {
getSlot().setKind(FrameSlotKind.Object);
frame.setObject(getSlot(), value);
return value;
}
}
@NodeField(name = "slot", type = FrameSlot.class)
public abstract class SLReadLocalVariableNode extends SLExpressionNode {
protected abstract FrameSlot getSlot();
@Specialization(guards = "isLong(frame)")
protected long readLong(VirtualFrame frame) {
return FrameUtil.getLongSafe(frame, getSlot());
}
protected boolean isLong(VirtualFrame frame) {
return getSlot().getKind() == FrameSlotKind.Long;
}
...
@Specialization(contains = {"readLong", "readBoolean"})
protected Object readObject(VirtualFrame frame) {
if (!frame.isObject(getSlot())) {
CompilerDirectives.transferToInterpreter();
Object result = frame.getValue(getSlot());
frame.setObject(getSlot(), result);
return result;
}
return FrameUtil.getObjectSafe(frame, getSlot());
}
} //Der Originaltext enthält keine schließende Klammer
Recommended Posts