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 |