Skip to content

Commit fbed77a

Browse files
committed
[truffle] Make more deserialization switch cases automatically generated
Make @deserialize work on static object creations method not only constructors Support passing the variable scopes as an argument for creating nodes
1 parent 44fff18 commit fbed77a

File tree

7 files changed

+111
-65
lines changed

7 files changed

+111
-65
lines changed

src/vm/jvm/dsl/org/perl6/nqp/dsl/AstBuilder.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@
1313
Class intClass();
1414
Class numClass();
1515
Class strClass();
16+
Class scopeClass();
1617
}

src/vm/jvm/dsl/org/perl6/nqp/dsl/Deserializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import java.lang.annotation.Retention;
66
import java.lang.annotation.RetentionPolicy;
77

8-
@Target(ElementType.CONSTRUCTOR)
8+
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
99
@Retention(RetentionPolicy.CLASS)
1010
public @interface Deserializer {
1111
String value() default "";

src/vm/jvm/dsl/org/perl6/nqp/dsl/Processor.java

Lines changed: 72 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.io.IOException;
1212
import javax.lang.model.element.TypeElement;
1313
import javax.lang.model.element.Element;
14+
import javax.lang.model.element.ElementKind;
1415
import javax.lang.model.element.ExecutableElement;
1516
import javax.lang.model.element.VariableElement;
1617
import javax.lang.model.type.TypeMirror;
@@ -28,6 +29,53 @@ public class Processor extends AbstractProcessor {
2829
Messager messager;
2930
String prefix = "NQP";
3031

32+
static class AstTypes {
33+
TypeMirror nodeClass;
34+
TypeMirror nodesClass;
35+
TypeMirror intClass;
36+
TypeMirror numClass;
37+
TypeMirror strClass;
38+
TypeMirror scopeClass;
39+
40+
AstTypes(AstBuilder annotation) {
41+
try {
42+
annotation.nodeClass();
43+
} catch (MirroredTypeException e) {
44+
nodeClass = e.getTypeMirror();
45+
}
46+
47+
try {
48+
annotation.nodesClass();
49+
} catch (MirroredTypeException e) {
50+
nodesClass = e.getTypeMirror();
51+
}
52+
53+
try {
54+
annotation.intClass();
55+
} catch (MirroredTypeException e) {
56+
intClass = e.getTypeMirror();
57+
}
58+
59+
try {
60+
annotation.numClass();
61+
} catch (MirroredTypeException e) {
62+
numClass = e.getTypeMirror();
63+
}
64+
65+
try {
66+
annotation.strClass();
67+
} catch (MirroredTypeException e) {
68+
strClass = e.getTypeMirror();
69+
}
70+
71+
try {
72+
annotation.scopeClass();
73+
} catch (MirroredTypeException e) {
74+
scopeClass = e.getTypeMirror();
75+
}
76+
}
77+
}
78+
3179
private String opNameFromClassName(String className) {
3280
return className.replaceFirst("^" + Pattern.quote(prefix), "")
3381
.replaceFirst("IntNode$", "_i")
@@ -40,43 +88,55 @@ private String opNameFromClassName(String className) {
4088
.toLowerCase();
4189
}
4290

43-
private void writeBuildMethod(TypeMirror nodeClass, TypeMirror nodesClass, TypeMirror intClass, TypeMirror numClass, TypeMirror strClass, PrintWriter writer, RoundEnvironment roundEnv) {
91+
private void writeBuildMethod(AstTypes astTypes, PrintWriter writer, RoundEnvironment roundEnv) {
4492
writer.append(" public NQPNode buildSimple(SixModelObject node, NQPScope scope, ThreadContext tc) {\n");
4593

4694
writer.append(" switch (node.at_pos_boxed(tc, 0).get_str(tc)) {\n");
4795

4896
for (Element element : roundEnv.getElementsAnnotatedWith(Deserializer.class)) {
4997

50-
ExecutableElement constructor = (ExecutableElement) element;
98+
ExecutableElement executableElement = (ExecutableElement) element;
5199
TypeElement type = (TypeElement) element.getEnclosingElement();
52100

53101
String gotOpName = ((Deserializer)element.getAnnotation(Deserializer.class)).value();
54102

103+
String typeName = type.getQualifiedName().toString();
104+
105+
String call = element.getKind() == ElementKind.CONSTRUCTOR
106+
? "new " + typeName
107+
: typeName + "." + executableElement.getSimpleName().toString();
108+
55109
String opName = gotOpName.equals("")
56110
? opNameFromClassName(type.getSimpleName().toString())
57111
: gotOpName;
58112

59-
writer.append(" case \"" + opName + "\": return new " + type.getQualifiedName() + "(");
113+
writer.append(" case \"" + opName + "\": return " + call + "(");
60114

115+
boolean first = true;;
61116
int i = 0;
62117

63-
for (VariableElement param : constructor. getParameters()) {
118+
for (VariableElement param : executableElement.getParameters()) {
64119
TypeMirror paramType = param.asType();
65120

66-
if (i != 0) {
121+
if (first) {
122+
first = false;
123+
} else {
67124
writer.append(",");
68125
}
69126

70-
if (paramType.equals(nodeClass)) {
127+
if (paramType.equals(astTypes.nodeClass)) {
71128
writer.append("build(node.at_pos_boxed(tc, " + (i+1) + "), scope, tc)");
72-
} else if (paramType.equals(nodesClass)) {
129+
} else if (paramType.equals(astTypes.nodesClass)) {
73130
writer.append("expressions(node, " + (i+1) + ", scope, tc)");
74-
} else if (paramType.equals(intClass)) {
131+
} else if (paramType.equals(astTypes.intClass)) {
75132
writer.append("node.at_pos_boxed(tc, " + (i+1) + ").get_int(tc)");
76-
} else if (paramType.equals(numClass)) {
133+
} else if (paramType.equals(astTypes.numClass)) {
77134
writer.append("node.at_pos_boxed(tc, " + (i+1) + ").get_num(tc)");
78-
} else if (paramType.equals(strClass)) {
135+
} else if (paramType.equals(astTypes.strClass)) {
79136
writer.append("node.at_pos_boxed(tc, " + (i+1) + ").get_str(tc)");
137+
} else if (paramType.equals(astTypes.scopeClass)) {
138+
writer.append("scope");
139+
i--;
80140
} else {
81141
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Wrong param type: " + paramType.toString());
82142
}
@@ -108,43 +168,8 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
108168
for (Element element : roundEnv.getElementsAnnotatedWith(AstBuilder.class)) {
109169
TypeElement type = (TypeElement) element;
110170

111-
AstBuilder annotation = element.getAnnotation(AstBuilder.class);
112-
113-
TypeMirror nodeClass = null;
114-
TypeMirror nodesClass = null;
115-
TypeMirror intClass = null;
116-
TypeMirror numClass = null;
117-
TypeMirror strClass = null;
118-
119-
try {
120-
annotation.nodeClass();
121-
} catch (MirroredTypeException e) {
122-
nodeClass = e.getTypeMirror();
123-
}
124-
125-
try {
126-
annotation.nodesClass();
127-
} catch (MirroredTypeException e) {
128-
nodesClass = e.getTypeMirror();
129-
}
171+
AstTypes astTypes = new AstTypes(element.getAnnotation(AstBuilder.class));
130172

131-
try {
132-
annotation.intClass();
133-
} catch (MirroredTypeException e) {
134-
intClass = e.getTypeMirror();
135-
}
136-
137-
try {
138-
annotation.numClass();
139-
} catch (MirroredTypeException e) {
140-
numClass = e.getTypeMirror();
141-
}
142-
143-
try {
144-
annotation.strClass();
145-
} catch (MirroredTypeException e) {
146-
strClass = e.getTypeMirror();
147-
}
148173

149174
String builderClass = type.getQualifiedName().toString();
150175
String generatedClassQualified = builderClass + "Gen";
@@ -163,7 +188,7 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
163188

164189
writer.append("public class " + generatedClassSimple + " extends " + builderClass + " {\n");
165190

166-
writeBuildMethod(nodeClass, nodesClass, intClass, numClass, strClass, writer, roundEnv);
191+
writeBuildMethod(astTypes, writer, roundEnv);
167192

168193
writer.append("}\n");
169194
}

src/vm/jvm/runtime/org/perl6/nqp/truffle/TruffleCompiler.java

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
nodesClass = NQPNode[].class,
2828
intClass = long.class,
2929
numClass = double.class,
30-
strClass = String.class
30+
strClass = String.class,
31+
scopeClass = NQPScope.class
3132
)
3233

3334
abstract class TruffleCompiler {
@@ -66,22 +67,6 @@ public NQPNode build(SixModelObject node, NQPScope scope, ThreadContext tc) {
6667
case "declare-lexical":
6768
scope.addLexical(node.at_pos_boxed(tc, 1).get_str(tc));
6869
return build(node.at_pos_boxed(tc, 2), scope, tc);
69-
case "get-lexical": {
70-
FoundLexical foundLexical = scope.findLexical(node.at_pos_boxed(tc, 1).get_str(tc));
71-
return new NQPReadLocalVariableNode(foundLexical.getFrameSlot(), foundLexical.getDepth());
72-
}
73-
case "bind-lexical": {
74-
FoundLexical foundLexical = scope.findLexical(node.at_pos_boxed(tc, 1).get_str(tc));
75-
NQPNode valueNode = build(node.at_pos_boxed(tc, 2), scope, tc);
76-
return new NQPBindLocalVariableNode(foundLexical.getFrameSlot(), foundLexical.getDepth(), valueNode);
77-
}
78-
case "get-lexical-positional": {
79-
scope.addLexical(node.at_pos_boxed(tc, 1).get_str(tc));
80-
int index = (int) node.at_pos_boxed(tc, 2).get_int(tc);
81-
FoundLexical foundLexical = scope.findLexical(node.at_pos_boxed(tc, 1).get_str(tc));
82-
assert foundLexical.getDepth() == 0;
83-
return new NQPGetPositionalNode(foundLexical.getFrameSlot(), index);
84-
}
8570
case "block": {
8671
FrameDescriptor frameDescriptor = new FrameDescriptor();
8772
NQPNode children[] = expressions(node, 1, new NQPScopeWithFrame(frameDescriptor, scope), tc);

src/vm/jvm/runtime/org/perl6/nqp/truffle/nodes/variables/NQPBindLocalVariableNode.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@
4949
import com.oracle.truffle.api.frame.VirtualFrame;
5050
import org.perl6.nqp.truffle.nodes.NQPNode;
5151

52+
import org.perl6.nqp.dsl.Deserializer;
53+
54+
import org.perl6.nqp.truffle.NQPScope;
55+
import org.perl6.nqp.truffle.FoundLexical;
56+
5257
@NodeField(name = "slot", type = FrameSlot.class)
5358
public class NQPBindLocalVariableNode extends FrameLookupNode {
5459
final private FrameSlot slot;
@@ -67,6 +72,12 @@ public Object execute(VirtualFrame frame) {
6772
return value;
6873
}
6974

75+
@Deserializer("bind-lexical")
76+
public static NQPBindLocalVariableNode create(NQPScope scope, String name, NQPNode valueNode) {
77+
FoundLexical foundLexical = scope.findLexical(name);
78+
return new NQPBindLocalVariableNode(foundLexical.getFrameSlot(), foundLexical.getDepth(), valueNode);
79+
}
80+
7081
@Override
7182
public void executeVoid(VirtualFrame frame) {
7283
execute(frame);

src/vm/jvm/runtime/org/perl6/nqp/truffle/nodes/variables/NQPGetPositionalNode.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@
5252
import org.perl6.nqp.truffle.nodes.NQPObjNode;
5353
import org.perl6.nqp.truffle.nodes.NQPNode;
5454

55+
import org.perl6.nqp.dsl.Deserializer;
56+
57+
import org.perl6.nqp.truffle.NQPScope;
58+
import org.perl6.nqp.truffle.FoundLexical;
59+
5560
public class NQPGetPositionalNode extends NQPObjNode {
5661
private final FrameSlot slot;
5762
private final int index;
@@ -61,6 +66,14 @@ public NQPGetPositionalNode(FrameSlot slot, int index) {
6166
this.index = index;
6267
}
6368

69+
@Deserializer("get-lexical-positional")
70+
public static NQPGetPositionalNode create(NQPScope scope, String name, long index) {
71+
scope.addLexical(name);
72+
FoundLexical foundLexical = scope.findLexical(name);
73+
assert foundLexical.getDepth() == 0;
74+
return new NQPGetPositionalNode(foundLexical.getFrameSlot(), (int) index);
75+
}
76+
6477
@Override
6578
public Object execute(VirtualFrame frame) {
6679
Object[] args = frame.getArguments();

src/vm/jvm/runtime/org/perl6/nqp/truffle/nodes/variables/NQPReadLocalVariableNode.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@
5252
import com.oracle.truffle.api.dsl.TypeSystemReference;
5353
import org.perl6.nqp.truffle.nodes.NQPNode;
5454
import org.perl6.nqp.truffle.NQPTypes;
55+
import org.perl6.nqp.dsl.Deserializer;
56+
57+
import org.perl6.nqp.truffle.NQPScope;
58+
import org.perl6.nqp.truffle.FoundLexical;
5559

5660
public class NQPReadLocalVariableNode extends FrameLookupNode {
5761
private final FrameSlot slot;
@@ -61,6 +65,13 @@ public NQPReadLocalVariableNode(FrameSlot slot, int depth) {
6165
this.slot = slot;
6266
}
6367

68+
69+
@Deserializer("get-lexical")
70+
public static NQPReadLocalVariableNode create(NQPScope scope, String name) {
71+
FoundLexical foundLexical = scope.findLexical(name);
72+
return new NQPReadLocalVariableNode(foundLexical.getFrameSlot(), foundLexical.getDepth());
73+
}
74+
6475
@Override
6576
public Object execute(VirtualFrame frame) {
6677
return FrameUtil.getObjectSafe(getFrame(frame), slot);

0 commit comments

Comments
 (0)