Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
| 6 | 6 |
| 7 import '../closure.dart'; | 7 import '../closure.dart'; |
| 8 import '../common/tasks.dart'; | 8 import '../common/tasks.dart'; |
| 9 import '../elements/entities.dart'; | 9 import '../elements/entities.dart'; |
| 10 import '../kernel/element_map.dart'; | 10 import '../kernel/element_map.dart'; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 /// For a general explanation of how closure conversion works at a high level, | 24 /// For a general explanation of how closure conversion works at a high level, |
| 25 /// check out: | 25 /// check out: |
| 26 /// http://siek.blogspot.com/2012/07/essence-of-closure-conversion.html or | 26 /// http://siek.blogspot.com/2012/07/essence-of-closure-conversion.html or |
| 27 /// http://matt.might.net/articles/closure-conversion/. | 27 /// http://matt.might.net/articles/closure-conversion/. |
| 28 // TODO(efortuna): Change inheritance hierarchy so that the | 28 // TODO(efortuna): Change inheritance hierarchy so that the |
| 29 // ClosureConversionTask doesn't inherit from ClosureTask because it's just a | 29 // ClosureConversionTask doesn't inherit from ClosureTask because it's just a |
| 30 // glorified timer. | 30 // glorified timer. |
| 31 class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> { | 31 class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> { |
| 32 final KernelToElementMapForBuilding _elementMap; | 32 final KernelToElementMapForBuilding _elementMap; |
| 33 final GlobalLocalsMap _globalLocalsMap; | 33 final GlobalLocalsMap _globalLocalsMap; |
| 34 | |
| 35 /// Map of the scoping information that corresponds to a particular entity. | |
| 36 /// This particular map contains ScopeInfos only for entities that are *not* | |
| 37 /// closures. Entities that are closures are stored in the | |
| 38 /// [_closureScopeMap]. | |
|
sra1
2017/07/12 23:57:41
Say why are they separate. Is it so these can be G
Emily Fortuna
2017/07/13 21:03:39
see comment below.
| |
| 39 Map<Entity, ScopeInfo> _scopeMap = <Entity, ScopeInfo>{}; | |
| 34 Map<ir.Node, ClosureScope> _closureScopeMap = <ir.Node, ClosureScope>{}; | 40 Map<ir.Node, ClosureScope> _closureScopeMap = <ir.Node, ClosureScope>{}; |
|
sra1
2017/07/12 23:57:41
Can this be Entity too?
Emily Fortuna
2017/07/13 21:03:39
yes, ended up combining with the above, since thes
| |
| 35 | 41 |
| 36 Map<Entity, ClosureRepresentationInfo> _closureRepresentationMap = | 42 Map<Entity, ClosureRepresentationInfo> _closureRepresentationMap = |
| 37 <Entity, ClosureRepresentationInfo>{}; | 43 <Entity, ClosureRepresentationInfo>{}; |
| 38 | 44 |
| 39 /// Should only be used at the very beginning to ensure we are looking at the | 45 /// Should only be used at the very beginning to ensure we are looking at the |
| 40 /// right kind of elements. | 46 /// right kind of elements. |
| 41 // TODO(efortuna): Remove this map once we have one kernel backend strategy. | 47 // TODO(efortuna): Remove this map once we have one kernel backend strategy. |
| 42 final JsToFrontendMap _kToJElementMap; | 48 final JsToFrontendMap _kToJElementMap; |
| 43 | 49 |
| 44 KernelClosureConversionTask(Measurer measurer, this._elementMap, | 50 KernelClosureConversionTask(Measurer measurer, this._elementMap, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 76 } | 82 } |
| 77 | 83 |
| 78 /// Inspect members and mark if those members capture any state that needs to | 84 /// Inspect members and mark if those members capture any state that needs to |
| 79 /// be marked as free variables. | 85 /// be marked as free variables. |
| 80 void _buildClosureModel( | 86 void _buildClosureModel( |
| 81 MemberEntity entity, | 87 MemberEntity entity, |
| 82 Map<ir.TreeNode, ScopeInfo> closuresToGenerate, | 88 Map<ir.TreeNode, ScopeInfo> closuresToGenerate, |
| 83 ClosedWorldRefiner closedWorldRefiner) { | 89 ClosedWorldRefiner closedWorldRefiner) { |
| 84 ir.Node node = _elementMap.getMemberNode(entity); | 90 ir.Node node = _elementMap.getMemberNode(entity); |
| 85 if (_closureScopeMap.keys.contains(node)) return; | 91 if (_closureScopeMap.keys.contains(node)) return; |
| 86 ClosureScopeBuilder translator = new ClosureScopeBuilder(_closureScopeMap, | 92 ClosureScopeBuilder translator = new ClosureScopeBuilder( |
| 87 closuresToGenerate, _globalLocalsMap.getLocalsMap(entity), _elementMap); | 93 _closureScopeMap, |
| 94 _scopeMap, | |
| 95 closuresToGenerate, | |
| 96 _globalLocalsMap.getLocalsMap(entity), | |
| 97 _elementMap); | |
| 88 if (entity.isField) { | 98 if (entity.isField) { |
| 89 if (node is ir.Field && node.initializer != null) { | 99 if (node is ir.Field && node.initializer != null) { |
| 90 translator.translateLazyInitializer(node); | 100 translator.translateLazyInitializer(node); |
| 91 } | 101 } |
| 92 } else { | 102 } else { |
| 93 assert(node is ir.Procedure || node is ir.Constructor); | 103 assert(node is ir.Procedure || node is ir.Constructor); |
| 94 translator.translateConstructorOrProcedure(node); | 104 translator.translateConstructorOrProcedure(node); |
| 95 } | 105 } |
| 96 } | 106 } |
| 97 | 107 |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 122 | 132 |
| 123 _closureRepresentationMap[entity] = closureClass; | 133 _closureRepresentationMap[entity] = closureClass; |
| 124 | 134 |
| 125 // Register that a new class has been created. | 135 // Register that a new class has been created. |
| 126 closedWorldRefiner.registerClosureClass( | 136 closedWorldRefiner.registerClosureClass( |
| 127 closureClass, node is ir.Member && node.isInstanceMember); | 137 closureClass, node is ir.Member && node.isInstanceMember); |
| 128 } | 138 } |
| 129 | 139 |
| 130 @override | 140 @override |
| 131 ScopeInfo getScopeInfo(Entity entity) { | 141 ScopeInfo getScopeInfo(Entity entity) { |
| 132 return getClosureRepresentationInfo(entity); | 142 // TODO(johnniwinther): Remove this check when constructor bodies a created |
| 143 // eagerly with the J-model; a constructor body should have it's own | |
| 144 // [ClosureRepresentationInfo]. | |
| 145 if (entity is ConstructorBodyEntity) { | |
| 146 ConstructorBodyEntity constructorBody = entity; | |
| 147 entity = constructorBody.constructor; | |
| 148 } | |
| 149 | |
| 150 return _scopeMap[entity] ?? getClosureRepresentationInfo(entity); | |
| 133 } | 151 } |
| 134 | 152 |
| 135 // TODO(efortuna): Eventually closureScopeMap[node] should always be non-null, | 153 // TODO(efortuna): Eventually closureScopeMap[node] should always be non-null, |
| 136 // and we should just test that with an assert. | 154 // and we should just test that with an assert. |
| 137 ClosureScope _getClosureScope(ir.Node node) => | 155 ClosureScope _getClosureScope(ir.Node node) => |
| 138 _closureScopeMap[node] ?? const ClosureScope(); | 156 _closureScopeMap[node] ?? const ClosureScope(); |
| 139 | 157 |
| 140 @override | 158 @override |
| 141 ClosureScope getClosureScope(MemberEntity entity) { | 159 ClosureScope getClosureScope(MemberEntity entity) { |
| 142 return _getClosureScope(_elementMap.getMemberNode(entity)); | 160 return _getClosureScope(_elementMap.getMemberNode(entity)); |
| 143 } | 161 } |
| 144 | 162 |
| 145 @override | 163 @override |
| 146 // TODO(efortuna): Eventually closureScopeMap[node] should always be non-null, | 164 // TODO(efortuna): Eventually closureScopeMap[node] should always be non-null, |
| 147 // and we should just test that with an assert. | 165 // and we should just test that with an assert. |
| 148 LoopClosureScope getLoopClosureScope(ir.Node loopNode) => | 166 LoopClosureScope getLoopClosureScope(ir.Node loopNode) => |
| 149 _closureScopeMap[loopNode] ?? const LoopClosureScope(); | 167 _closureScopeMap[loopNode] ?? const LoopClosureScope(); |
| 150 | 168 |
| 151 @override | 169 @override |
| 152 // TODO(efortuna): Eventually closureRepresentationMap[node] should always be | 170 // TODO(efortuna): Eventually closureRepresentationMap[node] should always be |
| 153 // non-null, and we should just test that with an assert. | 171 // non-null, and we should just test that with an assert. |
| 154 ClosureRepresentationInfo getClosureRepresentationInfo(Entity entity) { | 172 ClosureRepresentationInfo getClosureRepresentationInfo(Entity entity) { |
| 155 // TODO(johnniwinther): Remove this check when constructor bodies a created | |
| 156 // eagerly with the J-model; a constructor body should have it's own | |
| 157 // [ClosureRepresentationInfo]. | |
| 158 if (entity is ConstructorBodyEntity) { | |
| 159 ConstructorBodyEntity constructorBody = entity; | |
| 160 entity = constructorBody.constructor; | |
| 161 } | |
| 162 return _closureRepresentationMap[entity] ?? | 173 return _closureRepresentationMap[entity] ?? |
| 163 const ClosureRepresentationInfo(); | 174 const ClosureRepresentationInfo(); |
| 164 } | 175 } |
| 165 } | 176 } |
| 166 | 177 |
| 167 class KernelScopeInfo extends ScopeInfo { | 178 class KernelScopeInfo extends ScopeInfo { |
| 168 final Set<Local> localsUsedInTryOrSync; | 179 final Set<Local> localsUsedInTryOrSync; |
| 169 final Local thisLocal; | 180 final Local thisLocal; |
| 170 final Set<Local> boxedVariables; | 181 final Set<Local> boxedVariables; |
| 171 | 182 |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 273 // that (and the subsequent adjustment here) will follow soon. | 284 // that (and the subsequent adjustment here) will follow soon. |
| 274 bool get isClosure => false; | 285 bool get isClosure => false; |
| 275 | 286 |
| 276 bool get isAbstract => false; | 287 bool get isAbstract => false; |
| 277 | 288 |
| 278 // TODO(efortuna): Talk to Johnni. | 289 // TODO(efortuna): Talk to Johnni. |
| 279 JLibrary get library => null; | 290 JLibrary get library => null; |
| 280 | 291 |
| 281 String toString() => '${jsElementPrefix}class($name)'; | 292 String toString() => '${jsElementPrefix}class($name)'; |
| 282 } | 293 } |
| OLD | NEW |