comparison graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java @ 9279:2a4b57f02fb4

Implemented basic support for assumptions for sourcecode generation.
author Christian Humer <christian.humer@gmail.com>
date Wed, 24 Apr 2013 17:44:15 +0200
parents fe5bc02fcd19
children e16363e50252
comparison
equal deleted inserted replaced
9276:a9cfbe03d9c4 9279:2a4b57f02fb4
287 body.staticReference(singleton.getEnclosingElement().asType(), singleton.getSimpleName().toString()); 287 body.staticReference(singleton.getEnclosingElement().asType(), singleton.getSimpleName().toString());
288 body.string(".").startCall(methodName); 288 body.string(".").startCall(methodName);
289 } 289 }
290 290
291 private CodeTree createGuardAndCast(CodeTreeBuilder parent, String conditionPrefix, SpecializationData sourceSpecialization, SpecializationData targetSpecialization, boolean castValues, 291 private CodeTree createGuardAndCast(CodeTreeBuilder parent, String conditionPrefix, SpecializationData sourceSpecialization, SpecializationData targetSpecialization, boolean castValues,
292 CodeTree guardedStatements, CodeTree elseStatements) { 292 CodeTree guardedStatements, CodeTree elseStatements, boolean emitAssumptions) {
293 293
294 NodeData node = targetSpecialization.getNode(); 294 NodeData node = targetSpecialization.getNode();
295 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 295 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
296 CodeTree implicitGuards = createImplicitGuards(parent, conditionPrefix, sourceSpecialization, targetSpecialization); 296 CodeTree implicitGuards = createImplicitGuards(parent, conditionPrefix, sourceSpecialization, targetSpecialization, emitAssumptions);
297 CodeTree explicitGuards = createExplicitGuards(parent, implicitGuards == null ? conditionPrefix : null, sourceSpecialization, targetSpecialization); 297 CodeTree explicitGuards = createExplicitGuards(parent, implicitGuards == null ? conditionPrefix : null, sourceSpecialization, targetSpecialization);
298 298
299 Set<String> valuesNeedsCast; 299 Set<String> valuesNeedsCast;
300 if (castValues) { 300 if (castValues) {
301 // cast all 301 // cast all
390 } 390 }
391 391
392 return builder.getRoot(); 392 return builder.getRoot();
393 } 393 }
394 394
395 private CodeTree createImplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) { 395 private CodeTree createImplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization, boolean emitAssumptions) {
396 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 396 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
397 // Implict guards based on method signature 397 // Implict guards based on method signature
398 String andOperator = conditionPrefix != null ? conditionPrefix + " && " : ""; 398 String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
399
400 if (emitAssumptions) {
401 boolean isStatic = parent.findMethod().getModifiers().contains(STATIC);
402
403 for (String assumption : guardedSpecialization.getAssumptions()) {
404 builder.string(andOperator);
405 if (isStatic) {
406 builder.string(THIS_NODE_LOCAL_VAR_NAME);
407 } else {
408 builder.string("this");
409 }
410 builder.string(".").string(assumption).string(".isValid()");
411 andOperator = " && ";
412 }
413 }
414
399 for (ActualParameter guardedParam : guardedSpecialization.getParameters()) { 415 for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
400 NodeChildData field = guardedSpecialization.getNode().findChild(guardedParam.getSpecification().getName()); 416 NodeChildData field = guardedSpecialization.getNode().findChild(guardedParam.getSpecification().getName());
401 if (field == null) { 417 if (field == null) {
402 continue; 418 continue;
403 } 419 }
526 } 542 }
527 543
528 return constructors; 544 return constructors;
529 } 545 }
530 546
547 private static ExecutableElement findCopyConstructor(TypeMirror type) {
548 for (ExecutableElement constructor : ElementFilter.constructorsIn(Utils.fromTypeMirror(type).getEnclosedElements())) {
549 if (constructor.getModifiers().contains(PRIVATE)) {
550 continue;
551 }
552 if (isCopyConstructor(constructor)) {
553 return constructor;
554 }
555 }
556
557 return null;
558 }
559
531 private static boolean isCopyConstructor(ExecutableElement element) { 560 private static boolean isCopyConstructor(ExecutableElement element) {
532 if (element.getParameters().size() != 1) { 561 if (element.getParameters().size() != 1) {
533 return false; 562 return false;
534 } 563 }
535 VariableElement var = element.getParameters().get(0); 564 VariableElement var = element.getParameters().get(0);
576 method.createBuilder().startReturn().string("this.").string(child.getName()).end(); 605 method.createBuilder().startReturn().string("this.").string(child.getName()).end();
577 clazz.add(method); 606 clazz.add(method);
578 } 607 }
579 } 608 }
580 609
610 for (String assumption : node.getAssumptions()) {
611 clazz.add(createAssumptionField(assumption));
612 }
613
581 createConstructors(node, clazz); 614 createConstructors(node, clazz);
582 615
583 if (node.getExtensionElements() != null) { 616 if (node.getExtensionElements() != null) {
584 clazz.getEnclosedElements().addAll(node.getExtensionElements()); 617 clazz.getEnclosedElements().addAll(node.getExtensionElements());
585 } 618 }
586 619
587 return clazz; 620 return clazz;
588 } 621 }
589 622
590 private void createConstructors(NodeData node, CodeTypeElement clazz) { 623 private void createConstructors(NodeData node, CodeTypeElement clazz) {
591 List<ExecutableElement> signatureConstructors = new ArrayList<>(); 624 List<ExecutableElement> constructors = findUserConstructors(node.getNodeType());
592 ExecutableElement copyConstructor = null; 625 if (constructors.isEmpty()) {
593 List<? extends ExecutableElement> constructors = ElementFilter.constructorsIn(Utils.fromTypeMirror(node.getNodeType()).getEnclosedElements()); 626 clazz.add(createUserConstructor(clazz, null));
594 for (ExecutableElement constructor : constructors) {
595 if (constructor.getModifiers().contains(Modifier.PRIVATE) || constructor.getParameters().isEmpty()) {
596 continue;
597 }
598
599 if (isCopyConstructor(constructor)) {
600 assert copyConstructor == null;
601 copyConstructor = createConstructor(clazz, constructor, true);
602 } else {
603 signatureConstructors.add(createConstructor(clazz, constructor, false));
604 }
605 }
606
607 if (copyConstructor == null && node.needsRewrites(getContext())) {
608 clazz.add(createConstructor(clazz, null, true));
609 } else if (copyConstructor != null) {
610 clazz.add(copyConstructor);
611 }
612
613 if (signatureConstructors.isEmpty() && !node.getChildren().isEmpty()) {
614 clazz.add(createConstructor(clazz, null, false));
615 } else { 627 } else {
616 clazz.getEnclosedElements().addAll(signatureConstructors); 628 for (ExecutableElement constructor : constructors) {
617 } 629 clazz.add(createUserConstructor(clazz, constructor));
618 } 630 }
619 631 }
620 private CodeExecutableElement createConstructor(CodeTypeElement type, ExecutableElement superConstructor, boolean copyConstructor) { 632 clazz.add(createCopyConstructor(clazz, findCopyConstructor(node.getNodeType())));
633 }
634
635 private CodeExecutableElement createUserConstructor(CodeTypeElement type, ExecutableElement superConstructor) {
621 CodeExecutableElement method = new CodeExecutableElement(null, type.getSimpleName().toString()); 636 CodeExecutableElement method = new CodeExecutableElement(null, type.getSimpleName().toString());
622 CodeTreeBuilder builder = method.createBuilder(); 637 CodeTreeBuilder builder = method.createBuilder();
623 if (!copyConstructor) {
624 if (superConstructor != null) {
625 for (VariableElement param : superConstructor.getParameters()) {
626 method.getParameters().add(CodeVariableElement.clone(param));
627 }
628 }
629 for (NodeChildData child : getModel().getChildren()) {
630 method.getParameters().add(new CodeVariableElement(child.getNodeType(), child.getName()));
631 }
632 } else {
633 if (!(superConstructor == null && getModel().getChildren().isEmpty())) {
634 method.getParameters().add(new CodeVariableElement(type.asType(), "copy"));
635 }
636 }
637 638
638 if (superConstructor != null) { 639 if (superConstructor != null) {
640 for (VariableElement param : superConstructor.getParameters()) {
641 method.getParameters().add(CodeVariableElement.clone(param));
642 }
643 }
644
645 for (VariableElement var : type.getFields()) {
646 method.getParameters().add(new CodeVariableElement(var.asType(), var.getSimpleName().toString()));
647 }
648
649 if (superConstructor != null) {
650 builder.startStatement().startSuperCall();
651 for (VariableElement param : superConstructor.getParameters()) {
652 builder.string(param.getSimpleName().toString());
653 }
654 builder.end().end();
655 }
656
657 for (VariableElement var : type.getFields()) {
639 builder.startStatement(); 658 builder.startStatement();
640 builder.startSuperCall(); 659 String varName = var.getSimpleName().toString();
641 if (copyConstructor) { 660 builder.string("this.").string(varName);
642 builder.string("copy"); 661 if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNode())) {
662 builder.string(" = adoptChild(").string(varName).string(")");
663 } else if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNodeArray())) {
664 builder.string(" = adoptChildren(").string(varName).string(")");
643 } else { 665 } else {
644 for (VariableElement param : superConstructor.getParameters()) { 666 builder.string(" = ").string(varName);
645 builder.string(param.getSimpleName().toString());
646 }
647 } 667 }
648 builder.end(); 668 builder.end();
669 }
670 return method;
671 }
672
673 private CodeExecutableElement createCopyConstructor(CodeTypeElement type, ExecutableElement superConstructor) {
674 CodeExecutableElement method = new CodeExecutableElement(null, type.getSimpleName().toString());
675 CodeTreeBuilder builder = method.createBuilder();
676 if (!(superConstructor == null && type.getFields().isEmpty())) {
677 method.getParameters().add(new CodeVariableElement(type.asType(), "copy"));
678 }
679
680 if (superConstructor != null) {
681 builder.startStatement().startSuperCall().string("copy").end().end();
682 }
683
684 for (VariableElement var : type.getFields()) {
685 builder.startStatement();
686 String varName = var.getSimpleName().toString();
687 builder.string("this.").string(varName);
688 if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNode())) {
689 builder.string(" = adoptChild(copy.").string(varName).string(")");
690 } else if (Utils.isAssignable(getContext(), var.asType(), getContext().getTruffleTypes().getNodeArray())) {
691 builder.string(" = adoptChildren(copy.").string(varName).string(")");
692 } else {
693 builder.string(" = copy.").string(varName);
694 }
649 builder.end(); 695 builder.end();
650 } 696 }
651
652 for (NodeChildData child : getModel().getChildren()) {
653
654 builder.startStatement();
655 builder.string("this.").string(child.getName()).string(" = ");
656
657 if (child.getCardinality() == Cardinality.MANY) {
658 builder.startCall("adoptChildren");
659 } else {
660 builder.startCall("adoptChild");
661 }
662
663 builder.startGroup();
664 if (copyConstructor) {
665 builder.string("copy.");
666 }
667 builder.string(child.getName());
668 builder.end();
669
670 builder.end();
671 builder.end();
672
673 }
674
675 return method; 697 return method;
698 }
699
700 private CodeVariableElement createAssumptionField(String assumption) {
701 CodeVariableElement var = new CodeVariableElement(getContext().getTruffleTypes().getAssumption(), assumption);
702 var.getModifiers().add(Modifier.FINAL);
703 return var;
676 } 704 }
677 705
678 private CodeVariableElement createChildField(NodeChildData child) { 706 private CodeVariableElement createChildField(NodeChildData child) {
679 CodeVariableElement var = new CodeVariableElement(child.getNodeType(), child.getName()); 707 CodeVariableElement var = new CodeVariableElement(child.getNodeType(), child.getName());
680 var.getModifiers().add(Modifier.PROTECTED); 708 var.getModifiers().add(Modifier.PROTECTED);
726 add(factory, node); 754 add(factory, node);
727 generatedNode = factory.getElement(); 755 generatedNode = factory.getElement();
728 756
729 createFactoryMethods(node, clazz, createVisibility); 757 createFactoryMethods(node, clazz, createVisibility);
730 758
731 if (node.getSpecializations().size() > 1) { 759 if (node.needsRewrites(context)) {
732 clazz.add(createCreateSpecializedMethod(node, createVisibility)); 760 clazz.add(createCreateSpecializedMethod(node, createVisibility));
733 }
734
735 if (node.needsRewrites(context)) {
736 clazz.add(createSpecializeMethod(node)); 761 clazz.add(createSpecializeMethod(node));
737 } 762 }
738 763
739 if (node.getGenericSpecialization() != null) { 764 if (node.getGenericSpecialization() != null) {
740 List<CodeExecutableElement> genericMethods = createGeneratedGenericMethod(node); 765 List<CodeExecutableElement> genericMethods = createGeneratedGenericMethod(node);
910 return method; 935 return method;
911 } 936 }
912 937
913 private CodeExecutableElement createCreateNodeSpecializedMethod(NodeData node) { 938 private CodeExecutableElement createCreateNodeSpecializedMethod(NodeData node) {
914 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), node.getNodeType(), "createNodeSpecialized"); 939 CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), node.getNodeType(), "createNodeSpecialized");
915 CodeVariableElement nodeParam = new CodeVariableElement(node.getNodeType(), "thisNode"); 940 CodeVariableElement nodeParam = new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME);
916 CodeVariableElement arguments = new CodeVariableElement(getContext().getType(Class.class), "types"); 941 CodeVariableElement arguments = new CodeVariableElement(getContext().getType(Class.class), "types");
917 method.addParameter(nodeParam); 942 method.addParameter(nodeParam);
918 method.addParameter(arguments); 943 method.addParameter(arguments);
919 method.setVarArgs(true); 944 method.setVarArgs(true);
920 945
926 builder.string("types.length == 1"); 951 builder.string("types.length == 1");
927 builder.end(); 952 builder.end();
928 builder.startBlock(); 953 builder.startBlock();
929 954
930 builder.startReturn().startCall("createSpecialized"); 955 builder.startReturn().startCall("createSpecialized");
931 builder.string("thisNode"); 956 builder.startGroup();
957 builder.string(THIS_NODE_LOCAL_VAR_NAME);
958 builder.end();
932 builder.string("types[0]"); 959 builder.string("types[0]");
933 builder.end().end(); 960 builder.end().end();
934 961
935 builder.end(); 962 builder.end();
936 builder.startElseBlock(); 963 builder.startElseBlock();
1083 method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME)); 1110 method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME));
1084 method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "specializationClass")); 1111 method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "specializationClass"));
1085 1112
1086 CodeTreeBuilder body = method.createBuilder(); 1113 CodeTreeBuilder body = method.createBuilder();
1087 1114
1088 body.startStatement(); 1115 boolean hasCopyConstructor = findCopyConstructor(generatedNode.asType()) != null;
1089 body.type(generatedNode.asType()).string(" ").string(THIS_NODE_LOCAL_VAR_NAME + "Cast"); 1116
1090 body.string(" = ").string("(").type(generatedNode.asType()).string(") ").string(THIS_NODE_LOCAL_VAR_NAME); 1117 final String thisLocalVariableName = THIS_NODE_LOCAL_VAR_NAME + "Cast";
1091 body.end(); 1118
1119 if (hasCopyConstructor) {
1120 body.startStatement();
1121 body.type(generatedNode.asType()).string(" ").string(thisLocalVariableName);
1122 body.string(" = ").string("(").type(generatedNode.asType()).string(") ").string(THIS_NODE_LOCAL_VAR_NAME);
1123 body.end();
1124 }
1092 1125
1093 boolean first = true; 1126 boolean first = true;
1094 for (TypeData type : node.getTypeSystem().getTypes()) { 1127 for (TypeData type : node.getTypeSystem().getTypes()) {
1095 SpecializationData specialization = node.findUniqueSpecialization(type); 1128 SpecializationData specialization = node.findUniqueSpecialization(type);
1096 if (specialization != null && !type.isGeneric()) { 1129 if (specialization != null && !type.isGeneric()) {
1099 first = false; 1132 first = false;
1100 } else { 1133 } else {
1101 body.startElseIf(); 1134 body.startElseIf();
1102 } 1135 }
1103 body.string("specializationClass == ").type(type.getBoxedType()).string(".class").end().startBlock(); 1136 body.string("specializationClass == ").type(type.getBoxedType()).string(".class").end().startBlock();
1104 body.startReturn().startNew(nodeSpecializationClassName(specialization)); 1137 body.tree(createReturnNewSpecialization(body, specialization, thisLocalVariableName, hasCopyConstructor));
1105 body.string(THIS_NODE_LOCAL_VAR_NAME + "Cast");
1106 body.end().end(); // new, return
1107 1138
1108 body.end(); // if 1139 body.end(); // if
1109 } 1140 }
1110 } 1141 }
1111 body.startReturn().startNew(nodeSpecializationClassName(node.getGenericSpecialization())); 1142 body.tree(createReturnNewSpecialization(body, node.getGenericSpecialization(), thisLocalVariableName, hasCopyConstructor));
1112 body.string(THIS_NODE_LOCAL_VAR_NAME + "Cast");
1113 body.end().end();
1114 return method; 1143 return method;
1115 } 1144 }
1116 1145
1117 private CodeExecutableElement createSpecializeMethod(NodeData node) { 1146 private CodeExecutableElement createSpecializeMethod(NodeData node) {
1118 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), node.getNodeType(), "specialize"); 1147 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), node.getNodeType(), "specialize");
1121 addInternalValueParameters(method, node.getGenericSpecialization(), true); 1150 addInternalValueParameters(method, node.getGenericSpecialization(), true);
1122 1151
1123 CodeTreeBuilder body = method.createBuilder(); 1152 CodeTreeBuilder body = method.createBuilder();
1124 body.startStatement().string("boolean allowed = (minimumState == ").string(nodeSpecializationClassName(node.getSpecializations().get(0))).string(".class)").end(); 1153 body.startStatement().string("boolean allowed = (minimumState == ").string(nodeSpecializationClassName(node.getSpecializations().get(0))).string(".class)").end();
1125 1154
1155 boolean hasCopyConstructor = findCopyConstructor(generatedNode.asType()) != null;
1156
1126 for (int i = 1; i < node.getSpecializations().size(); i++) { 1157 for (int i = 1; i < node.getSpecializations().size(); i++) {
1127 SpecializationData specialization = node.getSpecializations().get(i); 1158 SpecializationData specialization = node.getSpecializations().get(i);
1128 body.startStatement().string("allowed = allowed || (minimumState == ").string(nodeSpecializationClassName(specialization)).string(".class)").end(); 1159 body.startStatement().string("allowed = allowed || (minimumState == ").string(nodeSpecializationClassName(specialization)).string(".class)").end();
1129 1160
1130 CodeTreeBuilder guarded = new CodeTreeBuilder(body); 1161 CodeTree guarded = createReturnNewSpecialization(body, specialization, THIS_NODE_LOCAL_VAR_NAME, hasCopyConstructor);
1131 guarded.startReturn().startNew(nodeSpecializationClassName(specialization)); 1162
1132 guarded.string(THIS_NODE_LOCAL_VAR_NAME); 1163 body.tree(createGuardAndCast(body, "allowed", node.getGenericSpecialization(), specialization, false, guarded, null, true));
1133 guarded.end().end();
1134
1135 body.tree(createGuardAndCast(body, "allowed", node.getGenericSpecialization(), specialization, false, guarded.getRoot(), null));
1136 } 1164 }
1137 body.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).end().end(); 1165 body.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).end().end();
1138 1166
1139 return method; 1167 return method;
1168 }
1169
1170 private CodeTree createReturnNewSpecialization(CodeTreeBuilder parent, SpecializationData specialization, String thisLocalVariableName, boolean hasCopyConstructor) {
1171 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
1172 builder.startReturn().startNew(nodeSpecializationClassName(specialization));
1173 if (hasCopyConstructor) {
1174 builder.string(thisLocalVariableName);
1175 }
1176 builder.end().end();
1177 return builder.getRoot();
1140 } 1178 }
1141 1179
1142 private List<CodeExecutableElement> createGeneratedGenericMethod(NodeData node) { 1180 private List<CodeExecutableElement> createGeneratedGenericMethod(NodeData node) {
1143 TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getType(); 1181 TypeMirror genericReturnType = node.getGenericSpecialization().getReturnType().getType();
1144 if (node.needsRewrites(context)) { 1182 if (node.needsRewrites(context)) {
1153 prev = current; 1191 prev = current;
1154 continue; 1192 continue;
1155 } else { 1193 } else {
1156 String methodName = generatedGenericMethodName(current); 1194 String methodName = generatedGenericMethodName(current);
1157 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), genericReturnType, methodName); 1195 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), genericReturnType, methodName);
1158 method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME)); 1196 method.addParameter(new CodeVariableElement(generatedNode.asType(), THIS_NODE_LOCAL_VAR_NAME));
1159 addInternalValueParameters(method, node.getGenericSpecialization(), true); 1197 addInternalValueParameters(method, node.getGenericSpecialization(), true);
1160 1198
1161 emitGeneratedGenericSpecialization(method.createBuilder(), current, next); 1199 emitGeneratedGenericSpecialization(method.createBuilder(), current, next);
1162 1200
1163 methods.add(method); 1201 methods.add(method);
1166 } 1204 }
1167 1205
1168 return methods; 1206 return methods;
1169 } else { 1207 } else {
1170 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), genericReturnType, generatedGenericMethodName(null)); 1208 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), genericReturnType, generatedGenericMethodName(null));
1171 method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME)); 1209 method.addParameter(new CodeVariableElement(generatedNode.asType(), THIS_NODE_LOCAL_VAR_NAME));
1172 addInternalValueParameters(method, node.getGenericSpecialization(), true); 1210 addInternalValueParameters(method, node.getGenericSpecialization(), true);
1173 emitInvokeDoMethod(method.createBuilder(), node.getGenericSpecialization(), 0); 1211 emitInvokeDoMethod(method.createBuilder(), node.getGenericSpecialization(), 0);
1174 return Arrays.asList(method); 1212 return Arrays.asList(method);
1175 } 1213 }
1176 } 1214 }
1186 nextBuilder.startReturn().startCall(generatedGenericMethodName(next)); 1224 nextBuilder.startReturn().startCall(generatedGenericMethodName(next));
1187 nextBuilder.string(THIS_NODE_LOCAL_VAR_NAME); 1225 nextBuilder.string(THIS_NODE_LOCAL_VAR_NAME);
1188 addInternalValueParameterNames(nextBuilder, next, next, null, true, true); 1226 addInternalValueParameterNames(nextBuilder, next, next, null, true, true);
1189 nextBuilder.end().end(); 1227 nextBuilder.end().end();
1190 1228
1191 invokeMethod = createGuardAndCast(builder, null, current.getNode().getGenericSpecialization(), current, true, invokeMethod, nextBuilder.getRoot()); 1229 invokeMethod = createGuardAndCast(builder, null, current.getNode().getGenericSpecialization(), current, true, invokeMethod, nextBuilder.getRoot(), true);
1192 } 1230 }
1193 1231
1194 builder.tree(invokeMethod); 1232 builder.tree(invokeMethod);
1195 1233
1196 if (next != null) { 1234 if (next != null) {
1272 } else { 1310 } else {
1273 clazz.remove(executeMethod); 1311 clazz.remove(executeMethod);
1274 } 1312 }
1275 } 1313 }
1276 1314
1277 if (node.needsRewrites(getContext()) && !specialization.isGeneric() && !specialization.isUninitialized()) { 1315 if (specialization.hasRewrite(getContext())) {
1278 buildSpecializeAndExecute(clazz, specialization); 1316 buildSpecializeAndExecute(clazz, specialization);
1279 } 1317 }
1280 } 1318 }
1281 1319
1282 private CodeTree createExecuteBody(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData execType) { 1320 private CodeTree createExecuteBody(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData execType) {
1467 SpecializationData next = specialization.findNextSpecialization(); 1505 SpecializationData next = specialization.findNextSpecialization();
1468 CodeTree returnSpecialized = null; 1506 CodeTree returnSpecialized = null;
1469 if (next != null) { 1507 if (next != null) {
1470 returnSpecialized = createReturnSpecializeAndExecute(builder, executable, next, null); 1508 returnSpecialized = createReturnSpecializeAndExecute(builder, executable, next, null);
1471 } 1509 }
1472 builder.tree(createGuardAndCast(builder, null, specialization, specialization, true, executeNode, returnSpecialized)); 1510 builder.tree(createGuardAndCast(builder, null, specialization, specialization, true, executeNode, returnSpecialized, false));
1473 1511
1474 return builder.getRoot(); 1512 return builder.getRoot();
1475 } 1513 }
1476 1514
1477 private CodeTree createDeoptimize(CodeTreeBuilder parent) { 1515 private CodeTree createDeoptimize(CodeTreeBuilder parent) {
1505 } 1543 }
1506 1544
1507 private CodeTree createExecute(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData specialization) { 1545 private CodeTree createExecute(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData specialization) {
1508 NodeData node = specialization.getNode(); 1546 NodeData node = specialization.getNode();
1509 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 1547 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
1510 if (!specialization.getExceptions().isEmpty()) { 1548 if (!specialization.getExceptions().isEmpty() || !specialization.getAssumptions().isEmpty()) {
1511 builder.startTryBlock(); 1549 builder.startTryBlock();
1550 }
1551
1552 for (String assumption : specialization.getAssumptions()) {
1553 builder.startStatement();
1554 builder.string("this.").string(assumption).string(".check()");
1555 builder.end();
1512 } 1556 }
1513 1557
1514 CodeTreeBuilder returnBuilder = new CodeTreeBuilder(parent); 1558 CodeTreeBuilder returnBuilder = new CodeTreeBuilder(parent);
1515 if (specialization.isUninitialized()) { 1559 if (specialization.isUninitialized()) {
1516 String genericMethodName = generatedGenericMethodName(null); 1560 String genericMethodName = generatedGenericMethodName(null);
1557 builder.end().startCatchBlock(exception.getJavaClass(), "ex"); 1601 builder.end().startCatchBlock(exception.getJavaClass(), "ex");
1558 builder.tree(createReturnSpecializeAndExecute(parent, executable, exception.getTransitionTo(), null)); 1602 builder.tree(createReturnSpecializeAndExecute(parent, executable, exception.getTransitionTo(), null));
1559 } 1603 }
1560 builder.end(); 1604 builder.end();
1561 } 1605 }
1606 if (!specialization.getAssumptions().isEmpty()) {
1607 builder.end().startCatchBlock(getContext().getTruffleTypes().getInvalidAssumption(), "ex");
1608 builder.tree(createReturnSpecializeAndExecute(parent, executable, specialization.findNextSpecialization(), null));
1609 builder.end();
1610 }
1611
1562 return builder.getRoot(); 1612 return builder.getRoot();
1563 } 1613 }
1564 1614
1565 private CodeTree createExecuteChildren(CodeTreeBuilder parent, ExecutableTypeData sourceExecutable, SpecializationData specialization, List<ActualParameter> targetParameters, 1615 private CodeTree createExecuteChildren(CodeTreeBuilder parent, ExecutableTypeData sourceExecutable, SpecializationData specialization, List<ActualParameter> targetParameters,
1566 ActualParameter unexpectedParameter, boolean cast) { 1616 ActualParameter unexpectedParameter, boolean cast) {