Diapositives du didacticiel sur les truffes (30-60p) Ceci est mon propre mémo de traduction.
Nous ne garantissons pas les erreurs de traduction ou les omissions.
S'il y a un problème, supprimez-le.
Tout type de clé et de valeur peut être utilisé
La clé est généralement de type String
Type SL | valeur | Implémentation en Java?(Java Type in Implementation) |
---|---|---|
Number | Entier de précision arbitraire | Long dans les 64 bits En cas de dépassement, java.lang.BigInteger |
Boolean | vrai ou faux | boolean |
String | Chaîne Unicode | java.lang.String |
Function | Référence à la fonction | SLFunction |
Object | Clé et valeur | DynamicObject |
Null | null | SLNull.SINGLETON |
Utilisez autant que possible les types primitifs pour les performances
N'utilisez pas Java null dans votre langue d'invité
Abréviation
Abréviation
Getting Started
Abréviation
Je suis désolé j'ai omis
Class Node
Classe de base du nœud Truffle? (classe de base de tous les nœuds de l'arbre Truffle)
NodeUtil fournit des méthodes utilitaires pratiques.
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);
}
}
}
Annotez les champs des nœuds enfants avec @Child et ne les rendez pas définitifs.
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);
}
}
}
Le profilage avec un interpréteur permet au compilateur de générer un meilleur code.
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);
}
}
}
Les champs qui représentent plusieurs nœuds sont représentés par un tableau final avec @Children.
Dois-je ajouter @ExplodeLoop lors de la répétition d'éléments enfants? (L'itération des enfants doit être annotée avec @ExplodeLoop)
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;
}
}
L'exception rembobine-t-elle toutes les images de la pile? (Exception déroule tous les cadres de la pile d'interpréteurs de la méthode (boucles, conditions, blocs, ...))
@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;
}
}
L'ordre des méthodes @Specialization est important. Le premier élément correspondant est sélectionné.
Dans toutes les autres spécialisations, la protection est implicite basée sur la signature de la méthode.
Code généré par la méthode d'usine
@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();
}
} //L'article d'origine n'a pas ce crochet de fermeture
}
@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
Abréviation
La fonction est-elle attribuée au prologue? (Alloué dans le prologue de la fonction)
Passé comme paramètre de la méthode execute ()? (Passé comme paramètre pour les méthodes execute ())
--Un cadre qui peut être stocké sans restrictions? (Un cadre qui peut être stocké sans restrictions)
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();
}
Les cadres prennent en charge tous les types et objets primitifs Java.
SL String, SLFunction, SLNull sont stockés en tant qu'objet.
N'allouez pas de cadres ou n'implémentez pas de cadres.
@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());
}
} //Il n'y a pas de parenthèse fermante dans le texte d'origine
Recommended Posts