| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library dart2js.ir_builder; | 5 library dart2js.ir_builder; |
| 6 | 6 |
| 7 import '../closure.dart' as closure; | 7 import '../closure.dart' as closure; |
| 8 import '../common.dart'; | 8 import '../common.dart'; |
| 9 import '../common/names.dart' show | 9 import '../common/names.dart' show |
| 10 Names, | 10 Names, |
| (...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 } | 688 } |
| 689 | 689 |
| 690 ir.Primitive buildInvokeStatic(Element element, | 690 ir.Primitive buildInvokeStatic(Element element, |
| 691 Selector selector, | 691 Selector selector, |
| 692 List<ir.Primitive> arguments, | 692 List<ir.Primitive> arguments, |
| 693 SourceInformation sourceInformation) { | 693 SourceInformation sourceInformation) { |
| 694 assert(!element.isLocal); | 694 assert(!element.isLocal); |
| 695 assert(!element.isInstanceMember); | 695 assert(!element.isInstanceMember); |
| 696 assert(isOpen); | 696 assert(isOpen); |
| 697 if (program.isJsInterop(element)) { | 697 if (program.isJsInterop(element)) { |
| 698 return buildInvokeJsInteropMember(element, arguments); | 698 return buildInvokeJsInteropMember(element, arguments, sourceInformation); |
| 699 } | 699 } |
| 700 return addPrimitive( | 700 return addPrimitive( |
| 701 new ir.InvokeStatic(element, selector, arguments, sourceInformation)); | 701 new ir.InvokeStatic(element, selector, arguments, sourceInformation)); |
| 702 } | 702 } |
| 703 | 703 |
| 704 ir.Primitive _buildInvokeSuper(Element target, | 704 ir.Primitive _buildInvokeSuper(Element target, |
| 705 Selector selector, | 705 Selector selector, |
| 706 List<ir.Primitive> arguments, | 706 List<ir.Primitive> arguments, |
| 707 SourceInformation sourceInformation) { | 707 SourceInformation sourceInformation) { |
| 708 assert(target.isInstanceMember); | 708 assert(target.isInstanceMember); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 719 assert(isOpen); | 719 assert(isOpen); |
| 720 return addPrimitive(new ir.InvokeMethod( | 720 return addPrimitive(new ir.InvokeMethod( |
| 721 receiver, selector, mask, arguments, | 721 receiver, selector, mask, arguments, |
| 722 sourceInformation: sourceInformation)); | 722 sourceInformation: sourceInformation)); |
| 723 } | 723 } |
| 724 | 724 |
| 725 ir.Primitive _buildInvokeCall(ir.Primitive target, | 725 ir.Primitive _buildInvokeCall(ir.Primitive target, |
| 726 CallStructure callStructure, | 726 CallStructure callStructure, |
| 727 TypeMask mask, | 727 TypeMask mask, |
| 728 List<ir.Definition> arguments, | 728 List<ir.Definition> arguments, |
| 729 {SourceInformation sourceInformation}) { | 729 SourceInformation sourceInformation) { |
| 730 Selector selector = callStructure.callSelector; | 730 Selector selector = callStructure.callSelector; |
| 731 return _buildInvokeDynamic( | 731 return _buildInvokeDynamic( |
| 732 target, selector, mask, arguments, sourceInformation); | 732 target, selector, mask, arguments, sourceInformation); |
| 733 } | 733 } |
| 734 | 734 |
| 735 ir.Primitive buildStaticNoSuchMethod(Selector selector, | 735 ir.Primitive buildStaticNoSuchMethod( |
| 736 List<ir.Primitive> arguments) { | 736 Selector selector, |
| 737 List<ir.Primitive> arguments, |
| 738 SourceInformation sourceInformation) { |
| 737 ir.Primitive receiver = buildStringConstant(''); | 739 ir.Primitive receiver = buildStringConstant(''); |
| 738 ir.Primitive name = buildStringConstant(selector.name); | 740 ir.Primitive name = buildStringConstant(selector.name); |
| 739 ir.Primitive argumentList = buildListLiteral(null, arguments); | 741 ir.Primitive argumentList = buildListLiteral(null, arguments); |
| 740 ir.Primitive expectedArgumentNames = buildNullConstant(); | 742 ir.Primitive expectedArgumentNames = buildNullConstant(); |
| 741 return buildStaticFunctionInvocation( | 743 return buildStaticFunctionInvocation( |
| 742 program.throwNoSuchMethod, | 744 program.throwNoSuchMethod, |
| 743 <ir.Primitive>[receiver, name, argumentList, expectedArgumentNames]); | 745 <ir.Primitive>[receiver, name, argumentList, expectedArgumentNames], |
| 746 sourceInformation); |
| 744 } | 747 } |
| 745 | 748 |
| 746 /// Create a [ir.Constant] from [value] and add it to the CPS term. | 749 /// Create a [ir.Constant] from [value] and add it to the CPS term. |
| 747 ir.Constant buildConstant(ConstantValue value, | 750 ir.Constant buildConstant(ConstantValue value, |
| 748 {SourceInformation sourceInformation}) { | 751 {SourceInformation sourceInformation}) { |
| 749 assert(isOpen); | 752 assert(isOpen); |
| 750 return addPrimitive( | 753 return addPrimitive( |
| 751 new ir.Constant(value, sourceInformation: sourceInformation)); | 754 new ir.Constant(value, sourceInformation: sourceInformation)); |
| 752 } | 755 } |
| 753 | 756 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 867 sourceInformation: sourceInformation); | 870 sourceInformation: sourceInformation); |
| 868 } | 871 } |
| 869 | 872 |
| 870 /// Create a invocation of the [method] on the super class where the call | 873 /// Create a invocation of the [method] on the super class where the call |
| 871 /// structure is defined [callStructure] and the argument values are defined | 874 /// structure is defined [callStructure] and the argument values are defined |
| 872 /// by [arguments]. | 875 /// by [arguments]. |
| 873 ir.Primitive buildSuperMethodInvocation( | 876 ir.Primitive buildSuperMethodInvocation( |
| 874 MethodElement method, | 877 MethodElement method, |
| 875 CallStructure callStructure, | 878 CallStructure callStructure, |
| 876 List<ir.Primitive> arguments, | 879 List<ir.Primitive> arguments, |
| 877 {SourceInformation sourceInformation}) { | 880 SourceInformation sourceInformation) { |
| 878 // TODO(johnniwinther): This shouldn't be necessary. | 881 // TODO(johnniwinther): This shouldn't be necessary. |
| 879 SelectorKind kind = Elements.isOperatorName(method.name) | 882 SelectorKind kind = Elements.isOperatorName(method.name) |
| 880 ? SelectorKind.OPERATOR : SelectorKind.CALL; | 883 ? SelectorKind.OPERATOR : SelectorKind.CALL; |
| 881 Selector selector = | 884 Selector selector = |
| 882 new Selector(kind, method.memberName, callStructure); | 885 new Selector(kind, method.memberName, callStructure); |
| 883 return _buildInvokeSuper(method, selector, arguments, sourceInformation); | 886 return _buildInvokeSuper(method, selector, arguments, sourceInformation); |
| 884 } | 887 } |
| 885 | 888 |
| 886 /// Create a read access of the [method] on the super class, i.e. a | 889 /// Create a read access of the [method] on the super class, i.e. a |
| 887 /// closurization of [method]. | 890 /// closurization of [method]. |
| 888 ir.Primitive buildSuperMethodGet(MethodElement method, | 891 ir.Primitive buildSuperMethodGet(MethodElement method, |
| 889 {SourceInformation sourceInformation}) { | 892 SourceInformation sourceInformation) { |
| 890 // TODO(johnniwinther): This should have its own ir node. | 893 // TODO(johnniwinther): This should have its own ir node. |
| 891 return _buildInvokeSuper( | 894 return _buildInvokeSuper( |
| 892 method, | 895 method, |
| 893 new Selector.getter(method.memberName), | 896 new Selector.getter(method.memberName), |
| 894 const <ir.Primitive>[], | 897 const <ir.Primitive>[], |
| 895 sourceInformation); | 898 sourceInformation); |
| 896 } | 899 } |
| 897 | 900 |
| 898 /// Create a getter invocation of the [getter] on the super class. | 901 /// Create a getter invocation of the [getter] on the super class. |
| 899 ir.Primitive buildSuperGetterGet(MethodElement getter, | 902 ir.Primitive buildSuperGetterGet(MethodElement getter, |
| 900 SourceInformation sourceInformation) { | 903 SourceInformation sourceInformation) { |
| 901 // TODO(johnniwinther): This should have its own ir node. | 904 // TODO(johnniwinther): This should have its own ir node. |
| 902 return _buildInvokeSuper( | 905 return _buildInvokeSuper( |
| 903 getter, | 906 getter, |
| 904 new Selector.getter(getter.memberName), | 907 new Selector.getter(getter.memberName), |
| 905 const <ir.Primitive>[], | 908 const <ir.Primitive>[], |
| 906 sourceInformation); | 909 sourceInformation); |
| 907 } | 910 } |
| 908 | 911 |
| 909 /// Create an setter invocation of the [setter] on the super class with | 912 /// Create an setter invocation of the [setter] on the super class with |
| 910 /// [value]. | 913 /// [value]. |
| 911 ir.Primitive buildSuperSetterSet(MethodElement setter, | 914 ir.Primitive buildSuperSetterSet(MethodElement setter, |
| 912 ir.Primitive value, | 915 ir.Primitive value, |
| 913 {SourceInformation sourceInformation}) { | 916 SourceInformation sourceInformation) { |
| 914 // TODO(johnniwinther): This should have its own ir node. | 917 // TODO(johnniwinther): This should have its own ir node. |
| 915 _buildInvokeSuper( | 918 _buildInvokeSuper( |
| 916 setter, | 919 setter, |
| 917 new Selector.setter(setter.memberName), | 920 new Selector.setter(setter.memberName), |
| 918 <ir.Primitive>[value], | 921 <ir.Primitive>[value], |
| 919 sourceInformation); | 922 sourceInformation); |
| 920 return value; | 923 return value; |
| 921 } | 924 } |
| 922 | 925 |
| 923 /// Create an invocation of the index [method] on the super class with | 926 /// Create an invocation of the index [method] on the super class with |
| 924 /// the provided [index]. | 927 /// the provided [index]. |
| 925 ir.Primitive buildSuperIndex(MethodElement method, | 928 ir.Primitive buildSuperIndex(MethodElement method, |
| 926 ir.Primitive index, | 929 ir.Primitive index, |
| 927 {SourceInformation sourceInformation}) { | 930 SourceInformation sourceInformation) { |
| 928 return _buildInvokeSuper( | 931 return _buildInvokeSuper( |
| 929 method, new Selector.index(), <ir.Primitive>[index], | 932 method, new Selector.index(), <ir.Primitive>[index], |
| 930 sourceInformation); | 933 sourceInformation); |
| 931 } | 934 } |
| 932 | 935 |
| 933 /// Create an invocation of the index set [method] on the super class with | 936 /// Create an invocation of the index set [method] on the super class with |
| 934 /// the provided [index] and [value]. | 937 /// the provided [index] and [value]. |
| 935 ir.Primitive buildSuperIndexSet(MethodElement method, | 938 ir.Primitive buildSuperIndexSet(MethodElement method, |
| 936 ir.Primitive index, | 939 ir.Primitive index, |
| 937 ir.Primitive value, | 940 ir.Primitive value, |
| 938 {SourceInformation sourceInformation}) { | 941 SourceInformation sourceInformation) { |
| 939 _buildInvokeSuper(method, new Selector.indexSet(), | 942 _buildInvokeSuper(method, new Selector.indexSet(), |
| 940 <ir.Primitive>[index, value], sourceInformation); | 943 <ir.Primitive>[index, value], sourceInformation); |
| 941 return value; | 944 return value; |
| 942 } | 945 } |
| 943 | 946 |
| 944 /// Create a dynamic invocation on [receiver] where the method name and | 947 /// Create a dynamic invocation on [receiver] where the method name and |
| 945 /// argument structure are defined by [selector] and the argument values are | 948 /// argument structure are defined by [selector] and the argument values are |
| 946 /// defined by [arguments]. | 949 /// defined by [arguments]. |
| 947 ir.Primitive buildDynamicInvocation(ir.Primitive receiver, | 950 ir.Primitive buildDynamicInvocation(ir.Primitive receiver, |
| 948 Selector selector, | 951 Selector selector, |
| 949 TypeMask mask, | 952 TypeMask mask, |
| 950 List<ir.Primitive> arguments, | 953 List<ir.Primitive> arguments, |
| 951 {SourceInformation sourceInformation}) { | 954 SourceInformation sourceInformation) { |
| 952 return _buildInvokeDynamic( | 955 return _buildInvokeDynamic( |
| 953 receiver, selector, mask, arguments, sourceInformation); | 956 receiver, selector, mask, arguments, sourceInformation); |
| 954 } | 957 } |
| 955 | 958 |
| 956 /// Create a dynamic getter invocation on [receiver] where the getter name is | 959 /// Create a dynamic getter invocation on [receiver] where the getter name is |
| 957 /// defined by [selector]. | 960 /// defined by [selector]. |
| 958 ir.Primitive buildDynamicGet(ir.Primitive receiver, | 961 ir.Primitive buildDynamicGet(ir.Primitive receiver, |
| 959 Selector selector, | 962 Selector selector, |
| 960 TypeMask mask, | 963 TypeMask mask, |
| 961 SourceInformation sourceInformation) { | 964 SourceInformation sourceInformation) { |
| 962 assert(selector.isGetter); | 965 assert(selector.isGetter); |
| 963 FieldElement field = program.locateSingleField(selector, mask); | 966 FieldElement field = program.locateSingleField(selector, mask); |
| 964 if (field != null) { | 967 if (field != null) { |
| 965 // If the world says this resolves to a unique field, then it MUST be | 968 // If the world says this resolves to a unique field, then it MUST be |
| 966 // treated as a field access, since the getter might not be emitted. | 969 // treated as a field access, since the getter might not be emitted. |
| 967 return buildFieldGet(receiver, field); | 970 return buildFieldGet(receiver, field, sourceInformation); |
| 968 } else { | 971 } else { |
| 969 return _buildInvokeDynamic( | 972 return _buildInvokeDynamic( |
| 970 receiver, selector, mask, const <ir.Primitive>[], sourceInformation); | 973 receiver, selector, mask, const <ir.Primitive>[], sourceInformation); |
| 971 } | 974 } |
| 972 } | 975 } |
| 973 | 976 |
| 974 /// Create a dynamic setter invocation on [receiver] where the setter name and | 977 /// Create a dynamic setter invocation on [receiver] where the setter name and |
| 975 /// argument are defined by [selector] and [value], respectively. | 978 /// argument are defined by [selector] and [value], respectively. |
| 976 ir.Primitive buildDynamicSet(ir.Primitive receiver, | 979 ir.Primitive buildDynamicSet(ir.Primitive receiver, |
| 977 Selector selector, | 980 Selector selector, |
| 978 TypeMask mask, | 981 TypeMask mask, |
| 979 ir.Primitive value, | 982 ir.Primitive value, |
| 980 {SourceInformation sourceInformation}) { | 983 SourceInformation sourceInformation) { |
| 981 assert(selector.isSetter); | 984 assert(selector.isSetter); |
| 982 FieldElement field = program.locateSingleField(selector, mask); | 985 FieldElement field = program.locateSingleField(selector, mask); |
| 983 if (field != null) { | 986 if (field != null) { |
| 984 // If the world says this resolves to a unique field, then it MUST be | 987 // If the world says this resolves to a unique field, then it MUST be |
| 985 // treated as a field access, since the setter might not be emitted. | 988 // treated as a field access, since the setter might not be emitted. |
| 986 buildFieldSet(receiver, field, value); | 989 buildFieldSet(receiver, field, value, sourceInformation); |
| 987 } else { | 990 } else { |
| 988 _buildInvokeDynamic(receiver, selector, mask, <ir.Primitive>[value], | 991 _buildInvokeDynamic(receiver, selector, mask, <ir.Primitive>[value], |
| 989 sourceInformation); | 992 sourceInformation); |
| 990 } | 993 } |
| 991 return value; | 994 return value; |
| 992 } | 995 } |
| 993 | 996 |
| 994 /// Create a dynamic index set invocation on [receiver] with the provided | 997 /// Create a dynamic index set invocation on [receiver] with the provided |
| 995 /// [index] and [value]. | 998 /// [index] and [value]. |
| 996 ir.Primitive buildDynamicIndexSet(ir.Primitive receiver, | 999 ir.Primitive buildDynamicIndexSet(ir.Primitive receiver, |
| 997 TypeMask mask, | 1000 TypeMask mask, |
| 998 ir.Primitive index, | 1001 ir.Primitive index, |
| 999 ir.Primitive value, | 1002 ir.Primitive value, |
| 1000 {SourceInformation sourceInformation}) { | 1003 SourceInformation sourceInformation) { |
| 1001 _buildInvokeDynamic( | 1004 _buildInvokeDynamic( |
| 1002 receiver, new Selector.indexSet(), mask, <ir.Primitive>[index, value], | 1005 receiver, new Selector.indexSet(), mask, <ir.Primitive>[index, value], |
| 1003 sourceInformation); | 1006 sourceInformation); |
| 1004 return value; | 1007 return value; |
| 1005 } | 1008 } |
| 1006 | 1009 |
| 1007 /// Create an invocation of the local [function] where argument structure is | 1010 /// Create an invocation of the local [function] where argument structure is |
| 1008 /// defined by [callStructure] and the argument values are defined by | 1011 /// defined by [callStructure] and the argument values are defined by |
| 1009 /// [arguments]. | 1012 /// [arguments]. |
| 1010 ir.Primitive buildLocalFunctionInvocation( | 1013 ir.Primitive buildLocalFunctionInvocation( |
| 1011 LocalFunctionElement function, | 1014 LocalFunctionElement function, |
| 1012 CallStructure callStructure, | 1015 CallStructure callStructure, |
| 1013 List<ir.Primitive> arguments, | 1016 List<ir.Primitive> arguments, |
| 1014 SourceInformation sourceInformation) { | 1017 SourceInformation sourceInformation) { |
| 1015 // TODO(johnniwinther): Maybe this should have its own ir node. | 1018 // TODO(johnniwinther): Maybe this should have its own ir node. |
| 1016 return buildCallInvocation( | 1019 return buildCallInvocation( |
| 1017 buildLocalGet(function), callStructure, arguments, | 1020 buildLocalGet(function), callStructure, arguments, |
| 1018 sourceInformation: sourceInformation); | 1021 sourceInformation); |
| 1019 } | 1022 } |
| 1020 | 1023 |
| 1021 /// Create a static invocation of [function]. | 1024 /// Create a static invocation of [function]. |
| 1022 /// | 1025 /// |
| 1023 /// The arguments are not named and their values are defined by [arguments]. | 1026 /// The arguments are not named and their values are defined by [arguments]. |
| 1024 ir.Primitive buildStaticFunctionInvocation( | 1027 ir.Primitive buildStaticFunctionInvocation( |
| 1025 MethodElement function, | 1028 MethodElement function, |
| 1026 List<ir.Primitive> arguments, | 1029 List<ir.Primitive> arguments, |
| 1027 {SourceInformation sourceInformation}) { | 1030 SourceInformation sourceInformation) { |
| 1028 Selector selector = new Selector.call( | 1031 Selector selector = new Selector.call( |
| 1029 function.memberName, new CallStructure(arguments.length)); | 1032 function.memberName, new CallStructure(arguments.length)); |
| 1030 return buildInvokeStatic(function, selector, arguments, sourceInformation); | 1033 return buildInvokeStatic(function, selector, arguments, sourceInformation); |
| 1031 } | 1034 } |
| 1032 | 1035 |
| 1033 /// Create a getter invocation of the static [getter]. | 1036 /// Create a getter invocation of the static [getter]. |
| 1034 ir.Primitive buildStaticGetterGet(MethodElement getter, | 1037 ir.Primitive buildStaticGetterGet(MethodElement getter, |
| 1035 SourceInformation sourceInformation) { | 1038 SourceInformation sourceInformation) { |
| 1036 Selector selector = new Selector.getter(getter.memberName); | 1039 Selector selector = new Selector.getter(getter.memberName); |
| 1037 return buildInvokeStatic( | 1040 return buildInvokeStatic( |
| 1038 getter, selector, const <ir.Primitive>[], sourceInformation); | 1041 getter, selector, const <ir.Primitive>[], sourceInformation); |
| 1039 } | 1042 } |
| 1040 | 1043 |
| 1041 /// Create a write access to the static [field] with the [value]. | 1044 /// Create a write access to the static [field] with the [value]. |
| 1042 ir.Primitive buildStaticFieldSet(FieldElement field, | 1045 ir.Primitive buildStaticFieldSet(FieldElement field, |
| 1043 ir.Primitive value, | 1046 ir.Primitive value, |
| 1044 [SourceInformation sourceInformation]) { | 1047 SourceInformation sourceInformation) { |
| 1045 addPrimitive(new ir.SetStatic(field, value, sourceInformation)); | 1048 addPrimitive(new ir.SetStatic(field, value, sourceInformation)); |
| 1046 return value; | 1049 return value; |
| 1047 } | 1050 } |
| 1048 | 1051 |
| 1049 /// Create a setter invocation of the static [setter] with the [value]. | 1052 /// Create a setter invocation of the static [setter] with the [value]. |
| 1050 ir.Primitive buildStaticSetterSet(MethodElement setter, | 1053 ir.Primitive buildStaticSetterSet(MethodElement setter, |
| 1051 ir.Primitive value, | 1054 ir.Primitive value, |
| 1052 {SourceInformation sourceInformation}) { | 1055 SourceInformation sourceInformation) { |
| 1053 Selector selector = new Selector.setter(setter.memberName); | 1056 Selector selector = new Selector.setter(setter.memberName); |
| 1054 buildInvokeStatic( | 1057 buildInvokeStatic( |
| 1055 setter, selector, <ir.Primitive>[value], sourceInformation); | 1058 setter, selector, <ir.Primitive>[value], sourceInformation); |
| 1056 return value; | 1059 return value; |
| 1057 } | 1060 } |
| 1058 | 1061 |
| 1059 /// Create an erroneous invocation where argument structure is defined by | 1062 /// Create an erroneous invocation where argument structure is defined by |
| 1060 /// [selector] and the argument values are defined by [arguments]. | 1063 /// [selector] and the argument values are defined by [arguments]. |
| 1061 // TODO(johnniwinther): Make this more fine-grained. | 1064 // TODO(johnniwinther): Make this more fine-grained. |
| 1062 ir.Primitive buildErroneousInvocation( | 1065 ir.Primitive buildErroneousInvocation( |
| 1063 Element element, | 1066 Element element, |
| 1064 Selector selector, | 1067 Selector selector, |
| 1065 List<ir.Primitive> arguments) { | 1068 List<ir.Primitive> arguments, |
| 1069 SourceInformation sourceInformation) { |
| 1066 // TODO(johnniwinther): This should have its own ir node. | 1070 // TODO(johnniwinther): This should have its own ir node. |
| 1067 return buildInvokeStatic(element, selector, arguments, null); | 1071 return buildInvokeStatic(element, selector, arguments, sourceInformation); |
| 1068 } | 1072 } |
| 1069 | 1073 |
| 1070 /// Concatenate string values. The arguments must be strings. | 1074 /// Concatenate string values. The arguments must be strings. |
| 1071 ir.Primitive buildStringConcatenation(List<ir.Primitive> arguments, | 1075 ir.Primitive buildStringConcatenation(List<ir.Primitive> arguments, |
| 1072 {SourceInformation sourceInformation}) { | 1076 SourceInformation sourceInformation) { |
| 1073 assert(isOpen); | 1077 assert(isOpen); |
| 1074 return addPrimitive(new ir.ApplyBuiltinOperator( | 1078 return addPrimitive(new ir.ApplyBuiltinOperator( |
| 1075 ir.BuiltinOperator.StringConcatenate, | 1079 ir.BuiltinOperator.StringConcatenate, |
| 1076 arguments, | 1080 arguments, |
| 1077 sourceInformation)); | 1081 sourceInformation)); |
| 1078 } | 1082 } |
| 1079 | 1083 |
| 1080 /// Create an invocation of the `call` method of [functionExpression], where | 1084 /// Create an invocation of the `call` method of [functionExpression], where |
| 1081 /// the structure of arguments are given by [callStructure]. | 1085 /// the structure of arguments are given by [callStructure]. |
| 1082 // TODO(johnniwinther): This should take a [TypeMask]. | 1086 // TODO(johnniwinther): This should take a [TypeMask]. |
| 1083 ir.Primitive buildCallInvocation( | 1087 ir.Primitive buildCallInvocation( |
| 1084 ir.Primitive functionExpression, | 1088 ir.Primitive functionExpression, |
| 1085 CallStructure callStructure, | 1089 CallStructure callStructure, |
| 1086 List<ir.Definition> arguments, | 1090 List<ir.Definition> arguments, |
| 1087 {SourceInformation sourceInformation}) { | 1091 SourceInformation sourceInformation) { |
| 1088 return _buildInvokeCall(functionExpression, callStructure, null, arguments, | 1092 return _buildInvokeCall( |
| 1089 sourceInformation: sourceInformation); | 1093 functionExpression, callStructure, null, arguments, sourceInformation); |
| 1090 } | 1094 } |
| 1091 | 1095 |
| 1092 /// Creates an if-then-else statement with the provided [condition] where the | 1096 /// Creates an if-then-else statement with the provided [condition] where the |
| 1093 /// then and else branches are created through the [buildThenPart] and | 1097 /// then and else branches are created through the [buildThenPart] and |
| 1094 /// [buildElsePart] functions, respectively. | 1098 /// [buildElsePart] functions, respectively. |
| 1095 /// | 1099 /// |
| 1096 /// An if-then statement is created if [buildElsePart] is a no-op. | 1100 /// An if-then statement is created if [buildElsePart] is a no-op. |
| 1097 // TODO(johnniwinther): Unify implementation with [buildConditional] and | 1101 // TODO(johnniwinther): Unify implementation with [buildConditional] and |
| 1098 // [_buildLogicalOperator]. | 1102 // [_buildLogicalOperator]. |
| 1099 void buildIf(ir.Primitive condition, | 1103 void buildIf(ir.Primitive condition, |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1330 /// 3) `v` is an instance variable in which case [variableSelector] | 1334 /// 3) `v` is an instance variable in which case [variableSelector] |
| 1331 /// defines its write access. | 1335 /// defines its write access. |
| 1332 /// [buildBody] creates the body, `b`, of the loop. The jump [target] is used | 1336 /// [buildBody] creates the body, `b`, of the loop. The jump [target] is used |
| 1333 /// to identify which `break` and `continue` statements that have this for-in | 1337 /// to identify which `break` and `continue` statements that have this for-in |
| 1334 /// statement as their target. | 1338 /// statement as their target. |
| 1335 void buildForIn({SubbuildFunction buildExpression, | 1339 void buildForIn({SubbuildFunction buildExpression, |
| 1336 SubbuildFunction buildVariableDeclaration, | 1340 SubbuildFunction buildVariableDeclaration, |
| 1337 Element variableElement, | 1341 Element variableElement, |
| 1338 Selector variableSelector, | 1342 Selector variableSelector, |
| 1339 TypeMask variableMask, | 1343 TypeMask variableMask, |
| 1344 SourceInformation variableSetSourceInformation, |
| 1340 TypeMask currentMask, | 1345 TypeMask currentMask, |
| 1346 SourceInformation currentSourceInformation, |
| 1341 TypeMask iteratorMask, | 1347 TypeMask iteratorMask, |
| 1348 SourceInformation iteratorSourceInformation, |
| 1342 TypeMask moveNextMask, | 1349 TypeMask moveNextMask, |
| 1350 SourceInformation moveNextSourceInformation, |
| 1343 SubbuildFunction buildBody, | 1351 SubbuildFunction buildBody, |
| 1344 JumpTarget target, | 1352 JumpTarget target, |
| 1345 ClosureScope closureScope}) { | 1353 ClosureScope closureScope}) { |
| 1346 // The for-in loop | 1354 // The for-in loop |
| 1347 // | 1355 // |
| 1348 // for (a in e) s; | 1356 // for (a in e) s; |
| 1349 // | 1357 // |
| 1350 // Is compiled analogously to: | 1358 // Is compiled analogously to: |
| 1351 // | 1359 // |
| 1352 // it = e.iterator; | 1360 // it = e.iterator; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1393 IrBuilder bodyBuilder = makeDelimitedBuilder(); | 1401 IrBuilder bodyBuilder = makeDelimitedBuilder(); |
| 1394 bodyBuilder._enterScope(closureScope); | 1402 bodyBuilder._enterScope(closureScope); |
| 1395 if (buildVariableDeclaration != null) { | 1403 if (buildVariableDeclaration != null) { |
| 1396 buildVariableDeclaration(bodyBuilder); | 1404 buildVariableDeclaration(bodyBuilder); |
| 1397 } | 1405 } |
| 1398 ir.Primitive currentValue = bodyBuilder.addPrimitive( | 1406 ir.Primitive currentValue = bodyBuilder.addPrimitive( |
| 1399 new ir.InvokeMethod( | 1407 new ir.InvokeMethod( |
| 1400 iterator, | 1408 iterator, |
| 1401 Selectors.current, | 1409 Selectors.current, |
| 1402 currentMask, | 1410 currentMask, |
| 1403 emptyArguments)); | 1411 emptyArguments, |
| 1412 sourceInformation: currentSourceInformation)); |
| 1404 // TODO(johnniwinther): Extract this as a provided strategy. | 1413 // TODO(johnniwinther): Extract this as a provided strategy. |
| 1405 if (Elements.isLocal(variableElement)) { | 1414 if (Elements.isLocal(variableElement)) { |
| 1406 bodyBuilder.buildLocalVariableSet(variableElement, currentValue); | 1415 bodyBuilder.buildLocalVariableSet( |
| 1416 variableElement, |
| 1417 currentValue, |
| 1418 variableSetSourceInformation); |
| 1407 } else if (Elements.isError(variableElement) || | 1419 } else if (Elements.isError(variableElement) || |
| 1408 Elements.isMalformed(variableElement)) { | 1420 Elements.isMalformed(variableElement)) { |
| 1409 Selector selector = new Selector.setter( | 1421 Selector selector = new Selector.setter( |
| 1410 new Name(variableElement.name, variableElement.library)); | 1422 new Name(variableElement.name, variableElement.library)); |
| 1411 List<ir.Primitive> value = <ir.Primitive>[currentValue]; | 1423 List<ir.Primitive> value = <ir.Primitive>[currentValue]; |
| 1412 // Note the comparison below. It can be the case that an element isError | 1424 // Note the comparison below. It can be the case that an element isError |
| 1413 // and isMalformed. | 1425 // and isMalformed. |
| 1414 if (Elements.isError(variableElement)) { | 1426 if (Elements.isError(variableElement)) { |
| 1415 bodyBuilder.buildStaticNoSuchMethod(selector, value); | 1427 bodyBuilder.buildStaticNoSuchMethod(selector, value, |
| 1428 variableSetSourceInformation); |
| 1416 } else { | 1429 } else { |
| 1417 bodyBuilder.buildErroneousInvocation(variableElement, selector, value); | 1430 bodyBuilder.buildErroneousInvocation( |
| 1431 variableElement, selector, value, variableSetSourceInformation); |
| 1418 } | 1432 } |
| 1419 } else if (Elements.isStaticOrTopLevel(variableElement)) { | 1433 } else if (Elements.isStaticOrTopLevel(variableElement)) { |
| 1420 if (variableElement.isField) { | 1434 if (variableElement.isField) { |
| 1421 bodyBuilder.addPrimitive( | 1435 bodyBuilder.addPrimitive( |
| 1422 new ir.SetStatic(variableElement, currentValue)); | 1436 new ir.SetStatic( |
| 1437 variableElement, currentValue, variableSetSourceInformation)); |
| 1423 } else { | 1438 } else { |
| 1424 bodyBuilder.buildStaticSetterSet(variableElement, currentValue); | 1439 bodyBuilder.buildStaticSetterSet( |
| 1440 variableElement, currentValue, variableSetSourceInformation); |
| 1425 } | 1441 } |
| 1426 } else { | 1442 } else { |
| 1427 ir.Primitive receiver = bodyBuilder.buildThis(); | 1443 ir.Primitive receiver = bodyBuilder.buildThis(); |
| 1428 assert(receiver != null); | 1444 assert(receiver != null); |
| 1429 bodyBuilder.buildDynamicSet( | 1445 bodyBuilder.buildDynamicSet( |
| 1430 receiver, variableSelector, variableMask, currentValue); | 1446 receiver, variableSelector, variableMask, currentValue, |
| 1447 variableSetSourceInformation); |
| 1431 } | 1448 } |
| 1432 | 1449 |
| 1433 // Translate the body in the hole in the delimited term above, and add | 1450 // Translate the body in the hole in the delimited term above, and add |
| 1434 // a jump to the loop if control flow is live after the body. | 1451 // a jump to the loop if control flow is live after the body. |
| 1435 JumpCollector breakCollector = | 1452 JumpCollector breakCollector = |
| 1436 new ForwardJumpCollector(environment, target: target); | 1453 new ForwardJumpCollector(environment, target: target); |
| 1437 state.breakCollectors.add(breakCollector); | 1454 state.breakCollectors.add(breakCollector); |
| 1438 state.continueCollectors.add(loop); | 1455 state.continueCollectors.add(loop); |
| 1439 buildBody(bodyBuilder); | 1456 buildBody(bodyBuilder); |
| 1440 assert(state.breakCollectors.last == breakCollector); | 1457 assert(state.breakCollectors.last == breakCollector); |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1850 thenContinuation.body = buildCatchClause(clause); | 1867 thenContinuation.body = buildCatchClause(clause); |
| 1851 elseContinuation.body = catchBody; | 1868 elseContinuation.body = catchBody; |
| 1852 | 1869 |
| 1853 // Build the type test guarding this clause. We can share the | 1870 // Build the type test guarding this clause. We can share the |
| 1854 // environment with the nested builder because this part cannot mutate | 1871 // environment with the nested builder because this part cannot mutate |
| 1855 // it. | 1872 // it. |
| 1856 IrBuilder checkBuilder = builder.makeDelimitedBuilder(environment); | 1873 IrBuilder checkBuilder = builder.makeDelimitedBuilder(environment); |
| 1857 ir.Primitive typeMatches = | 1874 ir.Primitive typeMatches = |
| 1858 checkBuilder.buildTypeOperator(exceptionParameter, | 1875 checkBuilder.buildTypeOperator(exceptionParameter, |
| 1859 clause.type, | 1876 clause.type, |
| 1877 clause.sourceInformation, |
| 1860 isTypeTest: true); | 1878 isTypeTest: true); |
| 1861 checkBuilder.add(new ir.LetCont.two(thenContinuation, elseContinuation, | 1879 checkBuilder.add(new ir.LetCont.two(thenContinuation, elseContinuation, |
| 1862 new ir.Branch.strict(typeMatches, | 1880 new ir.Branch.strict(typeMatches, |
| 1863 thenContinuation, | 1881 thenContinuation, |
| 1864 elseContinuation))); | 1882 elseContinuation))); |
| 1865 catchBody = checkBuilder.root; | 1883 catchBody = checkBuilder.root; |
| 1866 } | 1884 } |
| 1867 builder.add(catchBody); | 1885 builder.add(catchBody); |
| 1868 | 1886 |
| 1869 return <ir.Parameter>[exceptionParameter, traceParameter]; | 1887 return <ir.Parameter>[exceptionParameter, traceParameter]; |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2002 // Return without a subexpression is translated as if it were return null. | 2020 // Return without a subexpression is translated as if it were return null. |
| 2003 assert(isOpen); | 2021 assert(isOpen); |
| 2004 if (value == null) { | 2022 if (value == null) { |
| 2005 value = buildNullConstant(); | 2023 value = buildNullConstant(); |
| 2006 } | 2024 } |
| 2007 jumpTo(state.returnCollector, value, sourceInformation); | 2025 jumpTo(state.returnCollector, value, sourceInformation); |
| 2008 } | 2026 } |
| 2009 | 2027 |
| 2010 /// Generate the body for a native function [function] that is annotated with | 2028 /// Generate the body for a native function [function] that is annotated with |
| 2011 /// an implementation in JavaScript (provided as string in [javaScriptCode]). | 2029 /// an implementation in JavaScript (provided as string in [javaScriptCode]). |
| 2012 void buildNativeFunctionBody(FunctionElement function, | 2030 void buildNativeFunctionBody( |
| 2013 String javaScriptCode) { | 2031 FunctionElement function, |
| 2032 String javaScriptCode, |
| 2033 SourceInformation sourceInformation) { |
| 2014 NativeBehavior behavior = new NativeBehavior(); | 2034 NativeBehavior behavior = new NativeBehavior(); |
| 2015 behavior.sideEffects.setAllSideEffects(); | 2035 behavior.sideEffects.setAllSideEffects(); |
| 2016 // Generate a [ForeignCode] statement from the given native code. | 2036 // Generate a [ForeignCode] statement from the given native code. |
| 2017 buildForeignCode( | 2037 buildForeignCode( |
| 2018 js.js.statementTemplateYielding( | 2038 js.js.statementTemplateYielding( |
| 2019 new js.LiteralStatement(javaScriptCode)), | 2039 new js.LiteralStatement(javaScriptCode)), |
| 2020 <ir.Primitive>[], | 2040 <ir.Primitive>[], |
| 2021 behavior); | 2041 behavior, |
| 2042 sourceInformation); |
| 2022 } | 2043 } |
| 2023 | 2044 |
| 2024 /// Generate the body for a native function that redirects to a native | 2045 /// Generate the body for a native function that redirects to a native |
| 2025 /// JavaScript function, getter, or setter. | 2046 /// JavaScript function, getter, or setter. |
| 2026 /// | 2047 /// |
| 2027 /// Generates a call to the real target, which is given by [functions]'s | 2048 /// Generates a call to the real target, which is given by [functions]'s |
| 2028 /// `fixedBackendName`, passing all parameters as arguments. The target can | 2049 /// `fixedBackendName`, passing all parameters as arguments. The target can |
| 2029 /// be the JavaScript implementation of a function, getter, or setter. | 2050 /// be the JavaScript implementation of a function, getter, or setter. |
| 2030 void buildRedirectingNativeFunctionBody(FunctionElement function, | 2051 void buildRedirectingNativeFunctionBody(FunctionElement function, |
| 2031 String name, | 2052 String name, |
| 2032 SourceInformation source) { | 2053 SourceInformation sourceInformation) { |
| 2033 List<ir.Primitive> arguments = <ir.Primitive>[]; | 2054 List<ir.Primitive> arguments = <ir.Primitive>[]; |
| 2034 NativeBehavior behavior = new NativeBehavior(); | 2055 NativeBehavior behavior = new NativeBehavior(); |
| 2035 behavior.sideEffects.setAllSideEffects(); | 2056 behavior.sideEffects.setAllSideEffects(); |
| 2036 program.addNativeMethod(function); | 2057 program.addNativeMethod(function); |
| 2037 // Construct the access of the target element. | 2058 // Construct the access of the target element. |
| 2038 String code = function.isInstanceMember ? '#.$name' : name; | 2059 String code = function.isInstanceMember ? '#.$name' : name; |
| 2039 if (function.isInstanceMember) { | 2060 if (function.isInstanceMember) { |
| 2040 arguments.add(state.thisParameter); | 2061 arguments.add(state.thisParameter); |
| 2041 } | 2062 } |
| 2042 // Collect all parameters of the function and templates for them to be | 2063 // Collect all parameters of the function and templates for them to be |
| 2043 // inserted into the JavaScript code. | 2064 // inserted into the JavaScript code. |
| 2044 List<String> argumentTemplates = <String>[]; | 2065 List<String> argumentTemplates = <String>[]; |
| 2045 function.functionSignature.forEachParameter((ParameterElement parameter) { | 2066 function.functionSignature.forEachParameter((ParameterElement parameter) { |
| 2046 ir.Primitive input = environment.lookup(parameter); | 2067 ir.Primitive input = environment.lookup(parameter); |
| 2047 DartType type = program.unaliasType(parameter.type); | 2068 DartType type = program.unaliasType(parameter.type); |
| 2048 if (type is FunctionType) { | 2069 if (type is FunctionType) { |
| 2049 // The parameter type is a function type either directly or through | 2070 // The parameter type is a function type either directly or through |
| 2050 // typedef(s). | 2071 // typedef(s). |
| 2051 ir.Constant arity = buildIntegerConstant(type.computeArity()); | 2072 ir.Constant arity = buildIntegerConstant(type.computeArity()); |
| 2052 input = buildStaticFunctionInvocation( | 2073 input = buildStaticFunctionInvocation( |
| 2053 program.closureConverter, <ir.Primitive>[input, arity]); | 2074 program.closureConverter, <ir.Primitive>[input, arity], |
| 2075 sourceInformation); |
| 2054 } | 2076 } |
| 2055 arguments.add(input); | 2077 arguments.add(input); |
| 2056 argumentTemplates.add('#'); | 2078 argumentTemplates.add('#'); |
| 2057 }); | 2079 }); |
| 2058 // Construct the application of parameters for functions and setters. | 2080 // Construct the application of parameters for functions and setters. |
| 2059 if (function.kind == ElementKind.FUNCTION) { | 2081 if (function.kind == ElementKind.FUNCTION) { |
| 2060 code = "$code(${argumentTemplates.join(', ')})"; | 2082 code = "$code(${argumentTemplates.join(', ')})"; |
| 2061 } else if (function.kind == ElementKind.SETTER) { | 2083 } else if (function.kind == ElementKind.SETTER) { |
| 2062 code = "$code = ${argumentTemplates.single}"; | 2084 code = "$code = ${argumentTemplates.single}"; |
| 2063 } else { | 2085 } else { |
| 2064 assert(argumentTemplates.isEmpty); | 2086 assert(argumentTemplates.isEmpty); |
| 2065 assert(function.kind == ElementKind.GETTER); | 2087 assert(function.kind == ElementKind.GETTER); |
| 2066 } | 2088 } |
| 2067 // Generate the [ForeignCode] expression and a return statement to return | 2089 // Generate the [ForeignCode] expression and a return statement to return |
| 2068 // its value. | 2090 // its value. |
| 2069 ir.Primitive value = buildForeignCode( | 2091 ir.Primitive value = buildForeignCode( |
| 2070 js.js.uncachedExpressionTemplate(code), | 2092 js.js.uncachedExpressionTemplate(code), |
| 2071 arguments, | 2093 arguments, |
| 2072 behavior, | 2094 behavior, |
| 2095 sourceInformation, |
| 2073 type: program.getTypeMaskForNativeFunction(function)); | 2096 type: program.getTypeMaskForNativeFunction(function)); |
| 2074 buildReturn(value: value, sourceInformation: source); | 2097 buildReturn(value: value, sourceInformation: sourceInformation); |
| 2075 } | 2098 } |
| 2076 | 2099 |
| 2077 static _isNotNull(ir.Primitive value) => | 2100 static _isNotNull(ir.Primitive value) => |
| 2078 !(value is ir.Constant && value.value.isNull); | 2101 !(value is ir.Constant && value.value.isNull); |
| 2079 | 2102 |
| 2080 /// Builds a call to a resolved js-interop element. | 2103 /// Builds a call to a resolved js-interop element. |
| 2081 ir.Primitive buildInvokeJsInteropMember(FunctionElement element, | 2104 ir.Primitive buildInvokeJsInteropMember( |
| 2082 List<ir.Primitive> arguments) { | 2105 FunctionElement element, |
| 2106 List<ir.Primitive> arguments, |
| 2107 SourceInformation sourceInformation) { |
| 2083 program.addNativeMethod(element); | 2108 program.addNativeMethod(element); |
| 2084 String target = program.getJsInteropTargetPath(element); | 2109 String target = program.getJsInteropTargetPath(element); |
| 2085 // Strip off trailing arguments that were not specified. | 2110 // Strip off trailing arguments that were not specified. |
| 2086 // TODO(jacobr,sigmund): assert that the trailing arguments are all null. | 2111 // TODO(jacobr,sigmund): assert that the trailing arguments are all null. |
| 2087 // TODO(jacobr): rewrite named arguments to an object literal matching | 2112 // TODO(jacobr): rewrite named arguments to an object literal matching |
| 2088 // the factory constructor case. | 2113 // the factory constructor case. |
| 2089 var inputs = arguments.where(_isNotNull).toList(); | 2114 var inputs = arguments.where(_isNotNull).toList(); |
| 2090 | 2115 |
| 2091 var behavior = new NativeBehavior()..sideEffects.setAllSideEffects(); | 2116 var behavior = new NativeBehavior()..sideEffects.setAllSideEffects(); |
| 2092 DartType type = element.isConstructor ? | 2117 DartType type = element.isConstructor ? |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2112 | 2137 |
| 2113 String code; | 2138 String code; |
| 2114 if (element.isGetter) { | 2139 if (element.isGetter) { |
| 2115 code = target; | 2140 code = target; |
| 2116 } else if (element.isSetter) { | 2141 } else if (element.isSetter) { |
| 2117 code = "$target = #"; | 2142 code = "$target = #"; |
| 2118 } else { | 2143 } else { |
| 2119 var args = new List.filled(inputs.length, '#').join(','); | 2144 var args = new List.filled(inputs.length, '#').join(','); |
| 2120 code = element.isConstructor ? "new $target($args)" : "$target($args)"; | 2145 code = element.isConstructor ? "new $target($args)" : "$target($args)"; |
| 2121 } | 2146 } |
| 2122 return buildForeignCode(js.js.parseForeignJS(code), inputs, behavior); | 2147 return buildForeignCode(js.js.parseForeignJS(code), |
| 2148 inputs, behavior, sourceInformation); |
| 2123 // TODO(sigmund): should we record the source-information here? | 2149 // TODO(sigmund): should we record the source-information here? |
| 2124 } | 2150 } |
| 2125 | 2151 |
| 2126 /// Builds an object literal that results from invoking a factory constructor | 2152 /// Builds an object literal that results from invoking a factory constructor |
| 2127 /// of a js-interop anonymous type. | 2153 /// of a js-interop anonymous type. |
| 2128 ir.Primitive buildJsInteropObjectLiteral(ConstructorElement constructor, | 2154 ir.Primitive buildJsInteropObjectLiteral( |
| 2129 List<ir.Primitive> arguments, {SourceInformation source}) { | 2155 ConstructorElement constructor, |
| 2156 List<ir.Primitive> arguments, |
| 2157 SourceInformation sourceInformation) { |
| 2130 assert(program.isJsInteropAnonymous(constructor)); | 2158 assert(program.isJsInteropAnonymous(constructor)); |
| 2131 program.addNativeMethod(constructor); | 2159 program.addNativeMethod(constructor); |
| 2132 FunctionSignature params = constructor.functionSignature; | 2160 FunctionSignature params = constructor.functionSignature; |
| 2133 int i = 0; | 2161 int i = 0; |
| 2134 var filteredArguments = <ir.Primitive>[]; | 2162 var filteredArguments = <ir.Primitive>[]; |
| 2135 var entries = new Map<String, js.Expression>(); | 2163 var entries = new Map<String, js.Expression>(); |
| 2136 params.orderedForEachParameter((ParameterElement parameter) { | 2164 params.orderedForEachParameter((ParameterElement parameter) { |
| 2137 // TODO(jacobr): throw if parameter names do not match names of property | 2165 // TODO(jacobr): throw if parameter names do not match names of property |
| 2138 // names in the class. | 2166 // names in the class. |
| 2139 assert (parameter.isNamed); | 2167 assert (parameter.isNamed); |
| 2140 ir.Primitive argument = arguments[i++]; | 2168 ir.Primitive argument = arguments[i++]; |
| 2141 if (_isNotNull(argument)) { | 2169 if (_isNotNull(argument)) { |
| 2142 filteredArguments.add(argument); | 2170 filteredArguments.add(argument); |
| 2143 entries[parameter.name] = | 2171 entries[parameter.name] = |
| 2144 new js.InterpolatedExpression(filteredArguments.length - 1); | 2172 new js.InterpolatedExpression(filteredArguments.length - 1); |
| 2145 } | 2173 } |
| 2146 }); | 2174 }); |
| 2147 var code = new js.Template(null, js.objectLiteral(entries)); | 2175 var code = new js.Template(null, js.objectLiteral(entries)); |
| 2148 var behavior = new NativeBehavior(); | 2176 var behavior = new NativeBehavior(); |
| 2149 if (program.trustJSInteropTypeAnnotations) { | 2177 if (program.trustJSInteropTypeAnnotations) { |
| 2150 behavior.typesReturned.add(constructor.enclosingClass.thisType); | 2178 behavior.typesReturned.add(constructor.enclosingClass.thisType); |
| 2151 } | 2179 } |
| 2152 | 2180 |
| 2153 // TODO(sigmund): should we record the source-information here? | 2181 return buildForeignCode( |
| 2154 return buildForeignCode(code, filteredArguments, behavior); | 2182 code, filteredArguments, behavior, sourceInformation); |
| 2155 } | 2183 } |
| 2156 | 2184 |
| 2157 /// Create a blocks of [statements] by applying [build] to all reachable | 2185 /// Create a blocks of [statements] by applying [build] to all reachable |
| 2158 /// statements. The first statement is assumed to be reachable. | 2186 /// statements. The first statement is assumed to be reachable. |
| 2159 // TODO(johnniwinther): Type [statements] as `Iterable` when `NodeList` uses | 2187 // TODO(johnniwinther): Type [statements] as `Iterable` when `NodeList` uses |
| 2160 // `List` instead of `Link`. | 2188 // `List` instead of `Link`. |
| 2161 void buildBlock(var statements, BuildFunction build) { | 2189 void buildBlock(var statements, BuildFunction build) { |
| 2162 // Build(Block(stamements), C) = C' | 2190 // Build(Block(stamements), C) = C' |
| 2163 // where C' = statements.fold(Build, C) | 2191 // where C' = statements.fold(Build, C) |
| 2164 assert(isOpen); | 2192 assert(isOpen); |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2496 } else { | 2524 } else { |
| 2497 value = environment.lookup(field.local); | 2525 value = environment.lookup(field.local); |
| 2498 } | 2526 } |
| 2499 arguments.add(value); | 2527 arguments.add(value); |
| 2500 } | 2528 } |
| 2501 return addPrimitive(new ir.CreateInstance( | 2529 return addPrimitive(new ir.CreateInstance( |
| 2502 classElement, arguments, null, sourceInformation)); | 2530 classElement, arguments, null, sourceInformation)); |
| 2503 } | 2531 } |
| 2504 | 2532 |
| 2505 /// Create a read access of [local] function, variable, or parameter. | 2533 /// Create a read access of [local] function, variable, or parameter. |
| 2506 ir.Primitive buildLocalGet(LocalElement local) { | 2534 // TODO(johnniwinther): Make [sourceInformation] mandatory. |
| 2535 ir.Primitive buildLocalGet( |
| 2536 LocalElement local, |
| 2537 {SourceInformation sourceInformation}) { |
| 2507 assert(isOpen); | 2538 assert(isOpen); |
| 2508 ClosureLocation location = state.boxedVariables[local]; | 2539 ClosureLocation location = state.boxedVariables[local]; |
| 2509 if (location != null) { | 2540 if (location != null) { |
| 2510 ir.Primitive result = new ir.GetField(environment.lookup(location.box), | 2541 ir.Primitive result = new ir.GetField( |
| 2511 location.field); | 2542 environment.lookup(location.box), |
| 2543 location.field, |
| 2544 sourceInformation: sourceInformation); |
| 2512 result.useElementAsHint(local); | 2545 result.useElementAsHint(local); |
| 2513 return addPrimitive(result); | 2546 return addPrimitive(result); |
| 2514 } else if (isInMutableVariable(local)) { | 2547 } else if (isInMutableVariable(local)) { |
| 2515 return addPrimitive(new ir.GetMutable(getMutableVariable(local))); | 2548 return addPrimitive( |
| 2549 new ir.GetMutable( |
| 2550 getMutableVariable(local), sourceInformation: sourceInformation)); |
| 2516 } else { | 2551 } else { |
| 2517 return environment.lookup(local); | 2552 return environment.lookup(local); |
| 2518 } | 2553 } |
| 2519 } | 2554 } |
| 2520 | 2555 |
| 2521 /// Create a write access to [local] variable or parameter with the provided | 2556 /// Create a write access to [local] variable or parameter with the provided |
| 2522 /// [value]. | 2557 /// [value]. |
| 2523 ir.Primitive buildLocalVariableSet(LocalElement local, ir.Primitive value) { | 2558 ir.Primitive buildLocalVariableSet( |
| 2559 LocalElement local, |
| 2560 ir.Primitive value, |
| 2561 SourceInformation sourceInformation) { |
| 2524 assert(isOpen); | 2562 assert(isOpen); |
| 2525 ClosureLocation location = state.boxedVariables[local]; | 2563 ClosureLocation location = state.boxedVariables[local]; |
| 2526 if (location != null) { | 2564 if (location != null) { |
| 2527 addPrimitive(new ir.SetField( | 2565 addPrimitive(new ir.SetField( |
| 2528 environment.lookup(location.box), | 2566 environment.lookup(location.box), |
| 2529 location.field, | 2567 location.field, |
| 2530 value)); | 2568 value, |
| 2569 sourceInformation: sourceInformation)); |
| 2531 } else if (isInMutableVariable(local)) { | 2570 } else if (isInMutableVariable(local)) { |
| 2532 addPrimitive(new ir.SetMutable( | 2571 addPrimitive(new ir.SetMutable( |
| 2533 getMutableVariable(local), value)); | 2572 getMutableVariable(local), |
| 2573 value, |
| 2574 sourceInformation: sourceInformation)); |
| 2534 } else { | 2575 } else { |
| 2535 value.useElementAsHint(local); | 2576 value.useElementAsHint(local); |
| 2536 environment.update(local, value); | 2577 environment.update(local, value); |
| 2537 } | 2578 } |
| 2538 return value; | 2579 return value; |
| 2539 } | 2580 } |
| 2540 | 2581 |
| 2541 /// Called before building the initializer of a for-loop. | 2582 /// Called before building the initializer of a for-loop. |
| 2542 /// | 2583 /// |
| 2543 /// The loop variables will subsequently be declared using | 2584 /// The loop variables will subsequently be declared using |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2582 /// Creates an access to the receiver from the current (or enclosing) method. | 2623 /// Creates an access to the receiver from the current (or enclosing) method. |
| 2583 /// | 2624 /// |
| 2584 /// If inside a closure class, [buildThis] will redirect access through | 2625 /// If inside a closure class, [buildThis] will redirect access through |
| 2585 /// closure fields in order to access the receiver from the enclosing method. | 2626 /// closure fields in order to access the receiver from the enclosing method. |
| 2586 ir.Primitive buildThis() { | 2627 ir.Primitive buildThis() { |
| 2587 if (state.enclosingThis != null) return state.enclosingThis; | 2628 if (state.enclosingThis != null) return state.enclosingThis; |
| 2588 assert(state.thisParameter != null); | 2629 assert(state.thisParameter != null); |
| 2589 return state.thisParameter; | 2630 return state.thisParameter; |
| 2590 } | 2631 } |
| 2591 | 2632 |
| 2592 ir.Primitive buildFieldGet(ir.Primitive receiver, FieldElement target) { | 2633 ir.Primitive buildFieldGet( |
| 2634 ir.Primitive receiver, |
| 2635 FieldElement target, |
| 2636 SourceInformation sourceInformation) { |
| 2593 return addPrimitive(new ir.GetField(receiver, target, | 2637 return addPrimitive(new ir.GetField(receiver, target, |
| 2638 sourceInformation: sourceInformation, |
| 2594 isFinal: program.fieldNeverChanges(target))); | 2639 isFinal: program.fieldNeverChanges(target))); |
| 2595 } | 2640 } |
| 2596 | 2641 |
| 2597 void buildFieldSet(ir.Primitive receiver, | 2642 void buildFieldSet(ir.Primitive receiver, |
| 2598 FieldElement target, | 2643 FieldElement target, |
| 2599 ir.Primitive value) { | 2644 ir.Primitive value, |
| 2600 addPrimitive(new ir.SetField(receiver, target, value)); | 2645 SourceInformation sourceInformation) { |
| 2646 addPrimitive(new ir.SetField( |
| 2647 receiver, target, value, sourceInformation: sourceInformation)); |
| 2601 } | 2648 } |
| 2602 | 2649 |
| 2603 ir.Primitive buildSuperFieldGet(FieldElement target) { | 2650 ir.Primitive buildSuperFieldGet( |
| 2604 return addPrimitive(new ir.GetField(buildThis(), target)); | 2651 FieldElement target, |
| 2652 SourceInformation sourceInformation) { |
| 2653 return addPrimitive( |
| 2654 new ir.GetField( |
| 2655 buildThis(), target, sourceInformation: sourceInformation)); |
| 2605 } | 2656 } |
| 2606 | 2657 |
| 2607 ir.Primitive buildSuperFieldSet(FieldElement target, ir.Primitive value) { | 2658 ir.Primitive buildSuperFieldSet( |
| 2608 addPrimitive(new ir.SetField(buildThis(), target, value)); | 2659 FieldElement target, |
| 2660 ir.Primitive value, |
| 2661 SourceInformation sourceInformation) { |
| 2662 addPrimitive( |
| 2663 new ir.SetField( |
| 2664 buildThis(), target, value, sourceInformation: sourceInformation)); |
| 2609 return value; | 2665 return value; |
| 2610 } | 2666 } |
| 2611 | 2667 |
| 2612 /// Loads parameters to a constructor body into the environment. | 2668 /// Loads parameters to a constructor body into the environment. |
| 2613 /// | 2669 /// |
| 2614 /// The header for a constructor body differs from other functions in that | 2670 /// The header for a constructor body differs from other functions in that |
| 2615 /// some parameters are already boxed, and the box is passed as an argument | 2671 /// some parameters are already boxed, and the box is passed as an argument |
| 2616 /// instead of being created in the header. | 2672 /// instead of being created in the header. |
| 2617 void buildConstructorBodyHeader(Iterable<Local> parameters, | 2673 void buildConstructorBodyHeader(Iterable<Local> parameters, |
| 2618 ClosureScope closureScope) { | 2674 ClosureScope closureScope) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2635 DartType type, | 2691 DartType type, |
| 2636 List<ir.Primitive> arguments, | 2692 List<ir.Primitive> arguments, |
| 2637 SourceInformation sourceInformation, | 2693 SourceInformation sourceInformation, |
| 2638 {TypeMask allocationSiteType}) { | 2694 {TypeMask allocationSiteType}) { |
| 2639 assert(isOpen); | 2695 assert(isOpen); |
| 2640 Selector selector = | 2696 Selector selector = |
| 2641 new Selector(SelectorKind.CALL, element.memberName, callStructure); | 2697 new Selector(SelectorKind.CALL, element.memberName, callStructure); |
| 2642 ClassElement cls = element.enclosingClass; | 2698 ClassElement cls = element.enclosingClass; |
| 2643 if (program.isJsInterop(element)) { | 2699 if (program.isJsInterop(element)) { |
| 2644 if (program.isJsInteropAnonymous(element)) { | 2700 if (program.isJsInteropAnonymous(element)) { |
| 2645 return buildJsInteropObjectLiteral(element, arguments, | 2701 return buildJsInteropObjectLiteral( |
| 2646 source: sourceInformation); | 2702 element, arguments, sourceInformation); |
| 2647 } | 2703 } |
| 2648 return buildInvokeJsInteropMember(element, arguments); | 2704 return buildInvokeJsInteropMember(element, arguments, sourceInformation); |
| 2649 } | 2705 } |
| 2650 if (program.requiresRuntimeTypesFor(cls)) { | 2706 if (program.requiresRuntimeTypesFor(cls)) { |
| 2651 InterfaceType interface = type; | 2707 InterfaceType interface = type; |
| 2652 Iterable<ir.Primitive> typeArguments = | 2708 Iterable<ir.Primitive> typeArguments = |
| 2653 interface.typeArguments.map((DartType argument) { | 2709 interface.typeArguments.map((DartType argument) { |
| 2654 return type.treatAsRaw | 2710 return type.treatAsRaw |
| 2655 ? buildNullConstant() | 2711 ? buildNullConstant() |
| 2656 : buildTypeExpression(argument); | 2712 : buildTypeExpression(argument); |
| 2657 }); | 2713 }); |
| 2658 arguments = new List<ir.Primitive>.from(arguments) | 2714 arguments = new List<ir.Primitive>.from(arguments) |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2724 } | 2780 } |
| 2725 | 2781 |
| 2726 ir.Primitive buildInvocationMirror(Selector selector, | 2782 ir.Primitive buildInvocationMirror(Selector selector, |
| 2727 List<ir.Primitive> arguments) { | 2783 List<ir.Primitive> arguments) { |
| 2728 return addPrimitive(new ir.CreateInvocationMirror(selector, arguments)); | 2784 return addPrimitive(new ir.CreateInvocationMirror(selector, arguments)); |
| 2729 } | 2785 } |
| 2730 | 2786 |
| 2731 ir.Primitive buildForeignCode(js.Template codeTemplate, | 2787 ir.Primitive buildForeignCode(js.Template codeTemplate, |
| 2732 List<ir.Primitive> arguments, | 2788 List<ir.Primitive> arguments, |
| 2733 NativeBehavior behavior, | 2789 NativeBehavior behavior, |
| 2790 SourceInformation sourceInformation, |
| 2734 {Element dependency, | 2791 {Element dependency, |
| 2735 TypeMask type}) { | 2792 TypeMask type}) { |
| 2736 assert(behavior != null); | 2793 assert(behavior != null); |
| 2737 if (type == null) { | 2794 if (type == null) { |
| 2738 type = program.getTypeMaskForForeign(behavior); | 2795 type = program.getTypeMaskForForeign(behavior); |
| 2739 } | 2796 } |
| 2740 if (js.isIdentityTemplate(codeTemplate) && !program.isArrayType(type)) { | 2797 if (js.isIdentityTemplate(codeTemplate) && !program.isArrayType(type)) { |
| 2741 // JS expression is just a refinement. | 2798 // JS expression is just a refinement. |
| 2742 // Do not do this for arrays - those are special because array types can | 2799 // Do not do this for arrays - those are special because array types can |
| 2743 // change after creation. The input and output must therefore be modeled | 2800 // change after creation. The input and output must therefore be modeled |
| 2744 // as distinct values. | 2801 // as distinct values. |
| 2745 return addPrimitive(new ir.Refinement(arguments.single, type)); | 2802 return addPrimitive(new ir.Refinement(arguments.single, type)); |
| 2746 } | 2803 } |
| 2747 ir.Primitive result = addPrimitive(new ir.ForeignCode( | 2804 ir.Primitive result = addPrimitive(new ir.ForeignCode( |
| 2748 codeTemplate, | 2805 codeTemplate, |
| 2749 type, | 2806 type, |
| 2750 arguments, | 2807 arguments, |
| 2751 behavior, | 2808 behavior, |
| 2809 sourceInformation, |
| 2752 dependency: dependency)); | 2810 dependency: dependency)); |
| 2753 if (!codeTemplate.isExpression) { | 2811 if (!codeTemplate.isExpression) { |
| 2754 // Close the term if this is a "throw" expression or native body. | 2812 // Close the term if this is a "throw" expression or native body. |
| 2755 add(new ir.Unreachable()); | 2813 add(new ir.Unreachable()); |
| 2756 _current = null; | 2814 _current = null; |
| 2757 } | 2815 } |
| 2758 return result; | 2816 return result; |
| 2759 } | 2817 } |
| 2760 | 2818 |
| 2761 /// Creates a type test or type cast of [value] against [type]. | 2819 /// Creates a type test or type cast of [value] against [type]. |
| 2762 ir.Primitive buildTypeOperator(ir.Primitive value, | 2820 ir.Primitive buildTypeOperator(ir.Primitive value, |
| 2763 DartType type, | 2821 DartType type, |
| 2822 SourceInformation sourceInformation, |
| 2764 {bool isTypeTest}) { | 2823 {bool isTypeTest}) { |
| 2765 assert(isOpen); | 2824 assert(isOpen); |
| 2766 assert(isTypeTest != null); | 2825 assert(isTypeTest != null); |
| 2767 | 2826 |
| 2768 type = program.unaliasType(type); | 2827 type = program.unaliasType(type); |
| 2769 | 2828 |
| 2770 if (type.isMalformed) { | 2829 if (type.isMalformed) { |
| 2771 ErroneousElement element = type.element; | 2830 ErroneousElement element = type.element; |
| 2772 ir.Primitive message = buildStringConstant(element.message); | 2831 ir.Primitive message = buildStringConstant(element.message); |
| 2773 return buildStaticFunctionInvocation( | 2832 return buildStaticFunctionInvocation( |
| 2774 program.throwTypeErrorHelper, | 2833 program.throwTypeErrorHelper, |
| 2775 <ir.Primitive>[message]); | 2834 <ir.Primitive>[message], |
| 2835 sourceInformation); |
| 2776 } | 2836 } |
| 2777 | 2837 |
| 2778 List<ir.Primitive> typeArguments = const <ir.Primitive>[]; | 2838 List<ir.Primitive> typeArguments = const <ir.Primitive>[]; |
| 2779 if (type is GenericType && type.typeArguments.isNotEmpty) { | 2839 if (type is GenericType && type.typeArguments.isNotEmpty) { |
| 2780 typeArguments = type.typeArguments.map(buildTypeExpression).toList(); | 2840 typeArguments = type.typeArguments.map(buildTypeExpression).toList(); |
| 2781 } else if (type is TypeVariableType) { | 2841 } else if (type is TypeVariableType) { |
| 2782 typeArguments = <ir.Primitive>[buildTypeVariableAccess(type)]; | 2842 typeArguments = <ir.Primitive>[buildTypeVariableAccess(type)]; |
| 2783 } else if (type is FunctionType) { | 2843 } else if (type is FunctionType) { |
| 2784 typeArguments = <ir.Primitive>[buildTypeExpression(type)]; | 2844 typeArguments = <ir.Primitive>[buildTypeExpression(type)]; |
| 2785 } | 2845 } |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2926 final Set<LocalVariableElement> declared = new Set<LocalVariableElement>(); | 2986 final Set<LocalVariableElement> declared = new Set<LocalVariableElement>(); |
| 2927 final Set<LocalVariableElement> boxedOnEntry = | 2987 final Set<LocalVariableElement> boxedOnEntry = |
| 2928 new Set<LocalVariableElement>(); | 2988 new Set<LocalVariableElement>(); |
| 2929 } | 2989 } |
| 2930 | 2990 |
| 2931 class CatchClauseInfo { | 2991 class CatchClauseInfo { |
| 2932 final DartType type; | 2992 final DartType type; |
| 2933 final LocalVariableElement exceptionVariable; | 2993 final LocalVariableElement exceptionVariable; |
| 2934 final LocalVariableElement stackTraceVariable; | 2994 final LocalVariableElement stackTraceVariable; |
| 2935 final SubbuildFunction buildCatchBlock; | 2995 final SubbuildFunction buildCatchBlock; |
| 2996 final SourceInformation sourceInformation; |
| 2936 | 2997 |
| 2937 CatchClauseInfo({this.type, | 2998 CatchClauseInfo({this.type, |
| 2938 this.exceptionVariable, | 2999 this.exceptionVariable, |
| 2939 this.stackTraceVariable, | 3000 this.stackTraceVariable, |
| 2940 this.buildCatchBlock}); | 3001 this.buildCatchBlock, |
| 3002 this.sourceInformation}); |
| 2941 } | 3003 } |
| 2942 | 3004 |
| 2943 class SwitchCaseInfo { | 3005 class SwitchCaseInfo { |
| 2944 final SubbuildFunction buildCondition; | 3006 final SubbuildFunction buildCondition; |
| 2945 final SubbuildFunction buildBody; | 3007 final SubbuildFunction buildBody; |
| 2946 | 3008 |
| 2947 SwitchCaseInfo(this.buildCondition, this.buildBody); | 3009 SwitchCaseInfo(this.buildCondition, this.buildBody); |
| 2948 } | 3010 } |
| OLD | NEW |