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 TypeInformation inferred = called.isLocal |
| 214 ? inferrer.types.getInferredTypeOfLocalFunction(called) |
| 215 : inferrer.types.getInferredTypeOfMember(called); |
| 216 if (inferred == currentUser) { |
214 addNewEscapeInformation(info); | 217 addNewEscapeInformation(info); |
215 } | 218 } |
216 } | 219 } |
217 | 220 |
218 void analyzeStoredIntoList(ListTypeInformation list) { | 221 void analyzeStoredIntoList(ListTypeInformation list) { |
219 inferrer.analyzeListAndEnqueue(list); | 222 inferrer.analyzeListAndEnqueue(list); |
220 if (list.bailedOut) { | 223 if (list.bailedOut) { |
221 bailout('Stored in a list that bailed out'); | 224 bailout('Stored in a list that bailed out'); |
222 } else { | 225 } else { |
223 list.flowsInto.forEach((flow) { | 226 list.flowsInto.forEach((flow) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 | 293 |
291 /** | 294 /** |
292 * Checks whether the call site flows the currentUser to the value argument of | 295 * Checks whether the call site flows the currentUser to the value argument of |
293 * an indexing setter. This must be kept in sync with | 296 * an indexing setter. This must be kept in sync with |
294 * [isParameterOfListAddingMethod] and [isParameterOfMapAddingMethod]. | 297 * [isParameterOfListAddingMethod] and [isParameterOfMapAddingMethod]. |
295 */ | 298 */ |
296 bool isIndexSetValue(DynamicCallSiteTypeInformation info) { | 299 bool isIndexSetValue(DynamicCallSiteTypeInformation info) { |
297 return isIndexSetArgument(info, 1); | 300 return isIndexSetArgument(info, 1); |
298 } | 301 } |
299 | 302 |
300 void bailoutIfReaches(bool predicate(Element e)) { | 303 void bailoutIfReaches(bool predicate(ParameterElement e)) { |
301 for (var user in currentUser.users) { | 304 for (var user in currentUser.users) { |
302 if (user is ParameterTypeInformation) { | 305 if (user is ParameterTypeInformation) { |
303 if (predicate(user.element)) { | 306 if (predicate(user.element)) { |
304 bailout('Reached suppressed parameter without precise receiver'); | 307 bailout('Reached suppressed parameter without precise receiver'); |
305 break; | 308 break; |
306 } | 309 } |
307 } | 310 } |
308 } | 311 } |
309 } | 312 } |
310 | 313 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 } | 389 } |
387 | 390 |
388 if (info.targetsIncludeComplexNoSuchMethod(inferrer) && | 391 if (info.targetsIncludeComplexNoSuchMethod(inferrer) && |
389 info.arguments != null && | 392 info.arguments != null && |
390 info.arguments.contains(currentUser)) { | 393 info.arguments.contains(currentUser)) { |
391 bailout('Passed to noSuchMethod'); | 394 bailout('Passed to noSuchMethod'); |
392 } | 395 } |
393 | 396 |
394 Iterable<TypeInformation> inferredTargetTypes = | 397 Iterable<TypeInformation> inferredTargetTypes = |
395 info.targets.map((MemberEntity entity) { | 398 info.targets.map((MemberEntity entity) { |
396 MemberElement element = entity; | 399 return inferrer.types.getInferredTypeOfMember(entity); |
397 return inferrer.types.getInferredTypeOf(element); | |
398 }); | 400 }); |
399 if (inferredTargetTypes.any((user) => user == currentUser)) { | 401 if (inferredTargetTypes.any((user) => user == currentUser)) { |
400 addNewEscapeInformation(info); | 402 addNewEscapeInformation(info); |
401 } | 403 } |
402 } | 404 } |
403 | 405 |
404 /** | 406 /** |
405 * Check whether element is the parameter of a list adding method. | 407 * 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 | 408 * The definition of what a list adding method is has to stay in sync with |
407 * [mightAddToContainer]. | 409 * [mightAddToContainer]. |
408 */ | 410 */ |
409 bool isParameterOfListAddingMethod(Element element) { | 411 bool isParameterOfListAddingMethod(ParameterElement element) { |
410 if (!element.isRegularParameter) return false; | 412 if (!element.isRegularParameter) return false; |
411 if (element.enclosingClass != | 413 if (element.enclosingClass != |
412 inferrer.closedWorld.commonElements.jsArrayClass) { | 414 inferrer.closedWorld.commonElements.jsArrayClass) { |
413 return false; | 415 return false; |
414 } | 416 } |
415 String name = element.enclosingElement.name; | 417 String name = element.enclosingElement.name; |
416 return (name == '[]=') || (name == 'add') || (name == 'insert'); | 418 return (name == '[]=') || (name == 'add') || (name == 'insert'); |
417 } | 419 } |
418 | 420 |
419 /** | 421 /** |
420 * Check whether element is the parameter of a list adding method. | 422 * 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 | 423 * The definition of what a list adding method is has to stay in sync with |
422 * [isIndexSetKey] and [isIndexSetValue]. | 424 * [isIndexSetKey] and [isIndexSetValue]. |
423 */ | 425 */ |
424 bool isParameterOfMapAddingMethod(Element element) { | 426 bool isParameterOfMapAddingMethod(ParameterElement element) { |
425 if (!element.isRegularParameter) return false; | 427 if (!element.isRegularParameter) return false; |
426 if (element.enclosingClass != | 428 if (element.enclosingClass != |
427 inferrer.closedWorld.commonElements.mapLiteralClass) { | 429 inferrer.closedWorld.commonElements.mapLiteralClass) { |
428 return false; | 430 return false; |
429 } | 431 } |
430 String name = element.enclosingElement.name; | 432 String name = element.enclosingElement.name; |
431 return (name == '[]='); | 433 return (name == '[]='); |
432 } | 434 } |
433 | 435 |
434 bool isClosure(Element element) { | 436 bool isClosure(Element element) { |
(...skipping 20 matching lines...) Expand all Loading... |
455 } | 457 } |
456 if (info.element.isField && | 458 if (info.element.isField && |
457 !inferrer.compiler.backend.canFieldBeUsedForGlobalOptimizations( | 459 !inferrer.compiler.backend.canFieldBeUsedForGlobalOptimizations( |
458 info.element, inferrer.closedWorld)) { | 460 info.element, inferrer.closedWorld)) { |
459 bailout('Escape to code that has special backend treatment'); | 461 bailout('Escape to code that has special backend treatment'); |
460 } | 462 } |
461 addNewEscapeInformation(info); | 463 addNewEscapeInformation(info); |
462 } | 464 } |
463 | 465 |
464 void visitParameterTypeInformation(ParameterTypeInformation info) { | 466 void visitParameterTypeInformation(ParameterTypeInformation info) { |
465 ParameterElement element = info.element; | 467 if (inferrer.isNativeMember(info.declaration)) { |
466 if (inferrer.isNativeMember(element.functionDeclaration)) { | |
467 bailout('Passed to a native method'); | 468 bailout('Passed to a native method'); |
468 } | 469 } |
469 if (!inferrer.compiler.backend | 470 if (!inferrer.compiler.backend |
470 .canFunctionParametersBeUsedForGlobalOptimizations( | 471 .canFunctionParametersBeUsedForGlobalOptimizations( |
471 element.functionDeclaration, inferrer.closedWorld)) { | 472 info.declaration, inferrer.closedWorld)) { |
472 bailout('Escape to code that has special backend treatment'); | 473 bailout('Escape to code that has special backend treatment'); |
473 } | 474 } |
474 if (isParameterOfListAddingMethod(element) || | 475 if (isParameterOfListAddingMethod(info.element) || |
475 isParameterOfMapAddingMethod(element)) { | 476 isParameterOfMapAddingMethod(info.element)) { |
476 // These elements are being handled in | 477 // These elements are being handled in |
477 // [visitDynamicCallSiteTypeInformation]. | 478 // [visitDynamicCallSiteTypeInformation]. |
478 return; | 479 return; |
479 } | 480 } |
480 addNewEscapeInformation(info); | 481 addNewEscapeInformation(info); |
481 } | 482 } |
482 } | 483 } |
OLD | NEW |