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()) {