comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeGenFactory.java @ 20948:a0d97b639d57

Truffle-DSL: do not throw UnexpectedResultException for operations that guarantee the type.
author Christian Humer <christian.humer@gmail.com>
date Tue, 14 Apr 2015 19:23:33 +0200
parents 824ef485081f
children 9a83732f97eb
comparison
equal deleted inserted replaced
20947:824ef485081f 20948:a0d97b639d57
1499 CodeTree expectOrCast = expectOrCast(genericType, forType, builder.build()); 1499 CodeTree expectOrCast = expectOrCast(genericType, forType, builder.build());
1500 return expectOrCast; 1500 return expectOrCast;
1501 } 1501 }
1502 1502
1503 private CodeTree expectOrCast(TypeMirror sourceType, ExecutableTypeData targetType, CodeTree content) { 1503 private CodeTree expectOrCast(TypeMirror sourceType, ExecutableTypeData targetType, CodeTree content) {
1504 if (targetType.hasUnexpectedValue(context)) { 1504 if (needsUnexpectedResultException(targetType)) {
1505 return expect(sourceType, targetType.getReturnType(), content); 1505 return expect(sourceType, targetType.getReturnType(), content);
1506 } else { 1506 } else {
1507 return cast(sourceType, targetType.getReturnType(), content); 1507 return cast(sourceType, targetType.getReturnType(), content);
1508 } 1508 }
1509 } 1509 }
1541 executableType = child.getNodeData().findAnyGenericExecutableType(context, executeWithCount); 1541 executableType = child.getNodeData().findAnyGenericExecutableType(context, executeWithCount);
1542 } 1542 }
1543 return executableType; 1543 return executableType;
1544 } 1544 }
1545 1545
1546 private boolean hasUnexpectedResult(NodeExecutionData execution, TypeMirror type) { 1546 private boolean hasChildUnexpectedResult(NodeExecutionData execution, TypeMirror type) {
1547 for (ExecutableTypeData executableType : findSpecializedExecutableTypes(execution, type)) { 1547 for (ExecutableTypeData executableType : findSpecializedExecutableTypes(execution, type)) {
1548 if (executableType != null && (executableType.hasUnexpectedValue(context) || needsCastTo(executableType.getReturnType(), type))) { 1548 if (executableType != null && (executableType.hasUnexpectedValue(context) || needsCastTo(executableType.getReturnType(), type))) {
1549 return true; 1549 return true;
1550 } 1550 }
1551 } 1551 }
1634 } else { 1634 } else {
1635 executable = currentLocals.createMethod(modifiers(PUBLIC), returnType, methodName, FRAME_VALUE); 1635 executable = currentLocals.createMethod(modifiers(PUBLIC), returnType, methodName, FRAME_VALUE);
1636 } 1636 }
1637 executable.getThrownTypes().clear(); 1637 executable.getThrownTypes().clear();
1638 1638
1639 if (executedType.hasUnexpectedValue(context)) { 1639 if (needsUnexpectedResultException(executedType)) {
1640 executable.getThrownTypes().add(context.getDeclaredType(UnexpectedResultException.class)); 1640 executable.getThrownTypes().add(context.getDeclaredType(UnexpectedResultException.class));
1641 } 1641 }
1642 1642
1643 return executable; 1643 return executable;
1644 }
1645
1646 private boolean needsUnexpectedResultException(ExecutableTypeData executedType) {
1647 if (!executedType.hasUnexpectedValue(context)) {
1648 return false;
1649 }
1650
1651 SpecializationData polymorphicSpecialization = node.getPolymorphicSpecialization();
1652 if (polymorphicSpecialization != null && isSubtypeBoxed(context, polymorphicSpecialization.getReturnType().getType(), executedType.getReturnType())) {
1653 return false;
1654 } else {
1655 return true;
1656 }
1644 } 1657 }
1645 1658
1646 private CodeTree createFastPath(CodeTreeBuilder parent, SpecializationData specialization, final ExecutableTypeData executableType, List<ExecutableTypeData> allTypes, LocalContext currentLocals) { 1659 private CodeTree createFastPath(CodeTreeBuilder parent, SpecializationData specialization, final ExecutableTypeData executableType, List<ExecutableTypeData> allTypes, LocalContext currentLocals) {
1647 final CodeTreeBuilder builder = parent.create(); 1660 final CodeTreeBuilder builder = parent.create();
1648 TypeMirror returnType = executableType.getReturnType(); 1661 TypeMirror returnType = executableType.getReturnType();
1734 returnBuilder.startReturn().tree(call).end(); 1747 returnBuilder.startReturn().tree(call).end();
1735 } 1748 }
1736 1749
1737 CodeTreeBuilder builder = parent.create(); 1750 CodeTreeBuilder builder = parent.create();
1738 1751
1739 if (!source.hasUnexpectedValue(context) && delegate.hasUnexpectedValue(context)) { 1752 if (!needsUnexpectedResultException(source) && needsUnexpectedResultException(delegate)) {
1740 builder.startTryBlock(); 1753 builder.startTryBlock();
1741 builder.tree(returnBuilder.build()); 1754 builder.tree(returnBuilder.build());
1742 builder.end().startCatchBlock(context.getType(UnexpectedResultException.class), "ex"); 1755 builder.end().startCatchBlock(context.getType(UnexpectedResultException.class), "ex");
1743 if (!isVoid(source.getReturnType())) { 1756 if (!isVoid(source.getReturnType())) {
1744 builder.startReturn().tree(cast(context.getType(Object.class), source.getReturnType(), CodeTreeBuilder.singleString("ex.getResult()"))).end(); 1757 builder.startReturn().tree(cast(context.getType(Object.class), source.getReturnType(), CodeTreeBuilder.singleString("ex.getResult()"))).end();
2009 2022
2010 private CodeExecutableElement createExecuteChildMethod(NodeExecutionData execution, TypeMirror targetType) { 2023 private CodeExecutableElement createExecuteChildMethod(NodeExecutionData execution, TypeMirror targetType) {
2011 LocalContext locals = LocalContext.load(this, 0, varArgsThreshold); 2024 LocalContext locals = LocalContext.load(this, 0, varArgsThreshold);
2012 2025
2013 CodeExecutableElement method = locals.createMethod(modifiers(PROTECTED, FINAL), targetType, executeChildMethodName(execution, targetType), FRAME_VALUE); 2026 CodeExecutableElement method = locals.createMethod(modifiers(PROTECTED, FINAL), targetType, executeChildMethodName(execution, targetType), FRAME_VALUE);
2014 if (hasUnexpectedResult(execution, targetType)) { 2027 if (hasChildUnexpectedResult(execution, targetType)) {
2015 method.getThrownTypes().add(getType(UnexpectedResultException.class)); 2028 method.getThrownTypes().add(getType(UnexpectedResultException.class));
2016 } 2029 }
2017 2030
2018 CodeVariableElement implicitProfile = createImplicitProfileParameter(execution, targetType); 2031 CodeVariableElement implicitProfile = createImplicitProfileParameter(execution, targetType);
2019 if (implicitProfile != null) { 2032 if (implicitProfile != null) {
2082 } 2095 }
2083 2096
2084 private CodeTree createAssignExecuteChild(CodeTreeBuilder parent, NodeExecutionData execution, ExecutableTypeData type, LocalVariable targetValue, LocalVariable shortCircuit, 2097 private CodeTree createAssignExecuteChild(CodeTreeBuilder parent, NodeExecutionData execution, ExecutableTypeData type, LocalVariable targetValue, LocalVariable shortCircuit,
2085 LocalContext currentValues) { 2098 LocalContext currentValues) {
2086 CodeTreeBuilder builder = parent.create(); 2099 CodeTreeBuilder builder = parent.create();
2087 boolean hasUnexpected = hasUnexpectedResult(execution, targetValue.getTypeMirror()); 2100 boolean hasUnexpected = hasChildUnexpectedResult(execution, targetValue.getTypeMirror());
2088 2101
2089 CodeTree executeChild; 2102 CodeTree executeChild;
2090 if (isExecuteChildShared(execution, targetValue.getTypeMirror())) { 2103 if (isExecuteChildShared(execution, targetValue.getTypeMirror())) {
2091 executeChild = createCallSharedExecuteChild(execution, targetValue, currentValues); 2104 executeChild = createCallSharedExecuteChild(execution, targetValue, currentValues);
2092 } else { 2105 } else {