| 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); | |
| 198 } | |
| 199 closureRepresentationInfoStack = closureRepresentationInfoStack.prepend( | 193 closureRepresentationInfoStack = closureRepresentationInfoStack.prepend( |
| 200 closureDataLookup.getClosureRepresentationInfoForTesting(entity)); | 194 closureDataLookup.getMemberRepresentationInfoForTesting(member)); |
| 201 dump(entity); | 195 dump(member); |
| 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.prepend( |
| 205 closureDataLookup.getClosureRepresentationInfoForTesting(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 |