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

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

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

Powered by Google App Engine
This is Rietveld 408576698