Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(124)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/enqueue.dart

Issue 12334070: Support runtime check of function types. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Minor fix Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 part of dart2js; 5 part of dart2js;
6 6
7 class EnqueueTask extends CompilerTask { 7 class EnqueueTask extends CompilerTask {
8 final ResolutionEnqueuer resolution; 8 final ResolutionEnqueuer resolution;
9 final CodegenEnqueuer codegen; 9 final CodegenEnqueuer codegen;
10 10
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 } 170 }
171 } 171 }
172 }); 172 });
173 return true; 173 return true;
174 } 174 }
175 175
176 void processInstantiatedClass(ClassElement cls) { 176 void processInstantiatedClass(ClassElement cls) {
177 cls.implementation.forEachMember(processInstantiatedClassMember); 177 cls.implementation.forEachMember(processInstantiatedClassMember);
178 } 178 }
179 179
180 /**
181 * Documentation wanted -- johnniwinther
182 */
183 void processInstantiatedClassMember(ClassElement cls, Element member) { 180 void processInstantiatedClassMember(ClassElement cls, Element member) {
184 assert(invariant(member, member.isDeclaration)); 181 assert(invariant(member, member.isDeclaration));
185 if (isProcessed(member)) return; 182 if (isProcessed(member)) return;
186 if (!member.isInstanceMember()) return; 183 if (!member.isInstanceMember()) return;
187 184
188 String memberName = member.name.slowToString(); 185 String memberName = member.name.slowToString();
189 186
190 if (member.kind == ElementKind.FIELD) { 187 if (member.kind == ElementKind.FIELD) {
191 // The obvious thing to test here would be "member.isNative()", 188 // The obvious thing to test here would be "member.isNative()",
192 // however, that only works after metadata has been parsed/analyzed, 189 // however, that only works after metadata has been parsed/analyzed,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 // All field initializers must be resolved as they could 222 // All field initializers must be resolved as they could
226 // have an observable side-effect (and cannot be tree-shaken 223 // have an observable side-effect (and cannot be tree-shaken
227 // away). 224 // away).
228 addToWorkList(member); 225 addToWorkList(member);
229 return; 226 return;
230 } 227 }
231 } else if (member.kind == ElementKind.FUNCTION) { 228 } else if (member.kind == ElementKind.FUNCTION) {
232 if (member.name == Compiler.NO_SUCH_METHOD) { 229 if (member.name == Compiler.NO_SUCH_METHOD) {
233 enableNoSuchMethod(member); 230 enableNoSuchMethod(member);
234 } 231 }
232 if (member.name == Compiler.CALL_OPERATOR_NAME &&
233 !cls.typeVariables.isEmpty) {
234 registerGenericCallMethod(member, compiler.globalDependencies);
235 }
235 // If there is a property access with the same name as a method we 236 // If there is a property access with the same name as a method we
236 // need to emit the method. 237 // need to emit the method.
237 if (universe.hasInvokedGetter(member, compiler)) { 238 if (universe.hasInvokedGetter(member, compiler)) {
238 // We will emit a closure, so make sure the bound closure class is 239 registerClosurizedMember(member, compiler.globalDependencies);
240 // We will emit a closure, so make sure the closure class is
239 // generated. 241 // generated.
240 registerInstantiatedClass(compiler.boundClosureClass, 242 registerInstantiatedClass(compiler.boundClosureClass,
241 // Precise dependency is not important here. 243 // Precise dependency is not important here.
242 compiler.globalDependencies); 244 compiler.globalDependencies);
243 return addToWorkList(member); 245 return addToWorkList(member);
244 } 246 }
245 // Store the member in [instanceFunctionsByName] to catch 247 // Store the member in [instanceFunctionsByName] to catch
246 // getters on the function. 248 // getters on the function.
247 Link<Element> members = instanceFunctionsByName.putIfAbsent( 249 Link<Element> members = instanceFunctionsByName.putIfAbsent(
248 memberName, () => const Link<Element>()); 250 memberName, () => const Link<Element>());
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 } 403 }
402 hasEnqueuedEverything = true; 404 hasEnqueuedEverything = true;
403 } 405 }
404 406
405 processLink(Map<String, Link<Element>> map, 407 processLink(Map<String, Link<Element>> map,
406 SourceString n, 408 SourceString n,
407 bool f(Element e)) { 409 bool f(Element e)) {
408 String memberName = n.slowToString(); 410 String memberName = n.slowToString();
409 Link<Element> members = map[memberName]; 411 Link<Element> members = map[memberName];
410 if (members != null) { 412 if (members != null) {
413 // [f] might add elements to [: map[memberName] :] during the loop below
414 // so we create a new list for [: map[memberName] :] and prepend the
415 // [remaining] members after the loop.
416 map[memberName] = const Link<Element>();
411 LinkBuilder<Element> remaining = new LinkBuilder<Element>(); 417 LinkBuilder<Element> remaining = new LinkBuilder<Element>();
412 for (; !members.isEmpty; members = members.tail) { 418 for (; !members.isEmpty; members = members.tail) {
413 if (!f(members.head)) remaining.addLast(members.head); 419 if (!f(members.head)) remaining.addLast(members.head);
414 } 420 }
415 map[memberName] = remaining.toLink(); 421 map[memberName] = remaining.toLink(map[memberName]);
416 } 422 }
417 } 423 }
418 424
419 processInstanceMembers(SourceString n, bool f(Element e)) { 425 processInstanceMembers(SourceString n, bool f(Element e)) {
420 processLink(instanceMembersByName, n, f); 426 processLink(instanceMembersByName, n, f);
421 } 427 }
422 428
423 processInstanceFunctions(SourceString n, bool f(Element e)) { 429 processInstanceFunctions(SourceString n, bool f(Element e)) {
424 processLink(instanceFunctionsByName, n, f); 430 processLink(instanceFunctionsByName, n, f);
425 } 431 }
426 432
427 void handleUnseenSelector(SourceString methodName, Selector selector) { 433 void handleUnseenSelector(SourceString methodName, Selector selector) {
428 processInstanceMembers(methodName, (Element member) { 434 processInstanceMembers(methodName, (Element member) {
429 if (selector.appliesUnnamed(member, compiler)) { 435 if (selector.appliesUnnamed(member, compiler)) {
436 if (member.isFunction() && selector.isGetter()) {
437 registerClosurizedMember(member, compiler.globalDependencies);
438 }
430 if (member.isField() && member.getEnclosingClass().isNative()) { 439 if (member.isField() && member.getEnclosingClass().isNative()) {
431 if (selector.isGetter() || selector.isCall()) { 440 if (selector.isGetter() || selector.isCall()) {
432 nativeEnqueuer.registerFieldLoad(member); 441 nativeEnqueuer.registerFieldLoad(member);
433 // We have to also handle storing to the field because we only get 442 // We have to also handle storing to the field because we only get
434 // one look at each member and there might be a store we have not 443 // one look at each member and there might be a store we have not
435 // seen yet. 444 // seen yet.
436 // TODO(sra): Process fields for storing separately. 445 // TODO(sra): Process fields for storing separately.
437 nativeEnqueuer.registerFieldStore(member); 446 nativeEnqueuer.registerFieldStore(member);
438 } else { 447 } else {
439 assert(selector.isSetter()); 448 assert(selector.isSetter());
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 540
532 void registerFieldGetter(Element element) { 541 void registerFieldGetter(Element element) {
533 universe.fieldGetters.add(element); 542 universe.fieldGetters.add(element);
534 } 543 }
535 544
536 void registerFieldSetter(Element element) { 545 void registerFieldSetter(Element element) {
537 universe.fieldSetters.add(element); 546 universe.fieldSetters.add(element);
538 } 547 }
539 548
540 void registerIsCheck(DartType type, TreeElements elements) { 549 void registerIsCheck(DartType type, TreeElements elements) {
550 type = universe.registerIsCheck(type, compiler);
541 // Even in checked mode, type annotations for return type and argument 551 // Even in checked mode, type annotations for return type and argument
542 // types do not imply type checks, so there should never be a check 552 // types do not imply type checks, so there should never be a check
543 // against the type variable of a typedef. 553 // against the type variable of a typedef.
544 assert(type.kind != TypeKind.TYPE_VARIABLE || 554 assert(type.kind != TypeKind.TYPE_VARIABLE ||
545 !type.element.enclosingElement.isTypedef()); 555 !type.element.enclosingElement.isTypedef());
546 universe.isChecks.add(type);
547 compiler.backend.registerIsCheck(type, this, elements); 556 compiler.backend.registerIsCheck(type, this, elements);
548 } 557 }
549 558
550 /** 559 /**
551 * If a factory constructor is used with type arguments, we lose track 560 * If a factory constructor is used with type arguments, we lose track
552 * which arguments could be used to create instances of classes that use their 561 * which arguments could be used to create instances of classes that use their
553 * type variables as expressions, so we have to remember if we saw such a use. 562 * type variables as expressions, so we have to remember if we saw such a use.
554 */ 563 */
555 void registerFactoryWithTypeArguments(TreeElements elements) { 564 void registerFactoryWithTypeArguments(TreeElements elements) {
556 universe.usingFactoryWithTypeArguments = true; 565 universe.usingFactoryWithTypeArguments = true;
557 } 566 }
558 567
559 void registerAsCheck(DartType type, TreeElements elements) { 568 void registerAsCheck(DartType type, TreeElements elements) {
560 registerIsCheck(type, elements); 569 registerIsCheck(type, elements);
561 compiler.backend.registerAsCheck(type, elements); 570 compiler.backend.registerAsCheck(type, elements);
562 } 571 }
563 572
573 void registerGenericCallMethod(Element element, TreeElements elements) {
574 compiler.backend.registerGenericCallMethod(element, this, elements);
575 universe.genericCallMethods.add(element);
576 }
577
578 void registerClosurizedMember(Element element, TreeElements elements) {
579 if (element.computeType(compiler).containsTypeVariables) {
580 registerClosurizedGenericMember(element, elements);
581 }
582 universe.closurizedMembers.add(element);
583 }
584
585 void registerClosurizedGenericMember(Element element, TreeElements elements) {
586 compiler.backend.registerGenericClosure(element, this, elements);
587 universe.closurizedGenericMembers.add(element);
588 }
589
564 void forEach(f(WorkItem work)); 590 void forEach(f(WorkItem work));
565 591
566 void forEachPostProcessTask(f(PostProcessTask work)) {} 592 void forEachPostProcessTask(f(PostProcessTask work)) {}
567 593
568 void logSummary(log(message)) { 594 void logSummary(log(message)) {
569 _logSpecificSummary(log); 595 _logSpecificSummary(log);
570 nativeEnqueuer.logSummary(log); 596 nativeEnqueuer.logSummary(log);
571 } 597 }
572 598
573 /// Log summary specific to the concrete enqueuer. 599 /// Log summary specific to the concrete enqueuer.
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 } 674 }
649 } 675 }
650 676
651 if (element.isGetter() && element.name == Compiler.RUNTIME_TYPE) { 677 if (element.isGetter() && element.name == Compiler.RUNTIME_TYPE) {
652 // Enable runtime type support if we discover a getter called runtimeType. 678 // Enable runtime type support if we discover a getter called runtimeType.
653 // We have to enable runtime type before hitting the codegen, so 679 // We have to enable runtime type before hitting the codegen, so
654 // that constructors know whether they need to generate code for 680 // that constructors know whether they need to generate code for
655 // runtime type. 681 // runtime type.
656 compiler.enabledRuntimeType = true; 682 compiler.enabledRuntimeType = true;
657 // TODO(ahe): Record precise dependency here. 683 // TODO(ahe): Record precise dependency here.
658 compiler.backend.registerRuntimeType(compiler.globalDependencies); 684 compiler.backend.registerRuntimeType(this, compiler.globalDependencies);
659 } else if (element == compiler.functionApplyMethod) { 685 } else if (element == compiler.functionApplyMethod) {
660 compiler.enabledFunctionApply = true; 686 compiler.enabledFunctionApply = true;
661 } else if (element == compiler.invokeOnMethod) { 687 } else if (element == compiler.invokeOnMethod) {
662 compiler.enabledInvokeOn = true; 688 compiler.enabledInvokeOn = true;
663 } 689 }
664 690
665 nativeEnqueuer.registerElement(element); 691 nativeEnqueuer.registerElement(element);
666 } 692 }
667 693
668 void enableIsolateSupport(LibraryElement element) { 694 void enableIsolateSupport(LibraryElement element) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 while(!queue.isEmpty) { 785 while(!queue.isEmpty) {
760 // TODO(johnniwinther): Find an optimal process order for codegen. 786 // TODO(johnniwinther): Find an optimal process order for codegen.
761 f(queue.removeLast()); 787 f(queue.removeLast());
762 } 788 }
763 } 789 }
764 790
765 void _logSpecificSummary(log(message)) { 791 void _logSpecificSummary(log(message)) {
766 log('Compiled ${generatedCode.length} methods.'); 792 log('Compiled ${generatedCode.length} methods.');
767 } 793 }
768 } 794 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698