| 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.dart'; | 8 import '../common.dart'; |
| 9 import '../common/tasks.dart'; | 9 import '../common/tasks.dart'; |
| 10 import '../constants/expressions.dart'; | 10 import '../constants/expressions.dart'; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 ir.Field field = node; | 29 ir.Field field = node; |
| 30 // Skip top-level/static fields without an initializer. | 30 // Skip top-level/static fields without an initializer. |
| 31 if (field.initializer == null) return null; | 31 if (field.initializer == null) return null; |
| 32 } | 32 } |
| 33 | 33 |
| 34 ScopeModel model = new ScopeModel(); | 34 ScopeModel model = new ScopeModel(); |
| 35 CapturedScopeBuilder translator = new CapturedScopeBuilder(model, | 35 CapturedScopeBuilder translator = new CapturedScopeBuilder(model, |
| 36 hasThisLocal: entity.isInstanceMember || entity.isConstructor); | 36 hasThisLocal: entity.isInstanceMember || entity.isConstructor); |
| 37 if (entity.isField) { | 37 if (entity.isField) { |
| 38 if (node is ir.Field && node.initializer != null) { | 38 if (node is ir.Field && node.initializer != null) { |
| 39 translator.translateLazyInitializer(node); | 39 node.accept(translator); |
| 40 } else { | 40 } else { |
| 41 assert(entity.isInstanceMember); | 41 assert(entity.isInstanceMember); |
| 42 model.scopeInfo = new KernelScopeInfo(true); | 42 model.scopeInfo = new KernelScopeInfo(true); |
| 43 } | 43 } |
| 44 } else { | 44 } else { |
| 45 assert(node is ir.Procedure || node is ir.Constructor); | 45 assert(node is ir.Procedure || node is ir.Constructor); |
| 46 translator.translateConstructorOrProcedure(node); | 46 node.accept(translator); |
| 47 } | 47 } |
| 48 return model; | 48 return model; |
| 49 } | 49 } |
| 50 } | 50 } |
| 51 | 51 |
| 52 /// Closure conversion code using our new Entity model. Closure conversion is | 52 /// Closure conversion code using our new Entity model. Closure conversion is |
| 53 /// necessary because the semantics of closures are slightly different in Dart | 53 /// necessary because the semantics of closures are slightly different in Dart |
| 54 /// than JavaScript. Closure conversion is separated out into two phases: | 54 /// than JavaScript. Closure conversion is separated out into two phases: |
| 55 /// generation of a new (temporary) representation to store where variables need | 55 /// generation of a new (temporary) representation to store where variables need |
| 56 /// to be hoisted/captured up at another level to re-write the closure, and then | 56 /// to be hoisted/captured up at another level to re-write the closure, and then |
| (...skipping 13 matching lines...) Expand all Loading... |
| 70 final Map<MemberEntity, ScopeModel> _closureModels; | 70 final Map<MemberEntity, ScopeModel> _closureModels; |
| 71 | 71 |
| 72 /// Map of the scoping information that corresponds to a particular entity. | 72 /// Map of the scoping information that corresponds to a particular entity. |
| 73 Map<MemberEntity, ScopeInfo> _scopeMap = <MemberEntity, ScopeInfo>{}; | 73 Map<MemberEntity, ScopeInfo> _scopeMap = <MemberEntity, ScopeInfo>{}; |
| 74 Map<ir.Node, CapturedScope> _capturedScopesMap = <ir.Node, CapturedScope>{}; | 74 Map<ir.Node, CapturedScope> _capturedScopesMap = <ir.Node, CapturedScope>{}; |
| 75 | 75 |
| 76 Map<MemberEntity, ClosureRepresentationInfo> _memberClosureRepresentationMap = | 76 Map<MemberEntity, ClosureRepresentationInfo> _memberClosureRepresentationMap = |
| 77 <MemberEntity, ClosureRepresentationInfo>{}; | 77 <MemberEntity, ClosureRepresentationInfo>{}; |
| 78 | 78 |
| 79 // The key is either a [ir.FunctionDeclaration] or [ir.FunctionExpression]. | 79 // The key is either a [ir.FunctionDeclaration] or [ir.FunctionExpression]. |
| 80 Map<ir.Node, ClosureRepresentationInfo> _localClosureRepresentationMap = | 80 Map<ir.TreeNode, ClosureRepresentationInfo> _localClosureRepresentationMap = |
| 81 <ir.Node, ClosureRepresentationInfo>{}; | 81 <ir.TreeNode, ClosureRepresentationInfo>{}; |
| 82 | 82 |
| 83 KernelClosureConversionTask(Measurer measurer, this._elementMap, | 83 KernelClosureConversionTask(Measurer measurer, this._elementMap, |
| 84 this._globalLocalsMap, this._closureModels) | 84 this._globalLocalsMap, this._closureModels) |
| 85 : super(measurer); | 85 : super(measurer); |
| 86 | 86 |
| 87 /// The combined steps of generating our intermediate representation of | 87 /// The combined steps of generating our intermediate representation of |
| 88 /// closures that need to be rewritten and generating the element model. | 88 /// closures that need to be rewritten and generating the element model. |
| 89 /// Ultimately these two steps will be split apart with the second step | 89 /// Ultimately these two steps will be split apart with the second step |
| 90 /// happening later in compilation just before codegen. These steps are | 90 /// happening later in compilation just before codegen. These steps are |
| 91 /// combined here currently to provide a consistent interface to the rest of | 91 /// combined here currently to provide a consistent interface to the rest of |
| (...skipping 15 matching lines...) Expand all Loading... |
| 107 model.capturedScopesMap | 107 model.capturedScopesMap |
| 108 .forEach((ir.Node node, KernelCapturedScope scope) { | 108 .forEach((ir.Node node, KernelCapturedScope scope) { |
| 109 if (scope is KernelCapturedLoopScope) { | 109 if (scope is KernelCapturedLoopScope) { |
| 110 _capturedScopesMap[node] = | 110 _capturedScopesMap[node] = |
| 111 new JsCapturedLoopScope.from(scope, localsMap); | 111 new JsCapturedLoopScope.from(scope, localsMap); |
| 112 } else { | 112 } else { |
| 113 _capturedScopesMap[node] = new JsCapturedScope.from(scope, localsMap); | 113 _capturedScopesMap[node] = new JsCapturedScope.from(scope, localsMap); |
| 114 } | 114 } |
| 115 }); | 115 }); |
| 116 | 116 |
| 117 Map<ir.FunctionNode, KernelScopeInfo> closuresToGenerate = | 117 Map<ir.TreeNode, KernelScopeInfo> closuresToGenerate = |
| 118 model.closuresToGenerate; | 118 model.closuresToGenerate; |
| 119 for (ir.FunctionNode node in closuresToGenerate.keys) { | 119 for (ir.TreeNode node in closuresToGenerate.keys) { |
| 120 ir.FunctionNode functionNode; |
| 121 if (node is ir.FunctionDeclaration) { |
| 122 functionNode = node.function; |
| 123 } else if (node is ir.FunctionExpression) { |
| 124 functionNode = node.function; |
| 125 } else { |
| 126 failedAt(member, "Unexpected closure node ${node}"); |
| 127 } |
| 120 KernelClosureClass closureClass = _produceSyntheticElements( | 128 KernelClosureClass closureClass = _produceSyntheticElements( |
| 121 member, node, closuresToGenerate[node], closedWorldRefiner); | 129 member, functionNode, closuresToGenerate[node], closedWorldRefiner); |
| 122 // Add also for the call method. | 130 // Add also for the call method. |
| 123 _scopeMap[closureClass.callMethod] = closureClass; | 131 _scopeMap[closureClass.callMethod] = closureClass; |
| 124 } | 132 } |
| 125 }); | 133 }); |
| 126 } | 134 } |
| 127 | 135 |
| 128 /// Given what variables are captured at each point, construct closure classes | 136 /// Given what variables are captured at each point, construct closure classes |
| 129 /// with fields containing the captured variables to replicate the Dart | 137 /// with fields containing the captured variables to replicate the Dart |
| 130 /// closure semantics in JS. If this closure captures any variables (meaning | 138 /// closure semantics in JS. If this closure captures any variables (meaning |
| 131 /// the closure accesses a variable that gets accessed at some point), then | 139 /// the closure accesses a variable that gets accessed at some point), then |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 var closure = _memberClosureRepresentationMap[entity]; | 206 var closure = _memberClosureRepresentationMap[entity]; |
| 199 assert( | 207 assert( |
| 200 closure != null, | 208 closure != null, |
| 201 "Corresponding closure class not found for $entity. " | 209 "Corresponding closure class not found for $entity. " |
| 202 "Closures found for ${_memberClosureRepresentationMap.keys}"); | 210 "Closures found for ${_memberClosureRepresentationMap.keys}"); |
| 203 return closure; | 211 return closure; |
| 204 } | 212 } |
| 205 | 213 |
| 206 @override | 214 @override |
| 207 ClosureRepresentationInfo getClosureInfo(ir.Node node) { | 215 ClosureRepresentationInfo getClosureInfo(ir.Node node) { |
| 216 assert(node is ir.FunctionExpression || node is ir.FunctionDeclaration); |
| 208 var closure = _localClosureRepresentationMap[node]; | 217 var closure = _localClosureRepresentationMap[node]; |
| 209 assert( | 218 assert( |
| 210 closure != null, | 219 closure != null, |
| 211 "Corresponding closure class not found for $node. " | 220 "Corresponding closure class not found for $node. " |
| 212 "Closures found for ${_localClosureRepresentationMap.keys}"); | 221 "Closures found for ${_localClosureRepresentationMap.keys}"); |
| 213 return closure; | 222 return closure; |
| 214 } | 223 } |
| 215 } | 224 } |
| 216 | 225 |
| 217 class KernelScopeInfo { | 226 class KernelScopeInfo { |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 /// Collection of scope data collected for a single member. | 588 /// Collection of scope data collected for a single member. |
| 580 class ScopeModel { | 589 class ScopeModel { |
| 581 /// Collection [ScopeInfo] data for the member. | 590 /// Collection [ScopeInfo] data for the member. |
| 582 KernelScopeInfo scopeInfo; | 591 KernelScopeInfo scopeInfo; |
| 583 | 592 |
| 584 /// Collected [CapturedScope] data for nodes. | 593 /// Collected [CapturedScope] data for nodes. |
| 585 Map<ir.Node, KernelCapturedScope> capturedScopesMap = | 594 Map<ir.Node, KernelCapturedScope> capturedScopesMap = |
| 586 <ir.Node, KernelCapturedScope>{}; | 595 <ir.Node, KernelCapturedScope>{}; |
| 587 | 596 |
| 588 /// Collected [ScopeInfo] data for nodes. | 597 /// Collected [ScopeInfo] data for nodes. |
| 589 Map<ir.FunctionNode, KernelScopeInfo> closuresToGenerate = | 598 Map<ir.TreeNode, KernelScopeInfo> closuresToGenerate = |
| 590 <ir.FunctionNode, KernelScopeInfo>{}; | 599 <ir.TreeNode, KernelScopeInfo>{}; |
| 591 } | 600 } |
| OLD | NEW |