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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 this.callElement, | 72 this.callElement, |
73 this.thisElement) | 73 this.thisElement) |
74 : this.freeVariableMapping = new Map<Element, Element>(), | 74 : this.freeVariableMapping = new Map<Element, Element>(), |
75 this.capturedFieldMapping = new Map<Element, Element>(), | 75 this.capturedFieldMapping = new Map<Element, Element>(), |
76 this.capturingScopes = new Map<Node, ClosureScope>(), | 76 this.capturingScopes = new Map<Node, ClosureScope>(), |
77 this.usedVariablesInTry = new Set<Element>(); | 77 this.usedVariablesInTry = new Set<Element>(); |
78 | 78 |
79 bool isClosure() => closureElement !== null; | 79 bool isClosure() => closureElement !== null; |
80 } | 80 } |
81 | 81 |
82 Map<Node, ClosureData> _closureDataCache; | |
83 Map<Node, ClosureData> get closureDataCache() { | |
84 if (_closureDataCache === null) { | |
85 _closureDataCache = new HashMap<Node, ClosureData>(); | |
86 } | |
87 return _closureDataCache; | |
88 } | |
89 | |
90 class ClosureTranslator extends AbstractVisitor { | 82 class ClosureTranslator extends AbstractVisitor { |
91 final Compiler compiler; | 83 final Compiler compiler; |
92 final TreeElements elements; | 84 final TreeElements elements; |
93 int boxCounter = 0; | 85 int boxCounter = 0; |
94 bool inTryCatchOrFinally = false; | 86 bool inTryCatchOrFinally = false; |
| 87 final Map<Node, ClosureData> closureDataCache; |
95 | 88 |
96 // Map of captured variables. Initially they will map to themselves. If | 89 // Map of captured variables. Initially they will map to themselves. If |
97 // a variable needs to be boxed then the scope declaring the variable | 90 // a variable needs to be boxed then the scope declaring the variable |
98 // will update this mapping. | 91 // will update this mapping. |
99 Map<Element, Element> capturedVariableMapping; | 92 Map<Element, Element> capturedVariableMapping; |
100 // List of encountered closures. | 93 // List of encountered closures. |
101 List<FunctionExpression> closures; | 94 List<FunctionExpression> closures; |
102 | 95 |
103 // The variables that have been declared in the current scope. | 96 // The variables that have been declared in the current scope. |
104 List<Element> scopeVariables; | 97 List<Element> scopeVariables; |
105 | 98 |
106 FunctionElement currentFunctionElement; | 99 FunctionElement currentFunctionElement; |
107 // The closureData of the currentFunctionElement. | 100 // The closureData of the currentFunctionElement. |
108 ClosureData closureData; | 101 ClosureData closureData; |
109 | 102 |
110 bool insideClosure = false; | 103 bool insideClosure = false; |
111 | 104 |
112 ClosureTranslator(this.compiler, this.elements) | 105 ClosureTranslator(Compiler compiler, this.elements) |
113 : capturedVariableMapping = new Map<Element, Element>(), | 106 : capturedVariableMapping = new Map<Element, Element>(), |
114 closures = <FunctionExpression>[]; | 107 closures = <FunctionExpression>[], |
| 108 this.compiler = compiler, |
| 109 this.closureDataCache = compiler.builder.closureDataCache; |
115 | 110 |
116 ClosureData translate(Node node) { | 111 ClosureData translate(Node node) { |
117 // Closures have already been analyzed when visiting the surrounding | 112 // Closures have already been analyzed when visiting the surrounding |
118 // method/function. This also shortcuts for bailout functions. | 113 // method/function. This also shortcuts for bailout functions. |
119 ClosureData cached = closureDataCache[node]; | 114 ClosureData cached = closureDataCache[node]; |
120 if (cached !== null) return cached; | 115 if (cached !== null) return cached; |
121 | 116 |
122 visit(node); | 117 visit(node); |
123 // When variables need to be boxed their [capturedVariableMapping] is | 118 // When variables need to be boxed their [capturedVariableMapping] is |
124 // updated, but we delay updating the similar freeVariableMapping in the | 119 // updated, but we delay updating the similar freeVariableMapping in the |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 declareLocal(elements[node]); | 408 declareLocal(elements[node]); |
414 } | 409 } |
415 | 410 |
416 visitTryStatement(TryStatement node) { | 411 visitTryStatement(TryStatement node) { |
417 // TODO(ngeoffray): implement finer grain state. | 412 // TODO(ngeoffray): implement finer grain state. |
418 inTryCatchOrFinally = true; | 413 inTryCatchOrFinally = true; |
419 node.visitChildren(this); | 414 node.visitChildren(this); |
420 inTryCatchOrFinally = false; | 415 inTryCatchOrFinally = false; |
421 } | 416 } |
422 } | 417 } |
OLD | NEW |