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

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

Issue 979753002: enterForLoop body should be in scope in for-loop update (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated schematic in comment Created 5 years, 9 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 925 matching lines...) Expand 10 before | Expand all | Expand 10 after
936 JumpTarget target, 936 JumpTarget target,
937 ClosureScope closureScope, 937 ClosureScope closureScope,
938 List<LocalElement> loopVariables}) { 938 List<LocalElement> loopVariables}) {
939 assert(isOpen); 939 assert(isOpen);
940 940
941 // For loops use four named continuations: the entry to the condition, 941 // For loops use four named continuations: the entry to the condition,
942 // the entry to the body, the loop exit, and the loop successor (break). 942 // the entry to the body, the loop exit, and the loop successor (break).
943 // The CPS translation of 943 // The CPS translation of
944 // [[for (initializer; condition; update) body; successor]] is: 944 // [[for (initializer; condition; update) body; successor]] is:
945 // 945 //
946 // _enterForLoopInitializer();
946 // [[initializer]]; 947 // [[initializer]];
947 // let cont loop(x, ...) = 948 // let cont loop(x, ...) =
948 // let prim cond = [[condition]] in 949 // let prim cond = [[condition]] in
949 // let cont break() = [[successor]] in 950 // let cont break() = [[successor]] in
950 // let cont exit() = break(v, ...) in 951 // let cont exit() = break(v, ...) in
951 // let cont body() = 952 // let cont body() =
952 // let cont continue(x, ...) = [[update]]; loop(v, ...) in 953 // _enterForLoopBody();
953 // [[body]]; continue(v, ...) in 954 // let cont continue(x, ...) =
955 // _enterForLoopUpdate();
956 // [[update]];
957 // loop(v, ...) in
958 // [[body]];
959 // continue(v, ...) in
954 // branch cond (body, exit) in 960 // branch cond (body, exit) in
955 // loop(v, ...) 961 // loop(v, ...)
956 // 962 //
957 // If there are no breaks in the body, the break continuation is inlined 963 // If there are no breaks in the body, the break continuation is inlined
958 // in the exit continuation (i.e., the translation of the successor 964 // in the exit continuation (i.e., the translation of the successor
959 // statement occurs in the exit continuation). If there is only one 965 // statement occurs in the exit continuation). If there is only one
960 // invocation of the continue continuation (i.e., no continues in the 966 // invocation of the continue continuation (i.e., no continues in the
961 // body), the continue continuation is inlined in the body. 967 // body), the continue continuation is inlined in the body.
962 968
963 _enterForLoopInitializer(closureScope, loopVariables); 969 _enterForLoopInitializer(closureScope, loopVariables);
964 970
965 buildInitializer(this); 971 buildInitializer(this);
966 972
967 IrBuilder condBuilder = makeRecursiveBuilder(); 973 IrBuilder condBuilder = makeRecursiveBuilder();
968 ir.Primitive condition = buildCondition(condBuilder); 974 ir.Primitive condition = buildCondition(condBuilder);
969 if (condition == null) { 975 if (condition == null) {
970 // If the condition is empty then the body is entered unconditionally. 976 // If the condition is empty then the body is entered unconditionally.
971 condition = condBuilder.buildBooleanLiteral(true); 977 condition = condBuilder.buildBooleanLiteral(true);
972 } 978 }
973 979
974 JumpCollector breakCollector = new JumpCollector(target); 980 JumpCollector breakCollector = new JumpCollector(target);
975 JumpCollector continueCollector = new JumpCollector(target); 981 JumpCollector continueCollector = new JumpCollector(target);
976 state.breakCollectors.add(breakCollector); 982 state.breakCollectors.add(breakCollector);
977 state.continueCollectors.add(continueCollector); 983 state.continueCollectors.add(continueCollector);
978 984
979 IrBuilder bodyBuilder = condBuilder.makeDelimitedBuilder(); 985 IrBuilder outerBodyBuilder = condBuilder.makeDelimitedBuilder();
986 outerBodyBuilder._enterForLoopBody(closureScope, loopVariables);
980 987
981 bodyBuilder._enterForLoopBody(closureScope, loopVariables); 988 IrBuilder innerBodyBuilder = outerBodyBuilder.makeDelimitedBuilder();
982 989
983 buildBody(bodyBuilder); 990 buildBody(innerBodyBuilder);
984 assert(state.breakCollectors.last == breakCollector); 991 assert(state.breakCollectors.last == breakCollector);
985 assert(state.continueCollectors.last == continueCollector); 992 assert(state.continueCollectors.last == continueCollector);
986 state.breakCollectors.removeLast(); 993 state.breakCollectors.removeLast();
987 state.continueCollectors.removeLast(); 994 state.continueCollectors.removeLast();
988 995
989 // The binding of the continue continuation should occur as late as 996 // The binding of the continue continuation should occur as late as
990 // possible, that is, at the nearest common ancestor of all the continue 997 // possible, that is, at the nearest common ancestor of all the continue
991 // sites in the body. However, that is difficult to compute here, so it 998 // sites in the body. However, that is difficult to compute here, so it
992 // is instead placed just outside the body of the body continuation. 999 // is instead placed just outside the body of the body continuation.
993 bool hasContinues = !continueCollector.isEmpty; 1000 bool hasContinues = !continueCollector.isEmpty;
994 IrBuilder updateBuilder = hasContinues 1001 IrBuilder updateBuilder = hasContinues
995 ? condBuilder.makeRecursiveBuilder() 1002 ? outerBodyBuilder.makeRecursiveBuilder()
996 : bodyBuilder; 1003 : innerBodyBuilder;
997 updateBuilder._enterForLoopUpdate(closureScope, loopVariables); 1004 updateBuilder._enterForLoopUpdate(closureScope, loopVariables);
998 buildUpdate(updateBuilder); 1005 buildUpdate(updateBuilder);
999 1006
1000 // Create body entry and loop exit continuations and a branch to them. 1007 // Create body entry and loop exit continuations and a branch to them.
1001 ir.Continuation bodyContinuation = new ir.Continuation([]); 1008 ir.Continuation bodyContinuation = new ir.Continuation([]);
1002 ir.Continuation exitContinuation = new ir.Continuation([]); 1009 ir.Continuation exitContinuation = new ir.Continuation([]);
1003 // Note the order of continuations: the first one is the one that will 1010 // Note the order of continuations: the first one is the one that will
1004 // be filled by LetCont.plug. 1011 // be filled by LetCont.plug.
1005 ir.LetCont branch = 1012 ir.LetCont branch =
1006 new ir.LetCont.many(<ir.Continuation>[exitContinuation, 1013 new ir.LetCont.many(<ir.Continuation>[exitContinuation,
(...skipping 10 matching lines...) Expand all
1017 condBuilder.add(letJoin); 1024 condBuilder.add(letJoin);
1018 condBuilder._current = branch; 1025 condBuilder._current = branch;
1019 } else { 1026 } else {
1020 condBuilder.add(branch); 1027 condBuilder.add(branch);
1021 } 1028 }
1022 ir.Continuation continueContinuation; 1029 ir.Continuation continueContinuation;
1023 if (hasContinues) { 1030 if (hasContinues) {
1024 // If there are continues in the body, we need a named continue 1031 // If there are continues in the body, we need a named continue
1025 // continuation as a join point. 1032 // continuation as a join point.
1026 continueContinuation = new ir.Continuation(updateBuilder._parameters); 1033 continueContinuation = new ir.Continuation(updateBuilder._parameters);
1027 if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder); 1034 if (innerBodyBuilder.isOpen) continueCollector.addJump(innerBodyBuilder);
1028 invokeFullJoin(continueContinuation, continueCollector); 1035 invokeFullJoin(continueContinuation, continueCollector);
1029 } 1036 }
1030 ir.Continuation loopContinuation = 1037 ir.Continuation loopContinuation =
1031 new ir.Continuation(condBuilder._parameters); 1038 new ir.Continuation(condBuilder._parameters);
1032 if (updateBuilder.isOpen) { 1039 if (updateBuilder.isOpen) {
1033 JumpCollector backEdges = new JumpCollector(null); 1040 JumpCollector backEdges = new JumpCollector(null);
1034 backEdges.addJump(updateBuilder); 1041 backEdges.addJump(updateBuilder);
1035 invokeFullJoin(loopContinuation, backEdges, recursive: true); 1042 invokeFullJoin(loopContinuation, backEdges, recursive: true);
1036 } 1043 }
1037 1044
1038 // Fill in the body and possible continue continuation bodies. Do this 1045 // Fill in the body and possible continue continuation bodies. Do this
1039 // only after it is guaranteed that they are not empty. 1046 // only after it is guaranteed that they are not empty.
1040 if (hasContinues) { 1047 if (hasContinues) {
1041 continueContinuation.body = updateBuilder._root; 1048 continueContinuation.body = updateBuilder._root;
1042 bodyContinuation.body = 1049 outerBodyBuilder.add(new ir.LetCont(continueContinuation,
1043 new ir.LetCont(continueContinuation, 1050 innerBodyBuilder._root));
1044 bodyBuilder._root);
1045 } else { 1051 } else {
1046 bodyContinuation.body = bodyBuilder._root; 1052 outerBodyBuilder.add(innerBodyBuilder._root);
1047 } 1053 }
1054 bodyContinuation.body = outerBodyBuilder._root;
1048 1055
1049 loopContinuation.body = condBuilder._root; 1056 loopContinuation.body = condBuilder._root;
1050 add(new ir.LetCont(loopContinuation, 1057 add(new ir.LetCont(loopContinuation,
1051 new ir.InvokeContinuation(loopContinuation, 1058 new ir.InvokeContinuation(loopContinuation,
1052 environment.index2value))); 1059 environment.index2value)));
1053 if (hasBreaks) { 1060 if (hasBreaks) {
1054 _current = branch; 1061 _current = branch;
1055 environment = condBuilder.environment; 1062 environment = condBuilder.environment;
1056 breakCollector.addJump(this); 1063 breakCollector.addJump(this);
1057 letJoin.continuations = 1064 letJoin.continuations =
(...skipping 1053 matching lines...) Expand 10 before | Expand all | Expand 10 after
2111 final Map<Local, ClosureLocation> freeVariables; 2118 final Map<Local, ClosureLocation> freeVariables;
2112 2119
2113 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables); 2120 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables);
2114 } 2121 }
2115 2122
2116 class TryStatementInfo { 2123 class TryStatementInfo {
2117 final Set<LocalVariableElement> declared = new Set<LocalVariableElement>(); 2124 final Set<LocalVariableElement> declared = new Set<LocalVariableElement>();
2118 final Set<LocalVariableElement> boxedOnEntry = 2125 final Set<LocalVariableElement> boxedOnEntry =
2119 new Set<LocalVariableElement>(); 2126 new Set<LocalVariableElement>();
2120 } 2127 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698