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 '../compile_time_constants.dart' show BackendConstantEnvironment; | 7 import '../compile_time_constants.dart' show BackendConstantEnvironment; |
8 import '../constants/constant_system.dart'; | 8 import '../constants/constant_system.dart'; |
9 import '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
10 import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue; | 10 import '../constants/values.dart' show ConstantValue, PrimitiveConstantValue; |
(...skipping 1630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1641 // in [[body]]; continue(v, ...) | 1641 // in [[body]]; continue(v, ...) |
1642 loopBuilder.add( | 1642 loopBuilder.add( |
1643 new ir.LetCont(continueCollector.continuation, | 1643 new ir.LetCont(continueCollector.continuation, |
1644 bodyBuilder._root)); | 1644 bodyBuilder._root)); |
1645 | 1645 |
1646 // And tie it all together. | 1646 // And tie it all together. |
1647 add(new ir.LetCont(breakCollector.continuation, loopBuilder._root)); | 1647 add(new ir.LetCont(breakCollector.continuation, loopBuilder._root)); |
1648 environment = breakCollector.environment; | 1648 environment = breakCollector.environment; |
1649 } | 1649 } |
1650 | 1650 |
| 1651 void buildSimpleSwitch(JumpTarget target, |
| 1652 ir.Primitive value, |
| 1653 List<SwitchCaseInfo> cases, |
| 1654 SwitchCaseInfo defaultCase, |
| 1655 Element error, |
| 1656 SourceInformation sourceInformation) { |
| 1657 assert(isOpen); |
| 1658 JumpCollector join = new ForwardJumpCollector(environment, target: target); |
| 1659 |
| 1660 IrBuilder casesBuilder = makeDelimitedBuilder(); |
| 1661 casesBuilder.state.breakCollectors.add(join); |
| 1662 for (SwitchCaseInfo caseInfo in cases) { |
| 1663 buildConditionsFrom(int index) => (IrBuilder builder) { |
| 1664 ir.Primitive comparison = builder.addPrimitive( |
| 1665 new ir.Identical(value, caseInfo.constants[index])); |
| 1666 return (index == caseInfo.constants.length - 1) |
| 1667 ? comparison |
| 1668 : builder.buildLogicalOperator( |
| 1669 comparison, buildConditionsFrom(index + 1), isLazyOr: true); |
| 1670 }; |
| 1671 |
| 1672 ir.Primitive condition = buildConditionsFrom(0)(casesBuilder); |
| 1673 IrBuilder thenBuilder = makeDelimitedBuilder(); |
| 1674 caseInfo.buildBody(thenBuilder); |
| 1675 if (thenBuilder.isOpen) { |
| 1676 // It is a runtime error to reach the end of a switch case, unless |
| 1677 // it is the last case. |
| 1678 if (caseInfo == cases.last && defaultCase == null) { |
| 1679 thenBuilder.jumpTo(join); |
| 1680 } else { |
| 1681 ir.Primitive exception = thenBuilder._buildInvokeStatic( |
| 1682 error, |
| 1683 new Selector.fromElement(error), |
| 1684 <ir.Primitive>[], |
| 1685 sourceInformation); |
| 1686 thenBuilder.buildThrow(exception); |
| 1687 } |
| 1688 } |
| 1689 |
| 1690 ir.Continuation thenContinuation = new ir.Continuation([]); |
| 1691 thenContinuation.body = thenBuilder._root; |
| 1692 ir.Continuation elseContinuation = new ir.Continuation([]); |
| 1693 // A LetCont.many term has a hole as the body of the first listed |
| 1694 // continuation, to be plugged by the translation. Therefore put the |
| 1695 // else continuation first. |
| 1696 casesBuilder.add( |
| 1697 new ir.LetCont.many(<ir.Continuation>[elseContinuation, |
| 1698 thenContinuation], |
| 1699 new ir.Branch(new ir.IsTrue(condition), |
| 1700 thenContinuation, |
| 1701 elseContinuation))); |
| 1702 } |
| 1703 |
| 1704 if (defaultCase != null) { |
| 1705 defaultCase.buildBody(casesBuilder); |
| 1706 } |
| 1707 if (casesBuilder.isOpen) casesBuilder.jumpTo(join); |
| 1708 |
| 1709 casesBuilder.state.breakCollectors.removeLast(); |
| 1710 |
| 1711 if (!join.isEmpty) { |
| 1712 add(new ir.LetCont(join.continuation, casesBuilder._root)); |
| 1713 environment = join.environment; |
| 1714 } else if (casesBuilder._root != null) { |
| 1715 add(casesBuilder._root); |
| 1716 _current = casesBuilder._current; |
| 1717 environment = casesBuilder.environment; |
| 1718 } else { |
| 1719 // The translation of the cases did not emit any code. |
| 1720 } |
| 1721 } |
| 1722 |
1651 /// Creates a try-statement. | 1723 /// Creates a try-statement. |
1652 /// | 1724 /// |
1653 /// [tryInfo] provides information on local variables declared and boxed | 1725 /// [tryInfo] provides information on local variables declared and boxed |
1654 /// within this try statement. | 1726 /// within this try statement. |
1655 /// [buildTryBlock] builds the try block. | 1727 /// [buildTryBlock] builds the try block. |
1656 /// [catchClauseInfos] provides access to the catch type, exception variable, | 1728 /// [catchClauseInfos] provides access to the catch type, exception variable, |
1657 /// and stack trace variable, and a function for building the catch block. | 1729 /// and stack trace variable, and a function for building the catch block. |
1658 void buildTry( | 1730 void buildTry( |
1659 {TryStatementInfo tryStatementInfo, | 1731 {TryStatementInfo tryStatementInfo, |
1660 SubbuildFunction buildTryBlock, | 1732 SubbuildFunction buildTryBlock, |
(...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2549 final DartType type; | 2621 final DartType type; |
2550 final LocalVariableElement exceptionVariable; | 2622 final LocalVariableElement exceptionVariable; |
2551 final LocalVariableElement stackTraceVariable; | 2623 final LocalVariableElement stackTraceVariable; |
2552 final SubbuildFunction buildCatchBlock; | 2624 final SubbuildFunction buildCatchBlock; |
2553 | 2625 |
2554 CatchClauseInfo({this.type, | 2626 CatchClauseInfo({this.type, |
2555 this.exceptionVariable, | 2627 this.exceptionVariable, |
2556 this.stackTraceVariable, | 2628 this.stackTraceVariable, |
2557 this.buildCatchBlock}); | 2629 this.buildCatchBlock}); |
2558 } | 2630 } |
| 2631 |
| 2632 class SwitchCaseInfo { |
| 2633 final List<ir.Primitive> constants = <ir.Primitive>[]; |
| 2634 final SubbuildFunction buildBody; |
| 2635 |
| 2636 SwitchCaseInfo(this.buildBody); |
| 2637 |
| 2638 void addConstant(ir.Primitive constant) => constants.add(constant); |
| 2639 } |
OLD | NEW |