Mercurial > hg > graal-jvmci-8
comparison graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java @ 8251:cb70ed101b5f
Added automatic generation of generic specialization which throws unsupported operation if reached.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Wed, 13 Mar 2013 11:32:43 +0100 |
parents | c4c3f50fa9c2 |
children | 0905d796944a |
comparison
equal
deleted
inserted
replaced
8250:edc414f52e2b | 8251:cb70ed101b5f |
---|---|
32 import javax.lang.model.util.*; | 32 import javax.lang.model.util.*; |
33 | 33 |
34 import com.oracle.truffle.api.codegen.*; | 34 import com.oracle.truffle.api.codegen.*; |
35 import com.oracle.truffle.codegen.processor.*; | 35 import com.oracle.truffle.codegen.processor.*; |
36 import com.oracle.truffle.codegen.processor.ast.*; | 36 import com.oracle.truffle.codegen.processor.ast.*; |
37 import com.oracle.truffle.codegen.processor.node.NodeFieldData.*; | 37 import com.oracle.truffle.codegen.processor.node.NodeFieldData.ExecutionKind; |
38 import com.oracle.truffle.codegen.processor.node.NodeFieldData.FieldKind; | |
38 import com.oracle.truffle.codegen.processor.template.*; | 39 import com.oracle.truffle.codegen.processor.template.*; |
39 import com.oracle.truffle.codegen.processor.typesystem.*; | 40 import com.oracle.truffle.codegen.processor.typesystem.*; |
40 | 41 |
41 public class NodeCodeGenerator extends CompilationUnitFactory<NodeData> { | 42 public class NodeCodeGenerator extends CompilationUnitFactory<NodeData> { |
42 | 43 |
143 } | 144 } |
144 | 145 |
145 private void startCallOperationMethod(CodeTreeBuilder body, TemplateMethod templateMethod, boolean castedValues) { | 146 private void startCallOperationMethod(CodeTreeBuilder body, TemplateMethod templateMethod, boolean castedValues) { |
146 body.startGroup(); | 147 body.startGroup(); |
147 ExecutableElement method = templateMethod.getMethod(); | 148 ExecutableElement method = templateMethod.getMethod(); |
148 | 149 if (method == null) { |
150 throw new IllegalStateException("Cannot call synthtetic operation methods."); | |
151 } | |
149 TypeElement targetClass = Utils.findNearestEnclosingType(method.getEnclosingElement()); | 152 TypeElement targetClass = Utils.findNearestEnclosingType(method.getEnclosingElement()); |
150 NodeData node = (NodeData) templateMethod.getTemplate(); | 153 NodeData node = (NodeData) templateMethod.getTemplate(); |
151 | 154 |
152 boolean accessible = templateMethod.canBeAccessedByInstanceOf(node.getNodeType()); | 155 boolean accessible = templateMethod.canBeAccessedByInstanceOf(node.getNodeType()); |
153 if (accessible) { | 156 if (accessible) { |
417 builder.end(); // block | 420 builder.end(); // block |
418 } | 421 } |
419 return builder.getRoot(); | 422 return builder.getRoot(); |
420 } | 423 } |
421 | 424 |
425 private void emitEncounteredSynthetic(CodeTreeBuilder builder) { | |
426 builder.startThrow().startNew(getContext().getType(UnsupportedOperationException.class)).end().end(); | |
427 } | |
428 | |
422 @Override | 429 @Override |
423 protected void createChildren(NodeData node) { | 430 protected void createChildren(NodeData node) { |
424 Map<NodeData, List<TypeElement>> childTypes = new LinkedHashMap<>(); | 431 Map<NodeData, List<TypeElement>> childTypes = new LinkedHashMap<>(); |
425 if (node.getDeclaredChildren() != null && !node.getDeclaredChildren().isEmpty()) { | 432 if (node.getDeclaredChildren() != null && !node.getDeclaredChildren().isEmpty()) { |
426 for (NodeData nodeChild : node.getDeclaredChildren()) { | 433 for (NodeData nodeChild : node.getDeclaredChildren()) { |
985 private void emitInvokeDoMethod(CodeTreeBuilder builder, SpecializationData specialization, int level) { | 992 private void emitInvokeDoMethod(CodeTreeBuilder builder, SpecializationData specialization, int level) { |
986 if (!specialization.getExceptions().isEmpty()) { | 993 if (!specialization.getExceptions().isEmpty()) { |
987 builder.startTryBlock(); | 994 builder.startTryBlock(); |
988 } | 995 } |
989 | 996 |
990 builder.startReturn(); | 997 if (specialization.isSynthetic()) { |
991 startCallOperationMethod(builder, specialization, true); | 998 emitEncounteredSynthetic(builder); |
992 addValueParameterNamesWithCasts(builder, specialization.getNode().getGenericSpecialization(), specialization, false); | 999 } else { |
993 builder.end().end(); // start call operation | 1000 builder.startReturn(); |
994 builder.end(); // return | 1001 startCallOperationMethod(builder, specialization, true); |
1002 addValueParameterNamesWithCasts(builder, specialization.getNode().getGenericSpecialization(), specialization, false); | |
1003 builder.end().end(); // start call operation | |
1004 builder.end(); // return | |
1005 } | |
995 | 1006 |
996 if (!specialization.getExceptions().isEmpty()) { | 1007 if (!specialization.getExceptions().isEmpty()) { |
997 for (SpecializationThrowsData exception : specialization.getExceptions()) { | 1008 for (SpecializationThrowsData exception : specialization.getExceptions()) { |
998 builder.end().startCatchBlock(exception.getJavaClass(), "ex" + level); | 1009 builder.end().startCatchBlock(exception.getJavaClass(), "ex" + level); |
999 | 1010 |
1003 builder.end().end(); | 1014 builder.end().end(); |
1004 } | 1015 } |
1005 builder.end(); | 1016 builder.end(); |
1006 } | 1017 } |
1007 } | 1018 } |
1019 | |
1008 } | 1020 } |
1009 | 1021 |
1010 private class SpecializedNodeFactory extends ClassElementFactory<SpecializationData> { | 1022 private class SpecializedNodeFactory extends ClassElementFactory<SpecializationData> { |
1011 | 1023 |
1012 public SpecializedNodeFactory(ProcessorContext context) { | 1024 public SpecializedNodeFactory(ProcessorContext context) { |
1195 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | 1207 CodeTreeBuilder builder = new CodeTreeBuilder(parent); |
1196 if (!specialization.getExceptions().isEmpty()) { | 1208 if (!specialization.getExceptions().isEmpty()) { |
1197 builder.startTryBlock(); | 1209 builder.startTryBlock(); |
1198 } | 1210 } |
1199 | 1211 |
1200 if ((specialization.isUninitialized() || specialization.isGeneric()) && node.needsRewrites(getContext())) { | 1212 if (specialization.getMethod() == null) { |
1213 emitEncounteredSynthetic(builder); | |
1214 } else if (specialization.isUninitialized() || specialization.isGeneric()) { | |
1201 builder.startReturn().startCall(factoryClassName(node), generatedGenericMethodName(null)); | 1215 builder.startReturn().startCall(factoryClassName(node), generatedGenericMethodName(null)); |
1202 builder.string("this"); | 1216 builder.string("this"); |
1203 addValueParameterNames(builder, specialization, null, true, true); | 1217 addValueParameterNames(builder, specialization, null, true, true); |
1204 builder.end().end(); | 1218 builder.end().end(); |
1205 } else { | 1219 } else { |
1206 builder.startReturn(); | 1220 builder.startReturn(); |
1207 | 1221 |
1208 if (specialization.isUninitialized()) { | 1222 startCallOperationMethod(builder, specialization, false); |
1209 startCallOperationMethod(builder, specialization.getNode().getGenericSpecialization(), false); | |
1210 } else { | |
1211 startCallOperationMethod(builder, specialization, false); | |
1212 } | |
1213 addValueParameterNames(builder, specialization, null, false, false); | 1223 addValueParameterNames(builder, specialization, null, false, false); |
1224 | |
1214 builder.end().end(); // operation call | 1225 builder.end().end(); // operation call |
1215 builder.end(); // return | 1226 builder.end(); // return |
1216 } | 1227 } |
1217 | 1228 |
1218 if (!specialization.getExceptions().isEmpty()) { | 1229 if (!specialization.getExceptions().isEmpty()) { |