Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 compiler.src.inferrer.node_tracer; | 5 library compiler.src.inferrer.node_tracer; |
| 6 | 6 |
| 7 import '../common/names.dart' show Identifiers; | 7 import '../common/names.dart' show Identifiers; |
| 8 import '../compiler.dart' show Compiler; | 8 import '../compiler.dart' show Compiler; |
| 9 import '../elements/elements.dart'; | 9 import '../elements/elements.dart'; |
| 10 import '../elements/entities.dart'; | 10 import '../elements/entities.dart'; |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 203 | 203 |
| 204 void visitBoolLiteralTypeInformation(BoolLiteralTypeInformation info) {} | 204 void visitBoolLiteralTypeInformation(BoolLiteralTypeInformation info) {} |
| 205 | 205 |
| 206 void visitClosureTypeInformation(ClosureTypeInformation info) {} | 206 void visitClosureTypeInformation(ClosureTypeInformation info) {} |
| 207 | 207 |
| 208 void visitClosureCallSiteTypeInformation( | 208 void visitClosureCallSiteTypeInformation( |
| 209 ClosureCallSiteTypeInformation info) {} | 209 ClosureCallSiteTypeInformation info) {} |
| 210 | 210 |
| 211 visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) { | 211 visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) { |
| 212 Element called = info.calledElement; | 212 Element called = info.calledElement; |
| 213 if (inferrer.types.getInferredTypeOf(called) == currentUser) { | 213 if (called.isLocal) { |
| 214 addNewEscapeInformation(info); | 214 if (inferrer.types.getInferredTypeOfLocalFunction(called) == |
| 215 currentUser) { | |
| 216 addNewEscapeInformation(info); | |
| 217 } | |
| 218 } else { | |
| 219 if (inferrer.types.getInferredTypeOfMember(called) == currentUser) { | |
| 220 addNewEscapeInformation(info); | |
| 221 } | |
| 215 } | 222 } |
|
Siggi Cherem (dart-lang)
2017/06/28 16:30:24
nit: maybe use this style to avoid duplicating the
Johnni Winther
2017/06/29 12:36:48
Done.
| |
| 216 } | 223 } |
| 217 | 224 |
| 218 void analyzeStoredIntoList(ListTypeInformation list) { | 225 void analyzeStoredIntoList(ListTypeInformation list) { |
| 219 inferrer.analyzeListAndEnqueue(list); | 226 inferrer.analyzeListAndEnqueue(list); |
| 220 if (list.bailedOut) { | 227 if (list.bailedOut) { |
| 221 bailout('Stored in a list that bailed out'); | 228 bailout('Stored in a list that bailed out'); |
| 222 } else { | 229 } else { |
| 223 list.flowsInto.forEach((flow) { | 230 list.flowsInto.forEach((flow) { |
| 224 flow.users.forEach((dynamic user) { | 231 flow.users.forEach((dynamic user) { |
| 225 if (user is! DynamicCallSiteTypeInformation) return; | 232 if (user is! DynamicCallSiteTypeInformation) return; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 290 | 297 |
| 291 /** | 298 /** |
| 292 * Checks whether the call site flows the currentUser to the value argument of | 299 * Checks whether the call site flows the currentUser to the value argument of |
| 293 * an indexing setter. This must be kept in sync with | 300 * an indexing setter. This must be kept in sync with |
| 294 * [isParameterOfListAddingMethod] and [isParameterOfMapAddingMethod]. | 301 * [isParameterOfListAddingMethod] and [isParameterOfMapAddingMethod]. |
| 295 */ | 302 */ |
| 296 bool isIndexSetValue(DynamicCallSiteTypeInformation info) { | 303 bool isIndexSetValue(DynamicCallSiteTypeInformation info) { |
| 297 return isIndexSetArgument(info, 1); | 304 return isIndexSetArgument(info, 1); |
| 298 } | 305 } |
| 299 | 306 |
| 300 void bailoutIfReaches(bool predicate(Element e)) { | 307 void bailoutIfReaches(bool predicate(ParameterElement e)) { |
| 301 for (var user in currentUser.users) { | 308 for (var user in currentUser.users) { |
| 302 if (user is ParameterTypeInformation) { | 309 if (user is ParameterTypeInformation) { |
| 303 if (predicate(user.element)) { | 310 if (predicate(user.element)) { |
| 304 bailout('Reached suppressed parameter without precise receiver'); | 311 bailout('Reached suppressed parameter without precise receiver'); |
| 305 break; | 312 break; |
| 306 } | 313 } |
| 307 } | 314 } |
| 308 } | 315 } |
| 309 } | 316 } |
| 310 | 317 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 386 } | 393 } |
| 387 | 394 |
| 388 if (info.targetsIncludeComplexNoSuchMethod(inferrer) && | 395 if (info.targetsIncludeComplexNoSuchMethod(inferrer) && |
| 389 info.arguments != null && | 396 info.arguments != null && |
| 390 info.arguments.contains(currentUser)) { | 397 info.arguments.contains(currentUser)) { |
| 391 bailout('Passed to noSuchMethod'); | 398 bailout('Passed to noSuchMethod'); |
| 392 } | 399 } |
| 393 | 400 |
| 394 Iterable<TypeInformation> inferredTargetTypes = | 401 Iterable<TypeInformation> inferredTargetTypes = |
| 395 info.targets.map((MemberEntity entity) { | 402 info.targets.map((MemberEntity entity) { |
| 396 MemberElement element = entity; | 403 return inferrer.types.getInferredTypeOfMember(entity); |
| 397 return inferrer.types.getInferredTypeOf(element); | |
| 398 }); | 404 }); |
| 399 if (inferredTargetTypes.any((user) => user == currentUser)) { | 405 if (inferredTargetTypes.any((user) => user == currentUser)) { |
| 400 addNewEscapeInformation(info); | 406 addNewEscapeInformation(info); |
| 401 } | 407 } |
| 402 } | 408 } |
| 403 | 409 |
| 404 /** | 410 /** |
| 405 * Check whether element is the parameter of a list adding method. | 411 * Check whether element is the parameter of a list adding method. |
| 406 * The definition of what a list adding method is has to stay in sync with | 412 * The definition of what a list adding method is has to stay in sync with |
| 407 * [mightAddToContainer]. | 413 * [mightAddToContainer]. |
| 408 */ | 414 */ |
| 409 bool isParameterOfListAddingMethod(Element element) { | 415 bool isParameterOfListAddingMethod(ParameterElement element) { |
| 410 if (!element.isRegularParameter) return false; | 416 if (!element.isRegularParameter) return false; |
| 411 if (element.enclosingClass != | 417 if (element.enclosingClass != |
| 412 inferrer.closedWorld.commonElements.jsArrayClass) { | 418 inferrer.closedWorld.commonElements.jsArrayClass) { |
| 413 return false; | 419 return false; |
| 414 } | 420 } |
| 415 String name = element.enclosingElement.name; | 421 String name = element.enclosingElement.name; |
| 416 return (name == '[]=') || (name == 'add') || (name == 'insert'); | 422 return (name == '[]=') || (name == 'add') || (name == 'insert'); |
| 417 } | 423 } |
| 418 | 424 |
| 419 /** | 425 /** |
| 420 * Check whether element is the parameter of a list adding method. | 426 * Check whether element is the parameter of a list adding method. |
| 421 * The definition of what a list adding method is has to stay in sync with | 427 * The definition of what a list adding method is has to stay in sync with |
| 422 * [isIndexSetKey] and [isIndexSetValue]. | 428 * [isIndexSetKey] and [isIndexSetValue]. |
| 423 */ | 429 */ |
| 424 bool isParameterOfMapAddingMethod(Element element) { | 430 bool isParameterOfMapAddingMethod(ParameterElement element) { |
| 425 if (!element.isRegularParameter) return false; | 431 if (!element.isRegularParameter) return false; |
| 426 if (element.enclosingClass != | 432 if (element.enclosingClass != |
| 427 inferrer.closedWorld.commonElements.mapLiteralClass) { | 433 inferrer.closedWorld.commonElements.mapLiteralClass) { |
| 428 return false; | 434 return false; |
| 429 } | 435 } |
| 430 String name = element.enclosingElement.name; | 436 String name = element.enclosingElement.name; |
| 431 return (name == '[]='); | 437 return (name == '[]='); |
| 432 } | 438 } |
| 433 | 439 |
| 434 bool isClosure(Element element) { | 440 bool isClosure(Element element) { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 455 } | 461 } |
| 456 if (info.element.isField && | 462 if (info.element.isField && |
| 457 !inferrer.compiler.backend.canFieldBeUsedForGlobalOptimizations( | 463 !inferrer.compiler.backend.canFieldBeUsedForGlobalOptimizations( |
| 458 info.element, inferrer.closedWorld)) { | 464 info.element, inferrer.closedWorld)) { |
| 459 bailout('Escape to code that has special backend treatment'); | 465 bailout('Escape to code that has special backend treatment'); |
| 460 } | 466 } |
| 461 addNewEscapeInformation(info); | 467 addNewEscapeInformation(info); |
| 462 } | 468 } |
| 463 | 469 |
| 464 void visitParameterTypeInformation(ParameterTypeInformation info) { | 470 void visitParameterTypeInformation(ParameterTypeInformation info) { |
| 465 ParameterElement element = info.element; | 471 if (inferrer.isNativeMember(info.declaration)) { |
| 466 if (inferrer.isNativeMember(element.functionDeclaration)) { | |
| 467 bailout('Passed to a native method'); | 472 bailout('Passed to a native method'); |
| 468 } | 473 } |
| 469 if (!inferrer.compiler.backend | 474 if (!inferrer.compiler.backend |
| 470 .canFunctionParametersBeUsedForGlobalOptimizations( | 475 .canFunctionParametersBeUsedForGlobalOptimizations( |
| 471 element.functionDeclaration, inferrer.closedWorld)) { | 476 info.declaration, inferrer.closedWorld)) { |
| 472 bailout('Escape to code that has special backend treatment'); | 477 bailout('Escape to code that has special backend treatment'); |
| 473 } | 478 } |
| 474 if (isParameterOfListAddingMethod(element) || | 479 if (isParameterOfListAddingMethod(info.element) || |
| 475 isParameterOfMapAddingMethod(element)) { | 480 isParameterOfMapAddingMethod(info.element)) { |
| 476 // These elements are being handled in | 481 // These elements are being handled in |
| 477 // [visitDynamicCallSiteTypeInformation]. | 482 // [visitDynamicCallSiteTypeInformation]. |
| 478 return; | 483 return; |
| 479 } | 484 } |
| 480 addNewEscapeInformation(info); | 485 addNewEscapeInformation(info); |
| 481 } | 486 } |
| 482 } | 487 } |
| OLD | NEW |