| OLD | NEW |
| 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 Loading... |
| 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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 thenBuilder.environment.extend(null, thenValue); | 527 thenBuilder.environment.extend(null, thenValue); |
| 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, ...) |
| 538 // let cont else() = [[elsePart]]; join(v, ...) in | 538 // and else() = [[elsePart]]; join(v, ...) |
| 539 // in |
| 539 // if condition (then, else) | 540 // if condition (then, else) |
| 540 ir.Continuation thenContinuation = new ir.Continuation([]); | 541 ir.Continuation thenContinuation = new ir.Continuation([]); |
| 541 ir.Continuation elseContinuation = new ir.Continuation([]); | 542 ir.Continuation elseContinuation = new ir.Continuation([]); |
| 542 thenContinuation.body = thenBuilder._root; | 543 thenContinuation.body = thenBuilder._root; |
| 543 elseContinuation.body = elseBuilder._root; | 544 elseContinuation.body = elseBuilder._root; |
| 544 add(new ir.LetCont(<ir.Continuation>[joinContinuation], | 545 add(new ir.LetCont(joinContinuation, |
| 545 new ir.LetCont(<ir.Continuation>[thenContinuation, | 546 new ir.LetCont.many(<ir.Continuation>[thenContinuation, |
| 546 elseContinuation], | 547 elseContinuation], |
| 547 new ir.Branch(new ir.IsTrue(condition), | 548 new ir.Branch(new ir.IsTrue(condition), |
| 548 thenContinuation, | 549 thenContinuation, |
| 549 elseContinuation)))); | 550 elseContinuation)))); |
| 550 return (thenValue == elseValue) | 551 return (thenValue == elseValue) |
| 551 ? thenValue | 552 ? thenValue |
| 552 : joinContinuation.parameters.last; | 553 : joinContinuation.parameters.last; |
| 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 |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 780 void buildElsePart(IrBuilder builder)) { | 781 void buildElsePart(IrBuilder builder)) { |
| 781 assert(isOpen); | 782 assert(isOpen); |
| 782 | 783 |
| 783 // The then and else parts are delimited. | 784 // The then and else parts are delimited. |
| 784 IrBuilder thenBuilder = makeDelimitedBuilder(); | 785 IrBuilder thenBuilder = makeDelimitedBuilder(); |
| 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]] |
| 791 // let cont else() = [[elsePart]] in | 792 // and else() = [[elsePart]] |
| 793 // in |
| 792 // if condition (then, else) | 794 // if condition (then, else) |
| 793 ir.Continuation thenContinuation = new ir.Continuation([]); | 795 ir.Continuation thenContinuation = new ir.Continuation([]); |
| 794 ir.Continuation elseContinuation = new ir.Continuation([]); | 796 ir.Continuation elseContinuation = new ir.Continuation([]); |
| 795 // If exactly one of the then and else continuation bodies is open (i.e., | 797 // If exactly one of the then and else continuation bodies is open (i.e., |
| 796 // the other one has an exit on all paths), then Continuation.plug expects | 798 // the other one has an exit on all paths), then Continuation.plug expects |
| 797 // that continuation to be listed first. Arbitrarily use [then, else] | 799 // that continuation to be listed first. Arbitrarily use [then, else] |
| 798 // order otherwise. | 800 // order otherwise. |
| 799 List<ir.Continuation> arms = !thenBuilder.isOpen && elseBuilder.isOpen | 801 List<ir.Continuation> arms = !thenBuilder.isOpen && elseBuilder.isOpen |
| 800 ? <ir.Continuation>[elseContinuation, thenContinuation] | 802 ? <ir.Continuation>[elseContinuation, thenContinuation] |
| 801 : <ir.Continuation>[thenContinuation, elseContinuation]; | 803 : <ir.Continuation>[thenContinuation, elseContinuation]; |
| 802 | 804 |
| 803 ir.Expression result = | 805 ir.Expression result = |
| 804 new ir.LetCont(arms, | 806 new ir.LetCont.many(arms, |
| 805 new ir.Branch(new ir.IsTrue(condition), | 807 new ir.Branch(new ir.IsTrue(condition), |
| 806 thenContinuation, | 808 thenContinuation, |
| 807 elseContinuation)); | 809 elseContinuation)); |
| 808 | 810 |
| 809 ir.Continuation joinContinuation; // Null if there is no join. | 811 ir.Continuation joinContinuation; // Null if there is no join. |
| 810 if (thenBuilder.isOpen && elseBuilder.isOpen) { | 812 if (thenBuilder.isOpen && elseBuilder.isOpen) { |
| 811 // There is a join-point continuation. Build the term | 813 // There is a join-point continuation. Build the term |
| 812 // 'let cont join(x, ...) = [] in Result' and plug invocations of the | 814 // 'let cont join(x, ...) = [] in Result' and plug invocations of the |
| 813 // join-point continuation into the then and else continuations. | 815 // join-point continuation into the then and else continuations. |
| 814 JumpCollector jumps = new JumpCollector(null); | 816 JumpCollector jumps = new JumpCollector(null); |
| 815 jumps.addJump(thenBuilder); | 817 jumps.addJump(thenBuilder); |
| 816 jumps.addJump(elseBuilder); | 818 jumps.addJump(elseBuilder); |
| 817 joinContinuation = createJoin(environment.length, jumps); | 819 joinContinuation = createJoin(environment.length, jumps); |
| 818 result = new ir.LetCont(<ir.Continuation>[joinContinuation], result); | 820 result = new ir.LetCont(joinContinuation, result); |
| 819 } | 821 } |
| 820 | 822 |
| 821 // The then or else term root could be null, but not both. If there is | 823 // 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 | 824 // 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 | 825 // 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 | 826 // 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 | 827 // 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 | 828 // and thus contains the new hole in the context. This case is handled |
| 827 // after the branch is plugged into the current hole. | 829 // after the branch is plugged into the current hole. |
| 828 thenContinuation.body = thenBuilder._root; | 830 thenContinuation.body = thenBuilder._root; |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 updateBuilder._migrateLoopVariables(closureScope); | 959 updateBuilder._migrateLoopVariables(closureScope); |
| 958 } | 960 } |
| 959 buildUpdate(updateBuilder); | 961 buildUpdate(updateBuilder); |
| 960 | 962 |
| 961 // Create body entry and loop exit continuations and a branch to them. | 963 // Create body entry and loop exit continuations and a branch to them. |
| 962 ir.Continuation bodyContinuation = new ir.Continuation([]); | 964 ir.Continuation bodyContinuation = new ir.Continuation([]); |
| 963 ir.Continuation exitContinuation = new ir.Continuation([]); | 965 ir.Continuation exitContinuation = new ir.Continuation([]); |
| 964 // Note the order of continuations: the first one is the one that will | 966 // Note the order of continuations: the first one is the one that will |
| 965 // be filled by LetCont.plug. | 967 // be filled by LetCont.plug. |
| 966 ir.LetCont branch = | 968 ir.LetCont branch = |
| 967 new ir.LetCont(<ir.Continuation>[exitContinuation, bodyContinuation], | 969 new ir.LetCont.many(<ir.Continuation>[exitContinuation, |
| 970 bodyContinuation], |
| 968 new ir.Branch(new ir.IsTrue(condition), | 971 new ir.Branch(new ir.IsTrue(condition), |
| 969 bodyContinuation, | 972 bodyContinuation, |
| 970 exitContinuation)); | 973 exitContinuation)); |
| 971 // If there are breaks in the body, then there must be a join-point | 974 // If there are breaks in the body, then there must be a join-point |
| 972 // continuation for the normal exit and the breaks. | 975 // continuation for the normal exit and the breaks. |
| 973 bool hasBreaks = !breakCollector.isEmpty; | 976 bool hasBreaks = !breakCollector.isEmpty; |
| 974 ir.LetCont letJoin; | 977 ir.LetCont letJoin; |
| 975 if (hasBreaks) { | 978 if (hasBreaks) { |
| 976 letJoin = new ir.LetCont(null, branch); | 979 letJoin = new ir.LetCont(null, branch); |
| 977 condBuilder.add(letJoin); | 980 condBuilder.add(letJoin); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 993 JumpCollector backEdges = new JumpCollector(null); | 996 JumpCollector backEdges = new JumpCollector(null); |
| 994 backEdges.addJump(updateBuilder); | 997 backEdges.addJump(updateBuilder); |
| 995 invokeFullJoin(loopContinuation, backEdges, recursive: true); | 998 invokeFullJoin(loopContinuation, backEdges, recursive: true); |
| 996 } | 999 } |
| 997 | 1000 |
| 998 // Fill in the body and possible continue continuation bodies. Do this | 1001 // Fill in the body and possible continue continuation bodies. Do this |
| 999 // only after it is guaranteed that they are not empty. | 1002 // only after it is guaranteed that they are not empty. |
| 1000 if (hasContinues) { | 1003 if (hasContinues) { |
| 1001 continueContinuation.body = updateBuilder._root; | 1004 continueContinuation.body = updateBuilder._root; |
| 1002 bodyContinuation.body = | 1005 bodyContinuation.body = |
| 1003 new ir.LetCont(<ir.Continuation>[continueContinuation], | 1006 new ir.LetCont(continueContinuation, |
| 1004 bodyBuilder._root); | 1007 bodyBuilder._root); |
| 1005 } else { | 1008 } else { |
| 1006 bodyContinuation.body = bodyBuilder._root; | 1009 bodyContinuation.body = bodyBuilder._root; |
| 1007 } | 1010 } |
| 1008 | 1011 |
| 1009 loopContinuation.body = condBuilder._root; | 1012 loopContinuation.body = condBuilder._root; |
| 1010 add(new ir.LetCont(<ir.Continuation>[loopContinuation], | 1013 add(new ir.LetCont(loopContinuation, |
| 1011 new ir.InvokeContinuation(loopContinuation, | 1014 new ir.InvokeContinuation(loopContinuation, |
| 1012 environment.index2value))); | 1015 environment.index2value))); |
| 1013 if (hasBreaks) { | 1016 if (hasBreaks) { |
| 1014 _current = branch; | 1017 _current = branch; |
| 1015 environment = condBuilder.environment; | 1018 environment = condBuilder.environment; |
| 1016 breakCollector.addJump(this); | 1019 breakCollector.addJump(this); |
| 1017 letJoin.continuations = | 1020 letJoin.continuations = |
| 1018 <ir.Continuation>[createJoin(environment.length, breakCollector)]; | 1021 <ir.Continuation>[createJoin(environment.length, breakCollector)]; |
| 1019 _current = letJoin; | 1022 _current = letJoin; |
| 1020 } else { | 1023 } else { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1059 // } | 1062 // } |
| 1060 | 1063 |
| 1061 // The condition and body are delimited. | 1064 // The condition and body are delimited. |
| 1062 IrBuilder condBuilder = makeRecursiveBuilder(); | 1065 IrBuilder condBuilder = makeRecursiveBuilder(); |
| 1063 | 1066 |
| 1064 ir.Primitive expressionReceiver = buildExpression(this); | 1067 ir.Primitive expressionReceiver = buildExpression(this); |
| 1065 List<ir.Primitive> emptyArguments = new List<ir.Primitive>(); | 1068 List<ir.Primitive> emptyArguments = new List<ir.Primitive>(); |
| 1066 | 1069 |
| 1067 ir.Parameter iterator = new ir.Parameter(null); | 1070 ir.Parameter iterator = new ir.Parameter(null); |
| 1068 ir.Continuation iteratorInvoked = new ir.Continuation([iterator]); | 1071 ir.Continuation iteratorInvoked = new ir.Continuation([iterator]); |
| 1069 add(new ir.LetCont(<ir.Continuation>[iteratorInvoked], | 1072 add(new ir.LetCont(iteratorInvoked, |
| 1070 new ir.InvokeMethod(expressionReceiver, | 1073 new ir.InvokeMethod(expressionReceiver, |
| 1071 new Selector.getter("iterator", null), iteratorInvoked, | 1074 new Selector.getter("iterator", null), iteratorInvoked, |
| 1072 emptyArguments))); | 1075 emptyArguments))); |
| 1073 | 1076 |
| 1074 ir.Parameter condition = new ir.Parameter(null); | 1077 ir.Parameter condition = new ir.Parameter(null); |
| 1075 ir.Continuation moveNextInvoked = new ir.Continuation([condition]); | 1078 ir.Continuation moveNextInvoked = new ir.Continuation([condition]); |
| 1076 condBuilder.add(new ir.LetCont(<ir.Continuation>[moveNextInvoked], | 1079 condBuilder.add(new ir.LetCont(moveNextInvoked, |
| 1077 new ir.InvokeMethod(iterator, | 1080 new ir.InvokeMethod(iterator, |
| 1078 new Selector.call("moveNext", null, 0), | 1081 new Selector.call("moveNext", null, 0), |
| 1079 moveNextInvoked, emptyArguments))); | 1082 moveNextInvoked, emptyArguments))); |
| 1080 | 1083 |
| 1081 JumpCollector breakCollector = new JumpCollector(target); | 1084 JumpCollector breakCollector = new JumpCollector(target); |
| 1082 JumpCollector continueCollector = new JumpCollector(target); | 1085 JumpCollector continueCollector = new JumpCollector(target); |
| 1083 state.breakCollectors.add(breakCollector); | 1086 state.breakCollectors.add(breakCollector); |
| 1084 state.continueCollectors.add(continueCollector); | 1087 state.continueCollectors.add(continueCollector); |
| 1085 | 1088 |
| 1086 IrBuilder bodyBuilder = condBuilder.makeDelimitedBuilder(); | 1089 IrBuilder bodyBuilder = condBuilder.makeDelimitedBuilder(); |
| 1087 bodyBuilder._buildClosureScopeSetup(closureScope); | 1090 bodyBuilder._buildClosureScopeSetup(closureScope); |
| 1088 if (buildVariableDeclaration != null) { | 1091 if (buildVariableDeclaration != null) { |
| 1089 buildVariableDeclaration(bodyBuilder); | 1092 buildVariableDeclaration(bodyBuilder); |
| 1090 } | 1093 } |
| 1091 | 1094 |
| 1092 ir.Parameter currentValue = new ir.Parameter(null); | 1095 ir.Parameter currentValue = new ir.Parameter(null); |
| 1093 ir.Continuation currentInvoked = new ir.Continuation([currentValue]); | 1096 ir.Continuation currentInvoked = new ir.Continuation([currentValue]); |
| 1094 bodyBuilder.add(new ir.LetCont(<ir.Continuation>[currentInvoked], | 1097 bodyBuilder.add(new ir.LetCont(currentInvoked, |
| 1095 new ir.InvokeMethod(iterator, new Selector.getter("current", null), | 1098 new ir.InvokeMethod(iterator, new Selector.getter("current", null), |
| 1096 currentInvoked, emptyArguments))); | 1099 currentInvoked, emptyArguments))); |
| 1097 if (Elements.isLocal(variableElement)) { | 1100 if (Elements.isLocal(variableElement)) { |
| 1098 bodyBuilder.buildLocalSet(variableElement, currentValue); | 1101 bodyBuilder.buildLocalSet(variableElement, currentValue); |
| 1099 } else if (Elements.isStaticOrTopLevel(variableElement)) { | 1102 } else if (Elements.isStaticOrTopLevel(variableElement)) { |
| 1100 bodyBuilder.buildStaticSet( | 1103 bodyBuilder.buildStaticSet( |
| 1101 variableElement, variableSelector, currentValue); | 1104 variableElement, variableSelector, currentValue); |
| 1102 } else { | 1105 } else { |
| 1103 ir.Primitive receiver = bodyBuilder.buildThis(); | 1106 ir.Primitive receiver = bodyBuilder.buildThis(); |
| 1104 bodyBuilder.buildDynamicSet(receiver, variableSelector, currentValue); | 1107 bodyBuilder.buildDynamicSet(receiver, variableSelector, currentValue); |
| 1105 } | 1108 } |
| 1106 | 1109 |
| 1107 buildBody(bodyBuilder); | 1110 buildBody(bodyBuilder); |
| 1108 assert(state.breakCollectors.last == breakCollector); | 1111 assert(state.breakCollectors.last == breakCollector); |
| 1109 assert(state.continueCollectors.last == continueCollector); | 1112 assert(state.continueCollectors.last == continueCollector); |
| 1110 state.breakCollectors.removeLast(); | 1113 state.breakCollectors.removeLast(); |
| 1111 state.continueCollectors.removeLast(); | 1114 state.continueCollectors.removeLast(); |
| 1112 | 1115 |
| 1113 // Create body entry and loop exit continuations and a branch to them. | 1116 // Create body entry and loop exit continuations and a branch to them. |
| 1114 ir.Continuation bodyContinuation = new ir.Continuation([]); | 1117 ir.Continuation bodyContinuation = new ir.Continuation([]); |
| 1115 ir.Continuation exitContinuation = new ir.Continuation([]); | 1118 ir.Continuation exitContinuation = new ir.Continuation([]); |
| 1116 // Note the order of continuations: the first one is the one that will | 1119 // Note the order of continuations: the first one is the one that will |
| 1117 // be filled by LetCont.plug. | 1120 // be filled by LetCont.plug. |
| 1118 ir.LetCont branch = | 1121 ir.LetCont branch = |
| 1119 new ir.LetCont(<ir.Continuation>[exitContinuation, bodyContinuation], | 1122 new ir.LetCont.many(<ir.Continuation>[exitContinuation, |
| 1123 bodyContinuation], |
| 1120 new ir.Branch(new ir.IsTrue(condition), | 1124 new ir.Branch(new ir.IsTrue(condition), |
| 1121 bodyContinuation, | 1125 bodyContinuation, |
| 1122 exitContinuation)); | 1126 exitContinuation)); |
| 1123 // If there are breaks in the body, then there must be a join-point | 1127 // If there are breaks in the body, then there must be a join-point |
| 1124 // continuation for the normal exit and the breaks. | 1128 // continuation for the normal exit and the breaks. |
| 1125 bool hasBreaks = !breakCollector.isEmpty; | 1129 bool hasBreaks = !breakCollector.isEmpty; |
| 1126 ir.LetCont letJoin; | 1130 ir.LetCont letJoin; |
| 1127 if (hasBreaks) { | 1131 if (hasBreaks) { |
| 1128 letJoin = new ir.LetCont(null, branch); | 1132 letJoin = new ir.LetCont(null, branch); |
| 1129 condBuilder.add(letJoin); | 1133 condBuilder.add(letJoin); |
| 1130 condBuilder._current = branch; | 1134 condBuilder._current = branch; |
| 1131 } else { | 1135 } else { |
| 1132 condBuilder.add(branch); | 1136 condBuilder.add(branch); |
| 1133 } | 1137 } |
| 1134 ir.Continuation loopContinuation = | 1138 ir.Continuation loopContinuation = |
| 1135 new ir.Continuation(condBuilder._parameters); | 1139 new ir.Continuation(condBuilder._parameters); |
| 1136 if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder); | 1140 if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder); |
| 1137 invokeFullJoin( | 1141 invokeFullJoin( |
| 1138 loopContinuation, continueCollector, recursive: true); | 1142 loopContinuation, continueCollector, recursive: true); |
| 1139 bodyContinuation.body = bodyBuilder._root; | 1143 bodyContinuation.body = bodyBuilder._root; |
| 1140 | 1144 |
| 1141 loopContinuation.body = condBuilder._root; | 1145 loopContinuation.body = condBuilder._root; |
| 1142 add(new ir.LetCont(<ir.Continuation>[loopContinuation], | 1146 add(new ir.LetCont(loopContinuation, |
| 1143 new ir.InvokeContinuation(loopContinuation, | 1147 new ir.InvokeContinuation(loopContinuation, |
| 1144 environment.index2value))); | 1148 environment.index2value))); |
| 1145 if (hasBreaks) { | 1149 if (hasBreaks) { |
| 1146 _current = branch; | 1150 _current = branch; |
| 1147 environment = condBuilder.environment; | 1151 environment = condBuilder.environment; |
| 1148 breakCollector.addJump(this); | 1152 breakCollector.addJump(this); |
| 1149 letJoin.continuations = | 1153 letJoin.continuations = |
| 1150 <ir.Continuation>[createJoin(environment.length, breakCollector)]; | 1154 <ir.Continuation>[createJoin(environment.length, breakCollector)]; |
| 1151 _current = letJoin; | 1155 _current = letJoin; |
| 1152 } else { | 1156 } else { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1197 assert(state.continueCollectors.last == continueCollector); | 1201 assert(state.continueCollectors.last == continueCollector); |
| 1198 state.breakCollectors.removeLast(); | 1202 state.breakCollectors.removeLast(); |
| 1199 state.continueCollectors.removeLast(); | 1203 state.continueCollectors.removeLast(); |
| 1200 | 1204 |
| 1201 // Create body entry and loop exit continuations and a branch to them. | 1205 // Create body entry and loop exit continuations and a branch to them. |
| 1202 ir.Continuation bodyContinuation = new ir.Continuation([]); | 1206 ir.Continuation bodyContinuation = new ir.Continuation([]); |
| 1203 ir.Continuation exitContinuation = new ir.Continuation([]); | 1207 ir.Continuation exitContinuation = new ir.Continuation([]); |
| 1204 // Note the order of continuations: the first one is the one that will | 1208 // Note the order of continuations: the first one is the one that will |
| 1205 // be filled by LetCont.plug. | 1209 // be filled by LetCont.plug. |
| 1206 ir.LetCont branch = | 1210 ir.LetCont branch = |
| 1207 new ir.LetCont(<ir.Continuation>[exitContinuation, bodyContinuation], | 1211 new ir.LetCont.many(<ir.Continuation>[exitContinuation, |
| 1212 bodyContinuation], |
| 1208 new ir.Branch(new ir.IsTrue(condition), | 1213 new ir.Branch(new ir.IsTrue(condition), |
| 1209 bodyContinuation, | 1214 bodyContinuation, |
| 1210 exitContinuation)); | 1215 exitContinuation)); |
| 1211 // If there are breaks in the body, then there must be a join-point | 1216 // If there are breaks in the body, then there must be a join-point |
| 1212 // continuation for the normal exit and the breaks. | 1217 // continuation for the normal exit and the breaks. |
| 1213 bool hasBreaks = !breakCollector.isEmpty; | 1218 bool hasBreaks = !breakCollector.isEmpty; |
| 1214 ir.LetCont letJoin; | 1219 ir.LetCont letJoin; |
| 1215 if (hasBreaks) { | 1220 if (hasBreaks) { |
| 1216 letJoin = new ir.LetCont(null, branch); | 1221 letJoin = new ir.LetCont(null, branch); |
| 1217 condBuilder.add(letJoin); | 1222 condBuilder.add(letJoin); |
| 1218 condBuilder._current = branch; | 1223 condBuilder._current = branch; |
| 1219 } else { | 1224 } else { |
| 1220 condBuilder.add(branch); | 1225 condBuilder.add(branch); |
| 1221 } | 1226 } |
| 1222 ir.Continuation loopContinuation = | 1227 ir.Continuation loopContinuation = |
| 1223 new ir.Continuation(condBuilder._parameters); | 1228 new ir.Continuation(condBuilder._parameters); |
| 1224 if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder); | 1229 if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder); |
| 1225 invokeFullJoin(loopContinuation, continueCollector, recursive: true); | 1230 invokeFullJoin(loopContinuation, continueCollector, recursive: true); |
| 1226 bodyContinuation.body = bodyBuilder._root; | 1231 bodyContinuation.body = bodyBuilder._root; |
| 1227 | 1232 |
| 1228 loopContinuation.body = condBuilder._root; | 1233 loopContinuation.body = condBuilder._root; |
| 1229 add(new ir.LetCont(<ir.Continuation>[loopContinuation], | 1234 add(new ir.LetCont(loopContinuation, |
| 1230 new ir.InvokeContinuation(loopContinuation, | 1235 new ir.InvokeContinuation(loopContinuation, |
| 1231 environment.index2value))); | 1236 environment.index2value))); |
| 1232 if (hasBreaks) { | 1237 if (hasBreaks) { |
| 1233 _current = branch; | 1238 _current = branch; |
| 1234 environment = condBuilder.environment; | 1239 environment = condBuilder.environment; |
| 1235 breakCollector.addJump(this); | 1240 breakCollector.addJump(this); |
| 1236 letJoin.continuations = | 1241 letJoin.continuations = |
| 1237 <ir.Continuation>[createJoin(environment.length, breakCollector)]; | 1242 <ir.Continuation>[createJoin(environment.length, breakCollector)]; |
| 1238 _current = letJoin; | 1243 _current = letJoin; |
| 1239 } else { | 1244 } else { |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1326 } | 1331 } |
| 1327 | 1332 |
| 1328 ir.Constant trueConstant = makeBoolConstant(true); | 1333 ir.Constant trueConstant = makeBoolConstant(true); |
| 1329 ir.Constant falseConstant = makeBoolConstant(false); | 1334 ir.Constant falseConstant = makeBoolConstant(false); |
| 1330 | 1335 |
| 1331 thenContinuation.body = new ir.LetPrim(falseConstant) | 1336 thenContinuation.body = new ir.LetPrim(falseConstant) |
| 1332 ..plug(new ir.InvokeContinuation(joinContinuation, [falseConstant])); | 1337 ..plug(new ir.InvokeContinuation(joinContinuation, [falseConstant])); |
| 1333 elseContinuation.body = new ir.LetPrim(trueConstant) | 1338 elseContinuation.body = new ir.LetPrim(trueConstant) |
| 1334 ..plug(new ir.InvokeContinuation(joinContinuation, [trueConstant])); | 1339 ..plug(new ir.InvokeContinuation(joinContinuation, [trueConstant])); |
| 1335 | 1340 |
| 1336 add(new ir.LetCont(<ir.Continuation>[joinContinuation], | 1341 add(new ir.LetCont(joinContinuation, |
| 1337 new ir.LetCont(<ir.Continuation>[thenContinuation, elseContinuation], | 1342 new ir.LetCont.many(<ir.Continuation>[thenContinuation, |
| 1343 elseContinuation], |
| 1338 new ir.Branch(new ir.IsTrue(condition), | 1344 new ir.Branch(new ir.IsTrue(condition), |
| 1339 thenContinuation, | 1345 thenContinuation, |
| 1340 elseContinuation)))); | 1346 elseContinuation)))); |
| 1341 return resultParameter; | 1347 return resultParameter; |
| 1342 } | 1348 } |
| 1343 | 1349 |
| 1344 /// Creates a type test or type cast of [receiver] against [type]. | 1350 /// Creates a type test or type cast of [receiver] against [type]. |
| 1345 /// | 1351 /// |
| 1346 /// Set [isTypeTest] to `true` to create a type test and furthermore set | 1352 /// Set [isTypeTest] to `true` to create a type test and furthermore set |
| 1347 /// [isNotCheck] to `true` to create a negated type test. | 1353 /// [isNotCheck] to `true` to create a negated type test. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1409 ir.Continuation joinContinuation = | 1415 ir.Continuation joinContinuation = |
| 1410 createJoin(environment.length + 1, jumps); | 1416 createJoin(environment.length + 1, jumps); |
| 1411 ir.Continuation leftTrueContinuation = new ir.Continuation([]); | 1417 ir.Continuation leftTrueContinuation = new ir.Continuation([]); |
| 1412 ir.Continuation leftFalseContinuation = new ir.Continuation([]); | 1418 ir.Continuation leftFalseContinuation = new ir.Continuation([]); |
| 1413 ir.Continuation rightTrueContinuation = new ir.Continuation([]); | 1419 ir.Continuation rightTrueContinuation = new ir.Continuation([]); |
| 1414 ir.Continuation rightFalseContinuation = new ir.Continuation([]); | 1420 ir.Continuation rightFalseContinuation = new ir.Continuation([]); |
| 1415 rightTrueContinuation.body = rightTrueBuilder._root; | 1421 rightTrueContinuation.body = rightTrueBuilder._root; |
| 1416 rightFalseContinuation.body = rightFalseBuilder._root; | 1422 rightFalseContinuation.body = rightFalseBuilder._root; |
| 1417 // The right subexpression has two continuations. | 1423 // The right subexpression has two continuations. |
| 1418 rightBuilder.add( | 1424 rightBuilder.add( |
| 1419 new ir.LetCont(<ir.Continuation>[rightTrueContinuation, | 1425 new ir.LetCont.many(<ir.Continuation>[rightTrueContinuation, |
| 1420 rightFalseContinuation], | 1426 rightFalseContinuation], |
| 1421 new ir.Branch(new ir.IsTrue(rightValue), | 1427 new ir.Branch(new ir.IsTrue(rightValue), |
| 1422 rightTrueContinuation, | 1428 rightTrueContinuation, |
| 1423 rightFalseContinuation))); | 1429 rightFalseContinuation))); |
| 1424 // Depending on the operator, the left subexpression's continuations are | 1430 // Depending on the operator, the left subexpression's continuations are |
| 1425 // either the right subexpression or an invocation of the join-point | 1431 // either the right subexpression or an invocation of the join-point |
| 1426 // continuation. | 1432 // continuation. |
| 1427 if (isLazyOr) { | 1433 if (isLazyOr) { |
| 1428 leftTrueContinuation.body = emptyBuilder._root; | 1434 leftTrueContinuation.body = emptyBuilder._root; |
| 1429 leftFalseContinuation.body = rightBuilder._root; | 1435 leftFalseContinuation.body = rightBuilder._root; |
| 1430 } else { | 1436 } else { |
| 1431 leftTrueContinuation.body = rightBuilder._root; | 1437 leftTrueContinuation.body = rightBuilder._root; |
| 1432 leftFalseContinuation.body = emptyBuilder._root; | 1438 leftFalseContinuation.body = emptyBuilder._root; |
| 1433 } | 1439 } |
| 1434 | 1440 |
| 1435 add(new ir.LetCont(<ir.Continuation>[joinContinuation], | 1441 add(new ir.LetCont(joinContinuation, |
| 1436 new ir.LetCont(<ir.Continuation>[leftTrueContinuation, | 1442 new ir.LetCont.many(<ir.Continuation>[leftTrueContinuation, |
| 1437 leftFalseContinuation], | 1443 leftFalseContinuation], |
| 1438 new ir.Branch(new ir.IsTrue(leftValue), | 1444 new ir.Branch(new ir.IsTrue(leftValue), |
| 1439 leftTrueContinuation, | 1445 leftTrueContinuation, |
| 1440 leftFalseContinuation)))); | 1446 leftFalseContinuation)))); |
| 1441 // There is always a join parameter for the result value, because it | 1447 // There is always a join parameter for the result value, because it |
| 1442 // is different on at least two paths. | 1448 // is different on at least two paths. |
| 1443 return joinContinuation.parameters.last; | 1449 return joinContinuation.parameters.last; |
| 1444 } | 1450 } |
| 1445 | 1451 |
| 1446 /// Creates an access to the receiver from the current (or enclosing) method. | 1452 /// Creates an access to the receiver from the current (or enclosing) method. |
| 1447 /// | 1453 /// |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1887 | 1893 |
| 1888 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables); | 1894 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables); |
| 1889 } | 1895 } |
| 1890 | 1896 |
| 1891 /// Information about which variables are captured in a closure. | 1897 /// Information about which variables are captured in a closure. |
| 1892 /// This is used by the [DartIrBuilder] instead of [ClosureScope] and | 1898 /// This is used by the [DartIrBuilder] instead of [ClosureScope] and |
| 1893 /// [ClosureEnvironment]. | 1899 /// [ClosureEnvironment]. |
| 1894 abstract class ClosureVariableInfo { | 1900 abstract class ClosureVariableInfo { |
| 1895 Iterable<Local> get capturedVariables; | 1901 Iterable<Local> get capturedVariables; |
| 1896 } | 1902 } |
| OLD | NEW |