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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder.dart

Issue 702453002: Support for-in in analyzer2dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 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_backend/dart_backend.dart' show DartBackend; 9 import '../dart_backend/dart_backend.dart' show DartBackend;
10 import '../dart_types.dart'; 10 import '../dart_types.dart';
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after
877 environment = condBuilder.environment; 877 environment = condBuilder.environment;
878 breakCollector.addJump(this); 878 breakCollector.addJump(this);
879 letJoin.continuation = createJoin(environment.length, breakCollector); 879 letJoin.continuation = createJoin(environment.length, breakCollector);
880 _current = letJoin; 880 _current = letJoin;
881 } else { 881 } else {
882 _current = condBuilder._current; 882 _current = condBuilder._current;
883 environment = condBuilder.environment; 883 environment = condBuilder.environment;
884 } 884 }
885 } 885 }
886 886
887 /// Creates a for-in loop, `for (v in e) b`.
888 ///
889 /// [buildExpression] creates the expression, `e`. The variable, `v`, can
890 /// take one of three forms:
891 /// 1) `v` can be declared within the for-in statement, like in
892 /// `for (var v in e)`, in which case, [buildVariableDeclaration]
893 /// creates its declaration and [variableElement] is the element for
894 /// the declared variable,
895 /// 2) `v` is predeclared statically known variable, that is top-level,
896 /// static, or local variable, in which case [variableElement] is the
897 /// variable element, and [variableSelector] defines its write access,
898 /// 3) `v` is an instance variable in which case [variableSelector]
899 /// defines its write access.
900 /// [buildBody] creates the body, `b`, of the loop. The jump [target] is used
901 /// to identify which `break` and `continue` statements that have this for-in
902 /// statement as their target.
903 void buildForIn({SubbuildFunction buildExpression,
904 SubbuildFunction buildVariableDeclaration,
905 Element variableElement,
906 Selector variableSelector,
907 SubbuildFunction buildBody,
908 JumpTarget target}) {
909 // The for-in loop
910 //
911 // for (a in e) s;
912 //
913 // Is compiled analogously to:
914 //
915 // a = e.iterator;
916 // while (a.moveNext()) {
917 // var n0 = a.current;
918 // s;
919 // }
920
921 // The condition and body are delimited.
922 IrBuilder condBuilder = new IrBuilder.recursive(this);
923
924 ir.Primitive expressionReceiver = buildExpression(this);
925 List<ir.Primitive> emptyArguments = new List<ir.Primitive>();
926
927 ir.Parameter iterator = new ir.Parameter(null);
928 ir.Continuation iteratorInvoked = new ir.Continuation([iterator]);
929 add(new ir.LetCont(iteratorInvoked,
930 new ir.InvokeMethod(expressionReceiver,
931 new Selector.getter("iterator", null), iteratorInvoked,
932 emptyArguments)));
933
934 ir.Parameter condition = new ir.Parameter(null);
935 ir.Continuation moveNextInvoked = new ir.Continuation([condition]);
936 condBuilder.add(new ir.LetCont(moveNextInvoked,
937 new ir.InvokeMethod(iterator,
938 new Selector.call("moveNext", null, 0),
939 moveNextInvoked, emptyArguments)));
940
941 JumpCollector breakCollector = new JumpCollector(target);
942 JumpCollector continueCollector = new JumpCollector(target);
943 state.breakCollectors.add(breakCollector);
944 state.continueCollectors.add(continueCollector);
945
946 IrBuilder bodyBuilder = new IrBuilder.delimited(condBuilder);
947 if (buildVariableDeclaration != null) {
948 buildVariableDeclaration(bodyBuilder);
949 }
950
951 ir.Parameter currentValue = new ir.Parameter(null);
952 ir.Continuation currentInvoked = new ir.Continuation([currentValue]);
953 bodyBuilder.add(new ir.LetCont(currentInvoked,
954 new ir.InvokeMethod(iterator, new Selector.getter("current", null),
955 currentInvoked, emptyArguments)));
956 if (Elements.isLocal(variableElement)) {
957 bodyBuilder.buildLocalSet(variableElement, currentValue);
958 } else if (Elements.isStaticOrTopLevel(variableElement)) {
959 bodyBuilder.buildStaticSet(
960 variableElement, variableSelector, currentValue);
961 } else {
962 ir.Primitive receiver = bodyBuilder.buildThis();
963 bodyBuilder.buildDynamicSet(receiver, variableSelector, currentValue);
964 }
965
966 buildBody(bodyBuilder);
967 assert(state.breakCollectors.last == breakCollector);
968 assert(state.continueCollectors.last == continueCollector);
969 state.breakCollectors.removeLast();
970 state.continueCollectors.removeLast();
971
972 // Create body entry and loop exit continuations and a branch to them.
973 ir.Continuation bodyContinuation = new ir.Continuation([]);
974 ir.Continuation exitContinuation = new ir.Continuation([]);
975 ir.LetCont branch =
976 new ir.LetCont(exitContinuation,
977 new ir.LetCont(bodyContinuation,
978 new ir.Branch(new ir.IsTrue(condition),
979 bodyContinuation,
980 exitContinuation)));
981 // If there are breaks in the body, then there must be a join-point
982 // continuation for the normal exit and the breaks.
983 bool hasBreaks = !breakCollector.isEmpty;
984 ir.LetCont letJoin;
985 if (hasBreaks) {
986 letJoin = new ir.LetCont(null, branch);
987 condBuilder.add(letJoin);
988 condBuilder._current = branch;
989 } else {
990 condBuilder.add(branch);
991 }
992 ir.Continuation loopContinuation =
993 new ir.Continuation(condBuilder._parameters);
994 if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder);
995 invokeFullJoin(
996 loopContinuation, continueCollector, recursive: true);
997 bodyContinuation.body = bodyBuilder._root;
998
999 loopContinuation.body = condBuilder._root;
1000 add(new ir.LetCont(loopContinuation,
1001 new ir.InvokeContinuation(loopContinuation,
1002 environment.index2value)));
1003 if (hasBreaks) {
1004 _current = branch;
1005 environment = condBuilder.environment;
1006 breakCollector.addJump(this);
1007 letJoin.continuation = createJoin(environment.length, breakCollector);
1008 _current = letJoin;
1009 } else {
1010 _current = condBuilder._current;
1011 environment = condBuilder.environment;
1012 }
1013 }
887 1014
888 /// Creates a while loop in which the condition and body are created by 1015 /// Creates a while loop in which the condition and body are created by
889 /// [buildCondition] and [buildBody], respectively. 1016 /// [buildCondition] and [buildBody], respectively.
890 /// 1017 ///
891 /// The jump [target] is used to identify which `break` and `continue` 1018 /// The jump [target] is used to identify which `break` and `continue`
892 /// statements that have this `while` statement as their target. 1019 /// statements that have this `while` statement as their target.
893 void buildWhile({SubbuildFunction buildCondition, 1020 void buildWhile({SubbuildFunction buildCondition,
894 SubbuildFunction buildBody, 1021 SubbuildFunction buildBody,
895 JumpTarget target}) { 1022 JumpTarget target}) {
896 assert(isOpen); 1023 assert(isOpen);
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
1163 new ir.LetCont(leftTrueContinuation, 1290 new ir.LetCont(leftTrueContinuation,
1164 new ir.LetCont(leftFalseContinuation, 1291 new ir.LetCont(leftFalseContinuation,
1165 new ir.Branch(new ir.IsTrue(leftValue), 1292 new ir.Branch(new ir.IsTrue(leftValue),
1166 leftTrueContinuation, 1293 leftTrueContinuation,
1167 leftFalseContinuation))))); 1294 leftFalseContinuation)))));
1168 // There is always a join parameter for the result value, because it 1295 // There is always a join parameter for the result value, because it
1169 // is different on at least two paths. 1296 // is different on at least two paths.
1170 return joinContinuation.parameters.last; 1297 return joinContinuation.parameters.last;
1171 } 1298 }
1172 1299
1300 /// Creates an access to `this`.
1301 ir.Primitive buildThis() {
1302 assert(isOpen);
1303 ir.Primitive result = new ir.This();
1304 add(new ir.LetPrim(result));
1305 return result;
1306 }
1307
1173 /// Create a non-recursive join-point continuation. 1308 /// Create a non-recursive join-point continuation.
1174 /// 1309 ///
1175 /// Given the environment length at the join point and a list of 1310 /// Given the environment length at the join point and a list of
1176 /// jumps that should reach the join point, create a join-point 1311 /// jumps that should reach the join point, create a join-point
1177 /// continuation. The join-point continuation has a parameter for each 1312 /// continuation. The join-point continuation has a parameter for each
1178 /// variable that has different values reaching on different paths. 1313 /// variable that has different values reaching on different paths.
1179 /// 1314 ///
1180 /// The jumps are uninitialized [ir.InvokeContinuation] expressions. 1315 /// The jumps are uninitialized [ir.InvokeContinuation] expressions.
1181 /// They are filled in with the target continuation and appropriate 1316 /// They are filled in with the target continuation and appropriate
1182 /// arguments. 1317 /// arguments.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1268 index = 0; 1403 index = 0;
1269 for (int i = 0; i < environment.length; ++i) { 1404 for (int i = 0; i < environment.length; ++i) {
1270 if (common[i] == null) { 1405 if (common[i] == null) {
1271 environment.index2value[i] = parameters[index++]; 1406 environment.index2value[i] = parameters[index++];
1272 } 1407 }
1273 } 1408 }
1274 1409
1275 return join; 1410 return join;
1276 } 1411 }
1277 } 1412 }
OLDNEW
« no previous file with comments | « pkg/analyzer2dart/test/sexpr_data.dart ('k') | sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder_visitor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698