Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(448)

Side by Side Diff: pkg/compiler/lib/src/js_model/closure.dart

Issue 3002953002: Split getClosureRepresentationInfo into MemberEntity and (ir/ast) nodes (Closed)
Patch Set: Update cf. comments Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 /// http://matt.might.net/articles/closure-conversion/. 63 /// http://matt.might.net/articles/closure-conversion/.
64 // TODO(efortuna): Change inheritance hierarchy so that the 64 // TODO(efortuna): Change inheritance hierarchy so that the
65 // ClosureConversionTask doesn't inherit from ClosureTask because it's just a 65 // ClosureConversionTask doesn't inherit from ClosureTask because it's just a
66 // glorified timer. 66 // glorified timer.
67 class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> { 67 class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> {
68 final KernelToElementMapForBuilding _elementMap; 68 final KernelToElementMapForBuilding _elementMap;
69 final GlobalLocalsMap _globalLocalsMap; 69 final GlobalLocalsMap _globalLocalsMap;
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<Entity, ScopeInfo> _scopeMap = <Entity, 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<Entity, ClosureRepresentationInfo> _closureRepresentationMap = 76 Map<MemberEntity, ClosureRepresentationInfo> _memberClosureRepresentationMap =
77 <Entity, ClosureRepresentationInfo>{}; 77 <MemberEntity, ClosureRepresentationInfo>{};
78
79 // The key is either a [ir.FunctionDeclaration] or [ir.FunctionExpression].
80 Map<ir.Node, ClosureRepresentationInfo> _localClosureRepresentationMap =
81 <ir.Node, ClosureRepresentationInfo>{};
78 82
79 KernelClosureConversionTask(Measurer measurer, this._elementMap, 83 KernelClosureConversionTask(Measurer measurer, this._elementMap,
80 this._globalLocalsMap, this._closureModels) 84 this._globalLocalsMap, this._closureModels)
81 : super(measurer); 85 : super(measurer);
82 86
83 /// The combined steps of generating our intermediate representation of 87 /// The combined steps of generating our intermediate representation of
84 /// closures that need to be rewritten and generating the element model. 88 /// closures that need to be rewritten and generating the element model.
85 /// 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
86 /// happening later in compilation just before codegen. These steps are 90 /// happening later in compilation just before codegen. These steps are
87 /// 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 MemberEntity member, 135 MemberEntity member,
132 ir.FunctionNode node, 136 ir.FunctionNode node,
133 KernelScopeInfo info, 137 KernelScopeInfo info,
134 JsClosedWorld closedWorldRefiner) { 138 JsClosedWorld closedWorldRefiner) {
135 KernelToLocalsMap localsMap = _globalLocalsMap.getLocalsMap(member); 139 KernelToLocalsMap localsMap = _globalLocalsMap.getLocalsMap(member);
136 KernelClosureClass closureClass = closedWorldRefiner.buildClosureClass( 140 KernelClosureClass closureClass = closedWorldRefiner.buildClosureClass(
137 member, node, member.library, info, node.location, localsMap); 141 member, node, member.library, info, node.location, localsMap);
138 142
139 // We want the original declaration where that function is used to point 143 // We want the original declaration where that function is used to point
140 // to the correct closure class. 144 // to the correct closure class.
141 _closureRepresentationMap[closureClass.callMethod] = closureClass; 145 _memberClosureRepresentationMap[closureClass.callMethod] = closureClass;
142 Entity entity;
143 if (node.parent is ir.Member) { 146 if (node.parent is ir.Member) {
144 entity = _elementMap.getMember(node.parent); 147 assert(_elementMap.getMember(node.parent) == member);
148 _memberClosureRepresentationMap[member] = closureClass;
145 } else { 149 } else {
146 entity = localsMap.getLocalFunction(node.parent); 150 assert(node.parent is ir.FunctionExpression ||
151 node.parent is ir.FunctionDeclaration);
152 _localClosureRepresentationMap[node.parent] = closureClass;
147 } 153 }
148 assert(entity != null);
149 _closureRepresentationMap[entity] = closureClass;
150 return closureClass; 154 return closureClass;
151 } 155 }
152 156
153 @override 157 @override
154 ScopeInfo getScopeInfo(Entity entity) { 158 ScopeInfo getScopeInfo(MemberEntity entity) {
155 // TODO(johnniwinther): Remove this check when constructor bodies a created 159 // TODO(johnniwinther): Remove this check when constructor bodies a created
156 // eagerly with the J-model; a constructor body should have it's own 160 // eagerly with the J-model; a constructor body should have it's own
157 // [ClosureRepresentationInfo]. 161 // [ClosureRepresentationInfo].
158 if (entity is ConstructorBodyEntity) { 162 if (entity is ConstructorBodyEntity) {
159 ConstructorBodyEntity constructorBody = entity; 163 ConstructorBodyEntity constructorBody = entity;
160 entity = constructorBody.constructor; 164 entity = constructorBody.constructor;
161 } 165 }
162 166
163 return _scopeMap[entity] ?? getClosureRepresentationInfo(entity); 167 return _scopeMap[entity] ?? getClosureInfoForMember(entity);
164 } 168 }
165 169
166 // TODO(efortuna): Eventually capturedScopesMap[node] should always 170 // TODO(efortuna): Eventually capturedScopesMap[node] should always
167 // be non-null, and we should just test that with an assert. 171 // be non-null, and we should just test that with an assert.
168 @override 172 @override
169 CapturedScope getCapturedScope(MemberEntity entity) { 173 CapturedScope getCapturedScope(MemberEntity entity) {
170 MemberDefinition definition = _elementMap.getMemberDefinition(entity); 174 MemberDefinition definition = _elementMap.getMemberDefinition(entity);
171 switch (definition.kind) { 175 switch (definition.kind) {
172 case MemberKind.regular: 176 case MemberKind.regular:
173 case MemberKind.constructor: 177 case MemberKind.constructor:
174 case MemberKind.constructorBody: 178 case MemberKind.constructorBody:
175 case MemberKind.closureCall: 179 case MemberKind.closureCall:
176 return _capturedScopesMap[definition.node] ?? const CapturedScope(); 180 return _capturedScopesMap[definition.node] ?? const CapturedScope();
177 default: 181 default:
178 throw failedAt(entity, "Unexpected member definition $definition"); 182 throw failedAt(entity, "Unexpected member definition $definition");
179 } 183 }
180 } 184 }
181 185
182 @override 186 @override
183 // TODO(efortuna): Eventually capturedScopesMap[node] should always 187 // TODO(efortuna): Eventually capturedScopesMap[node] should always
184 // be non-null, and we should just test that with an assert. 188 // be non-null, and we should just test that with an assert.
185 CapturedLoopScope getCapturedLoopScope(ir.Node loopNode) => 189 CapturedLoopScope getCapturedLoopScope(ir.Node loopNode) =>
186 _capturedScopesMap[loopNode] ?? const CapturedLoopScope(); 190 _capturedScopesMap[loopNode] ?? const CapturedLoopScope();
187 191
188 @override 192 @override
189 ClosureRepresentationInfo getClosureRepresentationInfo(Entity entity) { 193 ClosureRepresentationInfo getClosureInfoForMember(MemberEntity entity) {
190 var closure = _closureRepresentationMap[entity]; 194 var closure = _memberClosureRepresentationMap[entity];
191 assert( 195 assert(
192 closure != null, 196 closure != null,
193 "Corresponding closure class not found for $entity. " 197 "Corresponding closure class not found for $entity. "
194 "Closures found for ${_closureRepresentationMap.keys}"); 198 "Closures found for ${_memberClosureRepresentationMap.keys}");
195 return closure; 199 return closure;
196 } 200 }
197 201
198 @override 202 @override
199 ClosureRepresentationInfo getClosureRepresentationInfoForTesting( 203 ClosureRepresentationInfo getClosureInfo(ir.Node node) {
200 Entity member) { 204 var closure = _localClosureRepresentationMap[node];
201 return _closureRepresentationMap[member]; 205 assert(
206 closure != null,
207 "Corresponding closure class not found for $node. "
208 "Closures found for ${_localClosureRepresentationMap.keys}");
209 return closure;
210 }
211
212 @override
213 ClosureRepresentationInfo getClosureInfoForMemberTesting(
214 MemberEntity entity) {
215 return _memberClosureRepresentationMap[entity];
216 }
217
218 @override
219 ClosureRepresentationInfo getClosureInfoForTesting(ir.Node node) {
220 return _localClosureRepresentationMap[node];
202 } 221 }
203 } 222 }
204 223
205 class KernelScopeInfo { 224 class KernelScopeInfo {
206 final Set<ir.VariableDeclaration> localsUsedInTryOrSync; 225 final Set<ir.VariableDeclaration> localsUsedInTryOrSync;
207 final bool hasThisLocal; 226 final bool hasThisLocal;
208 final Set<ir.VariableDeclaration> boxedVariables; 227 final Set<ir.VariableDeclaration> boxedVariables;
209 // If boxedVariables is empty, this will be null, because no variables will 228 // If boxedVariables is empty, this will be null, because no variables will
210 // need to be boxed. 229 // need to be boxed.
211 final NodeBox capturedVariablesAccessor; 230 final NodeBox capturedVariablesAccessor;
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 367
349 final Map<Local, JField> localToFieldMap = new Map<Local, JField>(); 368 final Map<Local, JField> localToFieldMap = new Map<Local, JField>();
350 369
351 KernelClosureClass.fromScopeInfo( 370 KernelClosureClass.fromScopeInfo(
352 this.closureClassEntity, 371 this.closureClassEntity,
353 ir.FunctionNode closureSourceNode, 372 ir.FunctionNode closureSourceNode,
354 KernelScopeInfo info, 373 KernelScopeInfo info,
355 KernelToLocalsMap localsMap) 374 KernelToLocalsMap localsMap)
356 : closureEntity = closureSourceNode.parent is ir.Member 375 : closureEntity = closureSourceNode.parent is ir.Member
357 ? null 376 ? null
377 // TODO(johnniwinther,efortuna): This is the only place we call
378 // [getLocalFunction]. Therefore the [closureEntity] doesn't need
379 // to be derived from the node.
380 //
381 // What we should do instead: If `closureSourceNode.parent` is
382 // an [ir.FunctionDeclaration] we should use the local for its
383 // variable. If `closureSourceNode.parent` is an
384 // [ir.FunctionExpression], we should create a fresh local.
358 : localsMap.getLocalFunction(closureSourceNode.parent), 385 : localsMap.getLocalFunction(closureSourceNode.parent),
359 thisLocal = 386 thisLocal =
360 info.hasThisLocal ? new ThisLocal(localsMap.currentMember) : null, 387 info.hasThisLocal ? new ThisLocal(localsMap.currentMember) : null,
361 super.from(info, localsMap); 388 super.from(info, localsMap);
362 389
363 List<Local> get createdFieldEntities => localToFieldMap.keys.toList(); 390 List<Local> get createdFieldEntities => localToFieldMap.keys.toList();
364 391
365 FieldEntity get thisFieldEntity => localToFieldMap[thisLocal]; 392 FieldEntity get thisFieldEntity => localToFieldMap[thisLocal];
366 393
367 void forEachCapturedVariable(f(Local from, JField to)) { 394 void forEachCapturedVariable(f(Local from, JField to)) {
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 KernelScopeInfo scopeInfo; 570 KernelScopeInfo scopeInfo;
544 571
545 /// Collected [CapturedScope] data for nodes. 572 /// Collected [CapturedScope] data for nodes.
546 Map<ir.Node, KernelCapturedScope> capturedScopesMap = 573 Map<ir.Node, KernelCapturedScope> capturedScopesMap =
547 <ir.Node, KernelCapturedScope>{}; 574 <ir.Node, KernelCapturedScope>{};
548 575
549 /// Collected [ScopeInfo] data for nodes. 576 /// Collected [ScopeInfo] data for nodes.
550 Map<ir.FunctionNode, KernelScopeInfo> closuresToGenerate = 577 Map<ir.FunctionNode, KernelScopeInfo> closuresToGenerate =
551 <ir.FunctionNode, KernelScopeInfo>{}; 578 <ir.FunctionNode, KernelScopeInfo>{};
552 } 579 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart ('k') | pkg/compiler/lib/src/js_model/locals.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698