| 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 class ClosureFieldElement extends Element { | 5 class ClosureFieldElement extends Element { |
| 6 ClosureFieldElement(SourceString name, ClassElement enclosing) | 6 ClosureFieldElement(SourceString name, ClassElement enclosing) |
| 7 : super(name, ElementKind.FIELD, enclosing); | 7 : super(name, ElementKind.FIELD, enclosing); |
| 8 | 8 |
| 9 bool isInstanceMember() => true; | 9 bool isInstanceMember() => true; |
| 10 bool isAssignable() => false; | 10 bool isAssignable() => false; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 this.capturingScopes = new Map<Node, ClosureScope>(), | 93 this.capturingScopes = new Map<Node, ClosureScope>(), |
| 94 this.usedVariablesInTry = new Set<Element>(); | 94 this.usedVariablesInTry = new Set<Element>(); |
| 95 | 95 |
| 96 bool isClosure() => closureElement !== null; | 96 bool isClosure() => closureElement !== null; |
| 97 } | 97 } |
| 98 | 98 |
| 99 class ClosureTranslator extends AbstractVisitor { | 99 class ClosureTranslator extends AbstractVisitor { |
| 100 final SsaBuilder builder; | 100 final SsaBuilder builder; |
| 101 final TreeElements elements; | 101 final TreeElements elements; |
| 102 int closureFieldCounter = 0; | 102 int closureFieldCounter = 0; |
| 103 bool inTryCatchOrFinally = false; | 103 bool inTryStatement = false; |
| 104 final Map<Node, ClosureData> closureDataCache; | 104 final Map<Node, ClosureData> closureDataCache; |
| 105 | 105 |
| 106 // Map of captured variables. Initially they will map to themselves. If | 106 // Map of captured variables. Initially they will map to themselves. If |
| 107 // a variable needs to be boxed then the scope declaring the variable | 107 // a variable needs to be boxed then the scope declaring the variable |
| 108 // will update this mapping. | 108 // will update this mapping. |
| 109 Map<Element, Element> capturedVariableMapping; | 109 Map<Element, Element> capturedVariableMapping; |
| 110 // List of encountered closures. | 110 // List of encountered closures. |
| 111 List<FunctionExpression> closures; | 111 List<FunctionExpression> closures; |
| 112 | 112 |
| 113 // The variables that have been declared in the current scope. | 113 // The variables that have been declared in the current scope. |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 ConstructorBodyElement body = functionElement; | 201 ConstructorBodyElement body = functionElement; |
| 202 functionElement = body.constructor; | 202 functionElement = body.constructor; |
| 203 } | 203 } |
| 204 // If the element is not declared in the current function and the element | 204 // If the element is not declared in the current function and the element |
| 205 // is not the closure itself we need to mark the element as free variable. | 205 // is not the closure itself we need to mark the element as free variable. |
| 206 if (element.enclosingElement != functionElement && | 206 if (element.enclosingElement != functionElement && |
| 207 element != functionElement) { | 207 element != functionElement) { |
| 208 assert(closureData.freeVariableMapping[element] == null || | 208 assert(closureData.freeVariableMapping[element] == null || |
| 209 closureData.freeVariableMapping[element] == element); | 209 closureData.freeVariableMapping[element] == element); |
| 210 closureData.freeVariableMapping[element] = element; | 210 closureData.freeVariableMapping[element] = element; |
| 211 } else if (inTryCatchOrFinally) { | 211 } else if (inTryStatement) { |
| 212 // Don't mark the this-element. This would complicate things in the | 212 // Don't mark the this-element. This would complicate things in the |
| 213 // builder. | 213 // builder. |
| 214 if (element != closureData.thisElement) { | 214 if (element != closureData.thisElement) { |
| 215 // TODO(ngeoffray): only do this if the variable is mutated. | 215 // TODO(ngeoffray): only do this if the variable is mutated. |
| 216 closureData.usedVariablesInTry.add(element); | 216 closureData.usedVariablesInTry.add(element); |
| 217 } | 217 } |
| 218 } | 218 } |
| 219 } | 219 } |
| 220 | 220 |
| 221 void declareLocal(Element element) { | 221 void declareLocal(Element element) { |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 } | 429 } |
| 430 } | 430 } |
| 431 | 431 |
| 432 visitFunctionDeclaration(FunctionDeclaration node) { | 432 visitFunctionDeclaration(FunctionDeclaration node) { |
| 433 node.visitChildren(this); | 433 node.visitChildren(this); |
| 434 declareLocal(elements[node]); | 434 declareLocal(elements[node]); |
| 435 } | 435 } |
| 436 | 436 |
| 437 visitTryStatement(TryStatement node) { | 437 visitTryStatement(TryStatement node) { |
| 438 // TODO(ngeoffray): implement finer grain state. | 438 // TODO(ngeoffray): implement finer grain state. |
| 439 bool oldInTryCatchOrFinally = inTryCatchOrFinally; | 439 bool oldInTryStatement = inTryStatement; |
| 440 inTryCatchOrFinally = true; | 440 inTryStatement = true; |
| 441 node.visitChildren(this); | 441 node.visitChildren(this); |
| 442 inTryCatchOrFinally = oldInTryCatchOrFinally; | 442 inTryStatement = oldInTryStatement; |
| 443 } | 443 } |
| 444 } | 444 } |
| OLD | NEW |