| 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.enqueue; | 5 library dart2js.enqueue; |
| 6 | 6 |
| 7 import 'dart:collection' show Queue; | 7 import 'dart:collection' show Queue; |
| 8 | 8 |
| 9 import 'common/codegen.dart' show CodegenWorkItem; | 9 import 'common/codegen.dart' show CodegenWorkItem; |
| 10 import 'common/names.dart' show Identifiers; | 10 import 'common/names.dart' show Identifiers; |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 if (member.isField) { | 192 if (member.isField) { |
| 193 // The obvious thing to test here would be "member.isNative", | 193 // The obvious thing to test here would be "member.isNative", |
| 194 // however, that only works after metadata has been parsed/analyzed, | 194 // however, that only works after metadata has been parsed/analyzed, |
| 195 // and that may not have happened yet. | 195 // and that may not have happened yet. |
| 196 // So instead we use the enclosing class, which we know have had | 196 // So instead we use the enclosing class, which we know have had |
| 197 // its metadata parsed and analyzed. | 197 // its metadata parsed and analyzed. |
| 198 // Note: this assumes that there are no non-native fields on native | 198 // Note: this assumes that there are no non-native fields on native |
| 199 // classes, which may not be the case when a native class is subclassed. | 199 // classes, which may not be the case when a native class is subclassed. |
| 200 if (compiler.backend.isNative(cls)) { | 200 if (compiler.backend.isNative(cls)) { |
| 201 compiler.world.registerUsedElement(member); | 201 compiler.world.registerUsedElement(member); |
| 202 nativeEnqueuer.handleFieldAnnotations(member); | |
| 203 if (universe.hasInvokedGetter(member, compiler.world) || | 202 if (universe.hasInvokedGetter(member, compiler.world) || |
| 204 universe.hasInvocation(member, compiler.world)) { | 203 universe.hasInvocation(member, compiler.world)) { |
| 205 nativeEnqueuer.registerFieldLoad(member); | |
| 206 // In handleUnseenSelector we can't tell if the field is loaded or | |
| 207 // stored. We need the basic algorithm to be Church-Rosser, since the | |
| 208 // resolution 'reduction' order is different to the codegen order. So | |
| 209 // register that the field is also stored. In other words: if we | |
| 210 // don't register the store here during resolution, the store could be | |
| 211 // registered during codegen on the handleUnseenSelector path, and | |
| 212 // cause the set of codegen elements to include unresolved elements. | |
| 213 nativeEnqueuer.registerFieldStore(member); | |
| 214 addToWorkList(member); | 204 addToWorkList(member); |
| 215 return; | 205 return; |
| 216 } | 206 } |
| 217 if (universe.hasInvokedSetter(member, compiler.world)) { | 207 if (universe.hasInvokedSetter(member, compiler.world)) { |
| 218 nativeEnqueuer.registerFieldStore(member); | |
| 219 // See comment after registerFieldLoad above. | |
| 220 nativeEnqueuer.registerFieldLoad(member); | |
| 221 addToWorkList(member); | 208 addToWorkList(member); |
| 222 return; | 209 return; |
| 223 } | 210 } |
| 224 // Native fields need to go into instanceMembersByName as they | 211 // Native fields need to go into instanceMembersByName as they |
| 225 // are virtual instantiation points and escape points. | 212 // are virtual instantiation points and escape points. |
| 226 } else { | 213 } else { |
| 227 // All field initializers must be resolved as they could | 214 // All field initializers must be resolved as they could |
| 228 // have an observable side-effect (and cannot be tree-shaken | 215 // have an observable side-effect (and cannot be tree-shaken |
| 229 // away). | 216 // away). |
| 230 addToWorkList(member); | 217 addToWorkList(member); |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 } | 529 } |
| 543 | 530 |
| 544 void handleUnseenSelectorInternal(DynamicUse dynamicUse) { | 531 void handleUnseenSelectorInternal(DynamicUse dynamicUse) { |
| 545 Selector selector = dynamicUse.selector; | 532 Selector selector = dynamicUse.selector; |
| 546 String methodName = selector.name; | 533 String methodName = selector.name; |
| 547 processInstanceMembers(methodName, (Element member) { | 534 processInstanceMembers(methodName, (Element member) { |
| 548 if (dynamicUse.appliesUnnamed(member, compiler.world)) { | 535 if (dynamicUse.appliesUnnamed(member, compiler.world)) { |
| 549 if (member.isFunction && selector.isGetter) { | 536 if (member.isFunction && selector.isGetter) { |
| 550 registerClosurizedMember(member); | 537 registerClosurizedMember(member); |
| 551 } | 538 } |
| 552 if (member.isField && | |
| 553 compiler.backend.isNative(member.enclosingClass)) { | |
| 554 if (selector.isGetter || selector.isCall) { | |
| 555 nativeEnqueuer.registerFieldLoad(member); | |
| 556 // We have to also handle storing to the field because we only get | |
| 557 // one look at each member and there might be a store we have not | |
| 558 // seen yet. | |
| 559 // TODO(sra): Process fields for storing separately. | |
| 560 nativeEnqueuer.registerFieldStore(member); | |
| 561 } else { | |
| 562 assert(selector.isSetter); | |
| 563 nativeEnqueuer.registerFieldStore(member); | |
| 564 // We have to also handle loading from the field because we only get | |
| 565 // one look at each member and there might be a load we have not | |
| 566 // seen yet. | |
| 567 // TODO(sra): Process fields for storing separately. | |
| 568 nativeEnqueuer.registerFieldLoad(member); | |
| 569 } | |
| 570 } | |
| 571 addToWorkList(member); | 539 addToWorkList(member); |
| 572 return true; | 540 return true; |
| 573 } | 541 } |
| 574 return false; | 542 return false; |
| 575 }); | 543 }); |
| 576 if (selector.isGetter) { | 544 if (selector.isGetter) { |
| 577 processInstanceFunctions(methodName, (Element member) { | 545 processInstanceFunctions(methodName, (Element member) { |
| 578 if (dynamicUse.appliesUnnamed(member, compiler.world)) { | 546 if (dynamicUse.appliesUnnamed(member, compiler.world)) { |
| 579 registerClosurizedMember(member); | 547 registerClosurizedMember(member); |
| 580 return true; | 548 return true; |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 803 // We have to enable runtime type before hitting the codegen, so | 771 // We have to enable runtime type before hitting the codegen, so |
| 804 // that constructors know whether they need to generate code for | 772 // that constructors know whether they need to generate code for |
| 805 // runtime type. | 773 // runtime type. |
| 806 compiler.enabledRuntimeType = true; | 774 compiler.enabledRuntimeType = true; |
| 807 // TODO(ahe): Record precise dependency here. | 775 // TODO(ahe): Record precise dependency here. |
| 808 compiler.backend.registerRuntimeType(this, compiler.globalDependencies); | 776 compiler.backend.registerRuntimeType(this, compiler.globalDependencies); |
| 809 } else if (element == compiler.functionApplyMethod) { | 777 } else if (element == compiler.functionApplyMethod) { |
| 810 compiler.enabledFunctionApply = true; | 778 compiler.enabledFunctionApply = true; |
| 811 } | 779 } |
| 812 | 780 |
| 813 nativeEnqueuer.registerElement(element); | |
| 814 return true; | 781 return true; |
| 815 } | 782 } |
| 816 | 783 |
| 817 void registerNoSuchMethod(Element element) { | 784 void registerNoSuchMethod(Element element) { |
| 818 compiler.backend.registerNoSuchMethod(element); | 785 compiler.backend.registerNoSuchMethod(element); |
| 819 } | 786 } |
| 820 | 787 |
| 821 void enableIsolateSupport() { | 788 void enableIsolateSupport() { |
| 822 compiler.hasIsolateSupport = true; | 789 compiler.hasIsolateSupport = true; |
| 823 compiler.backend.enableIsolateSupport(this); | 790 compiler.backend.enableIsolateSupport(this); |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1048 } | 1015 } |
| 1049 | 1016 |
| 1050 typedef void _DeferredActionFunction(); | 1017 typedef void _DeferredActionFunction(); |
| 1051 | 1018 |
| 1052 class _DeferredAction { | 1019 class _DeferredAction { |
| 1053 final Element element; | 1020 final Element element; |
| 1054 final _DeferredActionFunction action; | 1021 final _DeferredActionFunction action; |
| 1055 | 1022 |
| 1056 _DeferredAction(this.element, this.action); | 1023 _DeferredAction(this.element, this.action); |
| 1057 } | 1024 } |
| OLD | NEW |