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 'dart:io' hide Link; | 5 import 'dart:io' hide Link; |
6 import 'package:async_helper/async_helper.dart'; | 6 import 'package:async_helper/async_helper.dart'; |
7 import 'package:compiler/src/closure.dart'; | 7 import 'package:compiler/src/closure.dart'; |
8 import 'package:compiler/src/common.dart'; | 8 import 'package:compiler/src/common.dart'; |
9 import 'package:compiler/src/compiler.dart'; | 9 import 'package:compiler/src/compiler.dart'; |
10 import 'package:compiler/src/diagnostics/diagnostic_listener.dart'; | 10 import 'package:compiler/src/diagnostics/diagnostic_listener.dart'; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 /// Ast visitor for computing closure data. | 83 /// Ast visitor for computing closure data. |
84 class ClosureAstComputer extends AbstractResolvedAstComputer | 84 class ClosureAstComputer extends AbstractResolvedAstComputer |
85 with ComputeValueMixin { | 85 with ComputeValueMixin { |
86 final ClosureDataLookup<ast.Node> closureDataLookup; | 86 final ClosureDataLookup<ast.Node> closureDataLookup; |
87 final bool verbose; | 87 final bool verbose; |
88 | 88 |
89 ClosureAstComputer(DiagnosticReporter reporter, Map<Id, ActualData> actualMap, | 89 ClosureAstComputer(DiagnosticReporter reporter, Map<Id, ActualData> actualMap, |
90 ResolvedAst resolvedAst, this.closureDataLookup, | 90 ResolvedAst resolvedAst, this.closureDataLookup, |
91 {this.verbose: false}) | 91 {this.verbose: false}) |
92 : super(reporter, actualMap, resolvedAst) { | 92 : super(reporter, actualMap, resolvedAst) { |
93 push(resolvedAst.element); | 93 pushMember(resolvedAst.element as MemberElement); |
94 } | 94 } |
95 | 95 |
96 visitFunctionExpression(ast.FunctionExpression node) { | 96 visitFunctionExpression(ast.FunctionExpression node) { |
97 Entity localFunction = resolvedAst.elements.getFunctionDefinition(node); | 97 Entity localFunction = resolvedAst.elements.getFunctionDefinition(node); |
98 if (localFunction is LocalFunctionElement) { | 98 if (localFunction is LocalFunctionElement) { |
99 push(localFunction); | 99 pushLocalFunction(node); |
100 super.visitFunctionExpression(node); | 100 super.visitFunctionExpression(node); |
101 pop(); | 101 popLocalFunction(); |
102 } else { | 102 } else { |
103 super.visitFunctionExpression(node); | 103 super.visitFunctionExpression(node); |
104 } | 104 } |
105 } | 105 } |
106 | 106 |
107 @override | 107 @override |
108 String computeNodeValue(ast.Node node, [AstElement element]) { | 108 String computeNodeValue(ast.Node node, [AstElement element]) { |
109 if (element != null && element.isLocal) { | 109 if (element != null && element.isLocal) { |
110 if (element.isFunction) { | 110 if (element.isFunction) { |
111 return computeEntityValue(element); | 111 return computeEntityValue(element); |
(...skipping 10 matching lines...) Expand all Loading... |
122 String computeElementValue(AstElement element) { | 122 String computeElementValue(AstElement element) { |
123 // TODO(johnniwinther,efortuna): Collect data for the member | 123 // TODO(johnniwinther,efortuna): Collect data for the member |
124 // (has thisLocal, has box, etc.). | 124 // (has thisLocal, has box, etc.). |
125 return computeEntityValue(element); | 125 return computeEntityValue(element); |
126 } | 126 } |
127 } | 127 } |
128 | 128 |
129 /// Kernel IR visitor for computing closure data. | 129 /// Kernel IR visitor for computing closure data. |
130 class ClosureIrChecker extends AbstractIrComputer | 130 class ClosureIrChecker extends AbstractIrComputer |
131 with ComputeValueMixin<ir.Node> { | 131 with ComputeValueMixin<ir.Node> { |
| 132 final MemberEntity member; |
132 final ClosureDataLookup<ir.Node> closureDataLookup; | 133 final ClosureDataLookup<ir.Node> closureDataLookup; |
133 final KernelToLocalsMap _localsMap; | 134 final KernelToLocalsMap _localsMap; |
134 final bool verbose; | 135 final bool verbose; |
135 | 136 |
136 ClosureIrChecker( | 137 ClosureIrChecker( |
137 Map<Id, ActualData> actualMap, | 138 Map<Id, ActualData> actualMap, |
138 KernelToElementMapForBuilding elementMap, | 139 KernelToElementMapForBuilding elementMap, |
139 MemberEntity member, | 140 this.member, |
140 this._localsMap, | 141 this._localsMap, |
141 this.closureDataLookup, | 142 this.closureDataLookup, |
142 {this.verbose: false}) | 143 {this.verbose: false}) |
143 : super(actualMap) { | 144 : super(actualMap) { |
144 push(member); | 145 pushMember(member); |
145 } | 146 } |
146 | 147 |
147 visitFunctionExpression(ir.FunctionExpression node) { | 148 visitFunctionExpression(ir.FunctionExpression node) { |
148 Local localFunction = _localsMap.getLocalFunction(node); | 149 pushLocalFunction(node); |
149 push(localFunction); | |
150 super.visitFunctionExpression(node); | 150 super.visitFunctionExpression(node); |
151 pop(); | 151 popLocalFunction(); |
152 } | 152 } |
153 | 153 |
154 visitFunctionDeclaration(ir.FunctionDeclaration node) { | 154 visitFunctionDeclaration(ir.FunctionDeclaration node) { |
155 Local localFunction = _localsMap.getLocalFunction(node); | 155 pushLocalFunction(node); |
156 push(localFunction); | |
157 super.visitFunctionDeclaration(node); | 156 super.visitFunctionDeclaration(node); |
158 pop(); | 157 popLocalFunction(); |
159 } | 158 } |
160 | 159 |
161 @override | 160 @override |
162 String computeNodeValue(ir.Node node) { | 161 String computeNodeValue(ir.Node node) { |
163 if (node is ir.VariableDeclaration) { | 162 if (node is ir.VariableDeclaration) { |
164 Local local = _localsMap.getLocalVariable(node); | 163 Local local = _localsMap.getLocalVariable(node); |
165 return computeLocalValue(local); | 164 return computeLocalValue(local); |
166 } | 165 } |
167 // TODO(johnniwinther,efortuna): Collect data for other nodes? | 166 // TODO(johnniwinther,efortuna): Collect data for other nodes? |
168 return null; | 167 return null; |
169 } | 168 } |
170 | 169 |
171 @override | 170 @override |
172 String computeMemberValue(ir.Member member) { | 171 String computeMemberValue(ir.Member node) { |
173 // TODO(johnniwinther,efortuna): Collect data for the member | 172 // TODO(johnniwinther,efortuna): Collect data for the member |
174 // (has thisLocal, has box, etc.). | 173 // (has thisLocal, has box, etc.). |
175 return computeEntityValue(entity); | 174 return computeEntityValue(member); |
176 } | 175 } |
177 } | 176 } |
178 | 177 |
179 abstract class ComputeValueMixin<T> { | 178 abstract class ComputeValueMixin<T> { |
180 bool get verbose; | 179 bool get verbose; |
181 ClosureDataLookup<T> get closureDataLookup; | 180 ClosureDataLookup<T> get closureDataLookup; |
182 Entity get entity => entityStack.head; | |
183 Link<Entity> entityStack = const Link<Entity>(); | |
184 Link<ScopeInfo> scopeInfoStack = const Link<ScopeInfo>(); | 181 Link<ScopeInfo> scopeInfoStack = const Link<ScopeInfo>(); |
185 ScopeInfo get scopeInfo => scopeInfoStack.head; | 182 ScopeInfo get scopeInfo => scopeInfoStack.head; |
186 CapturedScope capturedScope; | 183 CapturedScope capturedScope; |
187 Link<ClosureRepresentationInfo> closureRepresentationInfoStack = | 184 Link<ClosureRepresentationInfo> closureRepresentationInfoStack = |
188 const Link<ClosureRepresentationInfo>(); | 185 const Link<ClosureRepresentationInfo>(); |
189 ClosureRepresentationInfo get closureRepresentationInfo => | 186 ClosureRepresentationInfo get closureRepresentationInfo => |
190 closureRepresentationInfoStack.head; | 187 closureRepresentationInfoStack.head; |
191 | 188 |
192 void push(Entity entity) { | 189 void pushMember(MemberEntity member) { |
193 entityStack = entityStack.prepend(entity); | |
194 scopeInfoStack = | 190 scopeInfoStack = |
195 scopeInfoStack.prepend(closureDataLookup.getScopeInfo(entity)); | 191 scopeInfoStack.prepend(closureDataLookup.getScopeInfo(member)); |
196 if (entity is MemberEntity) { | 192 capturedScope = closureDataLookup.getCapturedScope(member); |
197 capturedScope = closureDataLookup.getCapturedScope(entity); | 193 closureRepresentationInfoStack = closureRepresentationInfoStack |
198 } | 194 .prepend(closureDataLookup.getClosureInfoForMemberTesting(member)); |
199 closureRepresentationInfoStack = closureRepresentationInfoStack.prepend( | 195 dump(member); |
200 closureDataLookup.getClosureRepresentationInfoForTesting(entity)); | |
201 dump(entity); | |
202 } | 196 } |
203 | 197 |
204 void pop() { | 198 void popMember() { |
205 entityStack = entityStack.tail; | |
206 scopeInfoStack = scopeInfoStack.tail; | 199 scopeInfoStack = scopeInfoStack.tail; |
207 closureRepresentationInfoStack = closureRepresentationInfoStack.tail; | 200 closureRepresentationInfoStack = closureRepresentationInfoStack.tail; |
208 } | 201 } |
209 | 202 |
210 void dump(Entity entity) { | 203 void pushLocalFunction(T node) { |
| 204 closureRepresentationInfoStack = closureRepresentationInfoStack |
| 205 .prepend(closureDataLookup.getClosureInfoForTesting(node)); |
| 206 dump(node); |
| 207 } |
| 208 |
| 209 void popLocalFunction() { |
| 210 closureRepresentationInfoStack = closureRepresentationInfoStack.tail; |
| 211 } |
| 212 |
| 213 void dump(Object object) { |
211 if (!verbose) return; | 214 if (!verbose) return; |
212 | 215 |
213 print('entity: $entity'); | 216 print('object: $object'); |
214 print(' scopeInfo (${scopeInfo.runtimeType})'); | 217 if (object is MemberEntity) { |
215 scopeInfo.forEachBoxedVariable((a, b) => print(' boxed1: $a->$b')); | 218 print(' scopeInfo (${scopeInfo.runtimeType})'); |
216 print(' capturedScope (${capturedScope.runtimeType})'); | 219 scopeInfo.forEachBoxedVariable((a, b) => print(' boxed1: $a->$b')); |
217 capturedScope.forEachBoxedVariable((a, b) => print(' boxed2: $a->$b')); | 220 print(' capturedScope (${capturedScope.runtimeType})'); |
| 221 capturedScope.forEachBoxedVariable((a, b) => print(' boxed2: $a->$b')); |
| 222 } |
218 print( | 223 print( |
219 ' closureRepresentationInfo (${closureRepresentationInfo.runtimeType})')
; | 224 ' closureRepresentationInfo (${closureRepresentationInfo.runtimeType})')
; |
220 closureRepresentationInfo | 225 closureRepresentationInfo |
221 ?.forEachCapturedVariable((a, b) => print(' captured: $a->$b')); | 226 ?.forEachCapturedVariable((a, b) => print(' captured: $a->$b')); |
222 closureRepresentationInfo | 227 closureRepresentationInfo |
223 ?.forEachFreeVariable((a, b) => print(' free3: $a->$b')); | 228 ?.forEachFreeVariable((a, b) => print(' free3: $a->$b')); |
224 closureRepresentationInfo | 229 closureRepresentationInfo |
225 ?.forEachBoxedVariable((a, b) => print(' boxed3: $a->$b')); | 230 ?.forEachBoxedVariable((a, b) => print(' boxed3: $a->$b')); |
226 } | 231 } |
227 | 232 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 if (value != '') { | 317 if (value != '') { |
313 sb.write('='); | 318 sb.write('='); |
314 sb.write(value); | 319 sb.write(value); |
315 } | 320 } |
316 needsComma = true; | 321 needsComma = true; |
317 } | 322 } |
318 } | 323 } |
319 return sb.toString(); | 324 return sb.toString(); |
320 } | 325 } |
321 } | 326 } |
OLD | NEW |