Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(386)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 48383003: Support checking of malbounded types. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of ssa; 5 part of ssa;
6 6
7 /** 7 /**
8 * A special element for the extra parameter taken by intercepted 8 * A special element for the extra parameter taken by intercepted
9 * methods. We need to override [Element.computeType] because our 9 * methods. We need to override [Element.computeType] because our
10 * optimizers may look at its declared type. 10 * optimizers may look at its declared type.
(...skipping 1903 matching lines...) Expand 10 before | Expand all | Expand 10 after
1914 1914
1915 HInstruction potentiallyCheckType(HInstruction original, DartType type, 1915 HInstruction potentiallyCheckType(HInstruction original, DartType type,
1916 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { 1916 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) {
1917 if (!compiler.enableTypeAssertions) return original; 1917 if (!compiler.enableTypeAssertions) return original;
1918 HInstruction other = buildTypeConversion(original, type, kind); 1918 HInstruction other = buildTypeConversion(original, type, kind);
1919 if (other != original) add(other); 1919 if (other != original) add(other);
1920 compiler.enqueuer.codegen.registerIsCheck(type, work.resolutionTree); 1920 compiler.enqueuer.codegen.registerIsCheck(type, work.resolutionTree);
1921 return other; 1921 return other;
1922 } 1922 }
1923 1923
1924 void assertIsSubtype(Node node, DartType subtype, DartType supertype,
1925 String message) {
1926 HInstruction subtypeInstruction = analyzeTypeArgument(subtype);
1927 HInstruction supertypeInstruction = analyzeTypeArgument(supertype);
1928 HInstruction messageInstruction =
1929 graph.addConstantString(new DartString.literal(message),
1930 node, compiler);
1931 Element element = backend.getAssertIsSubtype();
1932 var inputs = <HInstruction>[subtypeInstruction, supertypeInstruction,
1933 messageInstruction];
1934 HInstruction assertIsSubtype = new HInvokeStatic(
1935 element, inputs, subtypeInstruction.instructionType);
1936 compiler.backend.registerTypeVariableBoundsSubtypeCheck(subtype, supertype);
1937 add(assertIsSubtype);
1938 }
1939
1924 HGraph closeFunction() { 1940 HGraph closeFunction() {
1925 // TODO(kasperl): Make this goto an implicit return. 1941 // TODO(kasperl): Make this goto an implicit return.
1926 if (!isAborted()) closeAndGotoExit(new HGoto()); 1942 if (!isAborted()) closeAndGotoExit(new HGoto());
1927 graph.finalize(); 1943 graph.finalize();
1928 return graph; 1944 return graph;
1929 } 1945 }
1930 1946
1931 HBasicBlock addNewBlock() { 1947 HBasicBlock addNewBlock() {
1932 HBasicBlock block = graph.addNewBlock(); 1948 HBasicBlock block = graph.addNewBlock();
1933 // If adding a new block during building of an expression, it is due to 1949 // If adding a new block during building of an expression, it is due to
(...skipping 1704 matching lines...) Expand 10 before | Expand all | Expand 10 after
3638 message: 'Constructor Symbol.validated is missing')); 3654 message: 'Constructor Symbol.validated is missing'));
3639 } 3655 }
3640 3656
3641 bool isRedirected = functionElement.isRedirectingFactory; 3657 bool isRedirected = functionElement.isRedirectingFactory;
3642 InterfaceType type = elements.getType(node); 3658 InterfaceType type = elements.getType(node);
3643 DartType expectedType = type; 3659 DartType expectedType = type;
3644 if (isRedirected) { 3660 if (isRedirected) {
3645 type = functionElement.computeTargetType(compiler, type); 3661 type = functionElement.computeTargetType(compiler, type);
3646 } 3662 }
3647 3663
3664 if (checkTypeVariableBounds(node, type)) return;
3665
3648 var inputs = <HInstruction>[]; 3666 var inputs = <HInstruction>[];
3649 if (constructor.isGenerativeConstructor() && 3667 if (constructor.isGenerativeConstructor() &&
3650 Elements.isNativeOrExtendsNative(constructor.getEnclosingClass())) { 3668 Elements.isNativeOrExtendsNative(constructor.getEnclosingClass())) {
3651 // Native class generative constructors take a pre-constructed object. 3669 // Native class generative constructors take a pre-constructed object.
3652 inputs.add(graph.addConstantNull(compiler)); 3670 inputs.add(graph.addConstantNull(compiler));
3653 } 3671 }
3654 // TODO(5347): Try to avoid the need for calling [implementation] before 3672 // TODO(5347): Try to avoid the need for calling [implementation] before
3655 // calling [addStaticSendArgumentsToList]. 3673 // calling [addStaticSendArgumentsToList].
3656 bool succeeded = addStaticSendArgumentsToList(selector, send.arguments, 3674 bool succeeded = addStaticSendArgumentsToList(selector, send.arguments,
3657 constructor.implementation, 3675 constructor.implementation,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
3695 // Finally, if we called a redirecting factory constructor, check the type. 3713 // Finally, if we called a redirecting factory constructor, check the type.
3696 if (isRedirected) { 3714 if (isRedirected) {
3697 HInstruction checked = potentiallyCheckType(newInstance, expectedType); 3715 HInstruction checked = potentiallyCheckType(newInstance, expectedType);
3698 if (checked != newInstance) { 3716 if (checked != newInstance) {
3699 pop(); 3717 pop();
3700 stack.add(checked); 3718 stack.add(checked);
3701 } 3719 }
3702 } 3720 }
3703 } 3721 }
3704 3722
3723 /// In checked mode checks the [type] of [node] to be well-bounded. The method
3724 /// returns [:true:] if an error can be statically determined.
3725 bool checkTypeVariableBounds(NewExpression node, InterfaceType type) {
3726 if (!compiler.enableTypeAssertions) return false;
3727
3728 Map<DartType, Set<DartType>> seenChecksMap =
3729 new Map<DartType, Set<DartType>>();
3730 bool staticError = false;
karlklose 2013/10/30 09:47:43 How about 'definitelyFails'?
Johnni Winther 2013/10/30 11:19:42 Done.
3731
3732 addTypeVariableBoundCheck(GenericType instance,
3733 DartType typeArgument,
3734 TypeVariableType typeVariable,
3735 DartType bound) {
3736 if (staticError) return;
3737
3738 int maybeSubtype = compiler.types.isMaybeSubtype(typeArgument, bound);
karlklose 2013/10/30 09:47:43 'maybeSubtype' -> 'subtypeRelation'?
Johnni Winther 2013/10/30 11:19:42 Done.
3739 if (maybeSubtype == Types.IS_SUBTYPE) return;
3740
3741 String message;
karlklose 2013/10/30 09:47:43 You can merge the two branches like this: String
Johnni Winther 2013/10/30 11:19:42 Done.
3742 if (type == instance) {
3743 message = "Can't create an instance of malbounded type '$type': "
3744 "'${typeArgument}' is not a subtype of bound '${bound}' for "
3745 "type variable '${typeVariable}' of type "
3746 "'${type.element.thisType}'.";
3747 } else {
3748 message = "Can't create an instance of malbounded type '$type': "
3749 "'${typeArgument}' is not a subtype of bound '${bound}' for "
3750 "type variable '${typeVariable}' of type "
3751 "'${instance.element.thisType}' on the supertype '${instance}' of "
3752 "'${type}'.";
3753 }
3754 if (maybeSubtype == Types.NOT_SUBTYPE) {
3755 generateTypeError(node, message);
3756 staticError = true;
3757 return;
3758 } else if (maybeSubtype == Types.MAYBE_SUBTYPE) {
3759 Set<DartType> seenChecks =
3760 seenChecksMap.putIfAbsent(typeArgument, () => new Set<DartType>());
3761 if (!seenChecks.contains(bound)) {
3762 seenChecks.add(bound);
3763 assertIsSubtype(node, typeArgument, bound, message);
3764 }
3765 }
3766 }
3767
3768 compiler.types.checkTypeVariableBounds(type, addTypeVariableBoundCheck);
3769 if (staticError) {
3770 return true;
3771 }
3772 for (InterfaceType supertype in type.element.allSupertypes) {
3773 DartType instance = type.asInstanceOf(supertype.element);
3774 compiler.types.checkTypeVariableBounds(instance,
3775 addTypeVariableBoundCheck);
3776 if (staticError) {
3777 return true;
3778 }
3779 }
3780 return false;
3781 }
3782
3705 visitAssert(node) { 3783 visitAssert(node) {
3706 if (!compiler.enableUserAssertions) { 3784 if (!compiler.enableUserAssertions) {
3707 stack.add(graph.addConstantNull(compiler)); 3785 stack.add(graph.addConstantNull(compiler));
3708 return; 3786 return;
3709 } 3787 }
3710 visitStaticSend(node); 3788 visitStaticSend(node);
3711 } 3789 }
3712 3790
3713 visitStaticSend(Send node) { 3791 visitStaticSend(Send node) {
3714 Selector selector = elements.getSelector(node); 3792 Selector selector = elements.getSelector(node);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
3807 3885
3808 void generateError(Node node, String message, Element helper) { 3886 void generateError(Node node, String message, Element helper) {
3809 HInstruction errorMessage = addConstantString(node, message); 3887 HInstruction errorMessage = addConstantString(node, message);
3810 pushInvokeStatic(node, helper, [errorMessage]); 3888 pushInvokeStatic(node, helper, [errorMessage]);
3811 } 3889 }
3812 3890
3813 void generateRuntimeError(Node node, String message) { 3891 void generateRuntimeError(Node node, String message) {
3814 generateError(node, message, backend.getThrowRuntimeError()); 3892 generateError(node, message, backend.getThrowRuntimeError());
3815 } 3893 }
3816 3894
3895 void generateTypeError(Node node, String message) {
3896 generateError(node, message, backend.getThrowTypeError());
3897 }
3898
3817 void generateAbstractClassInstantiationError(Node node, String message) { 3899 void generateAbstractClassInstantiationError(Node node, String message) {
3818 generateError(node, 3900 generateError(node,
3819 message, 3901 message,
3820 backend.getThrowAbstractClassInstantiationError()); 3902 backend.getThrowAbstractClassInstantiationError());
3821 } 3903 }
3822 3904
3823 void generateThrowNoSuchMethod(Node diagnosticNode, 3905 void generateThrowNoSuchMethod(Node diagnosticNode,
3824 String methodName, 3906 String methodName,
3825 {Link<Node> argumentNodes, 3907 {Link<Node> argumentNodes,
3826 List<HInstruction> argumentValues, 3908 List<HInstruction> argumentValues,
(...skipping 1767 matching lines...) Expand 10 before | Expand all | Expand 10 after
5594 new HSubGraphBlockInformation(elseBranch.graph)); 5676 new HSubGraphBlockInformation(elseBranch.graph));
5595 5677
5596 HBasicBlock conditionStartBlock = conditionBranch.block; 5678 HBasicBlock conditionStartBlock = conditionBranch.block;
5597 conditionStartBlock.setBlockFlow(info, joinBlock); 5679 conditionStartBlock.setBlockFlow(info, joinBlock);
5598 SubGraph conditionGraph = conditionBranch.graph; 5680 SubGraph conditionGraph = conditionBranch.graph;
5599 HIf branch = conditionGraph.end.last; 5681 HIf branch = conditionGraph.end.last;
5600 assert(branch is HIf); 5682 assert(branch is HIf);
5601 branch.blockInformation = conditionStartBlock.blockFlow; 5683 branch.blockInformation = conditionStartBlock.blockFlow;
5602 } 5684 }
5603 } 5685 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698