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

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

Issue 2985663002: Remove _nodeToEntity and _nodeToThisLocal from CapturedScopeBuilder (Closed)
Patch Set: Created 3 years, 5 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 '../elements/entities.dart'; 8 import '../elements/entities.dart';
9 import '../kernel/element_map.dart'; 9 import '../kernel/element_map.dart';
10 import 'closure.dart'; 10 import 'closure.dart';
11 11
12 /// This builder walks the code to determine what variables are captured/free at 12 /// This builder walks the code to determine what variables are captured/free at
13 /// various points to build CapturedScope that can respond to queries 13 /// various points to build CapturedScope that can respond to queries
14 /// about how a particular variable is being used at any point in the code. 14 /// about how a particular variable is being used at any point in the code.
15 class CapturedScopeBuilder extends ir.Visitor { 15 class CapturedScopeBuilder extends ir.Visitor {
16 final MemberEntity _currentMember;
17 Local _currentLocalFunction;
18
16 /// A map of each visited call node with the associated information about what 19 /// A map of each visited call node with the associated information about what
17 /// variables are captured/used. Each ir.Node key corresponds to a scope that 20 /// variables are captured/used. Each ir.Node key corresponds to a scope that
18 /// was encountered while visiting a closure (initially called through 21 /// was encountered while visiting a closure (initially called through
19 /// [translateLazyIntializer] or [translateConstructorOrProcedure]). 22 /// [translateLazyIntializer] or [translateConstructorOrProcedure]).
20 final Map<ir.Node, CapturedScope> _scopesCapturedInClosureMap; 23 final Map<ir.Node, CapturedScope> _scopesCapturedInClosureMap;
21 24
22 /// Map entities to their corresponding scope information (such as what 25 /// Map entities to their corresponding scope information (such as what
23 /// variables are captured/used). 26 /// variables are captured/used).
24 final Map<Entity, ScopeInfo> _scopeInfoMap; 27 final Map<Entity, ScopeInfo> _scopeInfoMap;
25 28
(...skipping 30 matching lines...) Expand all
56 /// If true, the visitor is currently traversing some nodes that are inside a 59 /// If true, the visitor is currently traversing some nodes that are inside a
57 /// try block. 60 /// try block.
58 bool _inTry = false; 61 bool _inTry = false;
59 62
60 /// Lookup the local entity that corresponds to a kernel variable declaration. 63 /// Lookup the local entity that corresponds to a kernel variable declaration.
61 final KernelToLocalsMap _localsMap; 64 final KernelToLocalsMap _localsMap;
62 65
63 /// The current scope we are in. 66 /// The current scope we are in.
64 KernelScopeInfo _currentScopeInfo; 67 KernelScopeInfo _currentScopeInfo;
65 68
69 // TODO(johnniwinther): Remove the need for this.
66 final KernelToElementMap _kernelToElementMap; 70 final KernelToElementMap _kernelToElementMap;
67 71
68 /// The original entity from which we start the tree-walk to find closure and 72 final Entity _thisLocal;
69 /// scope information.
70 final Entity _originalEntity;
71 73
72 CapturedScopeBuilder( 74 CapturedScopeBuilder(
75 this._currentMember,
73 this._scopesCapturedInClosureMap, 76 this._scopesCapturedInClosureMap,
74 this._scopeInfoMap, 77 this._scopeInfoMap,
75 this._originalEntity,
76 this._closuresToGenerate, 78 this._closuresToGenerate,
77 this._localsMap, 79 this._localsMap,
78 this._kernelToElementMap); 80 this._kernelToElementMap)
81 : this._thisLocal =
82 _currentMember.isInstanceMember || _currentMember.isConstructor
83 ? new ThisLocal(_currentMember)
84 : null;
79 85
80 /// Update the [CapturedScope] object corresponding to 86 /// Update the [CapturedScope] object corresponding to
81 /// this node if any variables are captured. 87 /// this node if any variables are captured.
82 void attachCapturedScopeVariables(ir.Node node) { 88 void attachCapturedScopeVariables(ir.Node node) {
83 Set<Local> capturedVariablesForScope = new Set<Local>(); 89 Set<Local> capturedVariablesForScope = new Set<Local>();
84 90
85 for (ir.VariableDeclaration variable in _scopeVariables) { 91 for (ir.VariableDeclaration variable in _scopeVariables) {
86 // No need to box non-assignable elements. 92 // No need to box non-assignable elements.
87 if (variable.isFinal || variable.isConst) continue; 93 if (variable.isFinal || variable.isConst) continue;
88 if (!_mutatedVariables.contains(variable)) continue; 94 if (!_mutatedVariables.contains(variable)) continue;
89 if (_capturedVariables.contains(variable)) { 95 if (_capturedVariables.contains(variable)) {
90 capturedVariablesForScope.add(_localsMap.getLocal(variable)); 96 capturedVariablesForScope.add(_localsMap.getLocal(variable));
91 } 97 }
92 } 98 }
93 if (!capturedVariablesForScope.isEmpty) { 99 if (!capturedVariablesForScope.isEmpty) {
94 ThisLocal thisLocal = null; 100 assert(_scopeInfoMap[_currentMember] != null);
95 if (node is ir.Member && node.isInstanceMember) { 101 assert(_currentLocalFunction != null);
96 if (node is ir.Procedure) { 102 KernelScopeInfo from = _scopeInfoMap[_currentMember];
97 thisLocal = new ThisLocal(_kernelToElementMap.getMethod(node));
98 } else if (node is ir.Field) {
99 thisLocal = new ThisLocal(_kernelToElementMap.getField(node));
100 }
101 } else if (node is ir.Constructor) {
102 thisLocal = new ThisLocal(_kernelToElementMap.getConstructor(node));
103 }
104
105 assert(_scopeInfoMap[_nodeToEntity(node)] != null);
106 KernelScopeInfo from = _scopeInfoMap[_nodeToEntity(node)];
107 _scopesCapturedInClosureMap[node] = new KernelCapturedScope( 103 _scopesCapturedInClosureMap[node] = new KernelCapturedScope(
108 capturedVariablesForScope, 104 capturedVariablesForScope,
109 _nodeToEntity(_executableContext), 105 _currentLocalFunction,
110 from.localsUsedInTryOrSync, 106 from.localsUsedInTryOrSync,
111 from.freeVariables, 107 from.freeVariables,
112 from.localsMap, 108 from.localsMap,
113 thisLocal); 109 _thisLocal);
114 }
115 }
116
117 Entity _nodeToEntity(ir.Node node) {
118 if (node is ir.Member) {
119 return _kernelToElementMap.getMember(node);
120 } else {
121 return _kernelToElementMap.getLocalFunction(node);
122 } 110 }
123 } 111 }
124 112
125 /// Perform book-keeping with the current set of local variables that have 113 /// Perform book-keeping with the current set of local variables that have
126 /// been seen thus far before entering this new scope. 114 /// been seen thus far before entering this new scope.
127 void enterNewScope(ir.Node node, Function visitNewScope) { 115 void enterNewScope(ir.Node node, void visitNewScope()) {
128 List<ir.VariableDeclaration> oldScopeVariables = _scopeVariables; 116 List<ir.VariableDeclaration> oldScopeVariables = _scopeVariables;
129 _scopeVariables = <ir.VariableDeclaration>[]; 117 _scopeVariables = <ir.VariableDeclaration>[];
130 visitNewScope(); 118 visitNewScope();
131 attachCapturedScopeVariables(node); 119 attachCapturedScopeVariables(node);
132 _mutatedVariables.removeAll(_scopeVariables); 120 _mutatedVariables.removeAll(_scopeVariables);
133 _scopeVariables = oldScopeVariables; 121 _scopeVariables = oldScopeVariables;
134 } 122 }
135 123
136 @override 124 @override
137 void defaultNode(ir.Node node) { 125 void defaultNode(ir.Node node) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 scope.localsUsedInTryOrSync, 216 scope.localsUsedInTryOrSync,
229 scope.freeVariables, 217 scope.freeVariables,
230 _localsMap, 218 _localsMap,
231 scope.thisLocal); 219 scope.thisLocal);
232 } 220 }
233 221
234 void visitInvokable(ir.TreeNode node) { 222 void visitInvokable(ir.TreeNode node) {
235 bool oldIsInsideClosure = _isInsideClosure; 223 bool oldIsInsideClosure = _isInsideClosure;
236 ir.Node oldExecutableContext = _executableContext; 224 ir.Node oldExecutableContext = _executableContext;
237 KernelScopeInfo oldScopeInfo = _currentScopeInfo; 225 KernelScopeInfo oldScopeInfo = _currentScopeInfo;
226 Local oldLocalFunction = _currentLocalFunction;
238 227
239 // _outermostNode is only null the first time we enter the body of the 228 // _outermostNode is only null the first time we enter the body of the
240 // field, constructor, or method that is being analyzed. 229 // field, constructor, or method that is being analyzed.
241 _isInsideClosure = _outermostNode != null; 230 _isInsideClosure = _outermostNode != null;
242 _executableContext = node; 231 _executableContext = node;
243 _currentScopeInfo = new KernelScopeInfo(_nodeToThisLocal(node), _localsMap); 232
233 _currentScopeInfo = new KernelScopeInfo(_thisLocal, _localsMap);
244 if (_isInsideClosure) { 234 if (_isInsideClosure) {
245 _closuresToGenerate[node] = _currentScopeInfo; 235 _closuresToGenerate[node] = _currentScopeInfo;
236 _currentLocalFunction = _kernelToElementMap.getLocalFunction(node.parent);
246 } else { 237 } else {
247 _outermostNode = node; 238 _outermostNode = node;
248 _scopeInfoMap[_originalEntity] = _currentScopeInfo; 239 _scopeInfoMap[_currentMember] = _currentScopeInfo;
249 } 240 }
250 241
251 enterNewScope(node, () { 242 enterNewScope(node, () {
252 node.visitChildren(this); 243 node.visitChildren(this);
253 }); 244 });
254 245
255 KernelScopeInfo savedScopeInfo = _currentScopeInfo; 246 KernelScopeInfo savedScopeInfo = _currentScopeInfo;
256 bool savedIsInsideClosure = _isInsideClosure; 247 bool savedIsInsideClosure = _isInsideClosure;
257 248
258 // Restore old values. 249 // Restore old values.
259 _isInsideClosure = oldIsInsideClosure; 250 _isInsideClosure = oldIsInsideClosure;
260 _currentScopeInfo = oldScopeInfo; 251 _currentScopeInfo = oldScopeInfo;
261 _executableContext = oldExecutableContext; 252 _executableContext = oldExecutableContext;
253 _currentLocalFunction = oldLocalFunction;
262 254
263 // Mark all free variables as captured and expect to encounter them in the 255 // Mark all free variables as captured and expect to encounter them in the
264 // outer function. 256 // outer function.
265 Iterable<ir.VariableDeclaration> freeVariables = 257 Iterable<ir.VariableDeclaration> freeVariables =
266 savedScopeInfo.freeVariables; 258 savedScopeInfo.freeVariables;
267 assert(freeVariables.isEmpty || savedIsInsideClosure); 259 assert(freeVariables.isEmpty || savedIsInsideClosure);
268 for (ir.VariableDeclaration freeVariable in freeVariables) { 260 for (ir.VariableDeclaration freeVariable in freeVariables) {
269 assert(!_capturedVariables.contains(freeVariable)); 261 assert(!_capturedVariables.contains(freeVariable));
270 _capturedVariables.add(freeVariable); 262 _capturedVariables.add(freeVariable);
271 _markVariableAsUsed(freeVariable); 263 _markVariableAsUsed(freeVariable);
(...skipping 14 matching lines...) Expand all
286 visitInvokable(field); 278 visitInvokable(field);
287 } 279 }
288 280
289 void translateConstructorOrProcedure(ir.Node constructorOrProcedure) { 281 void translateConstructorOrProcedure(ir.Node constructorOrProcedure) {
290 constructorOrProcedure.accept(this); 282 constructorOrProcedure.accept(this);
291 } 283 }
292 284
293 void visitFunctionNode(ir.FunctionNode functionNode) { 285 void visitFunctionNode(ir.FunctionNode functionNode) {
294 visitInvokable(functionNode); 286 visitInvokable(functionNode);
295 } 287 }
296
297 /// If [node] is an instance member return the corresponding `this` reference.
298 /// If not, return null.
299 Entity _nodeToThisLocal(
300 ir.TreeNode
301 /*ir.Field|ir.FunctionNode|ir.Constructor|ir.Procedure*/ node) {
302 ir.Node nodeToConvert = node;
303 if (nodeToConvert is ir.Field) {
304 if (!nodeToConvert.isInstanceMember) return null;
305 return new ThisLocal(_kernelToElementMap.getField(nodeToConvert));
306 } else {
307 if (nodeToConvert is ir.FunctionNode) {
308 // Step up one node higher to find the corresponding entity for this
309 // node.
310 nodeToConvert = node.parent;
311 }
312 if (nodeToConvert is ir.Constructor ||
313 (nodeToConvert is ir.Procedure &&
314 nodeToConvert.kind == ir.ProcedureKind.Factory &&
315 nodeToConvert.isInstanceMember)) {
316 return new ThisLocal(_kernelToElementMap.getConstructor(nodeToConvert));
317 } else if (nodeToConvert is ir.Procedure &&
318 nodeToConvert.isInstanceMember) {
319 return new ThisLocal(_kernelToElementMap.getMethod(nodeToConvert));
320 }
321 }
322 return null;
323 }
324 } 288 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_model/closure.dart ('k') | pkg/compiler/lib/src/kernel/element_map.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698