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

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: Updated cf. comments 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 definitelyFails = false;
3731
3732 addTypeVariableBoundCheck(GenericType instance,
3733 DartType typeArgument,
3734 TypeVariableType typeVariable,
3735 DartType bound) {
3736 if (definitelyFails) return;
3737
3738 int subtypeRelation = compiler.types.computeSubtypeRelation(typeArgument, bound);
3739 if (subtypeRelation == Types.IS_SUBTYPE) return;
3740
3741 String message =
3742 "Can't create an instance of malbounded type '$type': "
3743 "'${typeArgument}' is not a subtype of bound '${bound}' for "
3744 "type variable '${typeVariable}' of type "
3745 "${type == instance
3746 ? "'${type.element.thisType}'"
3747 : "'${instance.element.thisType}' on the supertype "
3748 "'${instance}' of '${type}'"
3749 }.";
3750 if (subtypeRelation == Types.NOT_SUBTYPE) {
3751 generateTypeError(node, message);
3752 definitelyFails = true;
3753 return;
3754 } else if (subtypeRelation == Types.MAYBE_SUBTYPE) {
3755 Set<DartType> seenChecks =
3756 seenChecksMap.putIfAbsent(typeArgument, () => new Set<DartType>());
3757 if (!seenChecks.contains(bound)) {
3758 seenChecks.add(bound);
3759 assertIsSubtype(node, typeArgument, bound, message);
3760 }
3761 }
3762 }
3763
3764 compiler.types.checkTypeVariableBounds(type, addTypeVariableBoundCheck);
3765 if (definitelyFails) {
3766 return true;
3767 }
3768 for (InterfaceType supertype in type.element.allSupertypes) {
3769 DartType instance = type.asInstanceOf(supertype.element);
3770 compiler.types.checkTypeVariableBounds(instance,
3771 addTypeVariableBoundCheck);
3772 if (definitelyFails) {
3773 return true;
3774 }
3775 }
3776 return false;
3777 }
3778
3705 visitAssert(node) { 3779 visitAssert(node) {
3706 if (!compiler.enableUserAssertions) { 3780 if (!compiler.enableUserAssertions) {
3707 stack.add(graph.addConstantNull(compiler)); 3781 stack.add(graph.addConstantNull(compiler));
3708 return; 3782 return;
3709 } 3783 }
3710 visitStaticSend(node); 3784 visitStaticSend(node);
3711 } 3785 }
3712 3786
3713 visitStaticSend(Send node) { 3787 visitStaticSend(Send node) {
3714 Selector selector = elements.getSelector(node); 3788 Selector selector = elements.getSelector(node);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
3807 3881
3808 void generateError(Node node, String message, Element helper) { 3882 void generateError(Node node, String message, Element helper) {
3809 HInstruction errorMessage = addConstantString(node, message); 3883 HInstruction errorMessage = addConstantString(node, message);
3810 pushInvokeStatic(node, helper, [errorMessage]); 3884 pushInvokeStatic(node, helper, [errorMessage]);
3811 } 3885 }
3812 3886
3813 void generateRuntimeError(Node node, String message) { 3887 void generateRuntimeError(Node node, String message) {
3814 generateError(node, message, backend.getThrowRuntimeError()); 3888 generateError(node, message, backend.getThrowRuntimeError());
3815 } 3889 }
3816 3890
3891 void generateTypeError(Node node, String message) {
3892 generateError(node, message, backend.getThrowTypeError());
3893 }
3894
3817 void generateAbstractClassInstantiationError(Node node, String message) { 3895 void generateAbstractClassInstantiationError(Node node, String message) {
3818 generateError(node, 3896 generateError(node,
3819 message, 3897 message,
3820 backend.getThrowAbstractClassInstantiationError()); 3898 backend.getThrowAbstractClassInstantiationError());
3821 } 3899 }
3822 3900
3823 void generateThrowNoSuchMethod(Node diagnosticNode, 3901 void generateThrowNoSuchMethod(Node diagnosticNode,
3824 String methodName, 3902 String methodName,
3825 {Link<Node> argumentNodes, 3903 {Link<Node> argumentNodes,
3826 List<HInstruction> argumentValues, 3904 List<HInstruction> argumentValues,
(...skipping 1767 matching lines...) Expand 10 before | Expand all | Expand 10 after
5594 new HSubGraphBlockInformation(elseBranch.graph)); 5672 new HSubGraphBlockInformation(elseBranch.graph));
5595 5673
5596 HBasicBlock conditionStartBlock = conditionBranch.block; 5674 HBasicBlock conditionStartBlock = conditionBranch.block;
5597 conditionStartBlock.setBlockFlow(info, joinBlock); 5675 conditionStartBlock.setBlockFlow(info, joinBlock);
5598 SubGraph conditionGraph = conditionBranch.graph; 5676 SubGraph conditionGraph = conditionBranch.graph;
5599 HIf branch = conditionGraph.end.last; 5677 HIf branch = conditionGraph.end.last;
5600 assert(branch is HIf); 5678 assert(branch is HIf);
5601 branch.blockInformation = conditionStartBlock.blockFlow; 5679 branch.blockInformation = conditionStartBlock.blockFlow;
5602 } 5680 }
5603 } 5681 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/resolution/members.dart ('k') | sdk/lib/_internal/lib/js_helper.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698