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 }