| 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 dart2js.world; | 5 library dart2js.world; |
| 6 | 6 |
| 7 import 'closure.dart' show SynthesizedCallMethodElementX; | 7 import 'closure.dart' show SynthesizedCallMethodElementX; |
| 8 import 'common/backend_api.dart' show Backend; | 8 import 'common/backend_api.dart' show Backend; |
| 9 import 'common.dart'; | 9 import 'common.dart'; |
| 10 import 'compiler.dart' show Compiler; | 10 import 'compiler.dart' show Compiler; |
| 11 import 'core_types.dart' show CoreClasses; | 11 import 'core_types.dart' show CoreClasses; |
| 12 import 'dart_types.dart'; | 12 import 'dart_types.dart'; |
| 13 import 'elements/elements.dart' | 13 import 'elements/elements.dart' |
| 14 show | 14 show |
| 15 ClassElement, | 15 ClassElement, |
| 16 Element, | 16 Element, |
| 17 FunctionElement, | 17 FunctionElement, |
| 18 MixinApplicationElement, | 18 MixinApplicationElement, |
| 19 TypedefElement, | 19 TypedefElement, |
| 20 VariableElement; | 20 VariableElement; |
| 21 import 'ordered_typeset.dart'; | 21 import 'ordered_typeset.dart'; |
| 22 import 'types/types.dart' as ti; | 22 import 'types/masks.dart' show TypeMask, FlatTypeMask; |
| 23 import 'universe/class_set.dart'; | 23 import 'universe/class_set.dart'; |
| 24 import 'universe/function_set.dart' show FunctionSet; | 24 import 'universe/function_set.dart' show FunctionSet; |
| 25 import 'universe/selector.dart' show Selector; | 25 import 'universe/selector.dart' show Selector; |
| 26 import 'universe/side_effects.dart' show SideEffects; | 26 import 'universe/side_effects.dart' show SideEffects; |
| 27 import 'util/util.dart' show Link; | 27 import 'util/util.dart' show Link; |
| 28 | 28 |
| 29 /// The [ClassWorld] represents the information known about a program when | 29 /// The [ClassWorld] represents the information known about a program when |
| 30 /// compiling with closed-world semantics. | 30 /// compiling with closed-world semantics. |
| 31 /// | 31 /// |
| 32 /// Given the entrypoint of an application, we can track what's reachable from | 32 /// Given the entrypoint of an application, we can track what's reachable from |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 class World implements ClassWorld { | 183 class World implements ClassWorld { |
| 184 ClassElement get objectClass => coreClasses.objectClass; | 184 ClassElement get objectClass => coreClasses.objectClass; |
| 185 ClassElement get functionClass => coreClasses.functionClass; | 185 ClassElement get functionClass => coreClasses.functionClass; |
| 186 ClassElement get boolClass => coreClasses.boolClass; | 186 ClassElement get boolClass => coreClasses.boolClass; |
| 187 ClassElement get numClass => coreClasses.numClass; | 187 ClassElement get numClass => coreClasses.numClass; |
| 188 ClassElement get intClass => coreClasses.intClass; | 188 ClassElement get intClass => coreClasses.intClass; |
| 189 ClassElement get doubleClass => coreClasses.doubleClass; | 189 ClassElement get doubleClass => coreClasses.doubleClass; |
| 190 ClassElement get stringClass => coreClasses.stringClass; | 190 ClassElement get stringClass => coreClasses.stringClass; |
| 191 ClassElement get nullClass => coreClasses.nullClass; | 191 ClassElement get nullClass => coreClasses.nullClass; |
| 192 | 192 |
| 193 /// Cache of [ti.FlatTypeMask]s grouped by the 8 possible values of the | 193 /// Cache of [FlatTypeMask]s grouped by the 8 possible values of the |
| 194 /// [ti.FlatTypeMask.flags] property. | 194 /// `FlatTypeMask.flags` property. |
| 195 List<Map<ClassElement, ti.TypeMask>> canonicalizedTypeMasks = | 195 List<Map<ClassElement, TypeMask>> canonicalizedTypeMasks = |
| 196 new List<Map<ClassElement, ti.TypeMask>>.filled(8, null); | 196 new List<Map<ClassElement, TypeMask>>.filled(8, null); |
| 197 | 197 |
| 198 bool checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) { | 198 bool checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) { |
| 199 return invariant(cls, cls.isDeclaration, | 199 return invariant(cls, cls.isDeclaration, |
| 200 message: '$cls must be the declaration.') && | 200 message: '$cls must be the declaration.') && |
| 201 invariant(cls, cls.isResolved, | 201 invariant(cls, cls.isResolved, |
| 202 message: | 202 message: |
| 203 '$cls must be resolved.') /* && | 203 '$cls must be resolved.') /* && |
| 204 // TODO(johnniwinther): Reinsert this or similar invariant. | 204 // TODO(johnniwinther): Reinsert this or similar invariant. |
| 205 (!mustBeInstantiated || | 205 (!mustBeInstantiated || |
| 206 invariant(cls, isInstantiated(cls), | 206 invariant(cls, isInstantiated(cls), |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 void registerMixinUse( | 703 void registerMixinUse( |
| 704 MixinApplicationElement mixinApplication, ClassElement mixin) { | 704 MixinApplicationElement mixinApplication, ClassElement mixin) { |
| 705 // TODO(johnniwinther): Add map restricted to live classes. | 705 // TODO(johnniwinther): Add map restricted to live classes. |
| 706 // We don't support patch classes as mixin. | 706 // We don't support patch classes as mixin. |
| 707 assert(mixin.isDeclaration); | 707 assert(mixin.isDeclaration); |
| 708 Set<MixinApplicationElement> users = | 708 Set<MixinApplicationElement> users = |
| 709 _mixinUses.putIfAbsent(mixin, () => new Set<MixinApplicationElement>()); | 709 _mixinUses.putIfAbsent(mixin, () => new Set<MixinApplicationElement>()); |
| 710 users.add(mixinApplication); | 710 users.add(mixinApplication); |
| 711 } | 711 } |
| 712 | 712 |
| 713 bool hasAnyUserDefinedGetter(Selector selector, ti.TypeMask mask) { | 713 bool hasAnyUserDefinedGetter(Selector selector, TypeMask mask) { |
| 714 return allFunctions.filter(selector, mask).any((each) => each.isGetter); | 714 return allFunctions.filter(selector, mask).any((each) => each.isGetter); |
| 715 } | 715 } |
| 716 | 716 |
| 717 void registerUsedElement(Element element) { | 717 void registerUsedElement(Element element) { |
| 718 if (element.isInstanceMember && !element.isAbstract) { | 718 if (element.isInstanceMember && !element.isAbstract) { |
| 719 allFunctions.add(element); | 719 allFunctions.add(element); |
| 720 } | 720 } |
| 721 } | 721 } |
| 722 | 722 |
| 723 VariableElement locateSingleField(Selector selector, ti.TypeMask mask) { | 723 VariableElement locateSingleField(Selector selector, TypeMask mask) { |
| 724 Element result = locateSingleElement(selector, mask); | 724 Element result = locateSingleElement(selector, mask); |
| 725 return (result != null && result.isField) ? result : null; | 725 return (result != null && result.isField) ? result : null; |
| 726 } | 726 } |
| 727 | 727 |
| 728 Element locateSingleElement(Selector selector, ti.TypeMask mask) { | 728 Element locateSingleElement(Selector selector, TypeMask mask) { |
| 729 mask = mask == null ? compiler.typesTask.dynamicType : mask; | 729 mask ??= compiler.commonMasks.dynamicType; |
| 730 return mask.locateSingleElement(selector, mask, compiler); | 730 return mask.locateSingleElement(selector, mask, compiler); |
| 731 } | 731 } |
| 732 | 732 |
| 733 ti.TypeMask extendMaskIfReachesAll(Selector selector, ti.TypeMask mask) { | 733 TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) { |
| 734 bool canReachAll = true; | 734 bool canReachAll = true; |
| 735 if (mask != null) { | 735 if (mask != null) { |
| 736 canReachAll = compiler.enabledInvokeOn && | 736 canReachAll = compiler.enabledInvokeOn && |
| 737 mask.needsNoSuchMethodHandling(selector, this); | 737 mask.needsNoSuchMethodHandling(selector, this); |
| 738 } | 738 } |
| 739 return canReachAll ? compiler.typesTask.dynamicType : mask; | 739 return canReachAll ? compiler.commonMasks.dynamicType : mask; |
| 740 } | 740 } |
| 741 | 741 |
| 742 void addFunctionCalledInLoop(Element element) { | 742 void addFunctionCalledInLoop(Element element) { |
| 743 functionsCalledInLoop.add(element.declaration); | 743 functionsCalledInLoop.add(element.declaration); |
| 744 } | 744 } |
| 745 | 745 |
| 746 bool isCalledInLoop(Element element) { | 746 bool isCalledInLoop(Element element) { |
| 747 return functionsCalledInLoop.contains(element.declaration); | 747 return functionsCalledInLoop.contains(element.declaration); |
| 748 } | 748 } |
| 749 | 749 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 784 void registerSideEffects(Element element, SideEffects effects) { | 784 void registerSideEffects(Element element, SideEffects effects) { |
| 785 if (sideEffectsFreeElements.contains(element)) return; | 785 if (sideEffectsFreeElements.contains(element)) return; |
| 786 sideEffects[element.declaration] = effects; | 786 sideEffects[element.declaration] = effects; |
| 787 } | 787 } |
| 788 | 788 |
| 789 void registerSideEffectsFree(Element element) { | 789 void registerSideEffectsFree(Element element) { |
| 790 sideEffects[element.declaration] = new SideEffects.empty(); | 790 sideEffects[element.declaration] = new SideEffects.empty(); |
| 791 sideEffectsFreeElements.add(element); | 791 sideEffectsFreeElements.add(element); |
| 792 } | 792 } |
| 793 | 793 |
| 794 SideEffects getSideEffectsOfSelector(Selector selector, ti.TypeMask mask) { | 794 SideEffects getSideEffectsOfSelector(Selector selector, TypeMask mask) { |
| 795 // We're not tracking side effects of closures. | 795 // We're not tracking side effects of closures. |
| 796 if (selector.isClosureCall) return new SideEffects(); | 796 if (selector.isClosureCall) return new SideEffects(); |
| 797 SideEffects sideEffects = new SideEffects.empty(); | 797 SideEffects sideEffects = new SideEffects.empty(); |
| 798 for (Element e in allFunctions.filter(selector, mask)) { | 798 for (Element e in allFunctions.filter(selector, mask)) { |
| 799 if (e.isField) { | 799 if (e.isField) { |
| 800 if (selector.isGetter) { | 800 if (selector.isGetter) { |
| 801 if (!fieldNeverChanges(e)) { | 801 if (!fieldNeverChanges(e)) { |
| 802 sideEffects.setDependsOnInstancePropertyStore(); | 802 sideEffects.setDependsOnInstancePropertyStore(); |
| 803 } | 803 } |
| 804 } else if (selector.isSetter) { | 804 } else if (selector.isSetter) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 835 // function expressions's element. | 835 // function expressions's element. |
| 836 // TODO(herhut): Generate classes for function expressions earlier. | 836 // TODO(herhut): Generate classes for function expressions earlier. |
| 837 if (element is SynthesizedCallMethodElementX) { | 837 if (element is SynthesizedCallMethodElementX) { |
| 838 return getMightBePassedToApply(element.expression); | 838 return getMightBePassedToApply(element.expression); |
| 839 } | 839 } |
| 840 return functionsThatMightBePassedToApply.contains(element); | 840 return functionsThatMightBePassedToApply.contains(element); |
| 841 } | 841 } |
| 842 | 842 |
| 843 bool get hasClosedWorldAssumption => !compiler.options.hasIncrementalSupport; | 843 bool get hasClosedWorldAssumption => !compiler.options.hasIncrementalSupport; |
| 844 } | 844 } |
| OLD | NEW |