comparison graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java @ 7847:06a7cd6aaf00

Casting is now done on demand using local variables for explicit guards.
author Christian Humer <christian.humer@gmail.com>
date Tue, 19 Feb 2013 17:20:45 +0100
parents 91cc98eae8ee
children 6e4fb0ccebb1
comparison
equal deleted inserted replaced
7846:91cc98eae8ee 7847:06a7cd6aaf00
81 81
82 private static String valueName(NodeFieldData field) { 82 private static String valueName(NodeFieldData field) {
83 return field.getName() + "Value"; 83 return field.getName() + "Value";
84 } 84 }
85 85
86 private static String valueName(TemplateMethod method, ActualParameter param) { 86 private static String valueName(ActualParameter param) {
87 NodeData node = (NodeData) method.getTemplate(); 87 NodeData node = (NodeData) param.getMethod().getTemplate();
88 NodeFieldData field = node.findField(param.getSpecification().getName()); 88 NodeFieldData field = node.findField(param.getSpecification().getName());
89 if (field != null) { 89 if (field != null) {
90 return valueName(field); 90 return valueName(field);
91 } else { 91 } else {
92 return param.getSpecification().getName(); 92 return param.getSpecification().getName();
93 } 93 }
94 } 94 }
95 95
96 private static String castValueName(ActualParameter parameter) {
97 return valueName(parameter) + "Cast";
98 }
99
100 private static String castValueName(NodeFieldData field) {
101 return valueName(field) + "Cast";
102 }
103
96 private void addValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame) { 104 private void addValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame) {
97 if (forceFrame) { 105 if (forceFrame) {
98 method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frame")); 106 method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frame"));
99 } 107 }
100 for (ActualParameter parameter : specialization.getParameters()) { 108 for (ActualParameter parameter : specialization.getParameters()) {
101 ParameterSpec spec = parameter.getSpecification(); 109 ParameterSpec spec = parameter.getSpecification();
102 if (forceFrame && spec.getName().equals("frame")) { 110 if (forceFrame && spec.getName().equals("frame")) {
103 continue; 111 continue;
104 } 112 }
105 method.addParameter(new CodeVariableElement(parameter.getActualType(), valueName(specialization, parameter))); 113 method.addParameter(new CodeVariableElement(parameter.getActualType(), valueName(parameter)));
106 } 114 }
107 } 115 }
108 116
109 private static void addValueParameterNames(CodeTreeBuilder builder, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame) { 117 private static void addValueParameterNames(CodeTreeBuilder builder, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame) {
110 if (forceFrame) { 118 if (forceFrame) {
117 } 125 }
118 126
119 if (unexpectedValueName != null && spec.getName().equals(unexpectedValueName)) { 127 if (unexpectedValueName != null && spec.getName().equals(unexpectedValueName)) {
120 builder.string("ex.getResult()"); 128 builder.string("ex.getResult()");
121 } else { 129 } else {
122 builder.string(valueName(specialization, parameter)); 130 builder.string(valueName(parameter));
123 } 131 }
124 } 132 }
125 } 133 }
126 134
127 private static void addValueParameterNamesWithCasts(ProcessorContext context, CodeTreeBuilder body, SpecializationData valueSpecialization, SpecializationData targetSpecialization) { 135 private static void addValueParameterNamesWithCasts(CodeTreeBuilder body, SpecializationData valueSpecialization, SpecializationData targetSpecialization) {
128 NodeData node = targetSpecialization.getNode(); 136 NodeData node = targetSpecialization.getNode();
129 TypeSystemData typeSystem = node.getTypeSystem(); 137 TypeSystemData typeSystem = node.getTypeSystem();
130 138
131 for (ActualParameter targetParameter : targetSpecialization.getParameters()) { 139 for (ActualParameter targetParameter : targetSpecialization.getParameters()) {
132 ActualParameter valueParameter = valueSpecialization.findParameter(targetParameter.getSpecification().getName()); 140 ActualParameter valueParameter = valueSpecialization.findParameter(targetParameter.getSpecification().getName());
136 if (valueParameter != null) { 144 if (valueParameter != null) {
137 valueType = valueParameter.getActualTypeData(typeSystem); 145 valueType = valueParameter.getActualTypeData(typeSystem);
138 } 146 }
139 147
140 if (targetType == null || targetType.isGeneric() || (valueType != null && valueType.equalsType(targetType))) { 148 if (targetType == null || targetType.isGeneric() || (valueType != null && valueType.equalsType(targetType))) {
141 body.string(valueName(targetSpecialization, targetParameter)); 149 body.string(valueName(targetParameter));
142 } else { 150 } else {
143 String methodName = TypeSystemCodeGenerator.asTypeMethodName(targetType); 151 body.string(castValueName(targetParameter));
144 startCallTypeSystemMethod(context, body, node, methodName);
145 body.string(valueName(targetSpecialization, targetParameter));
146 body.end().end();
147 } 152 }
148 } 153 }
149 } 154 }
150 155
151 private static String genClassName(Template operation) { 156 private static String genClassName(Template operation) {
182 prev = current; 187 prev = current;
183 } 188 }
184 return prefix; 189 return prefix;
185 } 190 }
186 191
192 private static CodeTree createCallTypeSystemMethod(ProcessorContext context, CodeTreeBuilder parent, NodeData node, String methodName, String value) {
193 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
194 startCallTypeSystemMethod(context, builder, node, methodName);
195 builder.string(value);
196 builder.end().end();
197 return builder.getRoot();
198 }
199
187 private static void startCallTypeSystemMethod(ProcessorContext context, CodeTreeBuilder body, NodeData node, String methodName) { 200 private static void startCallTypeSystemMethod(ProcessorContext context, CodeTreeBuilder body, NodeData node, String methodName) {
188 VariableElement singleton = TypeSystemCodeGenerator.findSingleton(context, node.getTypeSystem()); 201 VariableElement singleton = TypeSystemCodeGenerator.findSingleton(context, node.getTypeSystem());
189 assert singleton != null; 202 assert singleton != null;
190 203
191 body.startGroup(); 204 body.startGroup();
192 body.staticReference(singleton.getEnclosingElement().asType(), singleton.getSimpleName().toString()); 205 body.staticReference(singleton.getEnclosingElement().asType(), singleton.getSimpleName().toString());
193 body.string(".").startCall(methodName); 206 body.string(".").startCall(methodName);
194 } 207 }
195 208
196 private static CodeTree createGuardAndCast(ProcessorContext context, CodeTreeBuilder parent, String prefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization, 209 private CodeTree createGuardAndCast(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization, boolean onSpecialization,
197 boolean onSpecialization, CodeTree guardedStatements, CodeTree elseStatements) { 210 CodeTree guardedStatements, CodeTree elseStatements) {
198 211
199 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 212 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
200 CodeTree implicitGuards = createImplicitGuards(context, parent, prefix, valueSpecialization, guardedSpecialization); 213 CodeTree implicitGuards = createImplicitGuards(parent, conditionPrefix, valueSpecialization, guardedSpecialization);
201 CodeTree explicitGuards = createExplicitGuards(context, parent, implicitGuards == null ? prefix : null, valueSpecialization, guardedSpecialization, onSpecialization); 214 CodeTree explicitGuards = createExplicitGuards(parent, implicitGuards == null ? conditionPrefix : null, valueSpecialization, guardedSpecialization, onSpecialization);
202 215
203 int ifCount = 0; 216 int ifCount = 0;
204 217
205 if (implicitGuards != null) { 218 if (implicitGuards != null) {
206 builder.startIf(); 219 builder.startIf();
208 builder.end(); 221 builder.end();
209 builder.startBlock(); 222 builder.startBlock();
210 ifCount++; 223 ifCount++;
211 } 224 }
212 225
226 if (explicitGuards != null || !onSpecialization) {
227 builder.tree(createCasts(parent, valueSpecialization, guardedSpecialization));
228 }
229
213 if (explicitGuards != null) { 230 if (explicitGuards != null) {
214 builder.startIf(); 231 builder.startIf();
215 builder.tree(explicitGuards); 232 builder.tree(explicitGuards);
216 builder.end(); 233 builder.end();
217 builder.startBlock(); 234 builder.startBlock();
218 ifCount++; 235 ifCount++;
219 } 236 }
220 237
221 if (implicitGuards == null && explicitGuards == null && prefix != null && !prefix.isEmpty()) { 238 if (implicitGuards == null && explicitGuards == null && conditionPrefix != null && !conditionPrefix.isEmpty()) {
222 builder.startIf().string(prefix).end().startBlock(); 239 builder.startIf().string(conditionPrefix).end().startBlock();
223 ifCount++; 240 ifCount++;
224 } 241 }
225 242
226 builder.tree(guardedStatements); 243 builder.tree(guardedStatements);
227 244
233 } 250 }
234 251
235 return builder.getRoot(); 252 return builder.getRoot();
236 } 253 }
237 254
238 private static CodeTree createExplicitGuards(ProcessorContext context, CodeTreeBuilder parent, String prefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization, 255 private static CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization,
239 boolean onSpecialization) { 256 boolean onSpecialization) {
240 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 257 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
241 String andOperator = (prefix != null && !prefix.isEmpty()) ? (prefix + " && ") : ""; 258 String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
242 if (guardedSpecialization.getGuards().length > 0) { 259 if (guardedSpecialization.getGuards().length > 0) {
243 // Explicitly specified guards 260 // Explicitly specified guards
244 for (SpecializationGuardData guard : guardedSpecialization.getGuards()) { 261 for (SpecializationGuardData guard : guardedSpecialization.getGuards()) {
245 if ((guard.isOnSpecialization() && onSpecialization) || (guard.isOnExecution() && !onSpecialization)) { 262 if ((guard.isOnSpecialization() && onSpecialization) || (guard.isOnExecution() && !onSpecialization)) {
246 builder.string(andOperator); 263 builder.string(andOperator);
247 264
248 startCallOperationMethod(builder, guard.getGuardDeclaration()); 265 startCallOperationMethod(builder, guard.getGuardDeclaration());
249 addValueParameterNamesWithCasts(context, builder, valueSpecialization, guardedSpecialization); 266 addValueParameterNamesWithCasts(builder, valueSpecialization, guardedSpecialization);
250 267
251 builder.end().end(); // call 268 builder.end().end(); // call
252 andOperator = " && "; 269 andOperator = " && ";
253 } 270 }
254 } 271 }
255 } 272 }
256 273
257 return builder.isEmpty() ? null : builder.getRoot(); 274 return builder.isEmpty() ? null : builder.getRoot();
258 } 275 }
259 276
260 private static CodeTree createImplicitGuards(ProcessorContext context, CodeTreeBuilder parent, String prefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) { 277 private CodeTree createCasts(CodeTreeBuilder parent, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) {
261 NodeData node = guardedSpecialization.getNode(); 278 NodeData node = guardedSpecialization.getNode();
262 TypeSystemData typeSystem = node.getTypeSystem();
263 279
264 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 280 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
265 // Implict guards based on method signature 281 // Implict guards based on method signature
266 String andOperator = (prefix != null && !prefix.isEmpty()) ? (prefix + " && ") : "";
267 for (NodeFieldData field : node.getFields()) { 282 for (NodeFieldData field : node.getFields()) {
268 ActualParameter guardedParam = guardedSpecialization.findParameter(field.getName()); 283 ActualParameter guardedParam = guardedSpecialization.findParameter(field.getName());
269 ActualParameter valueParam = valueSpecialization.findParameter(field.getName()); 284 ActualParameter valueParam = valueSpecialization.findParameter(field.getName());
270 285
271 TypeData guardedType = guardedParam.getActualTypeData(typeSystem); 286 CodeTree cast = createCast(parent, field, valueParam, guardedParam);
272 TypeData valueType = valueParam.getActualTypeData(typeSystem); 287 if (cast == null) {
273
274 if (guardedType.equalsType(valueType) || guardedType.isGeneric()) {
275 continue; 288 continue;
276 } 289 }
290 builder.tree(cast);
291 }
292
293 return builder.getRoot();
294 }
295
296 private CodeTree createImplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) {
297 NodeData node = guardedSpecialization.getNode();
298
299 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
300 // Implict guards based on method signature
301 String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
302 for (NodeFieldData field : node.getFields()) {
303 ActualParameter guardedParam = guardedSpecialization.findParameter(field.getName());
304 ActualParameter valueParam = valueSpecialization.findParameter(field.getName());
305
306 CodeTree implicitGuard = createImplicitGuard(builder, field, valueParam, guardedParam);
307 if (implicitGuard == null) {
308 continue;
309 }
277 310
278 builder.string(andOperator); 311 builder.string(andOperator);
279 312 builder.tree(implicitGuard);
280 builder.startGroup();
281
282 if (field.isShortCircuit()) {
283 ActualParameter shortCircuit = guardedSpecialization.getPreviousParam(guardedParam);
284 builder.string("(");
285 builder.string("!").string(valueName(guardedSpecialization, shortCircuit));
286 builder.string(" || ");
287 }
288
289 startCallTypeSystemMethod(context, builder, guardedSpecialization.getNode(), TypeSystemCodeGenerator.isTypeMethodName(guardedType));
290 builder.string(valueName(guardedSpecialization, guardedParam));
291 builder.end().end(); // call
292
293 if (field.isShortCircuit()) {
294 builder.string(")");
295 }
296
297 builder.end(); // group
298 andOperator = " && "; 313 andOperator = " && ";
299 } 314 }
300 315
301 return builder.isEmpty() ? null : builder.getRoot(); 316 return builder.isEmpty() ? null : builder.getRoot();
317 }
318
319 private CodeTree createImplicitGuard(CodeTreeBuilder parent, NodeFieldData field, ActualParameter source, ActualParameter target) {
320 NodeData node = field.getNodeData();
321 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
322
323 TypeData targetType = target.getActualTypeData(node.getTypeSystem());
324 TypeData sourceType = source.getActualTypeData(node.getTypeSystem());
325
326 if (targetType.equalsType(sourceType) || targetType.isGeneric()) {
327 return null;
328 }
329
330 builder.startGroup();
331
332 if (field.isShortCircuit()) {
333 ActualParameter shortCircuit = target.getPreviousParameter();
334 assert shortCircuit != null;
335 builder.string("(");
336 builder.string("!").string(valueName(shortCircuit));
337 builder.string(" || ");
338 }
339
340 startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.isTypeMethodName(target.getActualTypeData(node.getTypeSystem())));
341 builder.string(valueName(field));
342 builder.end().end(); // call
343
344 if (field.isShortCircuit()) {
345 builder.string(")");
346 }
347
348 builder.end(); // group
349
350 return builder.getRoot();
351 }
352
353 private CodeTree createCast(CodeTreeBuilder parent, NodeFieldData field, ActualParameter source, ActualParameter target) {
354 NodeData node = field.getNodeData();
355 TypeSystemData typeSystem = node.getTypeSystem();
356
357 TypeData sourceType = source.getActualTypeData(typeSystem);
358 TypeData targetType = target.getActualTypeData(typeSystem);
359
360 if (targetType.equalsType(sourceType) || targetType.isGeneric()) {
361 return null;
362 }
363
364 CodeTree condition = null;
365 if (field.isShortCircuit()) {
366 ActualParameter shortCircuit = target.getPreviousParameter();
367 assert shortCircuit != null;
368 condition = CodeTreeBuilder.singleString(valueName(shortCircuit));
369 }
370
371 CodeTree value = createCallTypeSystemMethod(context, parent, node, TypeSystemCodeGenerator.asTypeMethodName(targetType), valueName(target));
372
373 return createLazyAssignment(parent, castValueName(field), target.getActualType(), condition, value);
374 }
375
376 /**
377 * <pre>
378 * variant1 $condition != null
379 *
380 * $type $name = defaultValue($type);
381 * if ($condition) {
382 * $name = $value;
383 * }
384 *
385 * variant2 $condition != null
386 * $type $name = $value;
387 * </pre>
388 *
389 * .
390 */
391 private static CodeTree createLazyAssignment(CodeTreeBuilder parent, String name, TypeMirror type, CodeTree condition, CodeTree value) {
392 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
393 if (condition == null) {
394 builder.declaration(type, name, value);
395 } else {
396 builder.declaration(type, name, new CodeTreeBuilder(parent).defaultValue(type).getRoot());
397
398 builder.startIf().tree(condition).end();
399 builder.startBlock();
400 builder.startStatement();
401 builder.string(name);
402 builder.string(" = ");
403 builder.tree(value);
404 builder.end(); // statement
405 builder.end(); // block
406 }
407 return builder.getRoot();
302 } 408 }
303 409
304 @Override 410 @Override
305 protected void createChildren(NodeData node) { 411 protected void createChildren(NodeData node) {
306 Map<NodeData, List<TypeElement>> childTypes = new LinkedHashMap<>(); 412 Map<NodeData, List<TypeElement>> childTypes = new LinkedHashMap<>();
518 CodeTreeBuilder guarded = new CodeTreeBuilder(body); 624 CodeTreeBuilder guarded = new CodeTreeBuilder(body);
519 guarded.startReturn().startNew(nodeClassName(specialization)); 625 guarded.startReturn().startNew(nodeClassName(specialization));
520 guarded.string(THIS_NODE_LOCAL_VAR_NAME); 626 guarded.string(THIS_NODE_LOCAL_VAR_NAME);
521 guarded.end().end(); 627 guarded.end().end();
522 628
523 body.tree(createGuardAndCast(getContext(), body, "allowed", node.getGenericSpecialization(), specialization, true, guarded.getRoot(), null)); 629 body.tree(createGuardAndCast(body, "allowed", node.getGenericSpecialization(), specialization, true, guarded.getRoot(), null));
524 } 630 }
525 body.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).end().end(); 631 body.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).end().end();
526 632
527 return method; 633 return method;
528 } 634 }
567 CodeTreeBuilder invokeMethodBuilder = new CodeTreeBuilder(builder); 673 CodeTreeBuilder invokeMethodBuilder = new CodeTreeBuilder(builder);
568 emitInvokeDoMethod(invokeMethodBuilder, current, 0); 674 emitInvokeDoMethod(invokeMethodBuilder, current, 0);
569 CodeTree invokeMethod = invokeMethodBuilder.getRoot(); 675 CodeTree invokeMethod = invokeMethodBuilder.getRoot();
570 676
571 if (next != null) { 677 if (next != null) {
572 invokeMethod = createGuardAndCast(getContext(), builder, "", current.getNode().getGenericSpecialization(), current, false, invokeMethod, null); 678 invokeMethod = createGuardAndCast(builder, null, current.getNode().getGenericSpecialization(), current, false, invokeMethod, null);
573 } 679 }
574 680
575 builder.tree(invokeMethod); 681 builder.tree(invokeMethod);
576 682
577 if (next != null) { 683 if (next != null) {
589 builder.startTryBlock(); 695 builder.startTryBlock();
590 } 696 }
591 697
592 builder.startReturn(); 698 builder.startReturn();
593 startCallOperationMethod(builder, specialization); 699 startCallOperationMethod(builder, specialization);
594 addValueParameterNamesWithCasts(context, builder, specialization.getNode().getGenericSpecialization(), specialization); 700 addValueParameterNamesWithCasts(builder, specialization.getNode().getGenericSpecialization(), specialization);
595 builder.end().end(); // start call operation 701 builder.end().end(); // start call operation
596 builder.end(); // return 702 builder.end(); // return
597 703
598 if (specialization.getExceptions().length > 0) { 704 if (specialization.getExceptions().length > 0) {
599 for (SpecializationThrowsData exception : specialization.getExceptions()) { 705 for (SpecializationThrowsData exception : specialization.getExceptions()) {
696 builder.end().startCatchBlock(getUnexpectedValueException(), "ex"); 802 builder.end().startCatchBlock(getUnexpectedValueException(), "ex");
697 if (returnVoid) { 803 if (returnVoid) {
698 builder.string("// ignore").newLine(); 804 builder.string("// ignore").newLine();
699 } else { 805 } else {
700 builder.startReturn(); 806 builder.startReturn();
701 builder.tree(castPrimaryExecute(node, castedType, CodeTreeBuilder.singleString("ex.getResult()"))); 807 builder.tree(createExpectType(node, castedType, CodeTreeBuilder.singleString("ex.getResult()")));
702 builder.end(); 808 builder.end();
703 } 809 }
704 builder.end(); 810 builder.end();
705 811
706 if (!returnVoid) { 812 if (!returnVoid) {
707 builder.startReturn(); 813 builder.startReturn();
708 builder.tree(castPrimaryExecute(node, castedType, CodeTreeBuilder.singleString("value"))); 814 builder.tree(createExpectType(node, castedType, CodeTreeBuilder.singleString("value")));
709 builder.end(); 815 builder.end();
710 } 816 }
711 } else { 817 } else {
712 if (returnVoid) { 818 if (returnVoid) {
713 builder.statement(primaryExecuteCall); 819 builder.statement(primaryExecuteCall);
714 } else { 820 } else {
715 builder.startReturn(); 821 builder.startReturn();
716 builder.tree(castPrimaryExecute(node, castedType, primaryExecuteCall)); 822 builder.tree(createExpectType(node, castedType, primaryExecuteCall));
717 builder.end(); 823 builder.end();
718 } 824 }
719 } 825 }
720 } 826 }
721 827
722 private CodeTree castPrimaryExecute(NodeData node, ExecutableTypeData castedType, CodeTree value) { 828 private CodeTree createExpectType(NodeData node, ExecutableTypeData castedType, CodeTree value) {
723 if (castedType == null) { 829 if (castedType == null) {
724 return value; 830 return value;
725 } else if (castedType.getType().isVoid()) { 831 } else if (castedType.getType().isVoid()) {
726 return value; 832 return value;
727 } else if (castedType.getType().isGeneric()) { 833 } else if (castedType.getType().isGeneric()) {
728 return value; 834 return value;
729 } 835 }
730 836
731 CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); 837 CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
838 String targetMethodName;
732 if (castedType.hasUnexpectedValue(getContext())) { 839 if (castedType.hasUnexpectedValue(getContext())) {
733 startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.expectTypeMethodName(castedType.getType())); 840 targetMethodName = TypeSystemCodeGenerator.expectTypeMethodName(castedType.getType());
734 } else { 841 } else {
735 startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.asTypeMethodName(castedType.getType())); 842 targetMethodName = TypeSystemCodeGenerator.asTypeMethodName(castedType.getType());
736 } 843 }
844 startCallTypeSystemMethod(getContext(), builder, node, targetMethodName);
845
737 builder.tree(value); 846 builder.tree(value);
738 builder.end().end(); 847 builder.end().end();
739 return builder.getRoot(); 848 return builder.getRoot();
740 } 849 }
741 850
755 SpecializationData next = specialization.findNextSpecialization(); 864 SpecializationData next = specialization.findNextSpecialization();
756 CodeTree returnSpecialized = null; 865 CodeTree returnSpecialized = null;
757 if (next != null) { 866 if (next != null) {
758 returnSpecialized = createReturnSpecializeAndExecute(builder, next, null); 867 returnSpecialized = createReturnSpecializeAndExecute(builder, next, null);
759 } 868 }
760 builder.tree(createGuardAndCast(context, builder, "", specialization, specialization, false, executeNode, returnSpecialized)); 869 builder.tree(createGuardAndCast(builder, null, specialization, specialization, false, executeNode, returnSpecialized));
761 } 870 }
762 871
763 private CodeTree createDeoptimize(CodeTreeBuilder parent) { 872 private CodeTree createDeoptimize(CodeTreeBuilder parent) {
764 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 873 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
765 builder.startStatement(); 874 builder.startStatement();
861 if (!shortCircuit) { 970 if (!shortCircuit) {
862 builder.type(specialization.getNode().getTypeSystem().getGenericType()); 971 builder.type(specialization.getNode().getTypeSystem().getGenericType());
863 builder.string(" "); 972 builder.string(" ");
864 } 973 }
865 974
866 builder.string(valueName(specialization, specParameter)); 975 builder.string(valueName(specParameter));
867 builder.string(" = "); 976 builder.string(" = ");
868 ExecutableTypeData genericExecutableType = field.getNodeData().findGenericExecutableType(getContext(), specParameter.getActualTypeData(node.getTypeSystem())); 977 ExecutableTypeData genericExecutableType = field.getNodeData().findGenericExecutableType(getContext(), specParameter.getActualTypeData(node.getTypeSystem()));
869 if (genericExecutableType == null) { 978 if (genericExecutableType == null) {
870 throw new AssertionError("Must have generic executable type. Parser validation most likely failed. " + Arrays.toString(field.getNodeData().getExecutableTypes())); 979 throw new AssertionError("Must have generic executable type. Parser validation most likely failed. " + Arrays.toString(field.getNodeData().getExecutableTypes()));
871 } 980 }
897 private void buildSpecializedValueExecute(CodeTreeBuilder builder, SpecializationData specialization, NodeFieldData field) { 1006 private void buildSpecializedValueExecute(CodeTreeBuilder builder, SpecializationData specialization, NodeFieldData field) {
898 ActualParameter param = specialization.findParameter(field.getName()); 1007 ActualParameter param = specialization.findParameter(field.getName());
899 boolean shortCircuit = startShortCircuit(builder, specialization, field, null); 1008 boolean shortCircuit = startShortCircuit(builder, specialization, field, null);
900 1009
901 if (!shortCircuit) { 1010 if (!shortCircuit) {
902 builder.startStatement().type(param.getActualType()).string(" ").string(valueName(specialization, param)).end(); 1011 builder.startStatement().type(param.getActualType()).string(" ").string(valueName(param)).end();
903 } 1012 }
904 1013
905 ExecutableTypeData execType = field.getNodeData().findExecutableType(param.getActualTypeData(field.getNodeData().getTypeSystem())); 1014 ExecutableTypeData execType = field.getNodeData().findExecutableType(param.getActualTypeData(field.getNodeData().getTypeSystem()));
906 1015
907 if (execType.hasUnexpectedValue(getContext())) { 1016 if (execType.hasUnexpectedValue(getContext())) {
949 } 1058 }
950 shortCircuitIndex++; 1059 shortCircuitIndex++;
951 } 1060 }
952 } 1061 }
953 1062
954 builder.startStatement().type(shortCircuitParam.getActualType()).string(" ").string(valueName(specialization, shortCircuitParam)).string(" = "); 1063 builder.startStatement().type(shortCircuitParam.getActualType()).string(" ").string(valueName(shortCircuitParam)).string(" = ");
955 ShortCircuitData shortCircuitData = specialization.getShortCircuits()[shortCircuitIndex]; 1064 ShortCircuitData shortCircuitData = specialization.getShortCircuits()[shortCircuitIndex];
956 1065
957 startCallOperationMethod(builder, shortCircuitData); 1066 startCallOperationMethod(builder, shortCircuitData);
958 addValueParameterNames(builder, shortCircuitData, exceptionField != null ? exceptionField.getName() : null, false); 1067 addValueParameterNames(builder, shortCircuitData, exceptionField != null ? exceptionField.getName() : null, false);
959 builder.end().end(); // call operation 1068 builder.end().end(); // call operation
960 1069
961 builder.end(); // statement 1070 builder.end(); // statement
962 1071
963 builder.declaration(parameter.getActualType(), valueName(specialization, parameter), CodeTreeBuilder.createBuilder().defaultValue(parameter.getActualType())); 1072 builder.declaration(parameter.getActualType(), valueName(parameter), CodeTreeBuilder.createBuilder().defaultValue(parameter.getActualType()));
964 builder.startIf().string(shortCircuitParam.getSpecification().getName()).end(); 1073 builder.startIf().string(shortCircuitParam.getSpecification().getName()).end();
965 builder.startBlock(); 1074 builder.startBlock();
966 1075
967 return true; 1076 return true;
968 } 1077 }
1021 genericExecute.startCall(factoryClassName(specialization.getNode()), generatedMethodName); 1130 genericExecute.startCall(factoryClassName(specialization.getNode()), generatedMethodName);
1022 genericExecute.string("this"); 1131 genericExecute.string("this");
1023 addValueParameterNames(genericExecute, specialization.getNode().getGenericSpecialization(), null, true); 1132 addValueParameterNames(genericExecute, specialization.getNode().getGenericSpecialization(), null, true);
1024 genericExecute.end(); // call generated generic 1133 genericExecute.end(); // call generated generic
1025 1134
1026 CodeTree genericInvocation = castPrimaryExecute(node, returnExecutableType, genericExecute.getRoot()); 1135 CodeTree genericInvocation = createExpectType(node, returnExecutableType, genericExecute.getRoot());
1027 1136
1028 if (generatedGeneric != null && Utils.isVoid(generatedGeneric.getReturnType())) { 1137 if (generatedGeneric != null && Utils.isVoid(generatedGeneric.getReturnType())) {
1029 builder.statement(genericInvocation); 1138 builder.statement(genericInvocation);
1030 1139
1031 if (!Utils.isVoid(builder.findMethod().asType())) { 1140 if (!Utils.isVoid(builder.findMethod().asType())) {