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 |