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/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 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 IrBuilderDelimitedState(this.constantSystem, this.currentElement); | 201 IrBuilderDelimitedState(this.constantSystem, this.currentElement); |
| 202 } | 202 } |
| 203 | 203 |
| 204 /// A factory for building the cps IR. | 204 /// A factory for building the cps IR. |
| 205 /// | 205 /// |
| 206 /// [DartIrBuilder] and [JsIrBuilder] implement nested functions and captured | 206 /// [DartIrBuilder] and [JsIrBuilder] implement nested functions and captured |
| 207 /// variables in different ways. | 207 /// variables in different ways. |
| 208 abstract class IrBuilder { | 208 abstract class IrBuilder { |
| 209 IrBuilder _makeInstance(); | 209 IrBuilder _makeInstance(); |
| 210 | 210 |
| 211 /// A map from TryStatements in the AST to their analysis information. | |
| 212 /// | |
| 213 /// This include which variables should be copied into [ir.MutableVariable]s | |
|
floitsch
2015/02/16 14:54:07
includes
Kevin Millikin (Google)
2015/02/24 11:59:24
Done.
| |
| 214 /// on entry to the try and copied out on exit. | |
| 215 Map<ast.TryStatement, TryStatementInfo> get tryStatements; | |
|
asgerf
2015/02/20 10:10:07
I thought the IR builder was supposed to be indepe
Kevin Millikin (Google)
2015/02/24 11:59:24
Acknowledged.
| |
| 216 | |
| 217 /// The set of local variables that will spend their lifetime as | |
| 218 /// [ir.MutableVariable]s due to being captured by a nested function. | |
| 219 Set<Local> get mutableCapturedVariables; | |
| 220 | |
| 221 /// True if [local] should currently be accessed from a [ir.MutableVariable]. | |
| 222 bool isInMutableVariable(Local local); | |
| 223 | |
| 224 /// Creates a [ir.MutableVariable] for the given local. | |
| 225 void makeMutableVariable(Local local); | |
| 226 | |
| 227 /// Remove an [ir.MutableVariable] for a local. | |
| 228 /// | |
| 229 /// Subsequent access to the local will be direct rather than through the | |
| 230 /// mutable variable. This is used for variables that do not spend their | |
| 231 /// entire lifetime as mutable variables (e.g., variables that are boxed | |
| 232 /// in mutable variables for a try block). | |
| 233 void removeMutableVariable(Local local); | |
| 234 | |
| 211 void declareLocalVariable(LocalVariableElement element, | 235 void declareLocalVariable(LocalVariableElement element, |
| 212 {ir.Primitive initialValue}); | 236 {ir.Primitive initialValue}); |
| 213 ir.Primitive buildLocalGet(LocalElement element); | 237 ir.Primitive buildLocalGet(LocalElement element); |
| 214 ir.Primitive buildLocalSet(LocalElement element, ir.Primitive value); | 238 ir.Primitive buildLocalSet(LocalElement element, ir.Primitive value); |
| 215 | 239 |
| 216 /// Called when entering a nested function with free variables. | 240 /// Called when entering a nested function with free variables. |
| 217 /// | 241 /// |
| 218 /// The free variables must subsequently be accessible using [buildLocalGet] | 242 /// The free variables must subsequently be accessible using [buildLocalGet] |
| 219 /// and [buildLocalSet]. | 243 /// and [buildLocalSet]. |
| 220 void _enterClosureEnvironment(ClosureEnvironment env); | 244 void _enterClosureEnvironment(ClosureEnvironment env); |
| (...skipping 1290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1511 return join; | 1535 return join; |
| 1512 } | 1536 } |
| 1513 } | 1537 } |
| 1514 | 1538 |
| 1515 /// Shared state between DartIrBuilders within the same method. | 1539 /// Shared state between DartIrBuilders within the same method. |
| 1516 class DartIrBuilderSharedState { | 1540 class DartIrBuilderSharedState { |
| 1517 /// Maps local variables to their corresponding [MutableVariable] object. | 1541 /// Maps local variables to their corresponding [MutableVariable] object. |
| 1518 final Map<Local, ir.MutableVariable> local2mutable = | 1542 final Map<Local, ir.MutableVariable> local2mutable = |
| 1519 <Local, ir.MutableVariable>{}; | 1543 <Local, ir.MutableVariable>{}; |
| 1520 | 1544 |
| 1521 final DartCapturedVariableInfo capturedVariables; | 1545 final DartCapturedVariables capturedVariables; |
| 1522 | 1546 |
| 1523 /// Creates a [MutableVariable] for the given local. | 1547 /// Creates a [MutableVariable] for the given local. |
| 1524 void makeMutableVariable(Local local) { | 1548 void makeMutableVariable(Local local) { |
| 1525 ir.MutableVariable variable = | 1549 ir.MutableVariable variable = |
| 1526 new ir.MutableVariable(local.executableContext, local); | 1550 new ir.MutableVariable(local.executableContext, local); |
| 1527 local2mutable[local] = variable; | 1551 local2mutable[local] = variable; |
| 1528 } | 1552 } |
| 1529 | 1553 |
| 1530 /// [MutableVariable]s that should temporarily be treated as registers. | 1554 /// [MutableVariable]s that should temporarily be treated as registers. |
| 1531 final Set<Local> registerizedMutableVariables = new Set<Local>(); | 1555 final Set<Local> registerizedMutableVariables = new Set<Local>(); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1543 /// Captured variables are translated to ref cells (see [MutableVariable]) | 1567 /// Captured variables are translated to ref cells (see [MutableVariable]) |
| 1544 /// using [GetMutableVariable] and [SetMutableVariable]. | 1568 /// using [GetMutableVariable] and [SetMutableVariable]. |
| 1545 class DartIrBuilder extends IrBuilder { | 1569 class DartIrBuilder extends IrBuilder { |
| 1546 final DartIrBuilderSharedState dartState; | 1570 final DartIrBuilderSharedState dartState; |
| 1547 | 1571 |
| 1548 IrBuilder _makeInstance() => new DartIrBuilder._blank(dartState); | 1572 IrBuilder _makeInstance() => new DartIrBuilder._blank(dartState); |
| 1549 DartIrBuilder._blank(this.dartState); | 1573 DartIrBuilder._blank(this.dartState); |
| 1550 | 1574 |
| 1551 DartIrBuilder(ConstantSystem constantSystem, | 1575 DartIrBuilder(ConstantSystem constantSystem, |
| 1552 ExecutableElement currentElement, | 1576 ExecutableElement currentElement, |
| 1553 DartCapturedVariableInfo capturedVariables) | 1577 DartCapturedVariables capturedVariables) |
| 1554 : dartState = new DartIrBuilderSharedState(capturedVariables) { | 1578 : dartState = new DartIrBuilderSharedState(capturedVariables) { |
| 1555 _init(constantSystem, currentElement); | 1579 _init(constantSystem, currentElement); |
| 1556 } | 1580 } |
| 1557 | 1581 |
| 1558 /// True if [local] should currently be accessed from a [MutableVariable]. | 1582 Map<ast.TryStatement, TryStatementInfo> get tryStatements { |
| 1583 return dartState.capturedVariables.tryStatements; | |
| 1584 } | |
| 1585 | |
| 1586 Set<Local> get mutableCapturedVariables { | |
| 1587 return dartState.capturedVariables.capturedVariables; | |
| 1588 } | |
| 1589 | |
| 1559 bool isInMutableVariable(Local local) { | 1590 bool isInMutableVariable(Local local) { |
| 1560 return dartState.local2mutable.containsKey(local) && | 1591 return dartState.local2mutable.containsKey(local) && |
| 1561 !dartState.registerizedMutableVariables.contains(local); | 1592 !dartState.registerizedMutableVariables.contains(local); |
| 1562 } | 1593 } |
| 1563 | 1594 |
| 1595 void makeMutableVariable(Local local) { | |
| 1596 dartState.makeMutableVariable(local); | |
| 1597 } | |
| 1598 | |
| 1599 void removeMutableVariable(Local local) { | |
| 1600 dartState.local2mutable.remove(local); | |
| 1601 } | |
| 1602 | |
| 1564 /// Gets the [MutableVariable] containing the value of [local]. | 1603 /// Gets the [MutableVariable] containing the value of [local]. |
| 1565 ir.MutableVariable getMutableVariable(Local local) { | 1604 ir.MutableVariable getMutableVariable(Local local) { |
| 1566 return dartState.local2mutable[local]; | 1605 return dartState.local2mutable[local]; |
| 1567 } | 1606 } |
| 1568 | 1607 |
| 1569 void _enterScope(ClosureScope scope) { | 1608 void _enterScope(ClosureScope scope) { |
| 1570 assert(scope == null); | 1609 assert(scope == null); |
| 1571 } | 1610 } |
| 1572 | 1611 |
| 1573 void _enterClosureEnvironment(ClosureEnvironment env) { | 1612 void _enterClosureEnvironment(ClosureEnvironment env) { |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1727 final JsIrBuilderSharedState jsState; | 1766 final JsIrBuilderSharedState jsState; |
| 1728 | 1767 |
| 1729 IrBuilder _makeInstance() => new JsIrBuilder._blank(jsState); | 1768 IrBuilder _makeInstance() => new JsIrBuilder._blank(jsState); |
| 1730 JsIrBuilder._blank(this.jsState); | 1769 JsIrBuilder._blank(this.jsState); |
| 1731 | 1770 |
| 1732 JsIrBuilder(ConstantSystem constantSystem, ExecutableElement currentElement) | 1771 JsIrBuilder(ConstantSystem constantSystem, ExecutableElement currentElement) |
| 1733 : jsState = new JsIrBuilderSharedState() { | 1772 : jsState = new JsIrBuilderSharedState() { |
| 1734 _init(constantSystem, currentElement); | 1773 _init(constantSystem, currentElement); |
| 1735 } | 1774 } |
| 1736 | 1775 |
| 1776 Map<ast.TryStatement, TryStatementInfo> get tryStatements => null; | |
| 1777 Set<Local> get mutableCapturedVariables => null; | |
| 1778 bool isInMutableVariable(Local local) => false; | |
| 1779 void makeMutableVariable(Local local) {} | |
| 1780 void removeMutableVariable(Local local) {} | |
| 1781 | |
| 1737 void _enterClosureEnvironment(ClosureEnvironment env) { | 1782 void _enterClosureEnvironment(ClosureEnvironment env) { |
| 1738 if (env == null) return; | 1783 if (env == null) return; |
| 1739 | 1784 |
| 1740 // Obtain a reference to the function object (this). | 1785 // Obtain a reference to the function object (this). |
| 1741 ir.Primitive thisPrim = new ir.This(); | 1786 ir.Primitive thisPrim = new ir.This(); |
| 1742 add(new ir.LetPrim(thisPrim)); | 1787 add(new ir.LetPrim(thisPrim)); |
| 1743 | 1788 |
| 1744 // Obtain access to the free variables. | 1789 // Obtain access to the free variables. |
| 1745 env.freeVariables.forEach((Local local, ClosureLocation location) { | 1790 env.freeVariables.forEach((Local local, ClosureLocation location) { |
| 1746 if (location.isBox) { | 1791 if (location.isBox) { |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2000 /// If non-null, [thisLocal] has an entry in [freeVariables] describing where | 2045 /// If non-null, [thisLocal] has an entry in [freeVariables] describing where |
| 2001 /// to find the captured value of `this`. | 2046 /// to find the captured value of `this`. |
| 2002 final ThisLocal thisLocal; | 2047 final ThisLocal thisLocal; |
| 2003 | 2048 |
| 2004 /// Maps [LocalElement]s, [BoxLocal]s and [ThisLocal] to their location. | 2049 /// Maps [LocalElement]s, [BoxLocal]s and [ThisLocal] to their location. |
| 2005 final Map<Local, ClosureLocation> freeVariables; | 2050 final Map<Local, ClosureLocation> freeVariables; |
| 2006 | 2051 |
| 2007 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables); | 2052 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables); |
| 2008 } | 2053 } |
| 2009 | 2054 |
| 2010 /// Information about which variables are captured by a nested function. | 2055 class TryStatementInfo { |
| 2011 /// | 2056 final TryStatementInfo parent; |
| 2012 /// This is used by the [DartIrBuilder] instead of [ClosureScope] and | 2057 final List<TryStatementInfo> children = <TryStatementInfo>[]; |
| 2013 /// [ClosureEnvironment]. | 2058 final Set<LocalVariableElement> declared = new Set<LocalVariableElement>(); |
| 2014 abstract class DartCapturedVariableInfo { | 2059 final Set<LocalVariableElement> boxedOnEntry = |
| 2015 Iterable<Local> get capturedVariables; | 2060 new Set<LocalVariableElement>(); |
| 2061 | |
| 2062 TryStatementInfo(this.parent) { | |
| 2063 if (parent != null) parent.children.add(this); | |
| 2064 } | |
| 2065 | |
| 2066 void computeVariablesBoxedOnEntry(Set<LocalVariableElement> boxedInParent) { | |
|
floitsch
2015/02/16 14:54:07
Comments.
At the very least mention that the argum
Kevin Millikin (Google)
2015/02/24 11:59:24
This whole approach is overly complicated. I've c
| |
| 2067 Set<LocalVariableElement> boxed = | |
| 2068 new Set<LocalVariableElement>.from(boxedOnEntry); | |
| 2069 if (boxedInParent != null) { | |
| 2070 // Initially, variables are marked as boxed on entry if they are assigned | |
| 2071 // in this try but not including variables assigned only in some nested | |
|
floitsch
2015/02/16 14:54:07
I don't understand this comment.
| |
| 2072 // try. However, these do not have to be boxed if they are boxed in the | |
| 2073 // immediately enclosing try. | |
|
asgerf
2015/02/20 10:10:07
I would remove the word "However" here.
| |
| 2074 boxedOnEntry.removeAll(boxedInParent); | |
| 2075 // Variables are boxed in this try if they are boxed in the immediately | |
| 2076 // enclosing try or boxed on entry to this try. | |
|
floitsch
2015/02/16 14:54:07
The boxed-on-entry happens earlier. It's slightly
| |
| 2077 boxed.addAll(boxedInParent); | |
| 2078 } | |
| 2079 for (TryStatementInfo child in children) { | |
| 2080 child.computeVariablesBoxedOnEntry(boxed); | |
| 2081 } | |
| 2082 } | |
| 2016 } | 2083 } |
| OLD | NEW |