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 1505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1516 environment.index2value[i] = parameters[index++]; | 1516 environment.index2value[i] = parameters[index++]; |
| 1517 } | 1517 } |
| 1518 } | 1518 } |
| 1519 | 1519 |
| 1520 return join; | 1520 return join; |
| 1521 } | 1521 } |
| 1522 } | 1522 } |
| 1523 | 1523 |
| 1524 /// Shared state between DartIrBuilders within the same method. | 1524 /// Shared state between DartIrBuilders within the same method. |
| 1525 class DartIrBuilderSharedState { | 1525 class DartIrBuilderSharedState { |
| 1526 /// Maps local variables to their corresponding [ClosureVariable] object. | 1526 /// Maps local variables to their corresponding [MutableVariable] object. |
| 1527 final Map<Local, ir.ClosureVariable> local2closure = | 1527 final Map<Local, ir.MutableVariable> local2mutable = |
| 1528 <Local, ir.ClosureVariable>{}; | 1528 <Local, ir.MutableVariable>{}; |
| 1529 | 1529 |
| 1530 /// Maps functions to the list of closure variables declared in that function. | 1530 /// Maps a function to the list of [MutableVariable]s declared in that |
| 1531 final Map<ExecutableElement, List<ir.ClosureVariable>> function2closures = | 1531 /// function. |
| 1532 <ExecutableElement, List<ir.ClosureVariable>>{}; | 1532 final Map<ExecutableElement, List<ir.MutableVariable>> function2mutables = |
| 1533 <ExecutableElement, List<ir.MutableVariable>>{}; | |
|
asgerf
2015/02/03 10:27:31
I think this can be deleted actually. I believe it
Kevin Millikin (Google)
2015/02/03 14:11:48
I had there feeling there was more I could get rid
| |
| 1533 | 1534 |
| 1534 final DartCapturedVariableInfo closureVariables; | 1535 final DartCapturedVariableInfo mutableVariables; |
|
asgerf
2015/02/03 10:27:31
I think either the field should be `capturedVariab
Kevin Millikin (Google)
2015/02/03 14:11:48
Yeah, it's the captured variables. capturedVariab
| |
| 1535 | 1536 |
| 1536 /// Returns the closure variables declared in the given function. | 1537 /// Returns the [MutableVariable]s declared in the given function. |
| 1537 List<ir.ClosureVariable> getClosureList(ExecutableElement element) { | 1538 List<ir.MutableVariable> getMutablesList(ExecutableElement element) { |
| 1538 return function2closures.putIfAbsent(element, () => <ir.ClosureVariable>[]); | 1539 return function2mutables.putIfAbsent(element, () => <ir.MutableVariable>[]); |
| 1539 } | 1540 } |
| 1540 | 1541 |
| 1541 /// Creates a closure variable for the given local. | 1542 /// Creates a [MutableVariable] for the given local. |
| 1542 void makeClosureVariable(Local local) { | 1543 void makeMutableVariable(Local local) { |
| 1543 ir.ClosureVariable variable = | 1544 ir.MutableVariable variable = |
| 1544 new ir.ClosureVariable(local.executableContext, local); | 1545 new ir.MutableVariable(local.executableContext, local); |
| 1545 local2closure[local] = variable; | 1546 local2mutable[local] = variable; |
| 1546 getClosureList(local.executableContext).add(variable); | 1547 getMutablesList(local.executableContext).add(variable); |
| 1547 } | 1548 } |
| 1548 | 1549 |
| 1549 /// Closure variables that should temporarily be treated as registers. | 1550 /// [MutableVariable]s that should temporarily be treated as registers. |
| 1550 final Set<Local> registerizedClosureVariables = new Set<Local>(); | 1551 final Set<Local> registerizedMutableVariables = new Set<Local>(); |
| 1551 | 1552 |
| 1552 DartIrBuilderSharedState(this.closureVariables) { | 1553 DartIrBuilderSharedState(this.mutableVariables) { |
| 1553 closureVariables.capturedVariables.forEach(makeClosureVariable); | 1554 mutableVariables.capturedVariables.forEach(makeMutableVariable); |
| 1554 } | 1555 } |
| 1555 } | 1556 } |
| 1556 | 1557 |
| 1557 /// Dart-specific subclass of [IrBuilder]. | 1558 /// Dart-specific subclass of [IrBuilder]. |
| 1558 /// | 1559 /// |
| 1559 /// Inner functions are represented by a [FunctionDefinition] with the | 1560 /// Inner functions are represented by a [FunctionDefinition] with the |
| 1560 /// IR for the inner function nested inside. | 1561 /// IR for the inner function nested inside. |
| 1561 /// | 1562 /// |
| 1562 /// Captured variables are translated to ref cells (see [ClosureVariable]) | 1563 /// Captured variables are translated to ref cells (see [MutableVariable]) |
| 1563 /// using [GetClosureVariable] and [SetClosureVariable]. | 1564 /// using [GetMutableVariable] and [SetMutableVariable]. |
| 1564 class DartIrBuilder extends IrBuilder { | 1565 class DartIrBuilder extends IrBuilder { |
| 1565 final DartIrBuilderSharedState dartState; | 1566 final DartIrBuilderSharedState dartState; |
| 1566 | 1567 |
| 1567 IrBuilder _makeInstance() => new DartIrBuilder._blank(dartState); | 1568 IrBuilder _makeInstance() => new DartIrBuilder._blank(dartState); |
| 1568 DartIrBuilder._blank(this.dartState); | 1569 DartIrBuilder._blank(this.dartState); |
| 1569 | 1570 |
| 1570 DartIrBuilder(ConstantSystem constantSystem, | 1571 DartIrBuilder(ConstantSystem constantSystem, |
| 1571 ExecutableElement currentElement, | 1572 ExecutableElement currentElement, |
| 1572 DartCapturedVariableInfo closureVariables) | 1573 DartCapturedVariableInfo mutableVariables) |
| 1573 : dartState = new DartIrBuilderSharedState(closureVariables) { | 1574 : dartState = new DartIrBuilderSharedState(mutableVariables) { |
| 1574 _init(constantSystem, currentElement); | 1575 _init(constantSystem, currentElement); |
| 1575 } | 1576 } |
| 1576 | 1577 |
| 1577 /// True if [local] should currently be accessed from a [ClosureVariable]. | 1578 /// True if [local] should currently be accessed from a [MutableVariable]. |
| 1578 bool isInClosureVariable(Local local) { | 1579 bool isInMutableVariable(Local local) { |
| 1579 return dartState.local2closure.containsKey(local) && | 1580 return dartState.local2mutable.containsKey(local) && |
| 1580 !dartState.registerizedClosureVariables.contains(local); | 1581 !dartState.registerizedMutableVariables.contains(local); |
| 1581 } | 1582 } |
| 1582 | 1583 |
| 1583 /// Gets the [ClosureVariable] containing the value of [local]. | 1584 /// Gets the [MutableVariable] containing the value of [local]. |
| 1584 ir.ClosureVariable getClosureVariable(Local local) { | 1585 ir.MutableVariable getMutableVariable(Local local) { |
| 1585 return dartState.local2closure[local]; | 1586 return dartState.local2mutable[local]; |
| 1586 } | 1587 } |
| 1587 | 1588 |
| 1588 void _enterScope(ClosureScope scope) { | 1589 void _enterScope(ClosureScope scope) { |
| 1589 assert(scope == null); | 1590 assert(scope == null); |
| 1590 } | 1591 } |
| 1591 | 1592 |
| 1592 void _enterClosureEnvironment(ClosureEnvironment env) { | 1593 void _enterClosureEnvironment(ClosureEnvironment env) { |
| 1593 assert(env == null); | 1594 assert(env == null); |
| 1594 } | 1595 } |
| 1595 | 1596 |
| 1596 void _enterForLoopInitializer(ClosureScope scope, | 1597 void _enterForLoopInitializer(ClosureScope scope, |
| 1597 List<LocalElement> loopVariables) { | 1598 List<LocalElement> loopVariables) { |
| 1598 assert(scope == null); | 1599 assert(scope == null); |
| 1599 for (LocalElement loopVariable in loopVariables) { | 1600 for (LocalElement loopVariable in loopVariables) { |
| 1600 if (dartState.local2closure.containsKey(loopVariable)) { | 1601 if (dartState.local2mutable.containsKey(loopVariable)) { |
| 1601 // Temporarily keep the loop variable in a primitive. | 1602 // Temporarily keep the loop variable in a primitive. |
| 1602 // The loop variable will be added to environment when | 1603 // The loop variable will be added to environment when |
| 1603 // [declareLocalVariable] is called. | 1604 // [declareLocalVariable] is called. |
| 1604 dartState.registerizedClosureVariables.add(loopVariable); | 1605 dartState.registerizedMutableVariables.add(loopVariable); |
| 1605 } | 1606 } |
| 1606 } | 1607 } |
| 1607 } | 1608 } |
| 1608 | 1609 |
| 1609 void _enterForLoopBody(ClosureScope scope, | 1610 void _enterForLoopBody(ClosureScope scope, |
| 1610 List<LocalElement> loopVariables) { | 1611 List<LocalElement> loopVariables) { |
| 1611 assert(scope == null); | 1612 assert(scope == null); |
| 1612 for (LocalElement loopVariable in loopVariables) { | 1613 for (LocalElement loopVariable in loopVariables) { |
| 1613 if (dartState.local2closure.containsKey(loopVariable)) { | 1614 if (dartState.local2mutable.containsKey(loopVariable)) { |
| 1614 // Move from primitive into ClosureVariable. | 1615 // Move from [Primitive] into [MutableVariable]. |
| 1615 dartState.registerizedClosureVariables.remove(loopVariable); | 1616 dartState.registerizedMutableVariables.remove(loopVariable); |
| 1616 add(new ir.SetClosureVariable(getClosureVariable(loopVariable), | 1617 add(new ir.LetMutable(getMutableVariable(loopVariable), |
| 1617 environment.lookup(loopVariable), | 1618 environment.lookup(loopVariable))); |
| 1618 isDeclaration: true)); | |
| 1619 } | 1619 } |
| 1620 } | 1620 } |
| 1621 } | 1621 } |
| 1622 | 1622 |
| 1623 void _enterForLoopUpdate(ClosureScope scope, | 1623 void _enterForLoopUpdate(ClosureScope scope, |
| 1624 List<LocalElement> loopVariables) { | 1624 List<LocalElement> loopVariables) { |
| 1625 assert(scope == null); | 1625 assert(scope == null); |
| 1626 // Move captured loop variables back into the local environment. | 1626 // Move captured loop variables back into the local environment. |
| 1627 // The update expression will use the values we put in the environment, | 1627 // The update expression will use the values we put in the environment, |
| 1628 // and then the environments for the initializer and update will be | 1628 // and then the environments for the initializer and update will be |
| 1629 // joined at the head of the body. | 1629 // joined at the head of the body. |
| 1630 for (LocalElement loopVariable in loopVariables) { | 1630 for (LocalElement loopVariable in loopVariables) { |
| 1631 if (isInClosureVariable(loopVariable)) { | 1631 if (isInMutableVariable(loopVariable)) { |
| 1632 ir.ClosureVariable closureVariable = getClosureVariable(loopVariable); | 1632 ir.MutableVariable mutableVariable = getMutableVariable(loopVariable); |
| 1633 ir.Primitive get = new ir.GetClosureVariable(closureVariable); | 1633 ir.Primitive get = new ir.GetMutableVariable(mutableVariable); |
| 1634 add(new ir.LetPrim(get)); | 1634 add(new ir.LetPrim(get)); |
| 1635 environment.update(loopVariable, get); | 1635 environment.update(loopVariable, get); |
| 1636 dartState.registerizedClosureVariables.add(loopVariable); | 1636 dartState.registerizedMutableVariables.add(loopVariable); |
| 1637 } | 1637 } |
| 1638 } | 1638 } |
| 1639 } | 1639 } |
| 1640 | 1640 |
| 1641 void _createFunctionParameter(ParameterElement parameterElement) { | 1641 void _createFunctionParameter(ParameterElement parameterElement) { |
| 1642 ir.Parameter parameter = new ir.Parameter(parameterElement); | 1642 ir.Parameter parameter = new ir.Parameter(parameterElement); |
| 1643 _parameters.add(parameter); | 1643 _parameters.add(parameter); |
| 1644 if (isInClosureVariable(parameterElement)) { | 1644 if (isInMutableVariable(parameterElement)) { |
| 1645 state.functionParameters.add(getClosureVariable(parameterElement)); | 1645 state.functionParameters.add(getMutableVariable(parameterElement)); |
| 1646 } else { | 1646 } else { |
| 1647 state.functionParameters.add(parameter); | 1647 state.functionParameters.add(parameter); |
| 1648 environment.extend(parameterElement, parameter); | 1648 environment.extend(parameterElement, parameter); |
| 1649 } | 1649 } |
| 1650 } | 1650 } |
| 1651 | 1651 |
| 1652 void declareLocalVariable(LocalVariableElement variableElement, | 1652 void declareLocalVariable(LocalVariableElement variableElement, |
| 1653 {ir.Primitive initialValue}) { | 1653 {ir.Primitive initialValue}) { |
| 1654 assert(isOpen); | 1654 assert(isOpen); |
| 1655 if (initialValue == null) { | 1655 if (initialValue == null) { |
| 1656 initialValue = buildNullLiteral(); | 1656 initialValue = buildNullLiteral(); |
| 1657 } | 1657 } |
| 1658 if (isInClosureVariable(variableElement)) { | 1658 if (isInMutableVariable(variableElement)) { |
| 1659 add(new ir.SetClosureVariable(getClosureVariable(variableElement), | 1659 add(new ir.LetMutable(getMutableVariable(variableElement), |
| 1660 initialValue, | 1660 initialValue)); |
| 1661 isDeclaration: true)); | |
| 1662 } else { | 1661 } else { |
| 1663 initialValue.useElementAsHint(variableElement); | 1662 initialValue.useElementAsHint(variableElement); |
| 1664 environment.extend(variableElement, initialValue); | 1663 environment.extend(variableElement, initialValue); |
| 1665 } | 1664 } |
| 1666 } | 1665 } |
| 1667 | 1666 |
| 1668 /// Add [functionElement] to the environment with provided [definition]. | 1667 /// Add [functionElement] to the environment with provided [definition]. |
| 1669 void declareLocalFunction(LocalFunctionElement functionElement, | 1668 void declareLocalFunction(LocalFunctionElement functionElement, |
| 1670 ir.FunctionDefinition definition) { | 1669 ir.FunctionDefinition definition) { |
| 1671 assert(isOpen); | 1670 assert(isOpen); |
| 1672 if (isInClosureVariable(functionElement)) { | 1671 if (isInMutableVariable(functionElement)) { |
| 1673 ir.ClosureVariable variable = getClosureVariable(functionElement); | 1672 ir.MutableVariable variable = getMutableVariable(functionElement); |
| 1674 add(new ir.DeclareFunction(variable, definition)); | 1673 add(new ir.DeclareFunction(variable, definition)); |
| 1675 } else { | 1674 } else { |
| 1676 ir.CreateFunction prim = new ir.CreateFunction(definition); | 1675 ir.CreateFunction prim = new ir.CreateFunction(definition); |
| 1677 add(new ir.LetPrim(prim)); | 1676 add(new ir.LetPrim(prim)); |
| 1678 environment.extend(functionElement, prim); | 1677 environment.extend(functionElement, prim); |
| 1679 prim.useElementAsHint(functionElement); | 1678 prim.useElementAsHint(functionElement); |
| 1680 } | 1679 } |
| 1681 } | 1680 } |
| 1682 | 1681 |
| 1683 /// Create a function expression from [definition]. | 1682 /// Create a function expression from [definition]. |
| 1684 ir.Primitive buildFunctionExpression(ir.FunctionDefinition definition) { | 1683 ir.Primitive buildFunctionExpression(ir.FunctionDefinition definition) { |
| 1685 ir.CreateFunction prim = new ir.CreateFunction(definition); | 1684 ir.CreateFunction prim = new ir.CreateFunction(definition); |
| 1686 add(new ir.LetPrim(prim)); | 1685 add(new ir.LetPrim(prim)); |
| 1687 return prim; | 1686 return prim; |
| 1688 } | 1687 } |
| 1689 | 1688 |
| 1690 /// Create a read access of [local]. | 1689 /// Create a read access of [local]. |
| 1691 ir.Primitive buildLocalGet(LocalElement local) { | 1690 ir.Primitive buildLocalGet(LocalElement local) { |
| 1692 assert(isOpen); | 1691 assert(isOpen); |
| 1693 if (isInClosureVariable(local)) { | 1692 if (isInMutableVariable(local)) { |
| 1694 // Do not use [local] as a hint on [result]. The variable should always | 1693 // Do not use [local] as a hint on [result]. The variable should always |
| 1695 // be inlined, but the hint prevents it. | 1694 // be inlined, but the hint prevents it. |
| 1696 ir.Primitive result = | 1695 ir.Primitive result = |
| 1697 new ir.GetClosureVariable(getClosureVariable(local)); | 1696 new ir.GetMutableVariable(getMutableVariable(local)); |
| 1698 add(new ir.LetPrim(result)); | 1697 add(new ir.LetPrim(result)); |
| 1699 return result; | 1698 return result; |
| 1700 } else { | 1699 } else { |
| 1701 return environment.lookup(local); | 1700 return environment.lookup(local); |
| 1702 } | 1701 } |
| 1703 } | 1702 } |
| 1704 | 1703 |
| 1705 /// Create a write access to [local] with the provided [value]. | 1704 /// Create a write access to [local] with the provided [value]. |
| 1706 ir.Primitive buildLocalSet(LocalElement local, ir.Primitive value) { | 1705 ir.Primitive buildLocalSet(LocalElement local, ir.Primitive value) { |
| 1707 assert(isOpen); | 1706 assert(isOpen); |
| 1708 if (isInClosureVariable(local)) { | 1707 if (isInMutableVariable(local)) { |
| 1709 add(new ir.SetClosureVariable(getClosureVariable(local), value)); | 1708 add(new ir.SetMutableVariable(getMutableVariable(local), value)); |
| 1710 } else { | 1709 } else { |
| 1711 value.useElementAsHint(local); | 1710 value.useElementAsHint(local); |
| 1712 environment.update(local, value); | 1711 environment.update(local, value); |
| 1713 } | 1712 } |
| 1714 return value; | 1713 return value; |
| 1715 } | 1714 } |
| 1716 | 1715 |
| 1717 ir.Primitive buildThis() { | 1716 ir.Primitive buildThis() { |
| 1718 ir.Primitive thisPrim = new ir.This(); | 1717 ir.Primitive thisPrim = new ir.This(); |
| 1719 add(new ir.LetPrim(thisPrim)); | 1718 add(new ir.LetPrim(thisPrim)); |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2028 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables); | 2027 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables); |
| 2029 } | 2028 } |
| 2030 | 2029 |
| 2031 /// Information about which variables are captured by a nested function. | 2030 /// Information about which variables are captured by a nested function. |
| 2032 /// | 2031 /// |
| 2033 /// This is used by the [DartIrBuilder] instead of [ClosureScope] and | 2032 /// This is used by the [DartIrBuilder] instead of [ClosureScope] and |
| 2034 /// [ClosureEnvironment]. | 2033 /// [ClosureEnvironment]. |
| 2035 abstract class DartCapturedVariableInfo { | 2034 abstract class DartCapturedVariableInfo { |
| 2036 Iterable<Local> get capturedVariables; | 2035 Iterable<Local> get capturedVariables; |
| 2037 } | 2036 } |
| OLD | NEW |