Mercurial > hg > graal-compiler
comparison graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java @ 7777:ca51efac4d57
Fixed rewrite in generated generic did not invoke guards.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Mon, 11 Feb 2013 16:20:52 +0100 |
parents | ef1b41ea0a90 |
children | b891ec348f8a |
comparison
equal
deleted
inserted
replaced
7776:10f1c713f4f0 | 7777:ca51efac4d57 |
---|---|
56 private static String nodeClassName(NodeData node) { | 56 private static String nodeClassName(NodeData node) { |
57 return Utils.getSimpleName(node.getTemplateType().asType()); | 57 return Utils.getSimpleName(node.getTemplateType().asType()); |
58 } | 58 } |
59 | 59 |
60 private static String nodeClassName(SpecializationData specialization) { | 60 private static String nodeClassName(SpecializationData specialization) { |
61 String name = specializationId(specialization); | |
62 name += nodeClassName(specialization.getNode()); | |
63 if (name.equals(Utils.getSimpleName(specialization.getNode().getNodeType())) || name.equals(Utils.getSimpleName(specialization.getNode().getTemplateType()))) { | |
64 name = name + "Impl"; | |
65 } | |
66 | |
67 return name; | |
68 } | |
69 | |
70 private static String specializationId(SpecializationData specialization) { | |
61 String name = ""; | 71 String name = ""; |
62 if (specialization.getNode().getSpecializations().length > 1) { | 72 if (specialization.getNode().getSpecializations().length > 1) { |
63 name = specialization.getMethodName(); | 73 name = specialization.getMethodName(); |
64 if (name.startsWith("do")) { | 74 if (name.startsWith("do")) { |
65 name = name.substring(2); | 75 name = name.substring(2); |
66 } | 76 } |
67 } | 77 } |
68 name += nodeClassName(specialization.getNode()); | |
69 if (name.equals(Utils.getSimpleName(specialization.getNode().getNodeType())) || name.equals(Utils.getSimpleName(specialization.getNode().getTemplateType()))) { | |
70 name = name + "Impl"; | |
71 } | |
72 | |
73 return name; | 78 return name; |
74 } | 79 } |
75 | 80 |
76 private static String valueName(NodeFieldData field) { | 81 private static String valueName(NodeFieldData field) { |
77 return field.getName() + "Value"; | 82 return field.getName() + "Value"; |
145 } | 150 } |
146 body.string("."); | 151 body.string("."); |
147 body.startCall(method.getMethodName()); | 152 body.startCall(method.getMethodName()); |
148 } | 153 } |
149 | 154 |
155 private static String generatedGenericMethodName(SpecializationData specialization) { | |
156 final String prefix = "generic"; | |
157 | |
158 if (specialization == null) { | |
159 return prefix; | |
160 } | |
161 | |
162 SpecializationData prev = null; | |
163 for (SpecializationData current : specialization.getNode().getSpecializations()) { | |
164 if (specialization == current) { | |
165 if (prev == null || prev.isUninitialized()) { | |
166 return prefix; | |
167 } else { | |
168 return prefix + specializationId(current); | |
169 } | |
170 } | |
171 prev = current; | |
172 } | |
173 return prefix; | |
174 } | |
175 | |
150 private static void startCallTypeSystemMethod(ProcessorContext context, CodeTreeBuilder body, NodeData node, String methodName) { | 176 private static void startCallTypeSystemMethod(ProcessorContext context, CodeTreeBuilder body, NodeData node, String methodName) { |
151 VariableElement singleton = TypeSystemCodeGenerator.findSingleton(context, node.getTypeSystem()); | 177 VariableElement singleton = TypeSystemCodeGenerator.findSingleton(context, node.getTypeSystem()); |
152 assert singleton != null; | 178 assert singleton != null; |
153 | 179 |
154 body.startGroup(); | 180 body.startGroup(); |
286 clazz.add(createCreateSpecializedMethod(node, createVisibility)); | 312 clazz.add(createCreateSpecializedMethod(node, createVisibility)); |
287 } | 313 } |
288 | 314 |
289 if (node.needsRewrites(getContext())) { | 315 if (node.needsRewrites(getContext())) { |
290 clazz.add(createSpecializeMethod(node)); | 316 clazz.add(createSpecializeMethod(node)); |
291 clazz.add(createGeneratedGenericMethod(node)); | 317 |
318 List<CodeExecutableElement> genericMethods = createGeneratedGenericMethod(node); | |
319 for (CodeExecutableElement method : genericMethods) { | |
320 clazz.add(method); | |
321 } | |
292 } | 322 } |
293 | 323 |
294 for (SpecializationData specialization : node.getSpecializations()) { | 324 for (SpecializationData specialization : node.getSpecializations()) { |
295 add(new SpecializedNodeFactory(context), specialization); | 325 add(new SpecializedNodeFactory(context), specialization); |
296 } | 326 } |
419 body.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).end().end(); | 449 body.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).end().end(); |
420 | 450 |
421 return method; | 451 return method; |
422 } | 452 } |
423 | 453 |
424 private CodeExecutableElement createGeneratedGenericMethod(NodeData node) { | 454 private List<CodeExecutableElement> createGeneratedGenericMethod(NodeData node) { |
425 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), node.getGenericSpecialization().getReturnType().getActualType(), "generatedGeneric"); | 455 TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getActualType(); |
426 method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME)); | |
427 addValueParameters(method, node.getGenericSpecialization(), true); | |
428 | |
429 CodeTreeBuilder builder = method.createBuilder(); | |
430 | |
431 if (node.getGenericSpecialization().isUseSpecializationsForGeneric()) { | 456 if (node.getGenericSpecialization().isUseSpecializationsForGeneric()) { |
432 boolean ifStarted = false; | 457 List<CodeExecutableElement> methods = new ArrayList<>(); |
433 for (int i = 0; i < node.getSpecializations().length; i++) { | 458 |
434 SpecializationData specialization = node.getSpecializations()[i]; | 459 SpecializationData[] specializations = node.getSpecializations(); |
435 if (specialization.isUninitialized()) { | 460 SpecializationData prev = null; |
461 for (int i = 0; i < specializations.length; i++) { | |
462 SpecializationData current = specializations[i]; | |
463 SpecializationData next = i + 1 < specializations.length ? specializations[i + 1] : null; | |
464 if (prev == null || current.isUninitialized()) { | |
465 prev = current; | |
436 continue; | 466 continue; |
467 } else { | |
468 String methodName = generatedGenericMethodName(current); | |
469 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), genericReturnType, methodName); | |
470 method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME)); | |
471 addValueParameters(method, node.getGenericSpecialization(), true); | |
472 | |
473 emitGeneratedGenericSpecialization(method.createBuilder(), current, next); | |
474 | |
475 methods.add(method); | |
437 } | 476 } |
438 if (!specialization.isGeneric()) { | 477 prev = current; |
439 if (!ifStarted) { | 478 } |
440 builder.startIf(); | 479 |
441 ifStarted = true; | 480 return methods; |
442 } else { | |
443 builder.startElseIf(); | |
444 } | |
445 emitGuards(getContext(), builder, "", specialization, false, true); | |
446 builder.end().startBlock(); | |
447 } else { | |
448 builder.startElseBlock(); | |
449 } | |
450 | |
451 emitInvokeDoMethod(builder, specialization, 0); | |
452 builder.end(); | |
453 } | |
454 } else { | 481 } else { |
455 emitInvokeDoMethod(builder, node.getGenericSpecialization(), 0); | 482 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), genericReturnType, generatedGenericMethodName(null)); |
456 } | 483 method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME)); |
457 return method; | 484 addValueParameters(method, node.getGenericSpecialization(), true); |
485 emitInvokeDoMethod(method.createBuilder(), node.getGenericSpecialization(), 0); | |
486 return Arrays.asList(method); | |
487 } | |
488 } | |
489 | |
490 private void emitGeneratedGenericSpecialization(CodeTreeBuilder builder, SpecializationData current, SpecializationData next) { | |
491 if (next != null) { | |
492 builder.startIf(); | |
493 emitGuards(context, builder, "", current, false, true); | |
494 builder.end().startBlock(); | |
495 } | |
496 | |
497 emitInvokeDoMethod(builder, current, 0); | |
498 | |
499 if (next != null) { | |
500 builder.end(); | |
501 builder.startElseBlock(); | |
502 | |
503 builder.startReturn().startCall(generatedGenericMethodName(next)); | |
504 builder.string(THIS_NODE_LOCAL_VAR_NAME); | |
505 addValueParameterNames(builder, next, null, true); | |
506 builder.end().end(); | |
507 | |
508 builder.end(); | |
509 } | |
458 } | 510 } |
459 | 511 |
460 private void emitInvokeDoMethod(CodeTreeBuilder builder, SpecializationData specialization, int level) { | 512 private void emitInvokeDoMethod(CodeTreeBuilder builder, SpecializationData specialization, int level) { |
461 if (specialization.getExceptions().length > 0) { | 513 if (specialization.getExceptions().length > 0) { |
462 builder.startTryBlock(); | 514 builder.startTryBlock(); |
469 builder.end(); // return | 521 builder.end(); // return |
470 | 522 |
471 if (specialization.getExceptions().length > 0) { | 523 if (specialization.getExceptions().length > 0) { |
472 for (SpecializationThrowsData exception : specialization.getExceptions()) { | 524 for (SpecializationThrowsData exception : specialization.getExceptions()) { |
473 builder.end().startCatchBlock(exception.getJavaClass(), "ex" + level); | 525 builder.end().startCatchBlock(exception.getJavaClass(), "ex" + level); |
474 emitInvokeDoMethod(builder, exception.getTransitionTo(), level + 1); | 526 |
527 builder.startReturn().startCall(generatedGenericMethodName(exception.getTransitionTo())); | |
528 builder.string(THIS_NODE_LOCAL_VAR_NAME); | |
529 addValueParameterNames(builder, exception.getTransitionTo(), null, true); | |
530 builder.end().end(); | |
475 } | 531 } |
476 builder.end(); | 532 builder.end(); |
477 } | 533 } |
478 } | 534 } |
479 } | 535 } |
656 } | 712 } |
657 builder.end().end(); | 713 builder.end().end(); |
658 } | 714 } |
659 | 715 |
660 if ((specialization.isUninitialized() || specialization.isGeneric()) && node.needsRewrites(getContext())) { | 716 if ((specialization.isUninitialized() || specialization.isGeneric()) && node.needsRewrites(getContext())) { |
661 builder.startReturn().startCall(factoryClassName(node), "generatedGeneric"); | 717 builder.startReturn().startCall(factoryClassName(node), generatedGenericMethodName(null)); |
662 builder.string("this"); | 718 builder.string("this"); |
663 addValueParameterNames(builder, specialization, null, true); | 719 addValueParameterNames(builder, specialization, null, true); |
664 builder.end().end(); | 720 builder.end().end(); |
665 } else { | 721 } else { |
666 builder.startReturn(); | 722 builder.startReturn(); |
861 addValueParameterNames(builder, specialization.getNode().getGenericSpecialization(), null, false); | 917 addValueParameterNames(builder, specialization.getNode().getGenericSpecialization(), null, false); |
862 builder.end(); | 918 builder.end(); |
863 builder.end(); // call replace | 919 builder.end(); // call replace |
864 builder.end(); // statement | 920 builder.end(); // statement |
865 | 921 |
866 ExecutableElement generatedGeneric = clazz.getEnclosingClass().getMethod("generatedGeneric"); | 922 String generatedMethodName = generatedGenericMethodName(specialization.findNextSpecialization()); |
923 | |
924 ExecutableElement generatedGeneric = clazz.getEnclosingClass().getMethod(generatedMethodName); | |
867 | 925 |
868 CodeTreeBuilder genericBuilder = CodeTreeBuilder.createBuilder(); | 926 CodeTreeBuilder genericBuilder = CodeTreeBuilder.createBuilder(); |
869 genericBuilder.startCall(factoryClassName(specialization.getNode()), "generatedGeneric"); | 927 genericBuilder.startCall(factoryClassName(specialization.getNode()), generatedMethodName); |
870 genericBuilder.string("this"); | 928 genericBuilder.string("this"); |
871 addValueParameterNames(genericBuilder, specialization.getNode().getGenericSpecialization(), null, true); | 929 addValueParameterNames(genericBuilder, specialization.getNode().getGenericSpecialization(), null, true); |
872 genericBuilder.end(); // call generated generic | 930 genericBuilder.end(); // call generated generic |
873 | 931 |
874 if (Utils.isVoid(generatedGeneric.getReturnType())) { | 932 if (generatedGeneric != null && Utils.isVoid(generatedGeneric.getReturnType())) { |
875 builder.declaration(generatedGeneric.getReturnType(), "genericResult", genericBuilder.getRoot()); | 933 builder.declaration(generatedGeneric.getReturnType(), "genericResult", genericBuilder.getRoot()); |
876 builder.startReturn().string("null").end(); | 934 builder.startReturn().string("null").end(); |
877 } else { | 935 } else { |
878 builder.startReturn().tree(genericBuilder.getRoot()).end(); | 936 builder.startReturn().tree(genericBuilder.getRoot()).end(); |
879 } | 937 } |