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

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

Issue 853083005: Revert "Allow LetCont to bind multiple continuations." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 11 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 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 _root = _current = expr; 390 _root = _current = expr;
391 } else { 391 } else {
392 _current = _current.plug(expr); 392 _current = _current.plug(expr);
393 } 393 }
394 } 394 }
395 395
396 ir.Primitive _continueWithExpression(ir.Expression build(ir.Continuation k)) { 396 ir.Primitive _continueWithExpression(ir.Expression build(ir.Continuation k)) {
397 ir.Parameter v = new ir.Parameter(null); 397 ir.Parameter v = new ir.Parameter(null);
398 ir.Continuation k = new ir.Continuation([v]); 398 ir.Continuation k = new ir.Continuation([v]);
399 ir.Expression expression = build(k); 399 ir.Expression expression = build(k);
400 add(new ir.LetCont(<ir.Continuation>[k], expression)); 400 add(new ir.LetCont(k, expression));
401 return v; 401 return v;
402 } 402 }
403 403
404 ir.Primitive _buildInvokeStatic(Element element, 404 ir.Primitive _buildInvokeStatic(Element element,
405 Selector selector, 405 Selector selector,
406 List<ir.Primitive> arguments) { 406 List<ir.Primitive> arguments) {
407 assert(isOpen); 407 assert(isOpen);
408 return _continueWithExpression( 408 return _continueWithExpression(
409 (k) => new ir.InvokeStatic(element, selector, k, arguments)); 409 (k) => new ir.InvokeStatic(element, selector, k, arguments));
410 } 410 }
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 534
535 // Build the term 535 // Build the term
536 // let cont join(x, ..., result) = [] in 536 // let cont join(x, ..., result) = [] in
537 // let cont then() = [[thenPart]]; join(v, ...) in 537 // let cont then() = [[thenPart]]; join(v, ...) in
538 // let cont else() = [[elsePart]]; join(v, ...) in 538 // let cont else() = [[elsePart]]; join(v, ...) in
539 // if condition (then, else) 539 // if condition (then, else)
540 ir.Continuation thenContinuation = new ir.Continuation([]); 540 ir.Continuation thenContinuation = new ir.Continuation([]);
541 ir.Continuation elseContinuation = new ir.Continuation([]); 541 ir.Continuation elseContinuation = new ir.Continuation([]);
542 thenContinuation.body = thenBuilder._root; 542 thenContinuation.body = thenBuilder._root;
543 elseContinuation.body = elseBuilder._root; 543 elseContinuation.body = elseBuilder._root;
544 add(new ir.LetCont(<ir.Continuation>[joinContinuation], 544 add(new ir.LetCont(joinContinuation,
545 new ir.LetCont(<ir.Continuation>[thenContinuation, 545 new ir.LetCont(thenContinuation,
546 elseContinuation], 546 new ir.LetCont(elseContinuation,
547 new ir.Branch(new ir.IsTrue(condition), 547 new ir.Branch(new ir.IsTrue(condition),
548 thenContinuation, 548 thenContinuation,
549 elseContinuation)))); 549 elseContinuation)))));
550 return (thenValue == elseValue) 550 return (thenValue == elseValue)
551 ? thenValue 551 ? thenValue
552 : joinContinuation.parameters.last; 552 : joinContinuation.parameters.last;
553
553 } 554 }
554 555
555 /** 556 /**
556 * Add an explicit `return null` for functions that don't have a return 557 * Add an explicit `return null` for functions that don't have a return
557 * statement on each branch. This includes functions with an empty body, 558 * statement on each branch. This includes functions with an empty body,
558 * such as `foo(){ }`. 559 * such as `foo(){ }`.
559 */ 560 */
560 void _ensureReturn() { 561 void _ensureReturn() {
561 if (!isOpen) return; 562 if (!isOpen) return;
562 ir.Constant constant = buildNullLiteral(); 563 ir.Constant constant = buildNullLiteral();
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 IrBuilder elseBuilder = makeDelimitedBuilder(); 786 IrBuilder elseBuilder = makeDelimitedBuilder();
786 buildThenPart(thenBuilder); 787 buildThenPart(thenBuilder);
787 buildElsePart(elseBuilder); 788 buildElsePart(elseBuilder);
788 789
789 // Build the term 790 // Build the term
790 // (Result =) let cont then() = [[thenPart]] in 791 // (Result =) let cont then() = [[thenPart]] in
791 // let cont else() = [[elsePart]] in 792 // let cont else() = [[elsePart]] in
792 // if condition (then, else) 793 // if condition (then, else)
793 ir.Continuation thenContinuation = new ir.Continuation([]); 794 ir.Continuation thenContinuation = new ir.Continuation([]);
794 ir.Continuation elseContinuation = new ir.Continuation([]); 795 ir.Continuation elseContinuation = new ir.Continuation([]);
795 // If exactly one of the then and else continuation bodies is open (i.e., 796 ir.Expression letElse =
796 // the other one has an exit on all paths), then Continuation.plug expects 797 new ir.LetCont(elseContinuation,
797 // that continuation to be listed first. Arbitrarily use [then, else] 798 new ir.Branch(new ir.IsTrue(condition),
798 // order otherwise. 799 thenContinuation,
799 List<ir.Continuation> arms = !thenBuilder.isOpen && elseBuilder.isOpen 800 elseContinuation));
800 ? <ir.Continuation>[elseContinuation, thenContinuation] 801 ir.Expression letThen = new ir.LetCont(thenContinuation, letElse);
801 : <ir.Continuation>[thenContinuation, elseContinuation]; 802 ir.Expression result = letThen;
802
803 ir.Expression result =
804 new ir.LetCont(arms,
805 new ir.Branch(new ir.IsTrue(condition),
806 thenContinuation,
807 elseContinuation));
808 803
809 ir.Continuation joinContinuation; // Null if there is no join. 804 ir.Continuation joinContinuation; // Null if there is no join.
810 if (thenBuilder.isOpen && elseBuilder.isOpen) { 805 if (thenBuilder.isOpen && elseBuilder.isOpen) {
811 // There is a join-point continuation. Build the term 806 // There is a join-point continuation. Build the term
812 // 'let cont join(x, ...) = [] in Result' and plug invocations of the 807 // 'let cont join(x, ...) = [] in Result' and plug invocations of the
813 // join-point continuation into the then and else continuations. 808 // join-point continuation into the then and else continuations.
814 JumpCollector jumps = new JumpCollector(null); 809 JumpCollector jumps = new JumpCollector(null);
815 jumps.addJump(thenBuilder); 810 jumps.addJump(thenBuilder);
816 jumps.addJump(elseBuilder); 811 jumps.addJump(elseBuilder);
817 joinContinuation = createJoin(environment.length, jumps); 812 joinContinuation = createJoin(environment.length, jumps);
818 result = new ir.LetCont(<ir.Continuation>[joinContinuation], result); 813 result = new ir.LetCont(joinContinuation, result);
819 } 814 }
820 815
821 // The then or else term root could be null, but not both. If there is 816 // The then or else term root could be null, but not both. If there is
822 // a join then an InvokeContinuation was just added to both of them. If 817 // a join then an InvokeContinuation was just added to both of them. If
823 // there is no join, then at least one of them is closed and thus has a 818 // there is no join, then at least one of them is closed and thus has a
824 // non-null root by the definition of the predicate isClosed. In the 819 // non-null root by the definition of the predicate isClosed. In the
825 // case that one of them is null, it must be the only one that is open 820 // case that one of them is null, it must be the only one that is open
826 // and thus contains the new hole in the context. This case is handled 821 // and thus contains the new hole in the context. This case is handled
827 // after the branch is plugged into the current hole. 822 // after the branch is plugged into the current hole.
828 thenContinuation.body = thenBuilder._root; 823 thenContinuation.body = thenBuilder._root;
829 elseContinuation.body = elseBuilder._root; 824 elseContinuation.body = elseBuilder._root;
830 825
831 add(result); 826 add(result);
832 if (joinContinuation == null) { 827 if (joinContinuation == null) {
833 // At least one subexpression is closed. 828 // At least one subexpression is closed.
834 if (thenBuilder.isOpen) { 829 if (thenBuilder.isOpen) {
835 if (thenBuilder._root != null) _current = thenBuilder._current; 830 _current =
831 (thenBuilder._root == null) ? letThen : thenBuilder._current;
836 environment = thenBuilder.environment; 832 environment = thenBuilder.environment;
837 } else if (elseBuilder.isOpen) { 833 } else if (elseBuilder.isOpen) {
838 if (elseBuilder._root != null) _current = elseBuilder._current; 834 _current =
835 (elseBuilder._root == null) ? letElse : elseBuilder._current;
839 environment = elseBuilder.environment; 836 environment = elseBuilder.environment;
840 } else { 837 } else {
841 _current = null; 838 _current = null;
842 } 839 }
843 } 840 }
844 } 841 }
845 842
846 /// Invoke a join-point continuation that contains arguments for all local 843 /// Invoke a join-point continuation that contains arguments for all local
847 /// variables. 844 /// variables.
848 /// 845 ///
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
954 ? condBuilder.makeRecursiveBuilder() 951 ? condBuilder.makeRecursiveBuilder()
955 : bodyBuilder; 952 : bodyBuilder;
956 if (hasBoxedLoopVariables) { 953 if (hasBoxedLoopVariables) {
957 updateBuilder._migrateLoopVariables(closureScope); 954 updateBuilder._migrateLoopVariables(closureScope);
958 } 955 }
959 buildUpdate(updateBuilder); 956 buildUpdate(updateBuilder);
960 957
961 // Create body entry and loop exit continuations and a branch to them. 958 // Create body entry and loop exit continuations and a branch to them.
962 ir.Continuation bodyContinuation = new ir.Continuation([]); 959 ir.Continuation bodyContinuation = new ir.Continuation([]);
963 ir.Continuation exitContinuation = new ir.Continuation([]); 960 ir.Continuation exitContinuation = new ir.Continuation([]);
964 // Note the order of continuations: the first one is the one that will
965 // be filled by LetCont.plug.
966 ir.LetCont branch = 961 ir.LetCont branch =
967 new ir.LetCont(<ir.Continuation>[exitContinuation, bodyContinuation], 962 new ir.LetCont(exitContinuation,
968 new ir.Branch(new ir.IsTrue(condition), 963 new ir.LetCont(bodyContinuation,
969 bodyContinuation, 964 new ir.Branch(new ir.IsTrue(condition),
970 exitContinuation)); 965 bodyContinuation,
966 exitContinuation)));
971 // If there are breaks in the body, then there must be a join-point 967 // If there are breaks in the body, then there must be a join-point
972 // continuation for the normal exit and the breaks. 968 // continuation for the normal exit and the breaks.
973 bool hasBreaks = !breakCollector.isEmpty; 969 bool hasBreaks = !breakCollector.isEmpty;
974 ir.LetCont letJoin; 970 ir.LetCont letJoin;
975 if (hasBreaks) { 971 if (hasBreaks) {
976 letJoin = new ir.LetCont(null, branch); 972 letJoin = new ir.LetCont(null, branch);
977 condBuilder.add(letJoin); 973 condBuilder.add(letJoin);
978 condBuilder._current = branch; 974 condBuilder._current = branch;
979 } else { 975 } else {
980 condBuilder.add(branch); 976 condBuilder.add(branch);
(...skipping 12 matching lines...) Expand all
993 JumpCollector backEdges = new JumpCollector(null); 989 JumpCollector backEdges = new JumpCollector(null);
994 backEdges.addJump(updateBuilder); 990 backEdges.addJump(updateBuilder);
995 invokeFullJoin(loopContinuation, backEdges, recursive: true); 991 invokeFullJoin(loopContinuation, backEdges, recursive: true);
996 } 992 }
997 993
998 // Fill in the body and possible continue continuation bodies. Do this 994 // Fill in the body and possible continue continuation bodies. Do this
999 // only after it is guaranteed that they are not empty. 995 // only after it is guaranteed that they are not empty.
1000 if (hasContinues) { 996 if (hasContinues) {
1001 continueContinuation.body = updateBuilder._root; 997 continueContinuation.body = updateBuilder._root;
1002 bodyContinuation.body = 998 bodyContinuation.body =
1003 new ir.LetCont(<ir.Continuation>[continueContinuation], 999 new ir.LetCont(continueContinuation, bodyBuilder._root);
1004 bodyBuilder._root);
1005 } else { 1000 } else {
1006 bodyContinuation.body = bodyBuilder._root; 1001 bodyContinuation.body = bodyBuilder._root;
1007 } 1002 }
1008 1003
1009 loopContinuation.body = condBuilder._root; 1004 loopContinuation.body = condBuilder._root;
1010 add(new ir.LetCont(<ir.Continuation>[loopContinuation], 1005 add(new ir.LetCont(loopContinuation,
1011 new ir.InvokeContinuation(loopContinuation, 1006 new ir.InvokeContinuation(loopContinuation,
1012 environment.index2value))); 1007 environment.index2value)));
1013 if (hasBreaks) { 1008 if (hasBreaks) {
1014 _current = branch; 1009 _current = branch;
1015 environment = condBuilder.environment; 1010 environment = condBuilder.environment;
1016 breakCollector.addJump(this); 1011 breakCollector.addJump(this);
1017 letJoin.continuations = 1012 letJoin.continuation = createJoin(environment.length, breakCollector);
1018 <ir.Continuation>[createJoin(environment.length, breakCollector)];
1019 _current = letJoin; 1013 _current = letJoin;
1020 } else { 1014 } else {
1021 _current = condBuilder._current; 1015 _current = condBuilder._current;
1022 environment = condBuilder.environment; 1016 environment = condBuilder.environment;
1023 } 1017 }
1024 } 1018 }
1025 1019
1026 /// Creates a for-in loop, `for (v in e) b`. 1020 /// Creates a for-in loop, `for (v in e) b`.
1027 /// 1021 ///
1028 /// [buildExpression] creates the expression, `e`. The variable, `v`, can 1022 /// [buildExpression] creates the expression, `e`. The variable, `v`, can
(...skipping 30 matching lines...) Expand all
1059 // } 1053 // }
1060 1054
1061 // The condition and body are delimited. 1055 // The condition and body are delimited.
1062 IrBuilder condBuilder = makeRecursiveBuilder(); 1056 IrBuilder condBuilder = makeRecursiveBuilder();
1063 1057
1064 ir.Primitive expressionReceiver = buildExpression(this); 1058 ir.Primitive expressionReceiver = buildExpression(this);
1065 List<ir.Primitive> emptyArguments = new List<ir.Primitive>(); 1059 List<ir.Primitive> emptyArguments = new List<ir.Primitive>();
1066 1060
1067 ir.Parameter iterator = new ir.Parameter(null); 1061 ir.Parameter iterator = new ir.Parameter(null);
1068 ir.Continuation iteratorInvoked = new ir.Continuation([iterator]); 1062 ir.Continuation iteratorInvoked = new ir.Continuation([iterator]);
1069 add(new ir.LetCont(<ir.Continuation>[iteratorInvoked], 1063 add(new ir.LetCont(iteratorInvoked,
1070 new ir.InvokeMethod(expressionReceiver, 1064 new ir.InvokeMethod(expressionReceiver,
1071 new Selector.getter("iterator", null), iteratorInvoked, 1065 new Selector.getter("iterator", null), iteratorInvoked,
1072 emptyArguments))); 1066 emptyArguments)));
1073 1067
1074 ir.Parameter condition = new ir.Parameter(null); 1068 ir.Parameter condition = new ir.Parameter(null);
1075 ir.Continuation moveNextInvoked = new ir.Continuation([condition]); 1069 ir.Continuation moveNextInvoked = new ir.Continuation([condition]);
1076 condBuilder.add(new ir.LetCont(<ir.Continuation>[moveNextInvoked], 1070 condBuilder.add(new ir.LetCont(moveNextInvoked,
1077 new ir.InvokeMethod(iterator, 1071 new ir.InvokeMethod(iterator,
1078 new Selector.call("moveNext", null, 0), 1072 new Selector.call("moveNext", null, 0),
1079 moveNextInvoked, emptyArguments))); 1073 moveNextInvoked, emptyArguments)));
1080 1074
1081 JumpCollector breakCollector = new JumpCollector(target); 1075 JumpCollector breakCollector = new JumpCollector(target);
1082 JumpCollector continueCollector = new JumpCollector(target); 1076 JumpCollector continueCollector = new JumpCollector(target);
1083 state.breakCollectors.add(breakCollector); 1077 state.breakCollectors.add(breakCollector);
1084 state.continueCollectors.add(continueCollector); 1078 state.continueCollectors.add(continueCollector);
1085 1079
1086 IrBuilder bodyBuilder = condBuilder.makeDelimitedBuilder(); 1080 IrBuilder bodyBuilder = condBuilder.makeDelimitedBuilder();
1087 bodyBuilder._buildClosureScopeSetup(closureScope); 1081 bodyBuilder._buildClosureScopeSetup(closureScope);
1088 if (buildVariableDeclaration != null) { 1082 if (buildVariableDeclaration != null) {
1089 buildVariableDeclaration(bodyBuilder); 1083 buildVariableDeclaration(bodyBuilder);
1090 } 1084 }
1091 1085
1092 ir.Parameter currentValue = new ir.Parameter(null); 1086 ir.Parameter currentValue = new ir.Parameter(null);
1093 ir.Continuation currentInvoked = new ir.Continuation([currentValue]); 1087 ir.Continuation currentInvoked = new ir.Continuation([currentValue]);
1094 bodyBuilder.add(new ir.LetCont(<ir.Continuation>[currentInvoked], 1088 bodyBuilder.add(new ir.LetCont(currentInvoked,
1095 new ir.InvokeMethod(iterator, new Selector.getter("current", null), 1089 new ir.InvokeMethod(iterator, new Selector.getter("current", null),
1096 currentInvoked, emptyArguments))); 1090 currentInvoked, emptyArguments)));
1097 if (Elements.isLocal(variableElement)) { 1091 if (Elements.isLocal(variableElement)) {
1098 bodyBuilder.buildLocalSet(variableElement, currentValue); 1092 bodyBuilder.buildLocalSet(variableElement, currentValue);
1099 } else if (Elements.isStaticOrTopLevel(variableElement)) { 1093 } else if (Elements.isStaticOrTopLevel(variableElement)) {
1100 bodyBuilder.buildStaticSet( 1094 bodyBuilder.buildStaticSet(
1101 variableElement, variableSelector, currentValue); 1095 variableElement, variableSelector, currentValue);
1102 } else { 1096 } else {
1103 ir.Primitive receiver = bodyBuilder.buildThis(); 1097 ir.Primitive receiver = bodyBuilder.buildThis();
1104 bodyBuilder.buildDynamicSet(receiver, variableSelector, currentValue); 1098 bodyBuilder.buildDynamicSet(receiver, variableSelector, currentValue);
1105 } 1099 }
1106 1100
1107 buildBody(bodyBuilder); 1101 buildBody(bodyBuilder);
1108 assert(state.breakCollectors.last == breakCollector); 1102 assert(state.breakCollectors.last == breakCollector);
1109 assert(state.continueCollectors.last == continueCollector); 1103 assert(state.continueCollectors.last == continueCollector);
1110 state.breakCollectors.removeLast(); 1104 state.breakCollectors.removeLast();
1111 state.continueCollectors.removeLast(); 1105 state.continueCollectors.removeLast();
1112 1106
1113 // Create body entry and loop exit continuations and a branch to them. 1107 // Create body entry and loop exit continuations and a branch to them.
1114 ir.Continuation bodyContinuation = new ir.Continuation([]); 1108 ir.Continuation bodyContinuation = new ir.Continuation([]);
1115 ir.Continuation exitContinuation = new ir.Continuation([]); 1109 ir.Continuation exitContinuation = new ir.Continuation([]);
1116 // Note the order of continuations: the first one is the one that will
1117 // be filled by LetCont.plug.
1118 ir.LetCont branch = 1110 ir.LetCont branch =
1119 new ir.LetCont(<ir.Continuation>[exitContinuation, bodyContinuation], 1111 new ir.LetCont(exitContinuation,
1120 new ir.Branch(new ir.IsTrue(condition), 1112 new ir.LetCont(bodyContinuation,
1121 bodyContinuation, 1113 new ir.Branch(new ir.IsTrue(condition),
1122 exitContinuation)); 1114 bodyContinuation,
1115 exitContinuation)));
1123 // If there are breaks in the body, then there must be a join-point 1116 // If there are breaks in the body, then there must be a join-point
1124 // continuation for the normal exit and the breaks. 1117 // continuation for the normal exit and the breaks.
1125 bool hasBreaks = !breakCollector.isEmpty; 1118 bool hasBreaks = !breakCollector.isEmpty;
1126 ir.LetCont letJoin; 1119 ir.LetCont letJoin;
1127 if (hasBreaks) { 1120 if (hasBreaks) {
1128 letJoin = new ir.LetCont(null, branch); 1121 letJoin = new ir.LetCont(null, branch);
1129 condBuilder.add(letJoin); 1122 condBuilder.add(letJoin);
1130 condBuilder._current = branch; 1123 condBuilder._current = branch;
1131 } else { 1124 } else {
1132 condBuilder.add(branch); 1125 condBuilder.add(branch);
1133 } 1126 }
1134 ir.Continuation loopContinuation = 1127 ir.Continuation loopContinuation =
1135 new ir.Continuation(condBuilder._parameters); 1128 new ir.Continuation(condBuilder._parameters);
1136 if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder); 1129 if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder);
1137 invokeFullJoin( 1130 invokeFullJoin(
1138 loopContinuation, continueCollector, recursive: true); 1131 loopContinuation, continueCollector, recursive: true);
1139 bodyContinuation.body = bodyBuilder._root; 1132 bodyContinuation.body = bodyBuilder._root;
1140 1133
1141 loopContinuation.body = condBuilder._root; 1134 loopContinuation.body = condBuilder._root;
1142 add(new ir.LetCont(<ir.Continuation>[loopContinuation], 1135 add(new ir.LetCont(loopContinuation,
1143 new ir.InvokeContinuation(loopContinuation, 1136 new ir.InvokeContinuation(loopContinuation,
1144 environment.index2value))); 1137 environment.index2value)));
1145 if (hasBreaks) { 1138 if (hasBreaks) {
1146 _current = branch; 1139 _current = branch;
1147 environment = condBuilder.environment; 1140 environment = condBuilder.environment;
1148 breakCollector.addJump(this); 1141 breakCollector.addJump(this);
1149 letJoin.continuations = 1142 letJoin.continuation = createJoin(environment.length, breakCollector);
1150 <ir.Continuation>[createJoin(environment.length, breakCollector)];
1151 _current = letJoin; 1143 _current = letJoin;
1152 } else { 1144 } else {
1153 _current = condBuilder._current; 1145 _current = condBuilder._current;
1154 environment = condBuilder.environment; 1146 environment = condBuilder.environment;
1155 } 1147 }
1156 } 1148 }
1157 1149
1158 /// Creates a while loop in which the condition and body are created by 1150 /// Creates a while loop in which the condition and body are created by
1159 /// [buildCondition] and [buildBody], respectively. 1151 /// [buildCondition] and [buildBody], respectively.
1160 /// 1152 ///
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 bodyBuilder._buildClosureScopeSetup(closureScope); 1186 bodyBuilder._buildClosureScopeSetup(closureScope);
1195 buildBody(bodyBuilder); 1187 buildBody(bodyBuilder);
1196 assert(state.breakCollectors.last == breakCollector); 1188 assert(state.breakCollectors.last == breakCollector);
1197 assert(state.continueCollectors.last == continueCollector); 1189 assert(state.continueCollectors.last == continueCollector);
1198 state.breakCollectors.removeLast(); 1190 state.breakCollectors.removeLast();
1199 state.continueCollectors.removeLast(); 1191 state.continueCollectors.removeLast();
1200 1192
1201 // Create body entry and loop exit continuations and a branch to them. 1193 // Create body entry and loop exit continuations and a branch to them.
1202 ir.Continuation bodyContinuation = new ir.Continuation([]); 1194 ir.Continuation bodyContinuation = new ir.Continuation([]);
1203 ir.Continuation exitContinuation = new ir.Continuation([]); 1195 ir.Continuation exitContinuation = new ir.Continuation([]);
1204 // Note the order of continuations: the first one is the one that will
1205 // be filled by LetCont.plug.
1206 ir.LetCont branch = 1196 ir.LetCont branch =
1207 new ir.LetCont(<ir.Continuation>[exitContinuation, bodyContinuation], 1197 new ir.LetCont(exitContinuation,
1208 new ir.Branch(new ir.IsTrue(condition), 1198 new ir.LetCont(bodyContinuation,
1209 bodyContinuation, 1199 new ir.Branch(new ir.IsTrue(condition),
1210 exitContinuation)); 1200 bodyContinuation,
1201 exitContinuation)));
1211 // If there are breaks in the body, then there must be a join-point 1202 // If there are breaks in the body, then there must be a join-point
1212 // continuation for the normal exit and the breaks. 1203 // continuation for the normal exit and the breaks.
1213 bool hasBreaks = !breakCollector.isEmpty; 1204 bool hasBreaks = !breakCollector.isEmpty;
1214 ir.LetCont letJoin; 1205 ir.LetCont letJoin;
1215 if (hasBreaks) { 1206 if (hasBreaks) {
1216 letJoin = new ir.LetCont(null, branch); 1207 letJoin = new ir.LetCont(null, branch);
1217 condBuilder.add(letJoin); 1208 condBuilder.add(letJoin);
1218 condBuilder._current = branch; 1209 condBuilder._current = branch;
1219 } else { 1210 } else {
1220 condBuilder.add(branch); 1211 condBuilder.add(branch);
1221 } 1212 }
1222 ir.Continuation loopContinuation = 1213 ir.Continuation loopContinuation =
1223 new ir.Continuation(condBuilder._parameters); 1214 new ir.Continuation(condBuilder._parameters);
1224 if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder); 1215 if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder);
1225 invokeFullJoin(loopContinuation, continueCollector, recursive: true); 1216 invokeFullJoin(loopContinuation, continueCollector, recursive: true);
1226 bodyContinuation.body = bodyBuilder._root; 1217 bodyContinuation.body = bodyBuilder._root;
1227 1218
1228 loopContinuation.body = condBuilder._root; 1219 loopContinuation.body = condBuilder._root;
1229 add(new ir.LetCont(<ir.Continuation>[loopContinuation], 1220 add(new ir.LetCont(loopContinuation,
1230 new ir.InvokeContinuation(loopContinuation, 1221 new ir.InvokeContinuation(loopContinuation,
1231 environment.index2value))); 1222 environment.index2value)));
1232 if (hasBreaks) { 1223 if (hasBreaks) {
1233 _current = branch; 1224 _current = branch;
1234 environment = condBuilder.environment; 1225 environment = condBuilder.environment;
1235 breakCollector.addJump(this); 1226 breakCollector.addJump(this);
1236 letJoin.continuations = 1227 letJoin.continuation = createJoin(environment.length, breakCollector);
1237 <ir.Continuation>[createJoin(environment.length, breakCollector)];
1238 _current = letJoin; 1228 _current = letJoin;
1239 } else { 1229 } else {
1240 _current = condBuilder._current; 1230 _current = condBuilder._current;
1241 environment = condBuilder.environment; 1231 environment = condBuilder.environment;
1242 } 1232 }
1243 } 1233 }
1244 1234
1245 /// Create a return statement `return value;` or `return;` if [value] is 1235 /// Create a return statement `return value;` or `return;` if [value] is
1246 /// null. 1236 /// null.
1247 void buildReturn([ir.Primitive value]) { 1237 void buildReturn([ir.Primitive value]) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1326 } 1316 }
1327 1317
1328 ir.Constant trueConstant = makeBoolConstant(true); 1318 ir.Constant trueConstant = makeBoolConstant(true);
1329 ir.Constant falseConstant = makeBoolConstant(false); 1319 ir.Constant falseConstant = makeBoolConstant(false);
1330 1320
1331 thenContinuation.body = new ir.LetPrim(falseConstant) 1321 thenContinuation.body = new ir.LetPrim(falseConstant)
1332 ..plug(new ir.InvokeContinuation(joinContinuation, [falseConstant])); 1322 ..plug(new ir.InvokeContinuation(joinContinuation, [falseConstant]));
1333 elseContinuation.body = new ir.LetPrim(trueConstant) 1323 elseContinuation.body = new ir.LetPrim(trueConstant)
1334 ..plug(new ir.InvokeContinuation(joinContinuation, [trueConstant])); 1324 ..plug(new ir.InvokeContinuation(joinContinuation, [trueConstant]));
1335 1325
1336 add(new ir.LetCont(<ir.Continuation>[joinContinuation], 1326 add(new ir.LetCont(joinContinuation,
1337 new ir.LetCont(<ir.Continuation>[thenContinuation, elseContinuation], 1327 new ir.LetCont(thenContinuation,
1328 new ir.LetCont(elseContinuation,
1338 new ir.Branch(new ir.IsTrue(condition), 1329 new ir.Branch(new ir.IsTrue(condition),
1339 thenContinuation, 1330 thenContinuation,
1340 elseContinuation)))); 1331 elseContinuation)))));
1341 return resultParameter; 1332 return resultParameter;
1342 } 1333 }
1343 1334
1344 /// Creates a type test or type cast of [receiver] against [type]. 1335 /// Creates a type test or type cast of [receiver] against [type].
1345 /// 1336 ///
1346 /// Set [isTypeTest] to `true` to create a type test and furthermore set 1337 /// Set [isTypeTest] to `true` to create a type test and furthermore set
1347 /// [isNotCheck] to `true` to create a negated type test. 1338 /// [isNotCheck] to `true` to create a negated type test.
1348 ir.Primitive buildTypeOperator(ir.Primitive receiver, 1339 ir.Primitive buildTypeOperator(ir.Primitive receiver,
1349 DartType type, 1340 DartType type,
1350 {bool isTypeTest: false, 1341 {bool isTypeTest: false,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1409 ir.Continuation joinContinuation = 1400 ir.Continuation joinContinuation =
1410 createJoin(environment.length + 1, jumps); 1401 createJoin(environment.length + 1, jumps);
1411 ir.Continuation leftTrueContinuation = new ir.Continuation([]); 1402 ir.Continuation leftTrueContinuation = new ir.Continuation([]);
1412 ir.Continuation leftFalseContinuation = new ir.Continuation([]); 1403 ir.Continuation leftFalseContinuation = new ir.Continuation([]);
1413 ir.Continuation rightTrueContinuation = new ir.Continuation([]); 1404 ir.Continuation rightTrueContinuation = new ir.Continuation([]);
1414 ir.Continuation rightFalseContinuation = new ir.Continuation([]); 1405 ir.Continuation rightFalseContinuation = new ir.Continuation([]);
1415 rightTrueContinuation.body = rightTrueBuilder._root; 1406 rightTrueContinuation.body = rightTrueBuilder._root;
1416 rightFalseContinuation.body = rightFalseBuilder._root; 1407 rightFalseContinuation.body = rightFalseBuilder._root;
1417 // The right subexpression has two continuations. 1408 // The right subexpression has two continuations.
1418 rightBuilder.add( 1409 rightBuilder.add(
1419 new ir.LetCont(<ir.Continuation>[rightTrueContinuation, 1410 new ir.LetCont(rightTrueContinuation,
1420 rightFalseContinuation], 1411 new ir.LetCont(rightFalseContinuation,
1421 new ir.Branch(new ir.IsTrue(rightValue), 1412 new ir.Branch(new ir.IsTrue(rightValue),
1422 rightTrueContinuation, 1413 rightTrueContinuation,
1423 rightFalseContinuation))); 1414 rightFalseContinuation))));
1424 // Depending on the operator, the left subexpression's continuations are 1415 // Depending on the operator, the left subexpression's continuations are
1425 // either the right subexpression or an invocation of the join-point 1416 // either the right subexpression or an invocation of the join-point
1426 // continuation. 1417 // continuation.
1427 if (isLazyOr) { 1418 if (isLazyOr) {
1428 leftTrueContinuation.body = emptyBuilder._root; 1419 leftTrueContinuation.body = emptyBuilder._root;
1429 leftFalseContinuation.body = rightBuilder._root; 1420 leftFalseContinuation.body = rightBuilder._root;
1430 } else { 1421 } else {
1431 leftTrueContinuation.body = rightBuilder._root; 1422 leftTrueContinuation.body = rightBuilder._root;
1432 leftFalseContinuation.body = emptyBuilder._root; 1423 leftFalseContinuation.body = emptyBuilder._root;
1433 } 1424 }
1434 1425
1435 add(new ir.LetCont(<ir.Continuation>[joinContinuation], 1426 add(new ir.LetCont(joinContinuation,
1436 new ir.LetCont(<ir.Continuation>[leftTrueContinuation, 1427 new ir.LetCont(leftTrueContinuation,
1437 leftFalseContinuation], 1428 new ir.LetCont(leftFalseContinuation,
1438 new ir.Branch(new ir.IsTrue(leftValue), 1429 new ir.Branch(new ir.IsTrue(leftValue),
1439 leftTrueContinuation, 1430 leftTrueContinuation,
1440 leftFalseContinuation)))); 1431 leftFalseContinuation)))));
1441 // There is always a join parameter for the result value, because it 1432 // There is always a join parameter for the result value, because it
1442 // is different on at least two paths. 1433 // is different on at least two paths.
1443 return joinContinuation.parameters.last; 1434 return joinContinuation.parameters.last;
1444 } 1435 }
1445 1436
1446 /// Creates an access to the receiver from the current (or enclosing) method. 1437 /// Creates an access to the receiver from the current (or enclosing) method.
1447 /// 1438 ///
1448 /// If inside a closure class, [buildThis] will redirect access through 1439 /// If inside a closure class, [buildThis] will redirect access through
1449 /// closure fields in order to access the receiver from the enclosing method. 1440 /// closure fields in order to access the receiver from the enclosing method.
1450 ir.Primitive buildThis() { 1441 ir.Primitive buildThis() {
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
1887 1878
1888 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables); 1879 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables);
1889 } 1880 }
1890 1881
1891 /// Information about which variables are captured in a closure. 1882 /// Information about which variables are captured in a closure.
1892 /// This is used by the [DartIrBuilder] instead of [ClosureScope] and 1883 /// This is used by the [DartIrBuilder] instead of [ClosureScope] and
1893 /// [ClosureEnvironment]. 1884 /// [ClosureEnvironment].
1894 abstract class ClosureVariableInfo { 1885 abstract class ClosureVariableInfo {
1895 Iterable<Local> get capturedVariables; 1886 Iterable<Local> get capturedVariables;
1896 } 1887 }
OLDNEW
« no previous file with comments | « pkg/analyzer2dart/test/sexpr_data.dart ('k') | pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698