Chromium Code Reviews| 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/constant_system.dart'; | 7 import '../constants/constant_system.dart'; |
| 8 import '../constants/expressions.dart'; | 8 import '../constants/expressions.dart'; |
| 9 import '../constants/values.dart' show PrimitiveConstantValue; | 9 import '../constants/values.dart' show PrimitiveConstantValue; |
| 10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
| (...skipping 1768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1779 IrBuilder catchBuilder = tryCatchBuilder.makeDelimitedBuilder(); | 1779 IrBuilder catchBuilder = tryCatchBuilder.makeDelimitedBuilder(); |
| 1780 for (LocalVariableElement variable in tryStatementInfo.boxedOnEntry) { | 1780 for (LocalVariableElement variable in tryStatementInfo.boxedOnEntry) { |
| 1781 assert(catchBuilder.isInMutableVariable(variable)); | 1781 assert(catchBuilder.isInMutableVariable(variable)); |
| 1782 ir.Primitive value = catchBuilder.buildLocalVariableGet(variable); | 1782 ir.Primitive value = catchBuilder.buildLocalVariableGet(variable); |
| 1783 // After this point, the variables that were boxed on entry to the try | 1783 // After this point, the variables that were boxed on entry to the try |
| 1784 // are no longer treated as mutable. | 1784 // are no longer treated as mutable. |
| 1785 catchBuilder.removeMutableVariable(variable); | 1785 catchBuilder.removeMutableVariable(variable); |
| 1786 catchBuilder.environment.update(variable, value); | 1786 catchBuilder.environment.update(variable, value); |
| 1787 } | 1787 } |
| 1788 | 1788 |
| 1789 // TODO(kmillikin): Handle multiple catch clauses. | 1789 // Handlers are always translated as having both exception and stack trace |
| 1790 assert(catchClauseInfos.length == 1); | 1790 // parameters. Multiple clauses do not have to use the same names for |
| 1791 for (CatchClauseInfo catchClauseInfo in catchClauseInfos) { | 1791 // them. Choose the first of each as the name hint for the respective |
| 1792 LocalVariableElement exceptionVariable = | 1792 // handler parameter. |
| 1793 catchClauseInfo.exceptionVariable; | 1793 ir.Parameter exceptionParameter = |
| 1794 ir.Parameter exceptionParameter = new ir.Parameter(exceptionVariable); | 1794 new ir.Parameter(catchClauseInfos.first.exceptionVariable); |
| 1795 catchBuilder.declareLocalVariable(exceptionVariable, | 1795 LocalVariableElement traceVariable; |
| 1796 initialValue: exceptionParameter); | 1796 CatchClauseInfo catchAll; |
| 1797 ir.Parameter traceParameter; | 1797 for (int i = 0; i < catchClauseInfos.length; ++i) { |
| 1798 LocalVariableElement stackTraceVariable = | 1798 CatchClauseInfo info = catchClauseInfos[i]; |
| 1799 catchClauseInfo.stackTraceVariable; | 1799 if (info.type == null) { |
| 1800 if (stackTraceVariable != null) { | 1800 catchAll = info; |
| 1801 traceParameter = new ir.Parameter(stackTraceVariable); | 1801 catchClauseInfos.length = i; |
| 1802 catchBuilder.declareLocalVariable(stackTraceVariable, | 1802 break; |
| 1803 initialValue: traceParameter); | |
| 1804 } else { | |
| 1805 // Use a dummy continuation parameter for the stack trace parameter. | |
| 1806 // This will ensure that all handlers have two parameters and so they | |
| 1807 // can be treated uniformly. | |
| 1808 traceParameter = new ir.Parameter(null); | |
| 1809 } | 1803 } |
| 1810 catchClauseInfo.buildCatchBlock(catchBuilder); | 1804 if (traceVariable == null) { |
| 1811 if (catchBuilder.isOpen) catchBuilder.jumpTo(join); | 1805 traceVariable = info.stackTraceVariable; |
| 1812 List<ir.Parameter> catchParameters = | 1806 } |
| 1813 <ir.Parameter>[exceptionParameter, traceParameter]; | 1807 } |
| 1814 ir.Continuation catchContinuation = new ir.Continuation(catchParameters); | 1808 ir.Parameter traceParameter = new ir.Parameter(traceVariable); |
| 1815 catchContinuation.body = catchBuilder._root; | 1809 // Expand multiple catch clauses into an explicit if/then/else. Iterate |
| 1810 // them in reverse so the current block becomes the next else block. | |
| 1811 ir.Expression catchBody; | |
| 1812 if (catchAll == null) { | |
| 1813 catchBody = new ir.Rethrow(); | |
| 1814 } else { | |
| 1815 IrBuilder clauseBuilder = catchBuilder.makeDelimitedBuilder(); | |
|
Kevin Millikin (Google)
2015/05/05 10:29:12
I'm going to move the next seven or eight lines in
| |
| 1816 clauseBuilder.declareLocalVariable(catchAll.exceptionVariable, | |
| 1817 initialValue: exceptionParameter); | |
| 1818 if (catchAll.stackTraceVariable != null) { | |
| 1819 clauseBuilder.declareLocalVariable(catchAll.stackTraceVariable, | |
| 1820 initialValue: traceParameter); | |
| 1821 } | |
| 1822 catchAll.buildCatchBlock(clauseBuilder); | |
| 1823 if (clauseBuilder.isOpen) clauseBuilder.jumpTo(join); | |
| 1824 catchBody = clauseBuilder._root; | |
| 1825 } | |
| 1826 for (CatchClauseInfo clause in catchClauseInfos.reversed) { | |
| 1827 IrBuilder clauseBuilder = catchBuilder.makeDelimitedBuilder(); | |
| 1828 clauseBuilder.declareLocalVariable(clause.exceptionVariable, | |
| 1829 initialValue: exceptionParameter); | |
| 1830 if (clause.stackTraceVariable != null) { | |
| 1831 clauseBuilder.declareLocalVariable(clause.stackTraceVariable, | |
| 1832 initialValue: traceParameter); | |
| 1833 } | |
| 1834 clause.buildCatchBlock(clauseBuilder); | |
| 1835 if (clauseBuilder.isOpen) clauseBuilder.jumpTo(join); | |
| 1836 ir.Continuation thenContinuation = new ir.Continuation([]); | |
| 1837 thenContinuation.body = clauseBuilder._root; | |
| 1838 ir.Continuation elseContinuation = new ir.Continuation([]); | |
| 1839 elseContinuation.body = catchBody; | |
| 1816 | 1840 |
| 1817 tryCatchBuilder.add( | 1841 ir.Parameter typeMatches = new ir.Parameter(null); |
| 1818 new ir.LetHandler(catchContinuation, tryBuilder._root)); | 1842 ir.Continuation checkType = new ir.Continuation([typeMatches]); |
| 1819 tryCatchBuilder._current = null; | 1843 checkType.body = |
| 1844 new ir.LetCont.many([thenContinuation, elseContinuation], | |
| 1845 new ir.Branch(new ir.IsTrue(typeMatches), | |
| 1846 thenContinuation, | |
| 1847 elseContinuation)); | |
| 1848 catchBody = | |
| 1849 new ir.LetCont(checkType, | |
| 1850 new ir.TypeOperator(exceptionParameter, clause.type, checkType, | |
| 1851 isTypeTest: true)); | |
| 1820 } | 1852 } |
| 1821 | 1853 |
| 1854 List<ir.Parameter> catchParameters = | |
| 1855 <ir.Parameter>[exceptionParameter, traceParameter]; | |
| 1856 ir.Continuation catchContinuation = new ir.Continuation(catchParameters); | |
| 1857 catchContinuation.body = catchBody; | |
| 1858 | |
| 1859 tryCatchBuilder.add( | |
| 1860 new ir.LetHandler(catchContinuation, tryBuilder._root)); | |
| 1822 add(new ir.LetCont(join.continuation, tryCatchBuilder._root)); | 1861 add(new ir.LetCont(join.continuation, tryCatchBuilder._root)); |
| 1823 environment = join.environment; | 1862 environment = join.environment; |
| 1824 } | 1863 } |
| 1825 | 1864 |
| 1826 /// Create a return statement `return value;` or `return;` if [value] is | 1865 /// Create a return statement `return value;` or `return;` if [value] is |
| 1827 /// null. | 1866 /// null. |
| 1828 void buildReturn([ir.Primitive value]) { | 1867 void buildReturn([ir.Primitive value]) { |
| 1829 // Build(Return(e), C) = C'[InvokeContinuation(return, x)] | 1868 // Build(Return(e), C) = C'[InvokeContinuation(return, x)] |
| 1830 // where (C', x) = Build(e, C) | 1869 // where (C', x) = Build(e, C) |
| 1831 // | 1870 // |
| (...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2641 | 2680 |
| 2642 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables); | 2681 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables); |
| 2643 } | 2682 } |
| 2644 | 2683 |
| 2645 class TryStatementInfo { | 2684 class TryStatementInfo { |
| 2646 final Set<LocalVariableElement> declared = new Set<LocalVariableElement>(); | 2685 final Set<LocalVariableElement> declared = new Set<LocalVariableElement>(); |
| 2647 final Set<LocalVariableElement> boxedOnEntry = | 2686 final Set<LocalVariableElement> boxedOnEntry = |
| 2648 new Set<LocalVariableElement>(); | 2687 new Set<LocalVariableElement>(); |
| 2649 } | 2688 } |
| 2650 | 2689 |
| 2651 // TODO(johnniwinther): Support passing of [DartType] for the exception. | |
| 2652 class CatchClauseInfo { | 2690 class CatchClauseInfo { |
| 2691 final DartType type; | |
| 2653 final LocalVariableElement exceptionVariable; | 2692 final LocalVariableElement exceptionVariable; |
| 2654 final LocalVariableElement stackTraceVariable; | 2693 final LocalVariableElement stackTraceVariable; |
| 2655 final SubbuildFunction buildCatchBlock; | 2694 final SubbuildFunction buildCatchBlock; |
| 2656 | 2695 |
| 2657 CatchClauseInfo({this.exceptionVariable, | 2696 CatchClauseInfo({this.type, |
| 2697 this.exceptionVariable, | |
| 2658 this.stackTraceVariable, | 2698 this.stackTraceVariable, |
| 2659 this.buildCatchBlock}); | 2699 this.buildCatchBlock}); |
| 2660 } | 2700 } |
| 2661 | 2701 |
| 2662 /// Synthetic parameter to a JavaScript factory method that takes the type | 2702 /// Synthetic parameter to a JavaScript factory method that takes the type |
| 2663 /// argument given for the type variable [variable]. | 2703 /// argument given for the type variable [variable]. |
| 2664 class TypeInformationParameter implements Local { | 2704 class TypeInformationParameter implements Local { |
| 2665 final TypeVariableElement variable; | 2705 final TypeVariableElement variable; |
| 2666 final ExecutableElement executableContext; | 2706 final ExecutableElement executableContext; |
| 2667 TypeInformationParameter(this.variable, this.executableContext); | 2707 TypeInformationParameter(this.variable, this.executableContext); |
| 2668 String get name => variable.name; | 2708 String get name => variable.name; |
| 2669 } | 2709 } |
| OLD | NEW |