| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 library closureToClassMapper; | 5 library closureToClassMapper; |
| 6 | 6 |
| 7 import "elements/elements.dart"; | 7 import "elements/elements.dart"; |
| 8 import "dart2jslib.dart"; | 8 import "dart2jslib.dart"; |
| 9 import "dart_types.dart"; | 9 import "dart_types.dart"; |
| 10 import "scanner/scannerlib.dart" show Token; | 10 import "scanner/scannerlib.dart" show Token; |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 | 240 |
| 241 // Maps scopes ([Loop] and [FunctionExpression] nodes) to their | 241 // Maps scopes ([Loop] and [FunctionExpression] nodes) to their |
| 242 // [ClosureScope] which contains their box and the | 242 // [ClosureScope] which contains their box and the |
| 243 // captured variables that are stored in the box. | 243 // captured variables that are stored in the box. |
| 244 // This map will be empty if the method/closure of this [ClosureData] does not | 244 // This map will be empty if the method/closure of this [ClosureData] does not |
| 245 // contain any nested closure. | 245 // contain any nested closure. |
| 246 final Map<Node, ClosureScope> capturingScopes; | 246 final Map<Node, ClosureScope> capturingScopes; |
| 247 | 247 |
| 248 final Set<Element> usedVariablesInTry; | 248 final Set<Element> usedVariablesInTry; |
| 249 | 249 |
| 250 // A map from the parameter element to the variable element that | |
| 251 // holds the sentinel check. | |
| 252 final Map<Element, Element> parametersWithSentinel; | |
| 253 | |
| 254 ClosureClassMap(this.closureElement, | 250 ClosureClassMap(this.closureElement, |
| 255 this.closureClassElement, | 251 this.closureClassElement, |
| 256 this.callElement, | 252 this.callElement, |
| 257 this.thisElement) | 253 this.thisElement) |
| 258 : this.freeVariableMapping = new Map<Element, Element>(), | 254 : this.freeVariableMapping = new Map<Element, Element>(), |
| 259 this.capturedFieldMapping = new Map<Element, Element>(), | 255 this.capturedFieldMapping = new Map<Element, Element>(), |
| 260 this.capturingScopes = new Map<Node, ClosureScope>(), | 256 this.capturingScopes = new Map<Node, ClosureScope>(), |
| 261 this.usedVariablesInTry = new Set<Element>(), | 257 this.usedVariablesInTry = new Set<Element>(); |
| 262 this.parametersWithSentinel = new Map<Element, Element>(); | |
| 263 | 258 |
| 264 bool isClosure() => closureElement != null; | 259 bool isClosure() => closureElement != null; |
| 265 | 260 |
| 266 bool isVariableCaptured(Element element) { | 261 bool isVariableCaptured(Element element) { |
| 267 return freeVariableMapping.containsKey(element); | 262 return freeVariableMapping.containsKey(element) |
| 263 || capturingScopesBox(element); |
| 264 } |
| 265 |
| 266 bool capturingScopesBox(Element element) { |
| 267 return capturingScopes.values.any((scope) { |
| 268 return scope.boxedLoopVariables.contains(element); |
| 269 }); |
| 268 } | 270 } |
| 269 | 271 |
| 270 bool isVariableBoxed(Element element) { | 272 bool isVariableBoxed(Element element) { |
| 271 Element copy = freeVariableMapping[element]; | 273 Element copy = freeVariableMapping[element]; |
| 272 return copy != null && !copy.isMember(); | 274 if (copy != null && !copy.isMember()) return true; |
| 275 return capturingScopesBox(element); |
| 273 } | 276 } |
| 274 | 277 |
| 275 void forEachCapturedVariable(void f(Element local, Element field)) { | 278 void forEachCapturedVariable(void f(Element local, Element field)) { |
| 276 freeVariableMapping.forEach((variable, copy) { | 279 freeVariableMapping.forEach((variable, copy) { |
| 277 if (variable is BoxElement) return; | 280 if (variable is BoxElement) return; |
| 278 f(variable, copy); | 281 f(variable, copy); |
| 279 }); | 282 }); |
| 283 capturingScopes.values.forEach((scope) { |
| 284 scope.capturedVariableMapping.forEach(f); |
| 285 }); |
| 280 } | 286 } |
| 281 | 287 |
| 282 void forEachBoxedVariable(void f(Element local, Element field)) { | 288 void forEachBoxedVariable(void f(Element local, Element field)) { |
| 283 freeVariableMapping.forEach((variable, copy) { | 289 freeVariableMapping.forEach((variable, copy) { |
| 284 if (!isVariableBoxed(variable)) return; | 290 if (!isVariableBoxed(variable)) return; |
| 285 f(variable, copy); | 291 f(variable, copy); |
| 286 }); | 292 }); |
| 293 capturingScopes.values.forEach((scope) { |
| 294 scope.capturedVariableMapping.forEach(f); |
| 295 }); |
| 287 } | 296 } |
| 288 | 297 |
| 289 void forEachNonBoxedCapturedVariable(void f(Element local, Element field)) { | 298 void forEachNonBoxedCapturedVariable(void f(Element local, Element field)) { |
| 290 freeVariableMapping.forEach((variable, copy) { | 299 freeVariableMapping.forEach((variable, copy) { |
| 291 if (variable is BoxElement) return; | 300 if (variable is BoxElement) return; |
| 292 if (isVariableBoxed(variable)) return; | 301 if (isVariableBoxed(variable)) return; |
| 293 f(variable, copy); | 302 f(variable, copy); |
| 294 }); | 303 }); |
| 295 } | 304 } |
| 296 } | 305 } |
| (...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 828 } | 837 } |
| 829 | 838 |
| 830 visitTryStatement(TryStatement node) { | 839 visitTryStatement(TryStatement node) { |
| 831 // TODO(ngeoffray): implement finer grain state. | 840 // TODO(ngeoffray): implement finer grain state. |
| 832 bool oldInTryStatement = inTryStatement; | 841 bool oldInTryStatement = inTryStatement; |
| 833 inTryStatement = true; | 842 inTryStatement = true; |
| 834 node.visitChildren(this); | 843 node.visitChildren(this); |
| 835 inTryStatement = oldInTryStatement; | 844 inTryStatement = oldInTryStatement; |
| 836 } | 845 } |
| 837 } | 846 } |
| OLD | NEW |