comparison graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java @ 8237:6b74ffe38183

Implemented support for executing nodes in @Children fields.
author Christian Humer <christian.humer@gmail.com>
date Fri, 01 Mar 2013 17:03:57 +0100
parents 3c68170fc9b0
children ac4e8c16ffdf
comparison
equal deleted inserted replaced
7860:dbbdc0a30a16 8237:6b74ffe38183
78 } 78 }
79 } 79 }
80 return name; 80 return name;
81 } 81 }
82 82
83 private static String valueName(NodeFieldData field) {
84 return field.getName() + "Value";
85 }
86
87 private static String valueName(ActualParameter param) { 83 private static String valueName(ActualParameter param) {
88 NodeData node = (NodeData) param.getMethod().getTemplate(); 84 return param.getName();
89 NodeFieldData field = node.findField(param.getSpecification().getName());
90 if (field != null) {
91 return valueName(field);
92 } else {
93 return param.getSpecification().getName();
94 }
95 } 85 }
96 86
97 private static String castValueName(ActualParameter parameter) { 87 private static String castValueName(ActualParameter parameter) {
98 return valueName(parameter) + "Cast"; 88 return valueName(parameter) + "Cast";
99 } 89 }
100 90
101 private static String castValueName(NodeFieldData field) {
102 return valueName(field) + "Cast";
103 }
104
105 private void addValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame) { 91 private void addValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame) {
106 if (forceFrame) { 92 if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) {
107 method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frame")); 93 method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue"));
108 } 94 }
109 for (ActualParameter parameter : specialization.getParameters()) { 95 for (ActualParameter parameter : specialization.getParameters()) {
110 ParameterSpec spec = parameter.getSpecification(); 96 ParameterSpec spec = parameter.getSpecification();
111 if (forceFrame && spec.getName().equals("frame")) { 97 if (forceFrame && spec.getName().equals("frame")) {
112 continue; 98 continue;
114 method.addParameter(new CodeVariableElement(parameter.getActualType(), valueName(parameter))); 100 method.addParameter(new CodeVariableElement(parameter.getActualType(), valueName(parameter)));
115 } 101 }
116 } 102 }
117 103
118 private static void addValueParameterNames(CodeTreeBuilder builder, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame) { 104 private static void addValueParameterNames(CodeTreeBuilder builder, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame) {
119 if (forceFrame) { 105 if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) {
120 builder.string("frame"); 106 builder.string("frameValue");
121 } 107 }
122 for (ActualParameter parameter : specialization.getParameters()) { 108 for (ActualParameter parameter : specialization.getParameters()) {
123 ParameterSpec spec = parameter.getSpecification(); 109 ParameterSpec spec = parameter.getSpecification();
124 if (forceFrame && spec.getName().equals("frame")) { 110 if (forceFrame && spec.getName().equals("frame")) {
125 continue; 111 continue;
126 } 112 }
127 113
128 if (unexpectedValueName != null && spec.getName().equals(unexpectedValueName)) { 114 if (unexpectedValueName != null && parameter.getName().equals(unexpectedValueName)) {
129 builder.string("ex.getResult()"); 115 builder.string("ex.getResult()");
130 } else { 116 } else {
131 builder.string(valueName(parameter)); 117 builder.string(valueName(parameter));
132 } 118 }
133 } 119 }
136 private static void addValueParameterNamesWithCasts(CodeTreeBuilder body, SpecializationData valueSpecialization, SpecializationData targetSpecialization) { 122 private static void addValueParameterNamesWithCasts(CodeTreeBuilder body, SpecializationData valueSpecialization, SpecializationData targetSpecialization) {
137 NodeData node = targetSpecialization.getNode(); 123 NodeData node = targetSpecialization.getNode();
138 TypeSystemData typeSystem = node.getTypeSystem(); 124 TypeSystemData typeSystem = node.getTypeSystem();
139 125
140 for (ActualParameter targetParameter : targetSpecialization.getParameters()) { 126 for (ActualParameter targetParameter : targetSpecialization.getParameters()) {
141 ActualParameter valueParameter = valueSpecialization.findParameter(targetParameter.getSpecification().getName()); 127 ActualParameter valueParameter = valueSpecialization.findParameter(targetParameter.getName());
142 TypeData targetType = targetParameter.getActualTypeData(typeSystem); 128 TypeData targetType = targetParameter.getActualTypeData(typeSystem);
143 129
144 TypeData valueType = null; 130 TypeData valueType = null;
145 if (valueParameter != null) { 131 if (valueParameter != null) {
146 valueType = valueParameter.getActualTypeData(typeSystem); 132 valueType = valueParameter.getActualTypeData(typeSystem);
274 260
275 return builder.isEmpty() ? null : builder.getRoot(); 261 return builder.isEmpty() ? null : builder.getRoot();
276 } 262 }
277 263
278 private CodeTree createCasts(CodeTreeBuilder parent, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) { 264 private CodeTree createCasts(CodeTreeBuilder parent, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) {
279 NodeData node = guardedSpecialization.getNode();
280
281 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 265 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
282 // Implict guards based on method signature 266 // Implict guards based on method signature
283 for (NodeFieldData field : node.getFields()) { 267 for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
284 ActualParameter guardedParam = guardedSpecialization.findParameter(field.getName()); 268 NodeFieldData field = guardedSpecialization.getNode().findField(guardedParam.getSpecification().getName());
285 ActualParameter valueParam = valueSpecialization.findParameter(field.getName()); 269 if (field == null) {
270 continue;
271 }
272 ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getName());
286 273
287 CodeTree cast = createCast(parent, field, valueParam, guardedParam); 274 CodeTree cast = createCast(parent, field, valueParam, guardedParam);
288 if (cast == null) { 275 if (cast == null) {
289 continue; 276 continue;
290 } 277 }
293 280
294 return builder.getRoot(); 281 return builder.getRoot();
295 } 282 }
296 283
297 private CodeTree createImplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) { 284 private CodeTree createImplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) {
298 NodeData node = guardedSpecialization.getNode();
299
300 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 285 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
301 // Implict guards based on method signature 286 // Implict guards based on method signature
302 String andOperator = conditionPrefix != null ? conditionPrefix + " && " : ""; 287 String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
303 for (NodeFieldData field : node.getFields()) { 288 for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
304 ActualParameter guardedParam = guardedSpecialization.findParameter(field.getName()); 289 NodeFieldData field = guardedSpecialization.getNode().findField(guardedParam.getSpecification().getName());
305 ActualParameter valueParam = valueSpecialization.findParameter(field.getName()); 290 if (field == null) {
291 continue;
292 }
293 ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getName());
306 294
307 CodeTree implicitGuard = createImplicitGuard(builder, field, valueParam, guardedParam); 295 CodeTree implicitGuard = createImplicitGuard(builder, field, valueParam, guardedParam);
308 if (implicitGuard == null) { 296 if (implicitGuard == null) {
309 continue; 297 continue;
310 } 298 }
337 builder.string("!").string(valueName(shortCircuit)); 325 builder.string("!").string(valueName(shortCircuit));
338 builder.string(" || "); 326 builder.string(" || ");
339 } 327 }
340 328
341 startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.isTypeMethodName(target.getActualTypeData(node.getTypeSystem()))); 329 startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.isTypeMethodName(target.getActualTypeData(node.getTypeSystem())));
342 builder.string(valueName(field)); 330 builder.string(valueName(source));
343 builder.end().end(); // call 331 builder.end().end(); // call
344 332
345 if (field.isShortCircuit()) { 333 if (field.isShortCircuit()) {
346 builder.string(")"); 334 builder.string(")");
347 } 335 }
369 condition = CodeTreeBuilder.singleString(valueName(shortCircuit)); 357 condition = CodeTreeBuilder.singleString(valueName(shortCircuit));
370 } 358 }
371 359
372 CodeTree value = createCallTypeSystemMethod(context, parent, node, TypeSystemCodeGenerator.asTypeMethodName(targetType), valueName(target)); 360 CodeTree value = createCallTypeSystemMethod(context, parent, node, TypeSystemCodeGenerator.asTypeMethodName(targetType), valueName(target));
373 361
374 return createLazyAssignment(parent, castValueName(field), target.getActualType(), condition, value); 362 return createLazyAssignment(parent, castValueName(target), target.getActualType(), condition, value);
375 } 363 }
376 364
377 /** 365 /**
378 * <pre> 366 * <pre>
379 * variant1 $condition != null 367 * variant1 $condition != null
979 continue; 967 continue;
980 } 968 }
981 CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), execType.getMethod()); 969 CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), execType.getMethod());
982 if (method.getParameters().size() == 1) { 970 if (method.getParameters().size() == 1) {
983 CodeVariableElement var = CodeVariableElement.clone(method.getParameters().get(0)); 971 CodeVariableElement var = CodeVariableElement.clone(method.getParameters().get(0));
984 var.setName("frame"); 972 var.setName("frameValue");
985 method.getParameters().set(0, var); 973 method.getParameters().set(0, var);
986 } 974 }
987 method.getModifiers().remove(Modifier.ABSTRACT); 975 method.getModifiers().remove(Modifier.ABSTRACT);
988 clazz.add(method); 976 clazz.add(method);
989 977
994 buildCastingExecuteMethod(method.createBuilder(), specialization, execType.getType()); 982 buildCastingExecuteMethod(method.createBuilder(), specialization, execType.getType());
995 } 983 }
996 } 984 }
997 985
998 if (node.needsRewrites(getContext()) && !specialization.isGeneric() && !specialization.isUninitialized()) { 986 if (node.needsRewrites(getContext()) && !specialization.isGeneric() && !specialization.isUninitialized()) {
999 buildSpecializeStateMethod(clazz, specialization); 987 buildSpecializeAndExecute(clazz, specialization);
1000 } 988 }
1001 } 989 }
1002 990
1003 private void buildCastingExecuteMethod(CodeTreeBuilder builder, SpecializationData specialization, TypeData type) { 991 private void buildCastingExecuteMethod(CodeTreeBuilder builder, SpecializationData specialization, TypeData type) {
1004 NodeData node = specialization.getNode(); 992 NodeData node = specialization.getNode();
1012 boolean returnVoid = type.isVoid(); 1000 boolean returnVoid = type.isVoid();
1013 1001
1014 CodeTree primaryExecuteCall = null; 1002 CodeTree primaryExecuteCall = null;
1015 1003
1016 CodeTreeBuilder executeBuilder = CodeTreeBuilder.createBuilder(); 1004 CodeTreeBuilder executeBuilder = CodeTreeBuilder.createBuilder();
1017 buildExecute(executeBuilder, null, execType); 1005 buildExecute(executeBuilder, null, null, execType);
1018 primaryExecuteCall = executeBuilder.getRoot(); 1006 primaryExecuteCall = executeBuilder.getRoot();
1019 1007
1020 if (needsTry) { 1008 if (needsTry) {
1021 if (!returnVoid) { 1009 if (!returnVoid) {
1022 builder.declaration(primaryType.getPrimitiveType(), "value"); 1010 builder.declaration(primaryType.getPrimitiveType(), "value");
1166 return builder.getRoot(); 1154 return builder.getRoot();
1167 } 1155 }
1168 1156
1169 private CodeTree createExecuteChildren(CodeTreeBuilder parent, SpecializationData specialization) { 1157 private CodeTree createExecuteChildren(CodeTreeBuilder parent, SpecializationData specialization) {
1170 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 1158 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
1171 for (NodeFieldData field : specialization.getNode().getFields()) { 1159 for (ActualParameter parameter : specialization.getParameters()) {
1172 if (field.getExecutionKind() == ExecutionKind.IGNORE) { 1160 NodeFieldData field = specialization.getNode().findField(parameter.getSpecification().getName());
1161 if (field == null) {
1173 continue; 1162 continue;
1174 } 1163 }
1175 1164
1176 ActualParameter parameterType = specialization.findParameter(field.getName()); 1165 if (parameter.getActualTypeData(specialization.getNode().getTypeSystem()).isGeneric()) {
1177 1166 buildGenericValueExecute(builder, specialization, parameter, field, null);
1178 if (parameterType.getActualTypeData(specialization.getNode().getTypeSystem()).isGeneric()) {
1179 buildGenericValueExecute(builder, specialization, field, null);
1180 } else { 1167 } else {
1181 buildSpecializedValueExecute(builder, specialization, field); 1168 buildSpecializedValueExecute(builder, specialization, parameter, field);
1182 } 1169 }
1183 } 1170 }
1184 return builder.getRoot(); 1171 return builder.getRoot();
1185 } 1172 }
1186 1173
1192 builder.end().end(); 1179 builder.end().end();
1193 builder.end(); // statement 1180 builder.end(); // statement
1194 } 1181 }
1195 } 1182 }
1196 1183
1197 private void buildGenericValueExecute(CodeTreeBuilder builder, SpecializationData specialization, NodeFieldData field, NodeFieldData exceptionSpec) { 1184 private void buildGenericValueExecute(CodeTreeBuilder builder, SpecializationData specialization, ActualParameter param, NodeFieldData field, ActualParameter exceptionParam) {
1198 ActualParameter specParameter = specialization.findParameter(field.getName());
1199 NodeData node = specialization.getNode(); 1185 NodeData node = specialization.getNode();
1200 boolean shortCircuit = startShortCircuit(builder, specialization, field, exceptionSpec); 1186 boolean shortCircuit = startShortCircuit(builder, specialization, param, exceptionParam);
1201 1187
1202 builder.startStatement(); 1188 builder.startStatement();
1203 if (!shortCircuit) { 1189 if (!shortCircuit) {
1204 builder.type(specialization.getNode().getTypeSystem().getGenericType()); 1190 builder.type(specialization.getNode().getTypeSystem().getGenericType());
1205 builder.string(" "); 1191 builder.string(" ");
1206 } 1192 }
1207 1193
1208 builder.string(valueName(specParameter)); 1194 builder.string(valueName(param));
1209 builder.string(" = "); 1195 builder.string(" = ");
1210 ExecutableTypeData genericExecutableType = field.getNodeData().findGenericExecutableType(getContext(), specParameter.getActualTypeData(node.getTypeSystem())); 1196 ExecutableTypeData genericExecutableType = field.getNodeData().findGenericExecutableType(getContext(), param.getActualTypeData(node.getTypeSystem()));
1211 if (genericExecutableType == null) { 1197 if (genericExecutableType == null) {
1212 throw new AssertionError("Must have generic executable type. Parser validation most likely failed. " + Arrays.toString(field.getNodeData().getExecutableTypes())); 1198 throw new AssertionError("Must have generic executable type. Parser validation most likely failed. " + Arrays.toString(field.getNodeData().getExecutableTypes()));
1213 } 1199 }
1214 buildExecute(builder, field, genericExecutableType); 1200 buildExecute(builder, param, field, genericExecutableType);
1215 builder.end(); 1201 builder.end();
1216 1202
1217 endShortCircuit(builder, shortCircuit); 1203 endShortCircuit(builder, shortCircuit);
1218 } 1204 }
1219 1205
1220 private void buildExecute(CodeTreeBuilder builder, NodeFieldData field, ExecutableTypeData execType) { 1206 private void buildExecute(CodeTreeBuilder builder, ActualParameter parameter, NodeFieldData field, ExecutableTypeData execType) {
1221 if (field != null) { 1207 if (field != null) {
1222 Element accessElement = field.getAccessElement(); 1208 Element accessElement = field.getAccessElement();
1223 if (accessElement.getKind() == ElementKind.METHOD) { 1209 if (accessElement.getKind() == ElementKind.METHOD) {
1224 builder.startCall(accessElement.getSimpleName().toString()).end(); 1210 builder.startCall(accessElement.getSimpleName().toString()).end();
1225 } else if (accessElement.getKind() == ElementKind.FIELD) { 1211 } else if (accessElement.getKind() == ElementKind.FIELD) {
1226 builder.string("this.").string(accessElement.getSimpleName().toString()); 1212 builder.string("this.").string(accessElement.getSimpleName().toString());
1227 } else { 1213 } else {
1228 throw new AssertionError(); 1214 throw new AssertionError();
1229 } 1215 }
1216 if (parameter.getSpecification().isIndexed()) {
1217 builder.string("[" + parameter.getIndex() + "]");
1218 }
1230 builder.string("."); 1219 builder.string(".");
1231 } 1220 }
1232 builder.startCall(execType.getMethodName()); 1221 builder.startCall(execType.getMethodName());
1233 if (execType.getParameters().length == 1) { 1222 if (execType.getParameters().length == 1) {
1234 builder.string("frame"); 1223 builder.string("frameValue");
1235 } 1224 }
1236 builder.end(); 1225 builder.end();
1237 } 1226 }
1238 1227
1239 private void buildSpecializedValueExecute(CodeTreeBuilder builder, SpecializationData specialization, NodeFieldData field) { 1228 private void buildSpecializedValueExecute(CodeTreeBuilder builder, SpecializationData specialization, ActualParameter param, NodeFieldData field) {
1240 ActualParameter param = specialization.findParameter(field.getName()); 1229 boolean shortCircuit = startShortCircuit(builder, specialization, param, null);
1241 boolean shortCircuit = startShortCircuit(builder, specialization, field, null);
1242 1230
1243 if (!shortCircuit) { 1231 if (!shortCircuit) {
1244 builder.startStatement().type(param.getActualType()).string(" ").string(valueName(param)).end(); 1232 builder.startStatement().type(param.getActualType()).string(" ").string(valueName(param)).end();
1245 } 1233 }
1246 1234
1248 1236
1249 if (execType.hasUnexpectedValue(getContext())) { 1237 if (execType.hasUnexpectedValue(getContext())) {
1250 builder.startTryBlock(); 1238 builder.startTryBlock();
1251 } 1239 }
1252 1240
1253 builder.startStatement().string(valueName(field)).string(" = "); 1241 builder.startStatement().string(valueName(param)).string(" = ");
1254 buildExecute(builder, field, execType); 1242 buildExecute(builder, param, field, execType);
1255 builder.end(); 1243 builder.end();
1256 1244
1257 if (execType.hasUnexpectedValue(getContext())) { 1245 if (execType.hasUnexpectedValue(getContext())) {
1258 builder.end().startCatchBlock(getUnexpectedValueException(), "ex"); 1246 builder.end().startCatchBlock(getUnexpectedValueException(), "ex");
1247 SpecializationData generic = specialization.getNode().getGenericSpecialization();
1259 boolean execute = false; 1248 boolean execute = false;
1260 for (NodeFieldData exField : specialization.getNode().getFields()) { 1249 for (ActualParameter exParam : generic.getParameters()) {
1261 if (exField.getExecutionKind() == ExecutionKind.IGNORE) { 1250 NodeFieldData exField = generic.getNode().findField(exParam.getSpecification().getName());
1251 if (exField == null) {
1262 continue; 1252 continue;
1263 } 1253 }
1264 if (execute) { 1254 if (execute) {
1265 buildGenericValueExecute(builder, specialization.getNode().getGenericSpecialization(), exField, field); 1255 buildGenericValueExecute(builder, specialization.getNode().getGenericSpecialization(), exParam, exField, param);
1266 } else if (exField == field) { 1256 } else if (exParam.getName().equals(param.getName())) {
1267 execute = true; 1257 execute = true;
1268 } 1258 }
1269 } 1259 }
1270 builder.tree(createReturnSpecializeAndExecute(builder, specialization.findNextSpecialization(), param.getSpecification())); 1260 builder.tree(createReturnSpecializeAndExecute(builder, specialization.findNextSpecialization(), param));
1271 builder.end(); // catch block 1261 builder.end(); // catch block
1272 } 1262 }
1273 1263
1274 endShortCircuit(builder, shortCircuit); 1264 endShortCircuit(builder, shortCircuit);
1275 builder.newLine(); 1265 builder.newLine();
1276 } 1266 }
1277 1267
1278 private boolean startShortCircuit(CodeTreeBuilder builder, SpecializationData specialization, NodeFieldData forField, NodeFieldData exceptionField) { 1268 private boolean startShortCircuit(CodeTreeBuilder builder, SpecializationData specialization, ActualParameter parameter, ActualParameter exceptionParam) {
1269 NodeFieldData forField = specialization.getNode().findField(parameter.getSpecification().getName());
1270 if (forField == null) {
1271 return false;
1272 }
1273
1279 if (forField.getExecutionKind() != ExecutionKind.SHORT_CIRCUIT) { 1274 if (forField.getExecutionKind() != ExecutionKind.SHORT_CIRCUIT) {
1280 return false; 1275 return false;
1281 } 1276 }
1282 1277
1283 ActualParameter parameter = specialization.findParameter(forField.getName());
1284 ActualParameter shortCircuitParam = specialization.getPreviousParam(parameter); 1278 ActualParameter shortCircuitParam = specialization.getPreviousParam(parameter);
1285 1279
1286 int shortCircuitIndex = 0; 1280 int shortCircuitIndex = 0;
1287 for (NodeFieldData field : specialization.getNode().getFields()) { 1281 for (NodeFieldData field : specialization.getNode().getFields()) {
1288 if (field.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT) { 1282 if (field.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT) {
1295 1289
1296 builder.startStatement().type(shortCircuitParam.getActualType()).string(" ").string(valueName(shortCircuitParam)).string(" = "); 1290 builder.startStatement().type(shortCircuitParam.getActualType()).string(" ").string(valueName(shortCircuitParam)).string(" = ");
1297 ShortCircuitData shortCircuitData = specialization.getShortCircuits()[shortCircuitIndex]; 1291 ShortCircuitData shortCircuitData = specialization.getShortCircuits()[shortCircuitIndex];
1298 1292
1299 startCallOperationMethod(builder, shortCircuitData); 1293 startCallOperationMethod(builder, shortCircuitData);
1300 addValueParameterNames(builder, shortCircuitData, exceptionField != null ? exceptionField.getName() : null, false); 1294 addValueParameterNames(builder, shortCircuitData, exceptionParam != null ? exceptionParam.getName() : null, false);
1301 builder.end().end(); // call operation 1295 builder.end().end(); // call operation
1302 1296
1303 builder.end(); // statement 1297 builder.end(); // statement
1304 1298
1305 builder.declaration(parameter.getActualType(), valueName(parameter), CodeTreeBuilder.createBuilder().defaultValue(parameter.getActualType())); 1299 builder.declaration(parameter.getActualType(), valueName(parameter), CodeTreeBuilder.createBuilder().defaultValue(parameter.getActualType()));
1306 builder.startIf().string(shortCircuitParam.getSpecification().getName()).end(); 1300 builder.startIf().string(shortCircuitParam.getName()).end();
1307 builder.startBlock(); 1301 builder.startBlock();
1308 1302
1309 return true; 1303 return true;
1310 } 1304 }
1311 1305
1313 if (shortCircuit) { 1307 if (shortCircuit) {
1314 builder.end(); 1308 builder.end();
1315 } 1309 }
1316 } 1310 }
1317 1311
1318 private CodeTree createReturnSpecializeAndExecute(CodeTreeBuilder parent, SpecializationData nextSpecialization, ParameterSpec exceptionSpec) { 1312 private CodeTree createReturnSpecializeAndExecute(CodeTreeBuilder parent, SpecializationData nextSpecialization, ActualParameter exceptionParam) {
1319 CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent); 1313 CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent);
1320 specializeCall.startCall("specializeAndExecute"); 1314 specializeCall.startCall("specializeAndExecute");
1321 specializeCall.string(nodeClassName(nextSpecialization) + ".class"); 1315 specializeCall.string(nodeClassName(nextSpecialization) + ".class");
1322 addValueParameterNames(specializeCall, nextSpecialization.getNode().getGenericSpecialization(), exceptionSpec != null ? exceptionSpec.getName() : null, true); 1316 addValueParameterNames(specializeCall, nextSpecialization.getNode().getGenericSpecialization(), exceptionParam != null ? exceptionParam.getName() : null, true);
1323 specializeCall.end().end(); 1317 specializeCall.end().end();
1324 1318
1325 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 1319 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
1326 builder.startReturn(); 1320 builder.startReturn();
1327 builder.tree(specializeCall.getRoot()); 1321 builder.tree(specializeCall.getRoot());
1328 builder.end(); 1322 builder.end();
1329 return builder.getRoot(); 1323 return builder.getRoot();
1330 } 1324 }
1331 1325
1332 private void buildSpecializeStateMethod(CodeTypeElement clazz, SpecializationData specialization) { 1326 private void buildSpecializeAndExecute(CodeTypeElement clazz, SpecializationData specialization) {
1333 NodeData node = specialization.getNode(); 1327 NodeData node = specialization.getNode();
1334 TypeData returnType = specialization.getReturnType().getActualTypeData(node.getTypeSystem()); 1328 TypeData returnType = specialization.getReturnType().getActualTypeData(node.getTypeSystem());
1335 ExecutableTypeData returnExecutableType = node.findExecutableType(returnType); 1329 ExecutableTypeData returnExecutableType = node.findExecutableType(returnType);
1336 boolean canThrowUnexpected = returnExecutableType == null ? true : returnExecutableType.hasUnexpectedValue(getContext()); 1330 boolean canThrowUnexpected = returnExecutableType == null ? true : returnExecutableType.hasUnexpectedValue(getContext());
1337 1331