| 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 'closure.dart'; | 8 import 'closure.dart'; |
| 9 | 9 |
| 10 /// This builder walks the code to determine what variables are captured/free at | 10 /// This builder walks the code to determine what variables are captured/free at |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 | 63 |
| 64 /// Keeps track of the number of boxes that we've created so that they each | 64 /// Keeps track of the number of boxes that we've created so that they each |
| 65 /// have unique names. | 65 /// have unique names. |
| 66 int _boxCounter = 0; | 66 int _boxCounter = 0; |
| 67 | 67 |
| 68 CapturedScopeBuilder(this._model, {bool hasThisLocal}) | 68 CapturedScopeBuilder(this._model, {bool hasThisLocal}) |
| 69 : this._hasThisLocal = hasThisLocal; | 69 : this._hasThisLocal = hasThisLocal; |
| 70 | 70 |
| 71 /// Update the [CapturedScope] object corresponding to | 71 /// Update the [CapturedScope] object corresponding to |
| 72 /// this node if any variables are captured. | 72 /// this node if any variables are captured. |
| 73 void attachCapturedScopeVariables(ir.Node node) { | 73 void attachCapturedScopeVariables(ir.TreeNode node) { |
| 74 Set<ir.VariableDeclaration> capturedVariablesForScope = | 74 Set<ir.VariableDeclaration> capturedVariablesForScope = |
| 75 new Set<ir.VariableDeclaration>(); | 75 new Set<ir.VariableDeclaration>(); |
| 76 | 76 |
| 77 for (ir.VariableDeclaration variable in _scopeVariables) { | 77 for (ir.VariableDeclaration variable in _scopeVariables) { |
| 78 // No need to box non-assignable elements. | 78 // No need to box non-assignable elements. |
| 79 if (variable.isFinal || variable.isConst) continue; | 79 if (variable.isFinal || variable.isConst) continue; |
| 80 if (!_mutatedVariables.contains(variable)) continue; | 80 if (!_mutatedVariables.contains(variable)) continue; |
| 81 if (_capturedVariables.contains(variable)) { | 81 if (_capturedVariables.contains(variable)) { |
| 82 capturedVariablesForScope.add(variable); | 82 capturedVariablesForScope.add(variable); |
| 83 } | 83 } |
| 84 } | 84 } |
| 85 if (!capturedVariablesForScope.isEmpty) { | 85 if (!capturedVariablesForScope.isEmpty) { |
| 86 assert(_model.scopeInfo != null); | 86 assert(_model.scopeInfo != null); |
| 87 assert(_currentLocalFunction != null); | 87 assert(_currentLocalFunction != null); |
| 88 KernelScopeInfo from = _model.scopeInfo; | 88 KernelScopeInfo from = _model.scopeInfo; |
| 89 _scopesCapturedInClosureMap[node] = new KernelCapturedScope( | 89 var capturedScope = new KernelCapturedScope( |
| 90 capturedVariablesForScope, | 90 capturedVariablesForScope, |
| 91 new NodeBox(getBoxName(), _executableContext), | 91 new NodeBox(getBoxName(), _executableContext), |
| 92 _currentLocalFunction, | 92 _currentLocalFunction, |
| 93 from.localsUsedInTryOrSync, | 93 from.localsUsedInTryOrSync, |
| 94 from.freeVariables, | 94 from.freeVariables, |
| 95 _hasThisLocal); | 95 _hasThisLocal); |
| 96 _model.scopeInfo = _scopesCapturedInClosureMap[node] = capturedScope; |
| 96 } | 97 } |
| 97 } | 98 } |
| 98 | 99 |
| 99 /// Generate a unique name for the [_boxCounter]th box field. | 100 /// Generate a unique name for the [_boxCounter]th box field. |
| 100 /// | 101 /// |
| 101 /// The result is used as the name of [NodeBox]s and [BoxLocal]s, and must | 102 /// The result is used as the name of [NodeBox]s and [BoxLocal]s, and must |
| 102 /// therefore be unique to avoid breaking an invariant in the element model | 103 /// therefore be unique to avoid breaking an invariant in the element model |
| 103 /// (classes cannot declare multiple fields with the same name). | 104 /// (classes cannot declare multiple fields with the same name). |
| 104 /// | 105 /// |
| 105 /// Also, the names should be distinct from real field names to prevent | 106 /// Also, the names should be distinct from real field names to prevent |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 // field, constructor, or method that is being analyzed. | 230 // field, constructor, or method that is being analyzed. |
| 230 _isInsideClosure = _outermostNode != null; | 231 _isInsideClosure = _outermostNode != null; |
| 231 _executableContext = node; | 232 _executableContext = node; |
| 232 | 233 |
| 233 _currentScopeInfo = new KernelScopeInfo(_hasThisLocal); | 234 _currentScopeInfo = new KernelScopeInfo(_hasThisLocal); |
| 234 if (_isInsideClosure) { | 235 if (_isInsideClosure) { |
| 235 _closuresToGenerate[node] = _currentScopeInfo; | 236 _closuresToGenerate[node] = _currentScopeInfo; |
| 236 _currentLocalFunction = node.parent; | 237 _currentLocalFunction = node.parent; |
| 237 } else { | 238 } else { |
| 238 _outermostNode = node; | 239 _outermostNode = node; |
| 239 _model.scopeInfo = _currentScopeInfo; | |
| 240 } | 240 } |
| 241 _model.scopeInfo = _currentScopeInfo; |
| 241 | 242 |
| 242 enterNewScope(node, () { | 243 enterNewScope(node, () { |
| 243 node.visitChildren(this); | 244 node.visitChildren(this); |
| 244 }); | 245 }); |
| 245 | 246 |
| 246 KernelScopeInfo savedScopeInfo = _currentScopeInfo; | 247 KernelScopeInfo savedScopeInfo = _currentScopeInfo; |
| 247 bool savedIsInsideClosure = _isInsideClosure; | 248 bool savedIsInsideClosure = _isInsideClosure; |
| 248 | 249 |
| 249 // Restore old values. | 250 // Restore old values. |
| 250 _isInsideClosure = oldIsInsideClosure; | 251 _isInsideClosure = oldIsInsideClosure; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 278 } | 279 } |
| 279 | 280 |
| 280 void translateConstructorOrProcedure(ir.Node constructorOrProcedure) { | 281 void translateConstructorOrProcedure(ir.Node constructorOrProcedure) { |
| 281 constructorOrProcedure.accept(this); | 282 constructorOrProcedure.accept(this); |
| 282 } | 283 } |
| 283 | 284 |
| 284 void visitFunctionNode(ir.FunctionNode functionNode) { | 285 void visitFunctionNode(ir.FunctionNode functionNode) { |
| 285 visitInvokable(functionNode); | 286 visitInvokable(functionNode); |
| 286 } | 287 } |
| 287 } | 288 } |
| OLD | NEW |