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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart

Issue 1076793005: Fine-grain field, getter, setter, and function access in IrBuilder. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 8 months 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) 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 '../constants/expressions.dart'; 7 import '../constants/expressions.dart';
8 import '../constants/values.dart' show PrimitiveConstantValue; 8 import '../constants/values.dart' show PrimitiveConstantValue;
9 import '../dart_types.dart'; 9 import '../dart_types.dart';
10 import '../dart2jslib.dart'; 10 import '../dart2jslib.dart';
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 /// Call [enterTry] before translating a try block and call this function 154 /// Call [enterTry] before translating a try block and call this function
155 /// after translating it. 155 /// after translating it.
156 void leaveTry() { 156 void leaveTry() {
157 _boxedTryVariables.removeLast(); 157 _boxedTryVariables.removeLast();
158 } 158 }
159 159
160 void _buildTryExit(IrBuilder builder) { 160 void _buildTryExit(IrBuilder builder) {
161 for (Iterable<LocalVariableElement> boxedOnEntry in _boxedTryVariables) { 161 for (Iterable<LocalVariableElement> boxedOnEntry in _boxedTryVariables) {
162 for (LocalVariableElement variable in boxedOnEntry) { 162 for (LocalVariableElement variable in boxedOnEntry) {
163 assert(builder.isInMutableVariable(variable)); 163 assert(builder.isInMutableVariable(variable));
164 ir.Primitive value = builder.buildLocalGet(variable); 164 ir.Primitive value = builder.buildLocalVariableGet(variable);
165 builder.environment.update(variable, value); 165 builder.environment.update(variable, value);
166 } 166 }
167 } 167 }
168 } 168 }
169 } 169 }
170 170
171 /// A class to collect 'forward' jumps. 171 /// A class to collect 'forward' jumps.
172 /// 172 ///
173 /// A forward jump to a continuation in the sense of the CPS translation is 173 /// A forward jump to a continuation in the sense of the CPS translation is
174 /// a jump where the jump is emitted before any code in the body of the 174 /// a jump where the jump is emitted before any code in the body of the
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 List<ir.Primitive> arguments) { 642 List<ir.Primitive> arguments) {
643 assert(target.isInstanceMember); 643 assert(target.isInstanceMember);
644 assert(isOpen); 644 assert(isOpen);
645 return _continueWithExpression( 645 return _continueWithExpression(
646 (k) => new ir.InvokeMethodDirectly( 646 (k) => new ir.InvokeMethodDirectly(
647 buildThis(), target, selector, k, arguments)); 647 buildThis(), target, selector, k, arguments));
648 } 648 }
649 649
650 ir.Primitive _buildInvokeDynamic(ir.Primitive receiver, 650 ir.Primitive _buildInvokeDynamic(ir.Primitive receiver,
651 Selector selector, 651 Selector selector,
652 List<ir.Primitive> arguments) { 652 List<ir.Primitive> arguments,
653 {SourceInformation sourceInformation}) {
653 assert(isOpen); 654 assert(isOpen);
654 return _continueWithExpression( 655 return _continueWithExpression(
655 (k) => new ir.InvokeMethod(receiver, selector, k, arguments)); 656 (k) => new ir.InvokeMethod(receiver, selector, k, arguments,
657 sourceInformation: sourceInformation));
656 } 658 }
657 659
658 ir.Primitive _buildInvokeCall(ir.Primitive target, 660 ir.Primitive _buildInvokeCall(ir.Primitive target,
659 Selector selector, 661 Selector selector,
660 List<ir.Definition> arguments) { 662 List<ir.Definition> arguments,
663 {SourceInformation sourceInformation}) {
661 Selector callSelector = new Selector.callClosureFrom(selector); 664 Selector callSelector = new Selector.callClosureFrom(selector);
662 return _buildInvokeDynamic(target, callSelector, arguments); 665 return _buildInvokeDynamic(target, callSelector, arguments,
666 sourceInformation: sourceInformation);
663 } 667 }
664 668
665 669
666 /// Create a constant literal from [constant]. 670 /// Create a constant literal from [constant].
667 ir.Constant buildConstantLiteral(ConstantExpression constant) { 671 ir.Constant buildConstantLiteral(ConstantExpression constant) {
668 assert(isOpen); 672 assert(isOpen);
669 return addPrimitive(new ir.Constant(constant)); 673 return addPrimitive(new ir.Constant(constant));
670 } 674 }
671 675
672 // Helper for building primitive literals. 676 // Helper for building primitive literals.
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 871
868 ir.ConstructorDefinition makeConstructorDefinition( 872 ir.ConstructorDefinition makeConstructorDefinition(
869 List<ConstantExpression> defaults, List<ir.Initializer> initializers) { 873 List<ConstantExpression> defaults, List<ir.Initializer> initializers) {
870 FunctionElement element = state.currentElement; 874 FunctionElement element = state.currentElement;
871 ir.RunnableBody body = makeRunnableBody(); 875 ir.RunnableBody body = makeRunnableBody();
872 return new ir.ConstructorDefinition( 876 return new ir.ConstructorDefinition(
873 element, state.thisParameter, state.functionParameters, body, initialize rs, 877 element, state.thisParameter, state.functionParameters, body, initialize rs,
874 state.localConstants, defaults); 878 state.localConstants, defaults);
875 } 879 }
876 880
877 /// Create a super invocation where the method name and the argument structure 881 /// Create a invocation of the [method] on the super class where the call
878 /// are defined by [selector] and the argument values are defined by 882 /// structure is defined [selector] and the argument values are defined by
879 /// [arguments]. 883 /// [arguments].
880 ir.Primitive buildSuperInvocation(Element target, 884 ir.Primitive buildSuperMethodInvocation(MethodElement method,
881 Selector selector, 885 Selector selector,
882 List<ir.Primitive> arguments); 886 List<ir.Primitive> arguments) {
883 887 return _buildInvokeSuper(method, selector, arguments);
884 /// Create a getter invocation of the [target] on the super class.
885 ir.Primitive buildSuperGet(Element target) {
886 Selector selector = new Selector.getter(target.name, target.library);
887 return buildSuperInvocation(target, selector, const <ir.Primitive>[]);
888 } 888 }
889 889
890 /// Create a setter invocation of the [target] on the super class of with 890 /// Create a call invocation on the value of [field] on the super class where
891 /// [value]. 891 /// the call structure is defined [selector] and the argument values are
892 ir.Primitive buildSuperSet(Element target, ir.Primitive value) { 892 /// defined by [arguments].
893 Selector selector = new Selector.setter(target.name, target.library); 893 ir.Primitive buildSuperFieldInvocation(FieldElement field,
894 buildSuperInvocation(target, selector, [value]); 894 Selector selector,
895 List<ir.Primitive> arguments) {
896 // TODO(johnniwinther): Maybe this should have its own ir node.
897 return buildCallInvocation(
898 buildSuperFieldGet(field),
899 selector,
900 arguments);
901 }
902
903 /// Create a call invocation on the value returned from the [getter] on the
904 /// super class where the call structure is defined [selector] and the
905 /// argument values are defined by [arguments].
906 ir.Primitive buildSuperGetterInvocation(MethodElement getter,
907 Selector selector,
908 List<ir.Primitive> arguments) {
909 // TODO(johnniwinther): Maybe this should have its own ir node.
910 return buildCallInvocation(
911 buildSuperGetterGet(getter),
912 selector,
913 arguments);
914 }
915
916 /// Create a read access of the [field] on the super class.
917 ir.Primitive buildSuperFieldGet(FieldElement field) {
918 // TODO(johnniwinther): This should have its own ir node.
919 return _buildInvokeSuper(
920 field,
921 new Selector.getter(field.name, field.library),
922 const <ir.Primitive>[]);
923 }
924
925 /// Create a read access of the [method] on the super class, i.e. a
926 /// closurization of [method].
927 ir.Primitive buildSuperMethodGet(MethodElement method) {
928 // TODO(johnniwinther): This should have its own ir node.
929 return _buildInvokeSuper(
930 method,
931 new Selector.getter(method.name, method.library),
932 const <ir.Primitive>[]);
933 }
934
935 /// Create a getter invocation of the [getter] on the super class.
936 ir.Primitive buildSuperGetterGet(MethodElement getter) {
937 // TODO(johnniwinther): This should have its own ir node.
938 return _buildInvokeSuper(
939 getter,
940 new Selector.getter(getter.name, getter.library),
941 const <ir.Primitive>[]);
942 }
943
944 /// Create a write access to the [field] on the super class of with [value].
945 ir.Primitive buildSuperFieldSet(Element field, ir.Primitive value) {
946 // TODO(johnniwinther): This should have its own ir node.
947 _buildInvokeSuper(
948 field,
949 new Selector.setter(field.name, field.library),
950 <ir.Primitive>[value]);
895 return value; 951 return value;
896 } 952 }
897 953
898 /// Create an index set invocation on the super class with the provided 954 /// Create an setter invocation of the [setter] on the super class with
899 /// [index] and [value]. 955 /// [value].
900 ir.Primitive buildSuperIndexSet(Element target, 956 ir.Primitive buildSuperSetterSet(MethodElement setter,
957 ir.Primitive value) {
958 // TODO(johnniwinther): This should have its own ir node.
959 _buildInvokeSuper(
960 setter,
961 new Selector.setter(setter.name, setter.library),
962 <ir.Primitive>[value]);
963 return value;
964 }
965
966 /// Create an invocation of the index set [method] on the super class with
967 /// the provided [index] and [value].
968 ir.Primitive buildSuperIndexSet(MethodElement method,
901 ir.Primitive index, 969 ir.Primitive index,
902 ir.Primitive value) { 970 ir.Primitive value) {
903 _buildInvokeSuper(target, new Selector.indexSet(), 971 _buildInvokeSuper(method, new Selector.indexSet(),
904 <ir.Primitive>[index, value]); 972 <ir.Primitive>[index, value]);
905 return value; 973 return value;
906 } 974 }
907 975
908 /// Create a dynamic invocation on [receiver] where the method name and 976 /// Create a dynamic invocation on [receiver] where the method name and
909 /// argument structure are defined by [selector] and the argument values are 977 /// argument structure are defined by [selector] and the argument values are
910 /// defined by [arguments]. 978 /// defined by [arguments].
911 ir.Primitive buildDynamicInvocation(ir.Primitive receiver, 979 ir.Primitive buildDynamicInvocation(ir.Primitive receiver,
912 Selector selector, 980 Selector selector,
913 List<ir.Primitive> arguments) { 981 List<ir.Primitive> arguments) {
(...skipping 20 matching lines...) Expand all
934 /// Create a dynamic index set invocation on [receiver] with the provided 1002 /// Create a dynamic index set invocation on [receiver] with the provided
935 /// [index] and [value]. 1003 /// [index] and [value].
936 ir.Primitive buildDynamicIndexSet(ir.Primitive receiver, 1004 ir.Primitive buildDynamicIndexSet(ir.Primitive receiver,
937 ir.Primitive index, 1005 ir.Primitive index,
938 ir.Primitive value) { 1006 ir.Primitive value) {
939 _buildInvokeDynamic( 1007 _buildInvokeDynamic(
940 receiver, new Selector.indexSet(), <ir.Primitive>[index, value]); 1008 receiver, new Selector.indexSet(), <ir.Primitive>[index, value]);
941 return value; 1009 return value;
942 } 1010 }
943 1011
944 /// Create a read access of [local]. 1012 ir.Primitive _buildLocalGet(LocalElement element);
945 ir.Primitive buildLocalGet(LocalElement element);
946 1013
947 /// Create a write access to [local] with the provided [value]. 1014 /// Create a read access of the [local] variable or parameter.
948 ir.Primitive buildLocalSet(LocalElement element, ir.Primitive value); 1015 ir.Primitive buildLocalVariableGet(LocalElement local) {
949 1016 // TODO(johnniwinther): Separate function access from variable access.
950 /// Create an invocation of the local [element] where argument structure is 1017 return _buildLocalGet(local);
951 /// defined by [selector] and the argument values are defined by [arguments].
952 ir.Primitive buildLocalInvocation(LocalElement element,
953 Selector selector,
954 List<ir.Primitive> arguments) {
955 return buildCallInvocation(buildLocalGet(element), selector, arguments);
956 } 1018 }
957 1019
958 /// Create a static invocation of [element] where argument structure is 1020 /// Create a read access of the local [function], i.e. closurization of
959 /// defined by [selector] and the argument values are defined by [arguments]. 1021 /// [function].
960 ir.Primitive buildStaticInvocation(Element element, 1022 ir.Primitive buildLocalFunctionGet(LocalFunctionElement function) {
961 Selector selector, 1023 // TODO(johnniwinther): Separate function access from variable access.
962 List<ir.Primitive> arguments, 1024 return _buildLocalGet(function);
963 {SourceInformation sourceInformation}) {
964 return _buildInvokeStatic(element, selector, arguments, sourceInformation);
965 } 1025 }
966 1026
967 /// Create a static getter invocation of [element] where the getter name is 1027 /// Create a write access to the [local] variable or parameter with the
968 /// defined by [selector]. 1028 /// provided [value].
969 ir.Primitive buildStaticGet(Element element, 1029 ir.Primitive buildLocalVariableSet(LocalElement local, ir.Primitive value);
970 {SourceInformation sourceInformation}) { 1030
971 Selector selector = new Selector.getter(element.name, element.library); 1031 /// Create an invocation of the the [local] variable or parameter where
1032 /// argument structure is defined by [selector] and the argument values are
1033 /// defined by [arguments].
1034 ir.Primitive buildLocalVariableInvocation(LocalVariableElement local,
1035 Selector selector,
1036 List<ir.Primitive> arguments) {
1037 return buildCallInvocation(
1038 buildLocalVariableGet(local), selector, arguments);
1039 }
1040
1041 /// Create an invocation of the local [function] where argument structure is
1042 /// defined by [selector] and the argument values are defined by [arguments].
1043 ir.Primitive buildLocalFunctionInvocation(
1044 LocalFunctionElement function,
1045 Selector selector,
1046 List<ir.Primitive> arguments) {
1047 // TODO(johnniwinther): Maybe this should have its own ir node.
1048 return buildCallInvocation(
1049 buildLocalFunctionGet(function), selector, arguments);
1050 }
1051
1052 /// Create a static invocation of [function] where argument structure is
1053 /// defined by [selector] and the argument values are defined by [arguments].
1054 ir.Primitive buildStaticFunctionInvocation(
1055 MethodElement function,
1056 Selector selector,
1057 List<ir.Primitive> arguments,
1058 {SourceInformation sourceInformation}) {
1059 return _buildInvokeStatic(function, selector, arguments, sourceInformation);
1060 }
1061
1062 /// Create a call invocation of the value of the static [field] where argument
1063 /// structure is defined by [selector] and the argument values are defined by
1064 /// [arguments].
1065 ir.Primitive buildStaticFieldInvocation(
1066 FieldElement field,
1067 Selector selector,
1068 List<ir.Primitive> arguments,
1069 {SourceInformation sourceInformation}) {
1070 // TODO(johnniwinther): Maybe this should have its own node.
1071 return buildCallInvocation(
1072 buildStaticFieldGet(field),
1073 selector,
1074 arguments,
1075 sourceInformation: sourceInformation);
1076 }
1077
1078 /// Create a call invocation of the result of calling the static [getter]
1079 /// where argument structure is defined by [selector] and the argument values
1080 /// are defined by [arguments].
1081 ir.Primitive buildStaticGetterInvocation(
1082 MethodElement getter,
1083 Selector selector,
1084 List<ir.Primitive> arguments,
1085 {SourceInformation sourceInformation}) {
1086 // TODO(johnniwinther): Maybe this should have its own node.
1087 return buildCallInvocation(
1088 buildStaticGetterGet(getter),
1089 selector,
1090 arguments,
1091 sourceInformation: sourceInformation);
1092 }
1093
1094 /// Create a read access of the static [field].
1095 ir.Primitive buildStaticFieldGet(FieldElement field,
1096 {SourceInformation sourceInformation}) {
1097 Selector selector = new Selector.getter(field.name, field.library);
972 // TODO(karlklose,sigurdm): build different nodes for getters. 1098 // TODO(karlklose,sigurdm): build different nodes for getters.
973 return _buildInvokeStatic( 1099 return _buildInvokeStatic(
974 element, selector, const <ir.Primitive>[], sourceInformation); 1100 field, selector, const <ir.Primitive>[], sourceInformation);
975 } 1101 }
976 1102
977 /// Create a static setter invocation of [element] where the setter name and 1103 /// Create a getter invocation of the static [getter].
978 /// argument are defined by [selector] and [value], respectively. 1104 ir.Primitive buildStaticGetterGet(MethodElement getter,
979 ir.Primitive buildStaticSet(Element element, 1105 {SourceInformation sourceInformation}) {
980 ir.Primitive value, 1106 Selector selector = new Selector.getter(getter.name, getter.library);
981 {SourceInformation sourceInformation}) { 1107 // TODO(karlklose,sigurdm): build different nodes for getters.
982 Selector selector = new Selector.setter(element.name, element.library); 1108 return _buildInvokeStatic(
1109 getter, selector, const <ir.Primitive>[], sourceInformation);
1110 }
1111
1112 /// Create a read access of the static [function], i.e. a closurization of
1113 /// [function].
1114 ir.Primitive buildStaticFunctionGet(MethodElement function,
1115 {SourceInformation sourceInformation}) {
1116 Selector selector =
1117 new Selector.getter(function.name, function.library);
1118 // TODO(karlklose,sigurdm): build different nodes for getters.
1119 return _buildInvokeStatic(
1120 function, selector, const <ir.Primitive>[], sourceInformation);
1121 }
1122
1123 /// Create a write access to the static [field] with the [value].
1124 ir.Primitive buildStaticFieldSet(FieldElement field,
1125 ir.Primitive value,
1126 {SourceInformation sourceInformation}) {
1127 Selector selector = new Selector.setter(field.name, field.library);
983 // TODO(karlklose,sigurdm): build different nodes for setters. 1128 // TODO(karlklose,sigurdm): build different nodes for setters.
984 _buildInvokeStatic( 1129 _buildInvokeStatic(
985 element, selector, <ir.Primitive>[value], sourceInformation); 1130 field, selector, <ir.Primitive>[value], sourceInformation);
986 return value; 1131 return value;
987 } 1132 }
988 1133
1134 /// Create a setter invocation of the static [setter] with the [value].
1135 ir.Primitive buildStaticSetterSet(MethodElement setter,
1136 ir.Primitive value,
1137 {SourceInformation sourceInformation}) {
1138 Selector selector = new Selector.setter(setter.name, setter.library);
1139 // TODO(karlklose,sigurdm): build different nodes for setters.
1140 _buildInvokeStatic(
1141 setter, selector, <ir.Primitive>[value], sourceInformation);
1142 return value;
1143 }
1144
1145 /// Create an erroneous invocation where argument structure is defined by
1146 /// [selector] and the argument values are defined by [arguments].
1147 // TODO(johnniwinther): Make this more fine-grained.
1148 ir.Primitive buildErroneousInvocation(
1149 Element element,
1150 Selector selector,
1151 List<ir.Primitive> arguments) {
1152 // TODO(johnniwinther): This should have its own ir node.
1153 return _buildInvokeStatic( element, selector, arguments, null);
1154 }
1155
989 /// Create a constructor invocation of [element] on [type] where the 1156 /// Create a constructor invocation of [element] on [type] where the
990 /// constructor name and argument structure are defined by [selector] and the 1157 /// constructor name and argument structure are defined by [selector] and the
991 /// argument values are defined by [arguments]. 1158 /// argument values are defined by [arguments].
992 ir.Primitive buildConstructorInvocation(FunctionElement element, 1159 ir.Primitive buildConstructorInvocation(FunctionElement element,
993 Selector selector, 1160 Selector selector,
994 DartType type, 1161 DartType type,
995 List<ir.Primitive> arguments); 1162 List<ir.Primitive> arguments);
996 1163
997 /// Create a string concatenation of the [arguments]. 1164 /// Create a string concatenation of the [arguments].
998 ir.Primitive buildStringConcatenation(List<ir.Primitive> arguments) { 1165 ir.Primitive buildStringConcatenation(List<ir.Primitive> arguments) {
999 assert(isOpen); 1166 assert(isOpen);
1000 return _continueWithExpression( 1167 return _continueWithExpression(
1001 (k) => new ir.ConcatenateStrings(k, arguments)); 1168 (k) => new ir.ConcatenateStrings(k, arguments));
1002 } 1169 }
1003 1170
1004 /// Create an invocation of the `call` method of [functionExpression], where 1171 /// Create an invocation of the `call` method of [functionExpression], where
1005 /// the named arguments are given by [selector]. 1172 /// the named arguments are given by [selector].
1006 ir.Primitive buildCallInvocation( 1173 ir.Primitive buildCallInvocation(
1007 ir.Primitive functionExpression, 1174 ir.Primitive functionExpression,
1008 Selector selector, 1175 Selector selector,
1009 List<ir.Definition> arguments) { 1176 List<ir.Definition> arguments,
1010 return _buildInvokeCall(functionExpression, selector, arguments); 1177 {SourceInformation sourceInformation}) {
1178 return _buildInvokeCall(functionExpression, selector, arguments,
1179 sourceInformation: sourceInformation);
1011 } 1180 }
1012 1181
1013 /// Creates an if-then-else statement with the provided [condition] where the 1182 /// Creates an if-then-else statement with the provided [condition] where the
1014 /// then and else branches are created through the [buildThenPart] and 1183 /// then and else branches are created through the [buildThenPart] and
1015 /// [buildElsePart] functions, respectively. 1184 /// [buildElsePart] functions, respectively.
1016 /// 1185 ///
1017 /// An if-then statement is created if [buildElsePart] is a no-op. 1186 /// An if-then statement is created if [buildElsePart] is a no-op.
1018 // TODO(johnniwinther): Unify implementation with [buildConditional] and 1187 // TODO(johnniwinther): Unify implementation with [buildConditional] and
1019 // [_buildLogicalOperator]. 1188 // [_buildLogicalOperator].
1020 void buildIf(ir.Primitive condition, 1189 void buildIf(ir.Primitive condition,
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1316 if (buildVariableDeclaration != null) { 1485 if (buildVariableDeclaration != null) {
1317 buildVariableDeclaration(bodyBuilder); 1486 buildVariableDeclaration(bodyBuilder);
1318 } 1487 }
1319 ir.Parameter currentValue = new ir.Parameter(null); 1488 ir.Parameter currentValue = new ir.Parameter(null);
1320 ir.Continuation currentInvoked = new ir.Continuation([currentValue]); 1489 ir.Continuation currentInvoked = new ir.Continuation([currentValue]);
1321 bodyBuilder.add(new ir.LetCont(currentInvoked, 1490 bodyBuilder.add(new ir.LetCont(currentInvoked,
1322 new ir.InvokeMethod(iterator, new Selector.getter("current", null), 1491 new ir.InvokeMethod(iterator, new Selector.getter("current", null),
1323 currentInvoked, emptyArguments))); 1492 currentInvoked, emptyArguments)));
1324 // TODO(sra): Does this cover all cases? The general setter case include 1493 // TODO(sra): Does this cover all cases? The general setter case include
1325 // super. 1494 // super.
1495 // TODO(johnniwinther): Extract this as a provided strategy.
1326 if (Elements.isLocal(variableElement)) { 1496 if (Elements.isLocal(variableElement)) {
1327 bodyBuilder.buildLocalSet(variableElement, currentValue); 1497 bodyBuilder.buildLocalVariableSet(variableElement, currentValue);
1328 } else if (Elements.isStaticOrTopLevel(variableElement) || 1498 } else if (Elements.isErroneous(variableElement)) {
1329 Elements.isErroneous(variableElement)) { 1499 bodyBuilder.buildErroneousInvocation(variableElement,
1330 bodyBuilder.buildStaticSet(variableElement, currentValue); 1500 new Selector.setter(variableElement.name, variableElement.library),
1501 <ir.Primitive>[currentValue]);
1502 } else if (Elements.isStaticOrTopLevel(variableElement)) {
1503 if (variableElement.isField) {
1504 bodyBuilder.buildStaticFieldSet(variableElement, currentValue);
1505 } else {
1506 bodyBuilder.buildStaticSetterSet(variableElement, currentValue);
1507 }
1331 } else { 1508 } else {
1332 ir.Primitive receiver = bodyBuilder.buildThis(); 1509 ir.Primitive receiver = bodyBuilder.buildThis();
1333 assert(receiver != null); 1510 assert(receiver != null);
1334 bodyBuilder.buildDynamicSet(receiver, variableSelector, currentValue); 1511 bodyBuilder.buildDynamicSet(receiver, variableSelector, currentValue);
1335 } 1512 }
1336 1513
1337 // Translate the body in the hole in the delimited term above, and add 1514 // Translate the body in the hole in the delimited term above, and add
1338 // a jump to the loop if control flow is live after the body. 1515 // a jump to the loop if control flow is live after the body.
1339 JumpCollector breakCollector = 1516 JumpCollector breakCollector =
1340 new ForwardJumpCollector(environment, target: target); 1517 new ForwardJumpCollector(environment, target: target);
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1592 // entry to any try block. They are not filtered out before this because 1769 // entry to any try block. They are not filtered out before this because
1593 // we can not identify all of them in the same pass where we identify the 1770 // we can not identify all of them in the same pass where we identify the
1594 // variables assigned in the try (they may be captured by a closure after 1771 // variables assigned in the try (they may be captured by a closure after
1595 // the try statement). 1772 // the try statement).
1596 Iterable<LocalVariableElement> boxedOnEntry = 1773 Iterable<LocalVariableElement> boxedOnEntry =
1597 tryStatementInfo.boxedOnEntry.where((LocalVariableElement variable) { 1774 tryStatementInfo.boxedOnEntry.where((LocalVariableElement variable) {
1598 return !tryCatchBuilder.mutableCapturedVariables.contains(variable); 1775 return !tryCatchBuilder.mutableCapturedVariables.contains(variable);
1599 }); 1776 });
1600 for (LocalVariableElement variable in boxedOnEntry) { 1777 for (LocalVariableElement variable in boxedOnEntry) {
1601 assert(!tryCatchBuilder.isInMutableVariable(variable)); 1778 assert(!tryCatchBuilder.isInMutableVariable(variable));
1602 ir.Primitive value = tryCatchBuilder.buildLocalGet(variable); 1779 ir.Primitive value = tryCatchBuilder.buildLocalVariableGet(variable);
1603 tryCatchBuilder.makeMutableVariable(variable); 1780 tryCatchBuilder.makeMutableVariable(variable);
1604 tryCatchBuilder.declareLocalVariable(variable, initialValue: value); 1781 tryCatchBuilder.declareLocalVariable(variable, initialValue: value);
1605 } 1782 }
1606 1783
1607 IrBuilder tryBuilder = tryCatchBuilder.makeDelimitedBuilder(); 1784 IrBuilder tryBuilder = tryCatchBuilder.makeDelimitedBuilder();
1608 1785
1609 void interceptJumps(JumpCollector collector) { 1786 void interceptJumps(JumpCollector collector) {
1610 collector.enterTry(boxedOnEntry); 1787 collector.enterTry(boxedOnEntry);
1611 } 1788 }
1612 void restoreJumps(JumpCollector collector) { 1789 void restoreJumps(JumpCollector collector) {
1613 collector.leaveTry(); 1790 collector.leaveTry();
1614 } 1791 }
1615 tryBuilder.state.breakCollectors.forEach(interceptJumps); 1792 tryBuilder.state.breakCollectors.forEach(interceptJumps);
1616 tryBuilder.state.continueCollectors.forEach(interceptJumps); 1793 tryBuilder.state.continueCollectors.forEach(interceptJumps);
1617 buildTryBlock(tryBuilder); 1794 buildTryBlock(tryBuilder);
1618 if (tryBuilder.isOpen) { 1795 if (tryBuilder.isOpen) {
1619 interceptJumps(join); 1796 interceptJumps(join);
1620 tryBuilder.jumpTo(join); 1797 tryBuilder.jumpTo(join);
1621 restoreJumps(join); 1798 restoreJumps(join);
1622 } 1799 }
1623 tryBuilder.state.breakCollectors.forEach(restoreJumps); 1800 tryBuilder.state.breakCollectors.forEach(restoreJumps);
1624 tryBuilder.state.continueCollectors.forEach(restoreJumps); 1801 tryBuilder.state.continueCollectors.forEach(restoreJumps);
1625 1802
1626 IrBuilder catchBuilder = tryCatchBuilder.makeDelimitedBuilder(); 1803 IrBuilder catchBuilder = tryCatchBuilder.makeDelimitedBuilder();
1627 for (LocalVariableElement variable in boxedOnEntry) { 1804 for (LocalVariableElement variable in boxedOnEntry) {
1628 assert(catchBuilder.isInMutableVariable(variable)); 1805 assert(catchBuilder.isInMutableVariable(variable));
1629 ir.Primitive value = catchBuilder.buildLocalGet(variable); 1806 ir.Primitive value = catchBuilder.buildLocalVariableGet(variable);
1630 // Note that we remove the variable from the set of mutable variables 1807 // Note that we remove the variable from the set of mutable variables
1631 // here (and not above for the try body). This is because the set of 1808 // here (and not above for the try body). This is because the set of
1632 // mutable variables is global for the whole function and not local to 1809 // mutable variables is global for the whole function and not local to
1633 // a delimited builder. 1810 // a delimited builder.
1634 catchBuilder.removeMutableVariable(variable); 1811 catchBuilder.removeMutableVariable(variable);
1635 catchBuilder.environment.update(variable, value); 1812 catchBuilder.environment.update(variable, value);
1636 } 1813 }
1637 1814
1638 // TODO(kmillikin): Handle multiple catch clauses. 1815 // TODO(kmillikin): Handle multiple catch clauses.
1639 assert(catchClauseInfos.length == 1); 1816 assert(catchClauseInfos.length == 1);
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
2077 prim.useElementAsHint(functionElement); 2254 prim.useElementAsHint(functionElement);
2078 } 2255 }
2079 } 2256 }
2080 2257
2081 /// Create a function expression from [definition]. 2258 /// Create a function expression from [definition].
2082 ir.Primitive buildFunctionExpression(ir.FunctionDefinition definition) { 2259 ir.Primitive buildFunctionExpression(ir.FunctionDefinition definition) {
2083 return addPrimitive(new ir.CreateFunction(definition)); 2260 return addPrimitive(new ir.CreateFunction(definition));
2084 } 2261 }
2085 2262
2086 /// Create a read access of [local]. 2263 /// Create a read access of [local].
2087 ir.Primitive buildLocalGet(LocalElement local) { 2264 @override
2265 ir.Primitive _buildLocalGet(LocalElement local) {
2088 assert(isOpen); 2266 assert(isOpen);
2089 if (isInMutableVariable(local)) { 2267 if (isInMutableVariable(local)) {
2090 // Do not use [local] as a hint on [result]. The variable should always 2268 // Do not use [local] as a hint on [result]. The variable should always
2091 // be inlined, but the hint prevents it. 2269 // be inlined, but the hint prevents it.
2092 return addPrimitive(new ir.GetMutableVariable(getMutableVariable(local))); 2270 return addPrimitive(new ir.GetMutableVariable(getMutableVariable(local)));
2093 } else { 2271 } else {
2094 return environment.lookup(local); 2272 return environment.lookup(local);
2095 } 2273 }
2096 } 2274 }
2097 2275
2098 /// Create a write access to [local] with the provided [value]. 2276 /// Create a write access to [local] with the provided [value].
2099 ir.Primitive buildLocalSet(LocalElement local, ir.Primitive value) { 2277 @override
2278 ir.Primitive buildLocalVariableSet(LocalElement local, ir.Primitive value) {
2100 assert(isOpen); 2279 assert(isOpen);
2101 if (isInMutableVariable(local)) { 2280 if (isInMutableVariable(local)) {
2102 add(new ir.SetMutableVariable(getMutableVariable(local), value)); 2281 add(new ir.SetMutableVariable(getMutableVariable(local), value));
2103 } else { 2282 } else {
2104 value.useElementAsHint(local); 2283 value.useElementAsHint(local);
2105 environment.update(local, value); 2284 environment.update(local, value);
2106 } 2285 }
2107 return value; 2286 return value;
2108 } 2287 }
2109 2288
2110 ir.Primitive buildThis() { 2289 ir.Primitive buildThis() {
2111 return state.enclosingMethodThisParameter; 2290 return state.enclosingMethodThisParameter;
2112 } 2291 }
2113 2292
2114 ir.Primitive buildSuperInvocation(Element target,
2115 Selector selector,
2116 List<ir.Primitive> arguments) {
2117 return _buildInvokeSuper(target, selector, arguments);
2118 }
2119
2120 @override 2293 @override
2121 ir.Primitive buildConstructorInvocation(FunctionElement element, 2294 ir.Primitive buildConstructorInvocation(FunctionElement element,
2122 Selector selector, 2295 Selector selector,
2123 DartType type, 2296 DartType type,
2124 List<ir.Primitive> arguments) { 2297 List<ir.Primitive> arguments) {
2125 assert(isOpen); 2298 assert(isOpen);
2126 return _continueWithExpression( 2299 return _continueWithExpression(
2127 (k) => new ir.InvokeConstructor(type, element, selector, k, 2300 (k) => new ir.InvokeConstructor(type, element, selector, k,
2128 arguments)); 2301 arguments));
2129 } 2302 }
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
2281 // so treat that specially. 2454 // so treat that specially.
2282 ir.Primitive value = field.local is ThisLocal 2455 ir.Primitive value = field.local is ThisLocal
2283 ? buildThis() 2456 ? buildThis()
2284 : environment.lookup(field.local); 2457 : environment.lookup(field.local);
2285 arguments.add(value); 2458 arguments.add(value);
2286 } 2459 }
2287 return addPrimitive( 2460 return addPrimitive(
2288 new ir.CreateInstance(classElement, arguments, const <ir.Primitive>[])); 2461 new ir.CreateInstance(classElement, arguments, const <ir.Primitive>[]));
2289 } 2462 }
2290 2463
2291 /// Create a read access of [local]. 2464 /// Create a read access of [local] variable or parameter.
2292 ir.Primitive buildLocalGet(LocalElement local) { 2465 @override
2466 ir.Primitive _buildLocalGet(LocalElement local) {
2293 assert(isOpen); 2467 assert(isOpen);
2294 ClosureLocation location = jsState.boxedVariables[local]; 2468 ClosureLocation location = jsState.boxedVariables[local];
2295 if (location != null) { 2469 if (location != null) {
2296 ir.Primitive result = new ir.GetField(environment.lookup(location.box), 2470 ir.Primitive result = new ir.GetField(environment.lookup(location.box),
2297 location.field); 2471 location.field);
2298 result.useElementAsHint(local); 2472 result.useElementAsHint(local);
2299 return addPrimitive(result); 2473 return addPrimitive(result);
2300 } else { 2474 } else {
2301 return environment.lookup(local); 2475 return environment.lookup(local);
2302 } 2476 }
2303 } 2477 }
2304 2478
2305 /// Create a write access to [local] with the provided [value]. 2479 /// Create a write access to [local] variable or parameter with the provided
2306 ir.Primitive buildLocalSet(LocalElement local, ir.Primitive value) { 2480 /// [value].
2481 @override
2482 ir.Primitive buildLocalVariableSet(LocalElement local, ir.Primitive value) {
2307 assert(isOpen); 2483 assert(isOpen);
2308 ClosureLocation location = jsState.boxedVariables[local]; 2484 ClosureLocation location = jsState.boxedVariables[local];
2309 if (location != null) { 2485 if (location != null) {
2310 add(new ir.SetField(environment.lookup(location.box), 2486 add(new ir.SetField(environment.lookup(location.box),
2311 location.field, 2487 location.field,
2312 value)); 2488 value));
2313 } else { 2489 } else {
2314 value.useElementAsHint(local); 2490 value.useElementAsHint(local);
2315 environment.update(local, value); 2491 environment.update(local, value);
2316 } 2492 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2350 add(new ir.SetField(newBox, location.field, value)); 2526 add(new ir.SetField(newBox, location.field, value));
2351 } 2527 }
2352 environment.update(scope.box, newBox); 2528 environment.update(scope.box, newBox);
2353 } 2529 }
2354 2530
2355 ir.Primitive buildThis() { 2531 ir.Primitive buildThis() {
2356 if (jsState.receiver != null) return jsState.receiver; 2532 if (jsState.receiver != null) return jsState.receiver;
2357 return state.thisParameter; 2533 return state.thisParameter;
2358 } 2534 }
2359 2535
2360 ir.Primitive buildSuperInvocation(Element target, 2536 @override
2361 Selector selector, 2537 ir.Primitive buildSuperFieldGet(FieldElement target) {
2362 List<ir.Primitive> arguments) { 2538 return addPrimitive(new ir.GetField(buildThis(), target));
2363 // Direct calls to FieldElements are currently problematic because the 2539 }
2364 // backend will not issue a getter for the field unless it finds a dynamic 2540
2365 // access that matches its getter. 2541 @override
2366 // As a workaround, we generate GetField for this case, although ideally 2542 ir.Primitive buildSuperFieldSet(FieldElement target, ir.Primitive value) {
2367 // this should be the result of inlining the field's getter. 2543 add(new ir.SetField(buildThis(), target, value));
2368 if (target is FieldElement) { 2544 return value;
2369 if (selector.isGetter) {
2370 return addPrimitive(new ir.GetField(buildThis(), target));
2371 } else {
2372 assert(selector.isSetter);
2373 add(new ir.SetField(buildThis(), target, arguments.single));
2374 return arguments.single;
2375 }
2376 } else {
2377 return _buildInvokeSuper(target, selector, arguments);
2378 }
2379 } 2545 }
2380 2546
2381 ir.Primitive buildInvokeDirectly(FunctionElement target, 2547 ir.Primitive buildInvokeDirectly(FunctionElement target,
2382 ir.Primitive receiver, 2548 ir.Primitive receiver,
2383 List<ir.Primitive> arguments) { 2549 List<ir.Primitive> arguments) {
2384 assert(isOpen); 2550 assert(isOpen);
2385 Selector selector = 2551 Selector selector =
2386 new Selector.call(target.name, target.library, arguments.length); 2552 new Selector.call(target.name, target.library, arguments.length);
2387 return _continueWithExpression( 2553 return _continueWithExpression(
2388 (k) => new ir.InvokeMethodDirectly( 2554 (k) => new ir.InvokeMethodDirectly(
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
2536 } 2702 }
2537 2703
2538 /// Synthetic parameter to a JavaScript factory method that takes the type 2704 /// Synthetic parameter to a JavaScript factory method that takes the type
2539 /// argument given for the type variable [variable]. 2705 /// argument given for the type variable [variable].
2540 class TypeInformationParameter implements Local { 2706 class TypeInformationParameter implements Local {
2541 final TypeVariableElement variable; 2707 final TypeVariableElement variable;
2542 final ExecutableElement executableContext; 2708 final ExecutableElement executableContext;
2543 TypeInformationParameter(this.variable, this.executableContext); 2709 TypeInformationParameter(this.variable, this.executableContext);
2544 String get name => variable.name; 2710 String get name => variable.name;
2545 } 2711 }
OLDNEW
« no previous file with comments | « pkg/analyzer2dart/lib/src/modely.dart ('k') | pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698