Mercurial > hg > graal-jvmci-8
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) { |