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

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

Issue 1779153002: Make source information on conditions mandatory in CPS (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
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 '../closure.dart' as closure; 7 import '../closure.dart' as closure;
8 import '../common.dart'; 8 import '../common.dart';
9 import '../common/names.dart' show 9 import '../common/names.dart' show
10 Names, 10 Names,
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 return addPrimitive(new ir.LiteralList(type, values.toList(), 794 return addPrimitive(new ir.LiteralList(type, values.toList(),
795 allocationSiteType: allocationSiteType)); 795 allocationSiteType: allocationSiteType));
796 } 796 }
797 797
798 /// Creates a conditional expression with the provided [condition] where the 798 /// Creates a conditional expression with the provided [condition] where the
799 /// then and else expression are created through the [buildThenExpression] 799 /// then and else expression are created through the [buildThenExpression]
800 /// and [buildElseExpression] functions, respectively. 800 /// and [buildElseExpression] functions, respectively.
801 ir.Primitive buildConditional( 801 ir.Primitive buildConditional(
802 ir.Primitive condition, 802 ir.Primitive condition,
803 ir.Primitive buildThenExpression(IrBuilder builder), 803 ir.Primitive buildThenExpression(IrBuilder builder),
804 ir.Primitive buildElseExpression(IrBuilder builder)) { 804 ir.Primitive buildElseExpression(IrBuilder builder),
805 SourceInformation sourceInformation) {
805 assert(isOpen); 806 assert(isOpen);
806 807
807 // The then and else expressions are delimited. 808 // The then and else expressions are delimited.
808 IrBuilder thenBuilder = makeDelimitedBuilder(); 809 IrBuilder thenBuilder = makeDelimitedBuilder();
809 IrBuilder elseBuilder = makeDelimitedBuilder(); 810 IrBuilder elseBuilder = makeDelimitedBuilder();
810 ir.Primitive thenValue = buildThenExpression(thenBuilder); 811 ir.Primitive thenValue = buildThenExpression(thenBuilder);
811 ir.Primitive elseValue = buildElseExpression(elseBuilder); 812 ir.Primitive elseValue = buildElseExpression(elseBuilder);
812 813
813 // Treat the values of the subexpressions as named values in the 814 // Treat the values of the subexpressions as named values in the
814 // environment, so they will be treated as arguments to the join-point 815 // environment, so they will be treated as arguments to the join-point
(...skipping 13 matching lines...) Expand all
828 // in 829 // in
829 // if condition (then, else) 830 // if condition (then, else)
830 ir.Continuation thenContinuation = new ir.Continuation([]); 831 ir.Continuation thenContinuation = new ir.Continuation([]);
831 ir.Continuation elseContinuation = new ir.Continuation([]); 832 ir.Continuation elseContinuation = new ir.Continuation([]);
832 thenContinuation.body = thenBuilder.root; 833 thenContinuation.body = thenBuilder.root;
833 elseContinuation.body = elseBuilder.root; 834 elseContinuation.body = elseBuilder.root;
834 add(new ir.LetCont(join.continuation, 835 add(new ir.LetCont(join.continuation,
835 new ir.LetCont.two(thenContinuation, elseContinuation, 836 new ir.LetCont.two(thenContinuation, elseContinuation,
836 new ir.Branch.strict(condition, 837 new ir.Branch.strict(condition,
837 thenContinuation, 838 thenContinuation,
838 elseContinuation)))); 839 elseContinuation,
840 sourceInformation))));
839 environment = join.environment; 841 environment = join.environment;
840 return environment.discard(1); 842 return environment.discard(1);
841 } 843 }
842 844
843 /** 845 /**
844 * Add an explicit `return null` for functions that don't have a return 846 * Add an explicit `return null` for functions that don't have a return
845 * statement on each branch. This includes functions with an empty body, 847 * statement on each branch. This includes functions with an empty body,
846 * such as `foo(){ }`. 848 * such as `foo(){ }`.
847 */ 849 */
848 void _ensureReturn() { 850 void _ensureReturn() {
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 1097
1096 /// Creates an if-then-else statement with the provided [condition] where the 1098 /// Creates an if-then-else statement with the provided [condition] where the
1097 /// then and else branches are created through the [buildThenPart] and 1099 /// then and else branches are created through the [buildThenPart] and
1098 /// [buildElsePart] functions, respectively. 1100 /// [buildElsePart] functions, respectively.
1099 /// 1101 ///
1100 /// An if-then statement is created if [buildElsePart] is a no-op. 1102 /// An if-then statement is created if [buildElsePart] is a no-op.
1101 // TODO(johnniwinther): Unify implementation with [buildConditional] and 1103 // TODO(johnniwinther): Unify implementation with [buildConditional] and
1102 // [_buildLogicalOperator]. 1104 // [_buildLogicalOperator].
1103 void buildIf(ir.Primitive condition, 1105 void buildIf(ir.Primitive condition,
1104 void buildThenPart(IrBuilder builder), 1106 void buildThenPart(IrBuilder builder),
1105 void buildElsePart(IrBuilder builder)) { 1107 void buildElsePart(IrBuilder builder),
1108 SourceInformation sourceInformation) {
1106 assert(isOpen); 1109 assert(isOpen);
1107 1110
1108 // The then and else parts are delimited. 1111 // The then and else parts are delimited.
1109 IrBuilder thenBuilder = makeDelimitedBuilder(); 1112 IrBuilder thenBuilder = makeDelimitedBuilder();
1110 IrBuilder elseBuilder = makeDelimitedBuilder(); 1113 IrBuilder elseBuilder = makeDelimitedBuilder();
1111 buildThenPart(thenBuilder); 1114 buildThenPart(thenBuilder);
1112 buildElsePart(elseBuilder); 1115 buildElsePart(elseBuilder);
1113 1116
1114 // Build the term 1117 // Build the term
1115 // (Result =) let cont then() = [[thenPart]] 1118 // (Result =) let cont then() = [[thenPart]]
1116 // and else() = [[elsePart]] 1119 // and else() = [[elsePart]]
1117 // in 1120 // in
1118 // if condition (then, else) 1121 // if condition (then, else)
1119 ir.Continuation thenContinuation = new ir.Continuation([]); 1122 ir.Continuation thenContinuation = new ir.Continuation([]);
1120 ir.Continuation elseContinuation = new ir.Continuation([]); 1123 ir.Continuation elseContinuation = new ir.Continuation([]);
1121 // If exactly one of the then and else continuation bodies is open (i.e., 1124 // If exactly one of the then and else continuation bodies is open (i.e.,
1122 // the other one has an exit on all paths), then Continuation.plug expects 1125 // the other one has an exit on all paths), then Continuation.plug expects
1123 // that continuation to be listed first. Arbitrarily use [then, else] 1126 // that continuation to be listed first. Arbitrarily use [then, else]
1124 // order otherwise. 1127 // order otherwise.
1125 List<ir.Continuation> arms = !thenBuilder.isOpen && elseBuilder.isOpen 1128 List<ir.Continuation> arms = !thenBuilder.isOpen && elseBuilder.isOpen
1126 ? <ir.Continuation>[elseContinuation, thenContinuation] 1129 ? <ir.Continuation>[elseContinuation, thenContinuation]
1127 : <ir.Continuation>[thenContinuation, elseContinuation]; 1130 : <ir.Continuation>[thenContinuation, elseContinuation];
1128 1131
1129 ir.Expression result = 1132 ir.Expression result =
1130 new ir.LetCont.many(arms, 1133 new ir.LetCont.many(arms,
1131 new ir.Branch.strict(condition, 1134 new ir.Branch.strict(condition,
1132 thenContinuation, 1135 thenContinuation,
1133 elseContinuation)); 1136 elseContinuation,
1137 sourceInformation));
1134 1138
1135 JumpCollector join; // Null if there is no join. 1139 JumpCollector join; // Null if there is no join.
1136 if (thenBuilder.isOpen && elseBuilder.isOpen) { 1140 if (thenBuilder.isOpen && elseBuilder.isOpen) {
1137 // There is a join-point continuation. Build the term 1141 // There is a join-point continuation. Build the term
1138 // 'let cont join(x, ...) = [] in Result' and plug invocations of the 1142 // 'let cont join(x, ...) = [] in Result' and plug invocations of the
1139 // join-point continuation into the then and else continuations. 1143 // join-point continuation into the then and else continuations.
1140 join = new ForwardJumpCollector(environment); 1144 join = new ForwardJumpCollector(environment);
1141 thenBuilder.jumpTo(join); 1145 thenBuilder.jumpTo(join);
1142 elseBuilder.jumpTo(join); 1146 elseBuilder.jumpTo(join);
1143 result = new ir.LetCont(join.continuation, result); 1147 result = new ir.LetCont(join.continuation, result);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 /// statements that have this `for` statement as their target. 1195 /// statements that have this `for` statement as their target.
1192 /// 1196 ///
1193 /// The [closureScope] identifies variables that should be boxed in this loop. 1197 /// The [closureScope] identifies variables that should be boxed in this loop.
1194 /// This includes variables declared inside the body of the loop as well as 1198 /// This includes variables declared inside the body of the loop as well as
1195 /// in the for-loop initializer. 1199 /// in the for-loop initializer.
1196 /// 1200 ///
1197 /// [loopVariables] is the list of variables declared in the for-loop 1201 /// [loopVariables] is the list of variables declared in the for-loop
1198 /// initializer. 1202 /// initializer.
1199 void buildFor({SubbuildFunction buildInitializer, 1203 void buildFor({SubbuildFunction buildInitializer,
1200 SubbuildFunction buildCondition, 1204 SubbuildFunction buildCondition,
1205 SourceInformation conditionSourceInformation,
1201 SubbuildFunction buildBody, 1206 SubbuildFunction buildBody,
1202 SubbuildFunction buildUpdate, 1207 SubbuildFunction buildUpdate,
1203 JumpTarget target, 1208 JumpTarget target,
1204 ClosureScope closureScope, 1209 ClosureScope closureScope,
1205 List<LocalElement> loopVariables}) { 1210 List<LocalElement> loopVariables}) {
1206 assert(isOpen); 1211 assert(isOpen);
1207 1212
1208 // For loops use four named continuations: the entry to the condition, 1213 // For loops use four named continuations: the entry to the condition,
1209 // the entry to the body, the loop exit, and the loop successor (break). 1214 // the entry to the body, the loop exit, and the loop successor (break).
1210 // The CPS translation of 1215 // The CPS translation of
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1295 // Create loop exit and body entry continuations and a branch to them. 1300 // Create loop exit and body entry continuations and a branch to them.
1296 ir.Continuation exitContinuation = new ir.Continuation([]); 1301 ir.Continuation exitContinuation = new ir.Continuation([]);
1297 ir.Continuation bodyContinuation = new ir.Continuation([]); 1302 ir.Continuation bodyContinuation = new ir.Continuation([]);
1298 bodyContinuation.body = outerBodyBuilder.root; 1303 bodyContinuation.body = outerBodyBuilder.root;
1299 // Note the order of continuations: the first one is the one that will 1304 // Note the order of continuations: the first one is the one that will
1300 // be filled by LetCont.plug. 1305 // be filled by LetCont.plug.
1301 ir.LetCont branch = 1306 ir.LetCont branch =
1302 new ir.LetCont.two(exitContinuation, bodyContinuation, 1307 new ir.LetCont.two(exitContinuation, bodyContinuation,
1303 new ir.Branch.strict(condition, 1308 new ir.Branch.strict(condition,
1304 bodyContinuation, 1309 bodyContinuation,
1305 exitContinuation)); 1310 exitContinuation,
1311 conditionSourceInformation));
1306 // If there are breaks in the body, then there must be a join-point 1312 // If there are breaks in the body, then there must be a join-point
1307 // continuation for the normal exit and the breaks. Otherwise, the 1313 // continuation for the normal exit and the breaks. Otherwise, the
1308 // successor is translated in the hole in the exit continuation. 1314 // successor is translated in the hole in the exit continuation.
1309 bool hasBreaks = !breakCollector.isEmpty; 1315 bool hasBreaks = !breakCollector.isEmpty;
1310 ir.LetCont letBreak; 1316 ir.LetCont letBreak;
1311 if (hasBreaks) { 1317 if (hasBreaks) {
1312 IrBuilder exitBuilder = makeDelimitedBuilder(); 1318 IrBuilder exitBuilder = makeDelimitedBuilder();
1313 exitBuilder.jumpTo(breakCollector); 1319 exitBuilder.jumpTo(breakCollector);
1314 exitContinuation.body = exitBuilder.root; 1320 exitContinuation.body = exitBuilder.root;
1315 letBreak = new ir.LetCont(breakCollector.continuation, branch); 1321 letBreak = new ir.LetCont(breakCollector.continuation, branch);
(...skipping 27 matching lines...) Expand all
1343 TypeMask variableMask, 1349 TypeMask variableMask,
1344 SourceInformation variableSetSourceInformation, 1350 SourceInformation variableSetSourceInformation,
1345 TypeMask currentMask, 1351 TypeMask currentMask,
1346 SourceInformation currentSourceInformation, 1352 SourceInformation currentSourceInformation,
1347 TypeMask iteratorMask, 1353 TypeMask iteratorMask,
1348 SourceInformation iteratorSourceInformation, 1354 SourceInformation iteratorSourceInformation,
1349 TypeMask moveNextMask, 1355 TypeMask moveNextMask,
1350 SourceInformation moveNextSourceInformation, 1356 SourceInformation moveNextSourceInformation,
1351 SubbuildFunction buildBody, 1357 SubbuildFunction buildBody,
1352 JumpTarget target, 1358 JumpTarget target,
1353 ClosureScope closureScope}) { 1359 ClosureScope closureScope,
1360 SourceInformation conditionSourceInformation}) {
1354 // The for-in loop 1361 // The for-in loop
1355 // 1362 //
1356 // for (a in e) s; 1363 // for (a in e) s;
1357 // 1364 //
1358 // Is compiled analogously to: 1365 // Is compiled analogously to:
1359 // 1366 //
1360 // it = e.iterator; 1367 // it = e.iterator;
1361 // while (it.moveNext()) { 1368 // while (it.moveNext()) {
1362 // var a = it.current; 1369 // var a = it.current;
1363 // s; 1370 // s;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1467 // in branch condition (body, exit) 1474 // in branch condition (body, exit)
1468 ir.Continuation exitContinuation = new ir.Continuation([]); 1475 ir.Continuation exitContinuation = new ir.Continuation([]);
1469 ir.Continuation bodyContinuation = new ir.Continuation([]); 1476 ir.Continuation bodyContinuation = new ir.Continuation([]);
1470 bodyContinuation.body = bodyBuilder.root; 1477 bodyContinuation.body = bodyBuilder.root;
1471 // Note the order of continuations: the first one is the one that will 1478 // Note the order of continuations: the first one is the one that will
1472 // be filled by LetCont.plug. 1479 // be filled by LetCont.plug.
1473 ir.LetCont branch = 1480 ir.LetCont branch =
1474 new ir.LetCont.two(exitContinuation, bodyContinuation, 1481 new ir.LetCont.two(exitContinuation, bodyContinuation,
1475 new ir.Branch.strict(condition, 1482 new ir.Branch.strict(condition,
1476 bodyContinuation, 1483 bodyContinuation,
1477 exitContinuation)); 1484 exitContinuation,
1485 conditionSourceInformation));
1478 // If there are breaks in the body, then there must be a join-point 1486 // If there are breaks in the body, then there must be a join-point
1479 // continuation for the normal exit and the breaks. Otherwise, the 1487 // continuation for the normal exit and the breaks. Otherwise, the
1480 // successor is translated in the hole in the exit continuation. 1488 // successor is translated in the hole in the exit continuation.
1481 bool hasBreaks = !breakCollector.isEmpty; 1489 bool hasBreaks = !breakCollector.isEmpty;
1482 ir.LetCont letBreak; 1490 ir.LetCont letBreak;
1483 if (hasBreaks) { 1491 if (hasBreaks) {
1484 IrBuilder exitBuilder = makeDelimitedBuilder(); 1492 IrBuilder exitBuilder = makeDelimitedBuilder();
1485 exitBuilder.jumpTo(breakCollector); 1493 exitBuilder.jumpTo(breakCollector);
1486 exitContinuation.body = exitBuilder.root; 1494 exitContinuation.body = exitBuilder.root;
1487 letBreak = new ir.LetCont(breakCollector.continuation, branch); 1495 letBreak = new ir.LetCont(breakCollector.continuation, branch);
1488 add(letBreak); 1496 add(letBreak);
1489 environment = breakCollector.environment; 1497 environment = breakCollector.environment;
1490 } else { 1498 } else {
1491 add(branch); 1499 add(branch);
1492 } 1500 }
1493 } 1501 }
1494 1502
1495 /// Creates a while loop in which the condition and body are created by 1503 /// Creates a while loop in which the condition and body are created by
1496 /// [buildCondition] and [buildBody], respectively. 1504 /// [buildCondition] and [buildBody], respectively.
1497 /// 1505 ///
1498 /// The jump [target] is used to identify which `break` and `continue` 1506 /// The jump [target] is used to identify which `break` and `continue`
1499 /// statements that have this `while` statement as their target. 1507 /// statements that have this `while` statement as their target.
1500 void buildWhile({SubbuildFunction buildCondition, 1508 void buildWhile({SubbuildFunction buildCondition,
1501 SubbuildFunction buildBody, 1509 SubbuildFunction buildBody,
1502 JumpTarget target, 1510 JumpTarget target,
1503 ClosureScope closureScope}) { 1511 ClosureScope closureScope,
1512 SourceInformation sourceInformation}) {
1504 assert(isOpen); 1513 assert(isOpen);
1505 // While loops use four named continuations: the entry to the body, the 1514 // While loops use four named continuations: the entry to the body, the
1506 // loop exit, the loop back edge (continue), and the loop exit (break). 1515 // loop exit, the loop back edge (continue), and the loop exit (break).
1507 // The CPS translation of [[while (condition) body; successor]] is: 1516 // The CPS translation of [[while (condition) body; successor]] is:
1508 // 1517 //
1509 // let cont continue(x, ...) = 1518 // let cont continue(x, ...) =
1510 // let prim cond = [[condition]] in 1519 // let prim cond = [[condition]] in
1511 // let cont break(x, ...) = [[successor]] in 1520 // let cont break(x, ...) = [[successor]] in
1512 // let cont exit() = break(v, ...) 1521 // let cont exit() = break(v, ...)
1513 // and body() = 1522 // and body() =
(...skipping 28 matching lines...) Expand all
1542 // Create body entry and loop exit continuations and a branch to them. 1551 // Create body entry and loop exit continuations and a branch to them.
1543 ir.Continuation exitContinuation = new ir.Continuation([]); 1552 ir.Continuation exitContinuation = new ir.Continuation([]);
1544 ir.Continuation bodyContinuation = new ir.Continuation([]); 1553 ir.Continuation bodyContinuation = new ir.Continuation([]);
1545 bodyContinuation.body = bodyBuilder.root; 1554 bodyContinuation.body = bodyBuilder.root;
1546 // Note the order of continuations: the first one is the one that will 1555 // Note the order of continuations: the first one is the one that will
1547 // be filled by LetCont.plug. 1556 // be filled by LetCont.plug.
1548 ir.LetCont branch = 1557 ir.LetCont branch =
1549 new ir.LetCont.two(exitContinuation, bodyContinuation, 1558 new ir.LetCont.two(exitContinuation, bodyContinuation,
1550 new ir.Branch.strict(condition, 1559 new ir.Branch.strict(condition,
1551 bodyContinuation, 1560 bodyContinuation,
1552 exitContinuation)); 1561 exitContinuation,
1562 sourceInformation));
1553 // If there are breaks in the body, then there must be a join-point 1563 // If there are breaks in the body, then there must be a join-point
1554 // continuation for the normal exit and the breaks. Otherwise, the 1564 // continuation for the normal exit and the breaks. Otherwise, the
1555 // successor is translated in the hole in the exit continuation. 1565 // successor is translated in the hole in the exit continuation.
1556 bool hasBreaks = !breakCollector.isEmpty; 1566 bool hasBreaks = !breakCollector.isEmpty;
1557 ir.LetCont letBreak; 1567 ir.LetCont letBreak;
1558 if (hasBreaks) { 1568 if (hasBreaks) {
1559 IrBuilder exitBuilder = makeDelimitedBuilder(); 1569 IrBuilder exitBuilder = makeDelimitedBuilder();
1560 exitBuilder.jumpTo(breakCollector); 1570 exitBuilder.jumpTo(breakCollector);
1561 exitContinuation.body = exitBuilder.root; 1571 exitContinuation.body = exitBuilder.root;
1562 letBreak = new ir.LetCont(breakCollector.continuation, branch); 1572 letBreak = new ir.LetCont(breakCollector.continuation, branch);
1563 add(letBreak); 1573 add(letBreak);
1564 environment = breakCollector.environment; 1574 environment = breakCollector.environment;
1565 } else { 1575 } else {
1566 add(branch); 1576 add(branch);
1567 } 1577 }
1568 } 1578 }
1569 1579
1570 1580
1571 /// Creates a do-while loop. 1581 /// Creates a do-while loop.
1572 /// 1582 ///
1573 /// The body and condition are created by [buildBody] and [buildCondition]. 1583 /// The body and condition are created by [buildBody] and [buildCondition].
1574 /// The jump target [target] is the target of `break` and `continue` 1584 /// The jump target [target] is the target of `break` and `continue`
1575 /// statements in the body that have the loop as their target. 1585 /// statements in the body that have the loop as their target.
1576 /// [closureScope] contains all the variables declared in the loop (but not 1586 /// [closureScope] contains all the variables declared in the loop (but not
1577 /// declared in some inner closure scope). 1587 /// declared in some inner closure scope).
1578 void buildDoWhile({SubbuildFunction buildBody, 1588 void buildDoWhile({SubbuildFunction buildBody,
1579 SubbuildFunction buildCondition, 1589 SubbuildFunction buildCondition,
1580 JumpTarget target, 1590 JumpTarget target,
1581 ClosureScope closureScope}) { 1591 ClosureScope closureScope,
1592 SourceInformation sourceInformation}) {
1582 assert(isOpen); 1593 assert(isOpen);
1583 // The CPS translation of [[do body; while (condition); successor]] is: 1594 // The CPS translation of [[do body; while (condition); successor]] is:
1584 // 1595 //
1585 // let cont break(x, ...) = [[successor]] in 1596 // let cont break(x, ...) = [[successor]] in
1586 // let cont rec loop(x, ...) = 1597 // let cont rec loop(x, ...) =
1587 // let cont continue(x, ...) = 1598 // let cont continue(x, ...) =
1588 // let prim cond = [[condition]] in 1599 // let prim cond = [[condition]] in
1589 // let cont exit() = break(v, ...) 1600 // let cont exit() = break(v, ...)
1590 // and repeat() = loop(v, ...) 1601 // and repeat() = loop(v, ...)
1591 // in branch cond (repeat, exit) 1602 // in branch cond (repeat, exit)
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1628 exitContinuation.body = exitBuilder.root; 1639 exitContinuation.body = exitBuilder.root;
1629 ir.Continuation repeatContinuation = new ir.Continuation([]); 1640 ir.Continuation repeatContinuation = new ir.Continuation([]);
1630 IrBuilder repeatBuilder = continueBuilder.makeDelimitedBuilder(); 1641 IrBuilder repeatBuilder = continueBuilder.makeDelimitedBuilder();
1631 repeatBuilder.jumpTo(loop); 1642 repeatBuilder.jumpTo(loop);
1632 repeatContinuation.body = repeatBuilder.root; 1643 repeatContinuation.body = repeatBuilder.root;
1633 1644
1634 continueBuilder.add( 1645 continueBuilder.add(
1635 new ir.LetCont.two(exitContinuation, repeatContinuation, 1646 new ir.LetCont.two(exitContinuation, repeatContinuation,
1636 new ir.Branch.strict(condition, 1647 new ir.Branch.strict(condition,
1637 repeatContinuation, 1648 repeatContinuation,
1638 exitContinuation))); 1649 exitContinuation,
1650 sourceInformation)));
1639 continueCollector.continuation.body = continueBuilder.root; 1651 continueCollector.continuation.body = continueBuilder.root;
1640 1652
1641 // Construct the loop continuation (i.e., the body and condition). 1653 // Construct the loop continuation (i.e., the body and condition).
1642 // <Loop> = 1654 // <Loop> =
1643 // let cont continue(x, ...) = 1655 // let cont continue(x, ...) =
1644 // <Continue> 1656 // <Continue>
1645 // in [[body]]; continue(v, ...) 1657 // in [[body]]; continue(v, ...)
1646 loopBuilder.add( 1658 loopBuilder.add(
1647 new ir.LetCont(continueCollector.continuation, 1659 new ir.LetCont(continueCollector.continuation,
1648 bodyBuilder.root)); 1660 bodyBuilder.root));
(...skipping 14 matching lines...) Expand all
1663 ir.Continuation thenContinuation = new ir.Continuation([]); 1675 ir.Continuation thenContinuation = new ir.Continuation([]);
1664 thenContinuation.body = thenBuilder.root; 1676 thenContinuation.body = thenBuilder.root;
1665 ir.Continuation elseContinuation = new ir.Continuation([]); 1677 ir.Continuation elseContinuation = new ir.Continuation([]);
1666 // A LetCont.two term has a hole as the body of the first listed 1678 // A LetCont.two term has a hole as the body of the first listed
1667 // continuation, to be plugged by the translation. Therefore put the 1679 // continuation, to be plugged by the translation. Therefore put the
1668 // else continuation first. 1680 // else continuation first.
1669 casesBuilder.add( 1681 casesBuilder.add(
1670 new ir.LetCont.two(elseContinuation, thenContinuation, 1682 new ir.LetCont.two(elseContinuation, thenContinuation,
1671 new ir.Branch.strict(condition, 1683 new ir.Branch.strict(condition,
1672 thenContinuation, 1684 thenContinuation,
1673 elseContinuation))); 1685 elseContinuation,
1686 caseInfo.sourceInformation)));
1674 } 1687 }
1675 1688
1676 if (buildDefaultBody == null) { 1689 if (buildDefaultBody == null) {
1677 casesBuilder.jumpTo(join); 1690 casesBuilder.jumpTo(join);
1678 } else { 1691 } else {
1679 buildDefaultBody(casesBuilder); 1692 buildDefaultBody(casesBuilder);
1680 } 1693 }
1681 1694
1682 if (!join.isEmpty) { 1695 if (!join.isEmpty) {
1683 add(new ir.LetCont(join.continuation, casesBuilder.root)); 1696 add(new ir.LetCont(join.continuation, casesBuilder.root));
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
1872 // it. 1885 // it.
1873 IrBuilder checkBuilder = builder.makeDelimitedBuilder(environment); 1886 IrBuilder checkBuilder = builder.makeDelimitedBuilder(environment);
1874 ir.Primitive typeMatches = 1887 ir.Primitive typeMatches =
1875 checkBuilder.buildTypeOperator(exceptionParameter, 1888 checkBuilder.buildTypeOperator(exceptionParameter,
1876 clause.type, 1889 clause.type,
1877 clause.sourceInformation, 1890 clause.sourceInformation,
1878 isTypeTest: true); 1891 isTypeTest: true);
1879 checkBuilder.add(new ir.LetCont.two(thenContinuation, elseContinuation, 1892 checkBuilder.add(new ir.LetCont.two(thenContinuation, elseContinuation,
1880 new ir.Branch.strict(typeMatches, 1893 new ir.Branch.strict(typeMatches,
1881 thenContinuation, 1894 thenContinuation,
1882 elseContinuation))); 1895 elseContinuation,
1896 clause.sourceInformation)));
1883 catchBody = checkBuilder.root; 1897 catchBody = checkBuilder.root;
1884 } 1898 }
1885 builder.add(catchBody); 1899 builder.add(catchBody);
1886 1900
1887 return <ir.Parameter>[exceptionParameter, traceParameter]; 1901 return <ir.Parameter>[exceptionParameter, traceParameter];
1888 } 1902 }
1889 1903
1890 void leaveTryCatch(IrBuilder builder, JumpCollector join, 1904 void leaveTryCatch(IrBuilder builder, JumpCollector join,
1891 ir.Expression body) { 1905 ir.Expression body) {
1892 // Add the binding for the join-point continuation and continue the 1906 // Add the binding for the join-point continuation and continue the
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
2269 return param; 2283 return param;
2270 } 2284 }
2271 2285
2272 void buildRethrow() { 2286 void buildRethrow() {
2273 assert(isOpen); 2287 assert(isOpen);
2274 add(new ir.Rethrow()); 2288 add(new ir.Rethrow());
2275 _current = null; 2289 _current = null;
2276 } 2290 }
2277 2291
2278 /// Create a negation of [condition]. 2292 /// Create a negation of [condition].
2279 ir.Primitive buildNegation(ir.Primitive condition) { 2293 ir.Primitive buildNegation(
2294 ir.Primitive condition,
2295 SourceInformation sourceInformation) {
2280 // ! e is translated as e ? false : true 2296 // ! e is translated as e ? false : true
2281 2297
2282 // Add a continuation parameter for the result of the expression. 2298 // Add a continuation parameter for the result of the expression.
2283 ir.Parameter resultParameter = new ir.Parameter(null); 2299 ir.Parameter resultParameter = new ir.Parameter(null);
2284 2300
2285 ir.Continuation joinContinuation = new ir.Continuation([resultParameter]); 2301 ir.Continuation joinContinuation = new ir.Continuation([resultParameter]);
2286 ir.Continuation thenContinuation = new ir.Continuation([]); 2302 ir.Continuation thenContinuation = new ir.Continuation([]);
2287 ir.Continuation elseContinuation = new ir.Continuation([]); 2303 ir.Continuation elseContinuation = new ir.Continuation([]);
2288 2304
2289 ir.Constant makeBoolConstant(bool value) { 2305 ir.Constant makeBoolConstant(bool value) {
2290 return new ir.Constant(state.constantSystem.createBool(value)); 2306 return new ir.Constant(state.constantSystem.createBool(value));
2291 } 2307 }
2292 2308
2293 ir.Constant trueConstant = makeBoolConstant(true); 2309 ir.Constant trueConstant = makeBoolConstant(true);
2294 ir.Constant falseConstant = makeBoolConstant(false); 2310 ir.Constant falseConstant = makeBoolConstant(false);
2295 2311
2296 thenContinuation.body = new ir.LetPrim(falseConstant) 2312 thenContinuation.body = new ir.LetPrim(falseConstant)
2297 ..plug(new ir.InvokeContinuation(joinContinuation, [falseConstant])); 2313 ..plug(new ir.InvokeContinuation(joinContinuation, [falseConstant]));
2298 elseContinuation.body = new ir.LetPrim(trueConstant) 2314 elseContinuation.body = new ir.LetPrim(trueConstant)
2299 ..plug(new ir.InvokeContinuation(joinContinuation, [trueConstant])); 2315 ..plug(new ir.InvokeContinuation(joinContinuation, [trueConstant]));
2300 2316
2301 add(new ir.LetCont(joinContinuation, 2317 add(new ir.LetCont(joinContinuation,
2302 new ir.LetCont.two(thenContinuation, elseContinuation, 2318 new ir.LetCont.two(thenContinuation, elseContinuation,
2303 new ir.Branch.strict(condition, 2319 new ir.Branch.strict(condition,
2304 thenContinuation, 2320 thenContinuation,
2305 elseContinuation)))); 2321 elseContinuation,
2322 sourceInformation))));
2306 return resultParameter; 2323 return resultParameter;
2307 } 2324 }
2308 2325
2309 /// Create a lazy and/or expression. [leftValue] is the value of the left 2326 /// Create a lazy and/or expression. [leftValue] is the value of the left
2310 /// operand and [buildRightValue] is called to process the value of the right 2327 /// operand and [buildRightValue] is called to process the value of the right
2311 /// operand in the context of its own [IrBuilder]. 2328 /// operand in the context of its own [IrBuilder].
2312 ir.Primitive buildLogicalOperator( 2329 ir.Primitive buildLogicalOperator(
2313 ir.Primitive leftValue, 2330 ir.Primitive leftValue,
2314 ir.Primitive buildRightValue(IrBuilder builder), 2331 ir.Primitive buildRightValue(IrBuilder builder),
2332 SourceInformation sourceInformation,
2315 {bool isLazyOr: false}) { 2333 {bool isLazyOr: false}) {
2316 // e0 && e1 is translated as if e0 ? (e1 == true) : false. 2334 // e0 && e1 is translated as if e0 ? (e1 == true) : false.
2317 // e0 || e1 is translated as if e0 ? true : (e1 == true). 2335 // e0 || e1 is translated as if e0 ? true : (e1 == true).
2318 // The translation must convert both e0 and e1 to booleans and handle 2336 // The translation must convert both e0 and e1 to booleans and handle
2319 // local variable assignments in e1. 2337 // local variable assignments in e1.
2320 IrBuilder rightBuilder = makeDelimitedBuilder(); 2338 IrBuilder rightBuilder = makeDelimitedBuilder();
2321 ir.Primitive rightValue = buildRightValue(rightBuilder); 2339 ir.Primitive rightValue = buildRightValue(rightBuilder);
2322 // A dummy empty target for the branch on the left subexpression branch. 2340 // A dummy empty target for the branch on the left subexpression branch.
2323 // This enables using the same infrastructure for join-point continuations 2341 // This enables using the same infrastructure for join-point continuations
2324 // as in visitIf and visitConditional. It will hold a definition of the 2342 // as in visitIf and visitConditional. It will hold a definition of the
(...skipping 30 matching lines...) Expand all
2355 ir.Continuation leftFalseContinuation = new ir.Continuation([]); 2373 ir.Continuation leftFalseContinuation = new ir.Continuation([]);
2356 ir.Continuation rightTrueContinuation = new ir.Continuation([]); 2374 ir.Continuation rightTrueContinuation = new ir.Continuation([]);
2357 ir.Continuation rightFalseContinuation = new ir.Continuation([]); 2375 ir.Continuation rightFalseContinuation = new ir.Continuation([]);
2358 rightTrueContinuation.body = rightTrueBuilder.root; 2376 rightTrueContinuation.body = rightTrueBuilder.root;
2359 rightFalseContinuation.body = rightFalseBuilder.root; 2377 rightFalseContinuation.body = rightFalseBuilder.root;
2360 // The right subexpression has two continuations. 2378 // The right subexpression has two continuations.
2361 rightBuilder.add( 2379 rightBuilder.add(
2362 new ir.LetCont.two(rightTrueContinuation, rightFalseContinuation, 2380 new ir.LetCont.two(rightTrueContinuation, rightFalseContinuation,
2363 new ir.Branch.strict(rightValue, 2381 new ir.Branch.strict(rightValue,
2364 rightTrueContinuation, 2382 rightTrueContinuation,
2365 rightFalseContinuation))); 2383 rightFalseContinuation,
2384 sourceInformation)));
2366 // Depending on the operator, the left subexpression's continuations are 2385 // Depending on the operator, the left subexpression's continuations are
2367 // either the right subexpression or an invocation of the join-point 2386 // either the right subexpression or an invocation of the join-point
2368 // continuation. 2387 // continuation.
2369 if (isLazyOr) { 2388 if (isLazyOr) {
2370 leftTrueContinuation.body = emptyBuilder.root; 2389 leftTrueContinuation.body = emptyBuilder.root;
2371 leftFalseContinuation.body = rightBuilder.root; 2390 leftFalseContinuation.body = rightBuilder.root;
2372 } else { 2391 } else {
2373 leftTrueContinuation.body = rightBuilder.root; 2392 leftTrueContinuation.body = rightBuilder.root;
2374 leftFalseContinuation.body = emptyBuilder.root; 2393 leftFalseContinuation.body = emptyBuilder.root;
2375 } 2394 }
2376 2395
2377 add(new ir.LetCont(join.continuation, 2396 add(new ir.LetCont(join.continuation,
2378 new ir.LetCont.two(leftTrueContinuation, leftFalseContinuation, 2397 new ir.LetCont.two(leftTrueContinuation, leftFalseContinuation,
2379 new ir.Branch.strict(leftValue, 2398 new ir.Branch.strict(leftValue,
2380 leftTrueContinuation, 2399 leftTrueContinuation,
2381 leftFalseContinuation)))); 2400 leftFalseContinuation,
2401 sourceInformation))));
2382 environment = join.environment; 2402 environment = join.environment;
2383 return environment.discard(1); 2403 return environment.discard(1);
2384 } 2404 }
2385 2405
2386 ir.Primitive buildIdentical(ir.Primitive x, ir.Primitive y, 2406 ir.Primitive buildIdentical(ir.Primitive x, ir.Primitive y,
2387 {SourceInformation sourceInformation}) { 2407 {SourceInformation sourceInformation}) {
2388 return addPrimitive(new ir.ApplyBuiltinOperator( 2408 return addPrimitive(new ir.ApplyBuiltinOperator(
2389 ir.BuiltinOperator.Identical, <ir.Primitive>[x, y], 2409 ir.BuiltinOperator.Identical, <ir.Primitive>[x, y],
2390 sourceInformation)); 2410 sourceInformation));
2391 } 2411 }
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
2848 // For type tests, we must treat specially the rare cases where `null` 2868 // For type tests, we must treat specially the rare cases where `null`
2849 // satisfies the test (which otherwise never satisfies a type test). 2869 // satisfies the test (which otherwise never satisfies a type test).
2850 // This is not an optimization: the TypeOperator assumes that `null` 2870 // This is not an optimization: the TypeOperator assumes that `null`
2851 // cannot satisfy the type test unless the type is a type variable. 2871 // cannot satisfy the type test unless the type is a type variable.
2852 if (type.isObject || type.isDynamic) { 2872 if (type.isObject || type.isDynamic) {
2853 // `x is Object` and `x is dynamic` are always true, even if x is null. 2873 // `x is Object` and `x is dynamic` are always true, even if x is null.
2854 return buildBooleanConstant(true); 2874 return buildBooleanConstant(true);
2855 } 2875 }
2856 if (type is InterfaceType && type.element == program.nullClass) { 2876 if (type is InterfaceType && type.element == program.nullClass) {
2857 // `x is Null` is true if and only if x is null. 2877 // `x is Null` is true if and only if x is null.
2858 return _buildCheckNull(value); 2878 return _buildCheckNull(value, sourceInformation);
2859 } 2879 }
2860 return addPrimitive(new ir.TypeTest(value, type, typeArguments)); 2880 return addPrimitive(new ir.TypeTest(value, type, typeArguments));
2861 } else { 2881 } else {
2862 if (type.isObject || type.isDynamic) { 2882 if (type.isObject || type.isDynamic) {
2863 // `x as Object` and `x as dynamic` are the same as `x`. 2883 // `x as Object` and `x as dynamic` are the same as `x`.
2864 return value; 2884 return value;
2865 } 2885 }
2866 return addPrimitive(new ir.TypeCast(value, type, typeArguments)); 2886 return addPrimitive(new ir.TypeCast(value, type, typeArguments));
2867 } 2887 }
2868 } 2888 }
2869 2889
2870 /// Create an if-null expression. This is equivalent to a conditional 2890 /// Create an if-null expression. This is equivalent to a conditional
2871 /// expression whose result is either [value] if [value] is not null, or 2891 /// expression whose result is either [value] if [value] is not null, or
2872 /// `right` if [value] is null. Only when [value] is null, [buildRight] is 2892 /// `right` if [value] is null. Only when [value] is null, [buildRight] is
2873 /// evaluated to produce the `right` value. 2893 /// evaluated to produce the `right` value.
2874 ir.Primitive buildIfNull(ir.Primitive value, 2894 ir.Primitive buildIfNull(ir.Primitive value,
2875 ir.Primitive buildRight(IrBuilder builder), 2895 ir.Primitive buildRight(IrBuilder builder),
2876 {SourceInformation sourceInformation}) { 2896 SourceInformation sourceInformation) {
2877 ir.Primitive condition = 2897 ir.Primitive condition =
2878 _buildCheckNull(value, sourceInformation: sourceInformation); 2898 _buildCheckNull(value, sourceInformation);
2879 return buildConditional(condition, buildRight, (_) => value); 2899 return buildConditional(
2900 condition, buildRight, (_) => value, sourceInformation);
2880 } 2901 }
2881 2902
2882 /// Create a conditional send. This is equivalent to a conditional expression 2903 /// Create a conditional send. This is equivalent to a conditional expression
2883 /// that checks if [receiver] is null, if so, it returns null, otherwise it 2904 /// that checks if [receiver] is null, if so, it returns null, otherwise it
2884 /// evaluates the [buildSend] expression. 2905 /// evaluates the [buildSend] expression.
2885 ir.Primitive buildIfNotNullSend(ir.Primitive receiver, 2906 ir.Primitive buildIfNotNullSend(ir.Primitive receiver,
2886 ir.Primitive buildSend(IrBuilder builder), 2907 ir.Primitive buildSend(IrBuilder builder),
2887 {SourceInformation sourceInformation}) { 2908 SourceInformation sourceInformation) {
2888 ir.Primitive condition = 2909 ir.Primitive condition =
2889 _buildCheckNull(receiver, sourceInformation: sourceInformation); 2910 _buildCheckNull(receiver, sourceInformation);
2890 return buildConditional(condition, (_) => receiver, buildSend); 2911 return buildConditional(
2912 condition, (_) => receiver, buildSend, sourceInformation);
2891 } 2913 }
2892 2914
2893 /// Creates a type test checking whether [value] is null. 2915 /// Creates a type test checking whether [value] is null.
2894 ir.Primitive _buildCheckNull(ir.Primitive value, 2916 ir.Primitive _buildCheckNull(ir.Primitive value,
2895 {SourceInformation sourceInformation}) { 2917 SourceInformation sourceInformation) {
2896 assert(isOpen); 2918 assert(isOpen);
2897 return buildIdentical(value, buildNullConstant(), 2919 return buildIdentical(value, buildNullConstant(),
2898 sourceInformation: sourceInformation); 2920 sourceInformation: sourceInformation);
2899 } 2921 }
2900 } 2922 }
2901 2923
2902 /// Location of a variable relative to a given closure. 2924 /// Location of a variable relative to a given closure.
2903 class ClosureLocation { 2925 class ClosureLocation {
2904 /// If not `null`, this location is [box].[field]. 2926 /// If not `null`, this location is [box].[field].
2905 /// The location of [box] can be obtained separately from an 2927 /// The location of [box] can be obtained separately from an
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
2998 CatchClauseInfo({this.type, 3020 CatchClauseInfo({this.type,
2999 this.exceptionVariable, 3021 this.exceptionVariable,
3000 this.stackTraceVariable, 3022 this.stackTraceVariable,
3001 this.buildCatchBlock, 3023 this.buildCatchBlock,
3002 this.sourceInformation}); 3024 this.sourceInformation});
3003 } 3025 }
3004 3026
3005 class SwitchCaseInfo { 3027 class SwitchCaseInfo {
3006 final SubbuildFunction buildCondition; 3028 final SubbuildFunction buildCondition;
3007 final SubbuildFunction buildBody; 3029 final SubbuildFunction buildBody;
3030 final SourceInformation sourceInformation;
3008 3031
3009 SwitchCaseInfo(this.buildCondition, this.buildBody); 3032 SwitchCaseInfo(this.buildCondition, this.buildBody, this.sourceInformation);
3010 } 3033 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_fragment.dart ('k') | pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698