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 library universe; | 5 library universe; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import '../common.dart'; | 9 import '../common.dart'; |
10 import '../compiler.dart' show | 10 import '../compiler.dart' show |
11 Compiler; | 11 Compiler; |
12 import '../elements/elements.dart'; | 12 import '../elements/elements.dart'; |
13 import '../dart_types.dart'; | 13 import '../dart_types.dart'; |
14 import '../util/util.dart'; | 14 import '../util/util.dart'; |
15 import '../world.dart' show | 15 import '../world.dart' show |
16 ClassWorld, | 16 ClassWorld, |
17 World; | 17 World; |
18 | 18 |
19 import 'selector.dart' show | 19 import 'selector.dart' show |
20 Selector; | 20 Selector; |
21 import 'use.dart' show | 21 import 'use.dart' show |
| 22 DynamicUse, |
| 23 DynamicUseKind, |
22 StaticUse, | 24 StaticUse, |
23 StaticUseKind; | 25 StaticUseKind; |
24 | 26 |
25 enum DynamicUseKind { | |
26 INVOKE, | |
27 GET, | |
28 SET, | |
29 } | |
30 | |
31 // TODO(johnniwinther): Rename to `DynamicUse` and move to 'use.dart'. | |
32 class UniverseSelector { | |
33 final Selector selector; | |
34 final ReceiverConstraint mask; | |
35 | |
36 UniverseSelector(this.selector, this.mask); | |
37 | |
38 bool appliesUnnamed(Element element, ClassWorld world) { | |
39 return selector.appliesUnnamed(element, world) && | |
40 (mask == null || mask.canHit(element, selector, world)); | |
41 } | |
42 | |
43 DynamicUseKind get kind { | |
44 if (selector.isGetter) { | |
45 return DynamicUseKind.GET; | |
46 } else if (selector.isSetter) { | |
47 return DynamicUseKind.SET; | |
48 } else { | |
49 return DynamicUseKind.INVOKE; | |
50 } | |
51 } | |
52 | |
53 int get hashCode => selector.hashCode * 13 + mask.hashCode * 17; | |
54 | |
55 bool operator ==(other) { | |
56 if (identical(this, other)) return true; | |
57 if (other is! UniverseSelector) return false; | |
58 return selector == other.selector && mask == other.mask; | |
59 } | |
60 | |
61 String toString() => '$selector,$mask'; | |
62 } | |
63 | |
64 /// The known constraint on receiver for a dynamic call site. | 27 /// The known constraint on receiver for a dynamic call site. |
65 /// | 28 /// |
66 /// This can for instance be used to constrain this dynamic call to `foo` to | 29 /// This can for instance be used to constrain this dynamic call to `foo` to |
67 /// 'receivers of the exact instance `Bar`': | 30 /// 'receivers of the exact instance `Bar`': |
68 /// | 31 /// |
69 /// class Bar { | 32 /// class Bar { |
70 /// void foo() {} | 33 /// void foo() {} |
71 /// } | 34 /// } |
72 /// main() => new Bar().foo(); | 35 /// main() => new Bar().foo(); |
73 /// | 36 /// |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 } | 299 } |
337 | 300 |
338 bool hasInvokedGetter(Element member, World world) { | 301 bool hasInvokedGetter(Element member, World world) { |
339 return _hasMatchingSelector(_invokedGetters[member.name], member, world); | 302 return _hasMatchingSelector(_invokedGetters[member.name], member, world); |
340 } | 303 } |
341 | 304 |
342 bool hasInvokedSetter(Element member, World world) { | 305 bool hasInvokedSetter(Element member, World world) { |
343 return _hasMatchingSelector(_invokedSetters[member.name], member, world); | 306 return _hasMatchingSelector(_invokedSetters[member.name], member, world); |
344 } | 307 } |
345 | 308 |
346 bool registerDynamicUse(UniverseSelector selector) { | 309 bool registerDynamicUse(DynamicUse dynamicUse) { |
347 switch (selector.kind) { | 310 switch (dynamicUse.kind) { |
348 case DynamicUseKind.INVOKE: | 311 case DynamicUseKind.INVOKE: |
349 return _registerNewSelector(selector, _invokedNames); | 312 return _registerNewSelector(dynamicUse, _invokedNames); |
350 case DynamicUseKind.GET: | 313 case DynamicUseKind.GET: |
351 return _registerNewSelector(selector, _invokedGetters); | 314 return _registerNewSelector(dynamicUse, _invokedGetters); |
352 case DynamicUseKind.SET: | 315 case DynamicUseKind.SET: |
353 return _registerNewSelector(selector, _invokedSetters); | 316 return _registerNewSelector(dynamicUse, _invokedSetters); |
354 } | 317 } |
355 } | 318 } |
356 | 319 |
357 bool _registerNewSelector( | 320 bool _registerNewSelector( |
358 UniverseSelector universeSelector, | 321 DynamicUse dynamicUse, |
359 Map<String, Map<Selector, SelectorConstraints>> selectorMap) { | 322 Map<String, Map<Selector, SelectorConstraints>> selectorMap) { |
360 Selector selector = universeSelector.selector; | 323 Selector selector = dynamicUse.selector; |
361 String name = selector.name; | 324 String name = selector.name; |
362 ReceiverConstraint mask = universeSelector.mask; | 325 ReceiverConstraint mask = dynamicUse.mask; |
363 Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent( | 326 Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent( |
364 name, () => new Maplet<Selector, SelectorConstraints>()); | 327 name, () => new Maplet<Selector, SelectorConstraints>()); |
365 UniverseSelectorConstraints constraints = selectors.putIfAbsent( | 328 UniverseSelectorConstraints constraints = selectors.putIfAbsent( |
366 selector, () => selectorConstraintsStrategy.createSelectorConstraints(se
lector)); | 329 selector, () => selectorConstraintsStrategy.createSelectorConstraints(se
lector)); |
367 return constraints.addReceiverConstraint(mask); | 330 return constraints.addReceiverConstraint(mask); |
368 } | 331 } |
369 | 332 |
370 Map<Selector, SelectorConstraints> _asUnmodifiable( | 333 Map<Selector, SelectorConstraints> _asUnmodifiable( |
371 Map<Selector, SelectorConstraints> map) { | 334 Map<Selector, SelectorConstraints> map) { |
372 if (map == null) return null; | 335 if (map == null) return null; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 // TODO(ahe): Replace this method with something that is O(1), for example, | 417 // TODO(ahe): Replace this method with something that is O(1), for example, |
455 // by using a map. | 418 // by using a map. |
456 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { | 419 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { |
457 // Return new list to guard against concurrent modifications. | 420 // Return new list to guard against concurrent modifications. |
458 return new List<LocalFunctionElement>.from( | 421 return new List<LocalFunctionElement>.from( |
459 allClosures.where((LocalFunctionElement closure) { | 422 allClosures.where((LocalFunctionElement closure) { |
460 return closure.executableContext == element; | 423 return closure.executableContext == element; |
461 })); | 424 })); |
462 } | 425 } |
463 } | 426 } |
OLD | NEW |