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

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

Issue 827763003: Reapply "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 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 _root = _current = expr; 381 _root = _current = expr;
382 } else { 382 } else {
383 _current = _current.plug(expr); 383 _current = _current.plug(expr);
384 } 384 }
385 } 385 }
386 386
387 ir.Primitive _continueWithExpression(ir.Expression build(ir.Continuation k)) { 387 ir.Primitive _continueWithExpression(ir.Expression build(ir.Continuation k)) {
388 ir.Parameter v = new ir.Parameter(null); 388 ir.Parameter v = new ir.Parameter(null);
389 ir.Continuation k = new ir.Continuation([v]); 389 ir.Continuation k = new ir.Continuation([v]);
390 ir.Expression expression = build(k); 390 ir.Expression expression = build(k);
391 add(new ir.LetCont(k, expression)); 391 add(new ir.LetCont(<ir.Continuation>[k], expression));
392 return v; 392 return v;
393 } 393 }
394 394
395 ir.Primitive _buildInvokeStatic(Element element, 395 ir.Primitive _buildInvokeStatic(Element element,
396 Selector selector, 396 Selector selector,
397 List<ir.Primitive> arguments) { 397 List<ir.Primitive> arguments) {
398 assert(isOpen); 398 assert(isOpen);
399 return _continueWithExpression( 399 return _continueWithExpression(
400 (k) => new ir.InvokeStatic(element, selector, k, arguments)); 400 (k) => new ir.InvokeStatic(element, selector, k, arguments));
401 } 401 }
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 525
526 // Build the term 526 // Build the term
527 // let cont join(x, ..., result) = [] in 527 // let cont join(x, ..., result) = [] in
528 // let cont then() = [[thenPart]]; join(v, ...) in 528 // let cont then() = [[thenPart]]; join(v, ...) in
529 // let cont else() = [[elsePart]]; join(v, ...) in 529 // let cont else() = [[elsePart]]; join(v, ...) in
530 // if condition (then, else) 530 // if condition (then, else)
531 ir.Continuation thenContinuation = new ir.Continuation([]); 531 ir.Continuation thenContinuation = new ir.Continuation([]);
532 ir.Continuation elseContinuation = new ir.Continuation([]); 532 ir.Continuation elseContinuation = new ir.Continuation([]);
533 thenContinuation.body = thenBuilder._root; 533 thenContinuation.body = thenBuilder._root;
534 elseContinuation.body = elseBuilder._root; 534 elseContinuation.body = elseBuilder._root;
535 add(new ir.LetCont(joinContinuation, 535 add(new ir.LetCont(<ir.Continuation>[joinContinuation],
536 new ir.LetCont(thenContinuation, 536 new ir.LetCont(<ir.Continuation>[thenContinuation,
537 new ir.LetCont(elseContinuation, 537 elseContinuation],
538 new ir.Branch(new ir.IsTrue(condition), 538 new ir.Branch(new ir.IsTrue(condition),
539 thenContinuation, 539 thenContinuation,
540 elseContinuation))))); 540 elseContinuation))));
541 return (thenValue == elseValue) 541 return (thenValue == elseValue)
542 ? thenValue 542 ? thenValue
543 : joinContinuation.parameters.last; 543 : joinContinuation.parameters.last;
544
545 } 544 }
546 545
547 /** 546 /**
548 * Add an explicit `return null` for functions that don't have a return 547 * Add an explicit `return null` for functions that don't have a return
549 * statement on each branch. This includes functions with an empty body, 548 * statement on each branch. This includes functions with an empty body,
550 * such as `foo(){ }`. 549 * such as `foo(){ }`.
551 */ 550 */
552 void _ensureReturn() { 551 void _ensureReturn() {
553 if (!isOpen) return; 552 if (!isOpen) return;
554 ir.Constant constant = buildNullLiteral(); 553 ir.Constant constant = buildNullLiteral();
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 IrBuilder elseBuilder = makeDelimitedBuilder(); 777 IrBuilder elseBuilder = makeDelimitedBuilder();
779 buildThenPart(thenBuilder); 778 buildThenPart(thenBuilder);
780 buildElsePart(elseBuilder); 779 buildElsePart(elseBuilder);
781 780
782 // Build the term 781 // Build the term
783 // (Result =) let cont then() = [[thenPart]] in 782 // (Result =) let cont then() = [[thenPart]] in
784 // let cont else() = [[elsePart]] in 783 // let cont else() = [[elsePart]] in
785 // if condition (then, else) 784 // if condition (then, else)
786 ir.Continuation thenContinuation = new ir.Continuation([]); 785 ir.Continuation thenContinuation = new ir.Continuation([]);
787 ir.Continuation elseContinuation = new ir.Continuation([]); 786 ir.Continuation elseContinuation = new ir.Continuation([]);
788 ir.Expression letElse = 787 // If exactly one of the then and else continuation bodies is open (i.e.,
789 new ir.LetCont(elseContinuation, 788 // the other one has an exit on all paths), then Continuation.plug expects
790 new ir.Branch(new ir.IsTrue(condition), 789 // that continuation to be listed first. Arbitrarily use [then, else]
791 thenContinuation, 790 // order otherwise.
792 elseContinuation)); 791 List<ir.Continuation> arms = !thenBuilder.isOpen && elseBuilder.isOpen
793 ir.Expression letThen = new ir.LetCont(thenContinuation, letElse); 792 ? <ir.Continuation>[elseContinuation, thenContinuation]
794 ir.Expression result = letThen; 793 : <ir.Continuation>[thenContinuation, elseContinuation];
794
795 ir.Expression result =
796 new ir.LetCont(arms,
797 new ir.Branch(new ir.IsTrue(condition),
798 thenContinuation,
799 elseContinuation));
795 800
796 ir.Continuation joinContinuation; // Null if there is no join. 801 ir.Continuation joinContinuation; // Null if there is no join.
797 if (thenBuilder.isOpen && elseBuilder.isOpen) { 802 if (thenBuilder.isOpen && elseBuilder.isOpen) {
798 // There is a join-point continuation. Build the term 803 // There is a join-point continuation. Build the term
799 // 'let cont join(x, ...) = [] in Result' and plug invocations of the 804 // 'let cont join(x, ...) = [] in Result' and plug invocations of the
800 // join-point continuation into the then and else continuations. 805 // join-point continuation into the then and else continuations.
801 JumpCollector jumps = new JumpCollector(null); 806 JumpCollector jumps = new JumpCollector(null);
802 jumps.addJump(thenBuilder); 807 jumps.addJump(thenBuilder);
803 jumps.addJump(elseBuilder); 808 jumps.addJump(elseBuilder);
804 joinContinuation = createJoin(environment.length, jumps); 809 joinContinuation = createJoin(environment.length, jumps);
805 result = new ir.LetCont(joinContinuation, result); 810 result = new ir.LetCont(<ir.Continuation>[joinContinuation], result);
806 } 811 }
807 812
808 // The then or else term root could be null, but not both. If there is 813 // The then or else term root could be null, but not both. If there is
809 // a join then an InvokeContinuation was just added to both of them. If 814 // a join then an InvokeContinuation was just added to both of them. If
810 // there is no join, then at least one of them is closed and thus has a 815 // there is no join, then at least one of them is closed and thus has a
811 // non-null root by the definition of the predicate isClosed. In the 816 // non-null root by the definition of the predicate isClosed. In the
812 // case that one of them is null, it must be the only one that is open 817 // case that one of them is null, it must be the only one that is open
813 // and thus contains the new hole in the context. This case is handled 818 // and thus contains the new hole in the context. This case is handled
814 // after the branch is plugged into the current hole. 819 // after the branch is plugged into the current hole.
815 thenContinuation.body = thenBuilder._root; 820 thenContinuation.body = thenBuilder._root;
816 elseContinuation.body = elseBuilder._root; 821 elseContinuation.body = elseBuilder._root;
817 822
818 add(result); 823 add(result);
819 if (joinContinuation == null) { 824 if (joinContinuation == null) {
820 // At least one subexpression is closed. 825 // At least one subexpression is closed.
821 if (thenBuilder.isOpen) { 826 if (thenBuilder.isOpen) {
822 _current = 827 if (thenBuilder._root != null) _current = thenBuilder._current;
823 (thenBuilder._root == null) ? letThen : thenBuilder._current;
824 environment = thenBuilder.environment; 828 environment = thenBuilder.environment;
825 } else if (elseBuilder.isOpen) { 829 } else if (elseBuilder.isOpen) {
826 _current = 830 if (elseBuilder._root != null) _current = elseBuilder._current;
827 (elseBuilder._root == null) ? letElse : elseBuilder._current;
828 environment = elseBuilder.environment; 831 environment = elseBuilder.environment;
829 } else { 832 } else {
830 _current = null; 833 _current = null;
831 } 834 }
832 } 835 }
833 } 836 }
834 837
835 /// Invoke a join-point continuation that contains arguments for all local 838 /// Invoke a join-point continuation that contains arguments for all local
836 /// variables. 839 /// variables.
837 /// 840 ///
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 bool hasContinues = !continueCollector.isEmpty; 932 bool hasContinues = !continueCollector.isEmpty;
930 IrBuilder updateBuilder = hasContinues 933 IrBuilder updateBuilder = hasContinues
931 ? condBuilder.makeRecursiveBuilder() 934 ? condBuilder.makeRecursiveBuilder()
932 : bodyBuilder; 935 : bodyBuilder;
933 updateBuilder._enterForLoopUpdate(closureScope, loopVariables); 936 updateBuilder._enterForLoopUpdate(closureScope, loopVariables);
934 buildUpdate(updateBuilder); 937 buildUpdate(updateBuilder);
935 938
936 // Create body entry and loop exit continuations and a branch to them. 939 // Create body entry and loop exit continuations and a branch to them.
937 ir.Continuation bodyContinuation = new ir.Continuation([]); 940 ir.Continuation bodyContinuation = new ir.Continuation([]);
938 ir.Continuation exitContinuation = new ir.Continuation([]); 941 ir.Continuation exitContinuation = new ir.Continuation([]);
942 // Note the order of continuations: the first one is the one that will
943 // be filled by LetCont.plug.
939 ir.LetCont branch = 944 ir.LetCont branch =
940 new ir.LetCont(exitContinuation, 945 new ir.LetCont(<ir.Continuation>[exitContinuation, bodyContinuation],
941 new ir.LetCont(bodyContinuation, 946 new ir.Branch(new ir.IsTrue(condition),
942 new ir.Branch(new ir.IsTrue(condition), 947 bodyContinuation,
943 bodyContinuation, 948 exitContinuation));
944 exitContinuation)));
945 // If there are breaks in the body, then there must be a join-point 949 // If there are breaks in the body, then there must be a join-point
946 // continuation for the normal exit and the breaks. 950 // continuation for the normal exit and the breaks.
947 bool hasBreaks = !breakCollector.isEmpty; 951 bool hasBreaks = !breakCollector.isEmpty;
948 ir.LetCont letJoin; 952 ir.LetCont letJoin;
949 if (hasBreaks) { 953 if (hasBreaks) {
950 letJoin = new ir.LetCont(null, branch); 954 letJoin = new ir.LetCont(null, branch);
951 condBuilder.add(letJoin); 955 condBuilder.add(letJoin);
952 condBuilder._current = branch; 956 condBuilder._current = branch;
953 } else { 957 } else {
954 condBuilder.add(branch); 958 condBuilder.add(branch);
(...skipping 12 matching lines...) Expand all
967 JumpCollector backEdges = new JumpCollector(null); 971 JumpCollector backEdges = new JumpCollector(null);
968 backEdges.addJump(updateBuilder); 972 backEdges.addJump(updateBuilder);
969 invokeFullJoin(loopContinuation, backEdges, recursive: true); 973 invokeFullJoin(loopContinuation, backEdges, recursive: true);
970 } 974 }
971 975
972 // Fill in the body and possible continue continuation bodies. Do this 976 // Fill in the body and possible continue continuation bodies. Do this
973 // only after it is guaranteed that they are not empty. 977 // only after it is guaranteed that they are not empty.
974 if (hasContinues) { 978 if (hasContinues) {
975 continueContinuation.body = updateBuilder._root; 979 continueContinuation.body = updateBuilder._root;
976 bodyContinuation.body = 980 bodyContinuation.body =
977 new ir.LetCont(continueContinuation, bodyBuilder._root); 981 new ir.LetCont(<ir.Continuation>[continueContinuation],
982 bodyBuilder._root);
978 } else { 983 } else {
979 bodyContinuation.body = bodyBuilder._root; 984 bodyContinuation.body = bodyBuilder._root;
980 } 985 }
981 986
982 loopContinuation.body = condBuilder._root; 987 loopContinuation.body = condBuilder._root;
983 add(new ir.LetCont(loopContinuation, 988 add(new ir.LetCont(<ir.Continuation>[loopContinuation],
984 new ir.InvokeContinuation(loopContinuation, 989 new ir.InvokeContinuation(loopContinuation,
985 environment.index2value))); 990 environment.index2value)));
986 if (hasBreaks) { 991 if (hasBreaks) {
987 _current = branch; 992 _current = branch;
988 environment = condBuilder.environment; 993 environment = condBuilder.environment;
989 breakCollector.addJump(this); 994 breakCollector.addJump(this);
990 letJoin.continuation = createJoin(environment.length, breakCollector); 995 letJoin.continuations =
996 <ir.Continuation>[createJoin(environment.length, breakCollector)];
991 _current = letJoin; 997 _current = letJoin;
992 } else { 998 } else {
993 _current = condBuilder._current; 999 _current = condBuilder._current;
994 environment = condBuilder.environment; 1000 environment = condBuilder.environment;
995 } 1001 }
996 } 1002 }
997 1003
998 /// Creates a for-in loop, `for (v in e) b`. 1004 /// Creates a for-in loop, `for (v in e) b`.
999 /// 1005 ///
1000 /// [buildExpression] creates the expression, `e`. The variable, `v`, can 1006 /// [buildExpression] creates the expression, `e`. The variable, `v`, can
(...skipping 30 matching lines...) Expand all
1031 // } 1037 // }
1032 1038
1033 // The condition and body are delimited. 1039 // The condition and body are delimited.
1034 IrBuilder condBuilder = makeRecursiveBuilder(); 1040 IrBuilder condBuilder = makeRecursiveBuilder();
1035 1041
1036 ir.Primitive expressionReceiver = buildExpression(this); 1042 ir.Primitive expressionReceiver = buildExpression(this);
1037 List<ir.Primitive> emptyArguments = new List<ir.Primitive>(); 1043 List<ir.Primitive> emptyArguments = new List<ir.Primitive>();
1038 1044
1039 ir.Parameter iterator = new ir.Parameter(null); 1045 ir.Parameter iterator = new ir.Parameter(null);
1040 ir.Continuation iteratorInvoked = new ir.Continuation([iterator]); 1046 ir.Continuation iteratorInvoked = new ir.Continuation([iterator]);
1041 add(new ir.LetCont(iteratorInvoked, 1047 add(new ir.LetCont(<ir.Continuation>[iteratorInvoked],
1042 new ir.InvokeMethod(expressionReceiver, 1048 new ir.InvokeMethod(expressionReceiver,
1043 new Selector.getter("iterator", null), iteratorInvoked, 1049 new Selector.getter("iterator", null), iteratorInvoked,
1044 emptyArguments))); 1050 emptyArguments)));
1045 1051
1046 ir.Parameter condition = new ir.Parameter(null); 1052 ir.Parameter condition = new ir.Parameter(null);
1047 ir.Continuation moveNextInvoked = new ir.Continuation([condition]); 1053 ir.Continuation moveNextInvoked = new ir.Continuation([condition]);
1048 condBuilder.add(new ir.LetCont(moveNextInvoked, 1054 condBuilder.add(new ir.LetCont(<ir.Continuation>[moveNextInvoked],
1049 new ir.InvokeMethod(iterator, 1055 new ir.InvokeMethod(iterator,
1050 new Selector.call("moveNext", null, 0), 1056 new Selector.call("moveNext", null, 0),
1051 moveNextInvoked, emptyArguments))); 1057 moveNextInvoked, emptyArguments)));
1052 1058
1053 JumpCollector breakCollector = new JumpCollector(target); 1059 JumpCollector breakCollector = new JumpCollector(target);
1054 JumpCollector continueCollector = new JumpCollector(target); 1060 JumpCollector continueCollector = new JumpCollector(target);
1055 state.breakCollectors.add(breakCollector); 1061 state.breakCollectors.add(breakCollector);
1056 state.continueCollectors.add(continueCollector); 1062 state.continueCollectors.add(continueCollector);
1057 1063
1058 IrBuilder bodyBuilder = condBuilder.makeDelimitedBuilder(); 1064 IrBuilder bodyBuilder = condBuilder.makeDelimitedBuilder();
1059 bodyBuilder._enterScope(closureScope); 1065 bodyBuilder._enterScope(closureScope);
1060 if (buildVariableDeclaration != null) { 1066 if (buildVariableDeclaration != null) {
1061 buildVariableDeclaration(bodyBuilder); 1067 buildVariableDeclaration(bodyBuilder);
1062 } 1068 }
1063 1069
1064 ir.Parameter currentValue = new ir.Parameter(null); 1070 ir.Parameter currentValue = new ir.Parameter(null);
1065 ir.Continuation currentInvoked = new ir.Continuation([currentValue]); 1071 ir.Continuation currentInvoked = new ir.Continuation([currentValue]);
1066 bodyBuilder.add(new ir.LetCont(currentInvoked, 1072 bodyBuilder.add(new ir.LetCont(<ir.Continuation>[currentInvoked],
1067 new ir.InvokeMethod(iterator, new Selector.getter("current", null), 1073 new ir.InvokeMethod(iterator, new Selector.getter("current", null),
1068 currentInvoked, emptyArguments))); 1074 currentInvoked, emptyArguments)));
1069 if (Elements.isLocal(variableElement)) { 1075 if (Elements.isLocal(variableElement)) {
1070 bodyBuilder.buildLocalSet(variableElement, currentValue); 1076 bodyBuilder.buildLocalSet(variableElement, currentValue);
1071 } else if (Elements.isStaticOrTopLevel(variableElement)) { 1077 } else if (Elements.isStaticOrTopLevel(variableElement)) {
1072 bodyBuilder.buildStaticSet( 1078 bodyBuilder.buildStaticSet(
1073 variableElement, variableSelector, currentValue); 1079 variableElement, variableSelector, currentValue);
1074 } else { 1080 } else {
1075 ir.Primitive receiver = bodyBuilder.buildThis(); 1081 ir.Primitive receiver = bodyBuilder.buildThis();
1076 bodyBuilder.buildDynamicSet(receiver, variableSelector, currentValue); 1082 bodyBuilder.buildDynamicSet(receiver, variableSelector, currentValue);
1077 } 1083 }
1078 1084
1079 buildBody(bodyBuilder); 1085 buildBody(bodyBuilder);
1080 assert(state.breakCollectors.last == breakCollector); 1086 assert(state.breakCollectors.last == breakCollector);
1081 assert(state.continueCollectors.last == continueCollector); 1087 assert(state.continueCollectors.last == continueCollector);
1082 state.breakCollectors.removeLast(); 1088 state.breakCollectors.removeLast();
1083 state.continueCollectors.removeLast(); 1089 state.continueCollectors.removeLast();
1084 1090
1085 // Create body entry and loop exit continuations and a branch to them. 1091 // Create body entry and loop exit continuations and a branch to them.
1086 ir.Continuation bodyContinuation = new ir.Continuation([]); 1092 ir.Continuation bodyContinuation = new ir.Continuation([]);
1087 ir.Continuation exitContinuation = new ir.Continuation([]); 1093 ir.Continuation exitContinuation = new ir.Continuation([]);
1094 // Note the order of continuations: the first one is the one that will
1095 // be filled by LetCont.plug.
1088 ir.LetCont branch = 1096 ir.LetCont branch =
1089 new ir.LetCont(exitContinuation, 1097 new ir.LetCont(<ir.Continuation>[exitContinuation, bodyContinuation],
1090 new ir.LetCont(bodyContinuation, 1098 new ir.Branch(new ir.IsTrue(condition),
1091 new ir.Branch(new ir.IsTrue(condition), 1099 bodyContinuation,
1092 bodyContinuation, 1100 exitContinuation));
1093 exitContinuation)));
1094 // If there are breaks in the body, then there must be a join-point 1101 // If there are breaks in the body, then there must be a join-point
1095 // continuation for the normal exit and the breaks. 1102 // continuation for the normal exit and the breaks.
1096 bool hasBreaks = !breakCollector.isEmpty; 1103 bool hasBreaks = !breakCollector.isEmpty;
1097 ir.LetCont letJoin; 1104 ir.LetCont letJoin;
1098 if (hasBreaks) { 1105 if (hasBreaks) {
1099 letJoin = new ir.LetCont(null, branch); 1106 letJoin = new ir.LetCont(null, branch);
1100 condBuilder.add(letJoin); 1107 condBuilder.add(letJoin);
1101 condBuilder._current = branch; 1108 condBuilder._current = branch;
1102 } else { 1109 } else {
1103 condBuilder.add(branch); 1110 condBuilder.add(branch);
1104 } 1111 }
1105 ir.Continuation loopContinuation = 1112 ir.Continuation loopContinuation =
1106 new ir.Continuation(condBuilder._parameters); 1113 new ir.Continuation(condBuilder._parameters);
1107 if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder); 1114 if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder);
1108 invokeFullJoin( 1115 invokeFullJoin(
1109 loopContinuation, continueCollector, recursive: true); 1116 loopContinuation, continueCollector, recursive: true);
1110 bodyContinuation.body = bodyBuilder._root; 1117 bodyContinuation.body = bodyBuilder._root;
1111 1118
1112 loopContinuation.body = condBuilder._root; 1119 loopContinuation.body = condBuilder._root;
1113 add(new ir.LetCont(loopContinuation, 1120 add(new ir.LetCont(<ir.Continuation>[loopContinuation],
1114 new ir.InvokeContinuation(loopContinuation, 1121 new ir.InvokeContinuation(loopContinuation,
1115 environment.index2value))); 1122 environment.index2value)));
1116 if (hasBreaks) { 1123 if (hasBreaks) {
1117 _current = branch; 1124 _current = branch;
1118 environment = condBuilder.environment; 1125 environment = condBuilder.environment;
1119 breakCollector.addJump(this); 1126 breakCollector.addJump(this);
1120 letJoin.continuation = createJoin(environment.length, breakCollector); 1127 letJoin.continuations =
1128 <ir.Continuation>[createJoin(environment.length, breakCollector)];
1121 _current = letJoin; 1129 _current = letJoin;
1122 } else { 1130 } else {
1123 _current = condBuilder._current; 1131 _current = condBuilder._current;
1124 environment = condBuilder.environment; 1132 environment = condBuilder.environment;
1125 } 1133 }
1126 } 1134 }
1127 1135
1128 /// Creates a while loop in which the condition and body are created by 1136 /// Creates a while loop in which the condition and body are created by
1129 /// [buildCondition] and [buildBody], respectively. 1137 /// [buildCondition] and [buildBody], respectively.
1130 /// 1138 ///
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 bodyBuilder._enterScope(closureScope); 1172 bodyBuilder._enterScope(closureScope);
1165 buildBody(bodyBuilder); 1173 buildBody(bodyBuilder);
1166 assert(state.breakCollectors.last == breakCollector); 1174 assert(state.breakCollectors.last == breakCollector);
1167 assert(state.continueCollectors.last == continueCollector); 1175 assert(state.continueCollectors.last == continueCollector);
1168 state.breakCollectors.removeLast(); 1176 state.breakCollectors.removeLast();
1169 state.continueCollectors.removeLast(); 1177 state.continueCollectors.removeLast();
1170 1178
1171 // Create body entry and loop exit continuations and a branch to them. 1179 // Create body entry and loop exit continuations and a branch to them.
1172 ir.Continuation bodyContinuation = new ir.Continuation([]); 1180 ir.Continuation bodyContinuation = new ir.Continuation([]);
1173 ir.Continuation exitContinuation = new ir.Continuation([]); 1181 ir.Continuation exitContinuation = new ir.Continuation([]);
1182 // Note the order of continuations: the first one is the one that will
1183 // be filled by LetCont.plug.
1174 ir.LetCont branch = 1184 ir.LetCont branch =
1175 new ir.LetCont(exitContinuation, 1185 new ir.LetCont(<ir.Continuation>[exitContinuation, bodyContinuation],
1176 new ir.LetCont(bodyContinuation, 1186 new ir.Branch(new ir.IsTrue(condition),
1177 new ir.Branch(new ir.IsTrue(condition), 1187 bodyContinuation,
1178 bodyContinuation, 1188 exitContinuation));
1179 exitContinuation)));
1180 // If there are breaks in the body, then there must be a join-point 1189 // If there are breaks in the body, then there must be a join-point
1181 // continuation for the normal exit and the breaks. 1190 // continuation for the normal exit and the breaks.
1182 bool hasBreaks = !breakCollector.isEmpty; 1191 bool hasBreaks = !breakCollector.isEmpty;
1183 ir.LetCont letJoin; 1192 ir.LetCont letJoin;
1184 if (hasBreaks) { 1193 if (hasBreaks) {
1185 letJoin = new ir.LetCont(null, branch); 1194 letJoin = new ir.LetCont(null, branch);
1186 condBuilder.add(letJoin); 1195 condBuilder.add(letJoin);
1187 condBuilder._current = branch; 1196 condBuilder._current = branch;
1188 } else { 1197 } else {
1189 condBuilder.add(branch); 1198 condBuilder.add(branch);
1190 } 1199 }
1191 ir.Continuation loopContinuation = 1200 ir.Continuation loopContinuation =
1192 new ir.Continuation(condBuilder._parameters); 1201 new ir.Continuation(condBuilder._parameters);
1193 if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder); 1202 if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder);
1194 invokeFullJoin(loopContinuation, continueCollector, recursive: true); 1203 invokeFullJoin(loopContinuation, continueCollector, recursive: true);
1195 bodyContinuation.body = bodyBuilder._root; 1204 bodyContinuation.body = bodyBuilder._root;
1196 1205
1197 loopContinuation.body = condBuilder._root; 1206 loopContinuation.body = condBuilder._root;
1198 add(new ir.LetCont(loopContinuation, 1207 add(new ir.LetCont(<ir.Continuation>[loopContinuation],
1199 new ir.InvokeContinuation(loopContinuation, 1208 new ir.InvokeContinuation(loopContinuation,
1200 environment.index2value))); 1209 environment.index2value)));
1201 if (hasBreaks) { 1210 if (hasBreaks) {
1202 _current = branch; 1211 _current = branch;
1203 environment = condBuilder.environment; 1212 environment = condBuilder.environment;
1204 breakCollector.addJump(this); 1213 breakCollector.addJump(this);
1205 letJoin.continuation = createJoin(environment.length, breakCollector); 1214 letJoin.continuations =
1215 <ir.Continuation>[createJoin(environment.length, breakCollector)];
1206 _current = letJoin; 1216 _current = letJoin;
1207 } else { 1217 } else {
1208 _current = condBuilder._current; 1218 _current = condBuilder._current;
1209 environment = condBuilder.environment; 1219 environment = condBuilder.environment;
1210 } 1220 }
1211 } 1221 }
1212 1222
1213 /// Create a return statement `return value;` or `return;` if [value] is 1223 /// Create a return statement `return value;` or `return;` if [value] is
1214 /// null. 1224 /// null.
1215 void buildReturn([ir.Primitive value]) { 1225 void buildReturn([ir.Primitive value]) {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1294 } 1304 }
1295 1305
1296 ir.Constant trueConstant = makeBoolConstant(true); 1306 ir.Constant trueConstant = makeBoolConstant(true);
1297 ir.Constant falseConstant = makeBoolConstant(false); 1307 ir.Constant falseConstant = makeBoolConstant(false);
1298 1308
1299 thenContinuation.body = new ir.LetPrim(falseConstant) 1309 thenContinuation.body = new ir.LetPrim(falseConstant)
1300 ..plug(new ir.InvokeContinuation(joinContinuation, [falseConstant])); 1310 ..plug(new ir.InvokeContinuation(joinContinuation, [falseConstant]));
1301 elseContinuation.body = new ir.LetPrim(trueConstant) 1311 elseContinuation.body = new ir.LetPrim(trueConstant)
1302 ..plug(new ir.InvokeContinuation(joinContinuation, [trueConstant])); 1312 ..plug(new ir.InvokeContinuation(joinContinuation, [trueConstant]));
1303 1313
1304 add(new ir.LetCont(joinContinuation, 1314 add(new ir.LetCont(<ir.Continuation>[joinContinuation],
1305 new ir.LetCont(thenContinuation, 1315 new ir.LetCont(<ir.Continuation>[thenContinuation, elseContinuation],
1306 new ir.LetCont(elseContinuation,
1307 new ir.Branch(new ir.IsTrue(condition), 1316 new ir.Branch(new ir.IsTrue(condition),
1308 thenContinuation, 1317 thenContinuation,
1309 elseContinuation))))); 1318 elseContinuation))));
1310 return resultParameter; 1319 return resultParameter;
1311 } 1320 }
1312 1321
1313 /// Creates a type test or type cast of [receiver] against [type]. 1322 /// Creates a type test or type cast of [receiver] against [type].
1314 /// 1323 ///
1315 /// Set [isTypeTest] to `true` to create a type test and furthermore set 1324 /// Set [isTypeTest] to `true` to create a type test and furthermore set
1316 /// [isNotCheck] to `true` to create a negated type test. 1325 /// [isNotCheck] to `true` to create a negated type test.
1317 ir.Primitive buildTypeOperator(ir.Primitive receiver, 1326 ir.Primitive buildTypeOperator(ir.Primitive receiver,
1318 DartType type, 1327 DartType type,
1319 {bool isTypeTest: false, 1328 {bool isTypeTest: false,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1378 ir.Continuation joinContinuation = 1387 ir.Continuation joinContinuation =
1379 createJoin(environment.length + 1, jumps); 1388 createJoin(environment.length + 1, jumps);
1380 ir.Continuation leftTrueContinuation = new ir.Continuation([]); 1389 ir.Continuation leftTrueContinuation = new ir.Continuation([]);
1381 ir.Continuation leftFalseContinuation = new ir.Continuation([]); 1390 ir.Continuation leftFalseContinuation = new ir.Continuation([]);
1382 ir.Continuation rightTrueContinuation = new ir.Continuation([]); 1391 ir.Continuation rightTrueContinuation = new ir.Continuation([]);
1383 ir.Continuation rightFalseContinuation = new ir.Continuation([]); 1392 ir.Continuation rightFalseContinuation = new ir.Continuation([]);
1384 rightTrueContinuation.body = rightTrueBuilder._root; 1393 rightTrueContinuation.body = rightTrueBuilder._root;
1385 rightFalseContinuation.body = rightFalseBuilder._root; 1394 rightFalseContinuation.body = rightFalseBuilder._root;
1386 // The right subexpression has two continuations. 1395 // The right subexpression has two continuations.
1387 rightBuilder.add( 1396 rightBuilder.add(
1388 new ir.LetCont(rightTrueContinuation, 1397 new ir.LetCont(<ir.Continuation>[rightTrueContinuation,
1389 new ir.LetCont(rightFalseContinuation, 1398 rightFalseContinuation],
1390 new ir.Branch(new ir.IsTrue(rightValue), 1399 new ir.Branch(new ir.IsTrue(rightValue),
1391 rightTrueContinuation, 1400 rightTrueContinuation,
1392 rightFalseContinuation)))); 1401 rightFalseContinuation)));
1393 // Depending on the operator, the left subexpression's continuations are 1402 // Depending on the operator, the left subexpression's continuations are
1394 // either the right subexpression or an invocation of the join-point 1403 // either the right subexpression or an invocation of the join-point
1395 // continuation. 1404 // continuation.
1396 if (isLazyOr) { 1405 if (isLazyOr) {
1397 leftTrueContinuation.body = emptyBuilder._root; 1406 leftTrueContinuation.body = emptyBuilder._root;
1398 leftFalseContinuation.body = rightBuilder._root; 1407 leftFalseContinuation.body = rightBuilder._root;
1399 } else { 1408 } else {
1400 leftTrueContinuation.body = rightBuilder._root; 1409 leftTrueContinuation.body = rightBuilder._root;
1401 leftFalseContinuation.body = emptyBuilder._root; 1410 leftFalseContinuation.body = emptyBuilder._root;
1402 } 1411 }
1403 1412
1404 add(new ir.LetCont(joinContinuation, 1413 add(new ir.LetCont(<ir.Continuation>[joinContinuation],
1405 new ir.LetCont(leftTrueContinuation, 1414 new ir.LetCont(<ir.Continuation>[leftTrueContinuation,
1406 new ir.LetCont(leftFalseContinuation, 1415 leftFalseContinuation],
1407 new ir.Branch(new ir.IsTrue(leftValue), 1416 new ir.Branch(new ir.IsTrue(leftValue),
1408 leftTrueContinuation, 1417 leftTrueContinuation,
1409 leftFalseContinuation))))); 1418 leftFalseContinuation))));
1410 // There is always a join parameter for the result value, because it 1419 // There is always a join parameter for the result value, because it
1411 // is different on at least two paths. 1420 // is different on at least two paths.
1412 return joinContinuation.parameters.last; 1421 return joinContinuation.parameters.last;
1413 } 1422 }
1414 1423
1415 /// Create a non-recursive join-point continuation. 1424 /// Create a non-recursive join-point continuation.
1416 /// 1425 ///
1417 /// Given the environment length at the join point and a list of 1426 /// Given the environment length at the join point and a list of
1418 /// jumps that should reach the join point, create a join-point 1427 /// jumps that should reach the join point, create a join-point
1419 /// continuation. The join-point continuation has a parameter for each 1428 /// continuation. The join-point continuation has a parameter for each
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after
1979 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables); 1988 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables);
1980 } 1989 }
1981 1990
1982 /// Information about which variables are captured in a closure. 1991 /// Information about which variables are captured in a closure.
1983 /// 1992 ///
1984 /// This is used by the [DartIrBuilder] instead of [ClosureScope] and 1993 /// This is used by the [DartIrBuilder] instead of [ClosureScope] and
1985 /// [ClosureEnvironment]. 1994 /// [ClosureEnvironment].
1986 abstract class ClosureVariableInfo { 1995 abstract class ClosureVariableInfo {
1987 Iterable<Local> get capturedVariables; 1996 Iterable<Local> get capturedVariables;
1988 } 1997 }
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