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

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: Fix status files 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 return true; 172 return true;
173 } 173 }
174 174
175 void processInstantiatedClass(ClassElement cls) { 175 void processInstantiatedClass(ClassElement cls) {
176 cls.implementation.forEachMember(processInstantiatedClassMember); 176 cls.implementation.forEachMember(processInstantiatedClassMember);
177 } 177 }
178 178
179 /** 179 /**
180 * Documentation wanted -- johnniwinther 180 * Documentation wanted -- johnniwinther
karlklose 2013/06/19 14:37:05 I think we can remove this 'documentation'.
Johnni Winther 2013/06/21 12:19:15 Done.
181 */ 181 */
182 void processInstantiatedClassMember(ClassElement cls, Element member) { 182 void processInstantiatedClassMember(ClassElement cls, Element member) {
183 assert(invariant(member, member.isDeclaration)); 183 assert(invariant(member, member.isDeclaration));
184 if (isProcessed(member)) return; 184 if (isProcessed(member)) return;
185 if (!member.isInstanceMember()) return; 185 if (!member.isInstanceMember()) return;
186 186
187 String memberName = member.name.slowToString(); 187 String memberName = member.name.slowToString();
188 188
189 if (member.kind == ElementKind.FIELD) { 189 if (member.kind == ElementKind.FIELD) {
190 // The obvious thing to test here would be "member.isNative()", 190 // The obvious thing to test here would be "member.isNative()",
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 // All field initializers must be resolved as they could 224 // All field initializers must be resolved as they could
225 // have an observable side-effect (and cannot be tree-shaken 225 // have an observable side-effect (and cannot be tree-shaken
226 // away). 226 // away).
227 addToWorkList(member); 227 addToWorkList(member);
228 return; 228 return;
229 } 229 }
230 } else if (member.kind == ElementKind.FUNCTION) { 230 } else if (member.kind == ElementKind.FUNCTION) {
231 if (member.name == Compiler.NO_SUCH_METHOD) { 231 if (member.name == Compiler.NO_SUCH_METHOD) {
232 enableNoSuchMethod(member); 232 enableNoSuchMethod(member);
233 } 233 }
234 if (member.name == Compiler.CALL_OPERATOR_NAME) {
235 if (!cls.typeVariables.isEmpty) {
karlklose 2013/06/19 14:37:05 Join the two conditions.
Johnni Winther 2013/06/21 12:19:15 Done.
236 registerGenericCallMethod(member, compiler.globalDependencies);
237 }
238 }
234 // If there is a property access with the same name as a method we 239 // If there is a property access with the same name as a method we
235 // need to emit the method. 240 // need to emit the method.
236 if (universe.hasInvokedGetter(member, compiler)) { 241 if (universe.hasInvokedGetter(member, compiler)) {
237 // We will emit a closure, so make sure the bound closure class is 242 registerClosure(member, compiler.globalDependencies);
243 // We will emit a closure, so make sure the closure class is
238 // generated. 244 // generated.
239 registerInstantiatedClass(compiler.boundClosureClass, 245 registerInstantiatedClass(compiler.boundClosureClass,
240 // Precise dependency is not important here. 246 // Precise dependency is not important here.
241 compiler.globalDependencies); 247 compiler.globalDependencies);
242 return addToWorkList(member); 248 return addToWorkList(member);
243 } 249 }
244 // Store the member in [instanceFunctionsByName] to catch 250 // Store the member in [instanceFunctionsByName] to catch
245 // getters on the function. 251 // getters on the function.
246 Link<Element> members = instanceFunctionsByName.putIfAbsent( 252 Link<Element> members = instanceFunctionsByName.putIfAbsent(
247 memberName, () => const Link<Element>()); 253 memberName, () => const Link<Element>());
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 /// Called when [:new Symbol(...):] is seen. 389 /// Called when [:new Symbol(...):] is seen.
384 void registerNewSymbol(TreeElements elements) { 390 void registerNewSymbol(TreeElements elements) {
385 } 391 }
386 392
387 processLink(Map<String, Link<Element>> map, 393 processLink(Map<String, Link<Element>> map,
388 SourceString n, 394 SourceString n,
389 bool f(Element e)) { 395 bool f(Element e)) {
390 String memberName = n.slowToString(); 396 String memberName = n.slowToString();
391 Link<Element> members = map[memberName]; 397 Link<Element> members = map[memberName];
392 if (members != null) { 398 if (members != null) {
399 map[memberName] = const Link<Element>();
393 LinkBuilder<Element> remaining = new LinkBuilder<Element>(); 400 LinkBuilder<Element> remaining = new LinkBuilder<Element>();
394 for (; !members.isEmpty; members = members.tail) { 401 for (; !members.isEmpty; members = members.tail) {
395 if (!f(members.head)) remaining.addLast(members.head); 402 if (!f(members.head)) remaining.addLast(members.head);
396 } 403 }
397 map[memberName] = remaining.toLink(); 404 map[memberName] = remaining.toLink(map[memberName]);
karlklose 2013/06/19 14:37:05 Isn't the constant empty link already the default
Johnni Winther 2013/06/21 12:19:15 Comment added.
398 } 405 }
399 } 406 }
400 407
401 processInstanceMembers(SourceString n, bool f(Element e)) { 408 processInstanceMembers(SourceString n, bool f(Element e)) {
402 processLink(instanceMembersByName, n, f); 409 processLink(instanceMembersByName, n, f);
403 } 410 }
404 411
405 processInstanceFunctions(SourceString n, bool f(Element e)) { 412 processInstanceFunctions(SourceString n, bool f(Element e)) {
406 processLink(instanceFunctionsByName, n, f); 413 processLink(instanceFunctionsByName, n, f);
407 } 414 }
408 415
409 void handleUnseenSelector(SourceString methodName, Selector selector) { 416 void handleUnseenSelector(SourceString methodName, Selector selector) {
410 processInstanceMembers(methodName, (Element member) { 417 processInstanceMembers(methodName, (Element member) {
411 if (selector.appliesUnnamed(member, compiler)) { 418 if (selector.appliesUnnamed(member, compiler)) {
419 if (member.isFunction() && selector.isGetter()) {
420 registerClosure(member, compiler.globalDependencies);
421 }
412 if (member.isField() && member.getEnclosingClass().isNative()) { 422 if (member.isField() && member.getEnclosingClass().isNative()) {
413 if (selector.isGetter() || selector.isCall()) { 423 if (selector.isGetter() || selector.isCall()) {
414 nativeEnqueuer.registerFieldLoad(member); 424 nativeEnqueuer.registerFieldLoad(member);
415 // We have to also handle storing to the field because we only get 425 // We have to also handle storing to the field because we only get
416 // one look at each member and there might be a store we have not 426 // one look at each member and there might be a store we have not
417 // seen yet. 427 // seen yet.
418 // TODO(sra): Process fields for storing separately. 428 // TODO(sra): Process fields for storing separately.
419 nativeEnqueuer.registerFieldStore(member); 429 nativeEnqueuer.registerFieldStore(member);
420 } else { 430 } else {
421 assert(selector.isSetter()); 431 assert(selector.isSetter());
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 522
513 void registerFieldGetter(Element element) { 523 void registerFieldGetter(Element element) {
514 universe.fieldGetters.add(element); 524 universe.fieldGetters.add(element);
515 } 525 }
516 526
517 void registerFieldSetter(Element element) { 527 void registerFieldSetter(Element element) {
518 universe.fieldSetters.add(element); 528 universe.fieldSetters.add(element);
519 } 529 }
520 530
521 void registerIsCheck(DartType type, TreeElements elements) { 531 void registerIsCheck(DartType type, TreeElements elements) {
532 type = universe.registerIsCheck(type, compiler);
522 // Even in checked mode, type annotations for return type and argument 533 // Even in checked mode, type annotations for return type and argument
523 // types do not imply type checks, so there should never be a check 534 // types do not imply type checks, so there should never be a check
524 // against the type variable of a typedef. 535 // against the type variable of a typedef.
525 assert(type.kind != TypeKind.TYPE_VARIABLE || 536 assert(type.kind != TypeKind.TYPE_VARIABLE ||
526 !type.element.enclosingElement.isTypedef()); 537 !type.element.enclosingElement.isTypedef());
527 universe.isChecks.add(type);
528 compiler.backend.registerIsCheck(type, this, elements); 538 compiler.backend.registerIsCheck(type, this, elements);
529 } 539 }
530 540
531 /** 541 /**
532 * If a factory constructor is used with type arguments, we lose track 542 * If a factory constructor is used with type arguments, we lose track
533 * which arguments could be used to create instances of classes that use their 543 * which arguments could be used to create instances of classes that use their
534 * type variables as expressions, so we have to remember if we saw such a use. 544 * type variables as expressions, so we have to remember if we saw such a use.
535 */ 545 */
536 void registerFactoryWithTypeArguments(TreeElements elements) { 546 void registerFactoryWithTypeArguments(TreeElements elements) {
537 universe.usingFactoryWithTypeArguments = true; 547 universe.usingFactoryWithTypeArguments = true;
538 } 548 }
539 549
540 void registerAsCheck(DartType type, TreeElements elements) { 550 void registerAsCheck(DartType type, TreeElements elements) {
541 registerIsCheck(type, elements); 551 registerIsCheck(type, elements);
542 compiler.backend.registerAsCheck(type, elements); 552 compiler.backend.registerAsCheck(type, elements);
543 } 553 }
544 554
555 void registerGenericCallMethod(Element element, TreeElements elements) {
556 compiler.backend.registerGenericCallMethod(element, this, elements);
557 universe.genericCallMethods.add(element);
558 }
559
560 void registerClosure(Element element, TreeElements elements) {
karlklose 2013/06/19 14:37:05 'registerClosurizedMember'?
Johnni Winther 2013/06/21 12:19:15 Done.
561 if (element.computeType(compiler).containsTypeVariables) {
562 registerGenericClosure(element, elements);
563 }
564 universe.closurizedMembers.add(element);
565 }
566
567 void registerGenericClosure(Element element, TreeElements elements) {
karlklose 2013/06/19 14:37:05 'registerClosurizedGenericMember'?
Johnni Winther 2013/06/21 12:19:15 Done.
568 compiler.backend.registerGenericClosure(element, this, elements);
569 universe.closurizedGenericMembers.add(element);
570 }
571
545 void forEach(f(WorkItem work)); 572 void forEach(f(WorkItem work));
546 573
547 void forEachPostProcessTask(f(PostProcessTask work)) {} 574 void forEachPostProcessTask(f(PostProcessTask work)) {}
548 575
549 void logSummary(log(message)) { 576 void logSummary(log(message)) {
550 _logSpecificSummary(log); 577 _logSpecificSummary(log);
551 nativeEnqueuer.logSummary(log); 578 nativeEnqueuer.logSummary(log);
552 } 579 }
553 580
554 /// Log summary specific to the concrete enqueuer. 581 /// Log summary specific to the concrete enqueuer.
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 } 656 }
630 } 657 }
631 658
632 if (element.isGetter() && element.name == Compiler.RUNTIME_TYPE) { 659 if (element.isGetter() && element.name == Compiler.RUNTIME_TYPE) {
633 // Enable runtime type support if we discover a getter called runtimeType. 660 // Enable runtime type support if we discover a getter called runtimeType.
634 // We have to enable runtime type before hitting the codegen, so 661 // We have to enable runtime type before hitting the codegen, so
635 // that constructors know whether they need to generate code for 662 // that constructors know whether they need to generate code for
636 // runtime type. 663 // runtime type.
637 compiler.enabledRuntimeType = true; 664 compiler.enabledRuntimeType = true;
638 // TODO(ahe): Record precise dependency here. 665 // TODO(ahe): Record precise dependency here.
639 compiler.backend.registerRuntimeType(compiler.globalDependencies); 666 compiler.backend.registerRuntimeType(this, compiler.globalDependencies);
640 } else if (element == compiler.functionApplyMethod) { 667 } else if (element == compiler.functionApplyMethod) {
641 compiler.enabledFunctionApply = true; 668 compiler.enabledFunctionApply = true;
642 } else if (element == compiler.invokeOnMethod) { 669 } else if (element == compiler.invokeOnMethod) {
643 compiler.enabledInvokeOn = true; 670 compiler.enabledInvokeOn = true;
644 } 671 }
645 672
646 nativeEnqueuer.registerElement(element); 673 nativeEnqueuer.registerElement(element);
647 } 674 }
648 675
649 void enableIsolateSupport(LibraryElement element) { 676 void enableIsolateSupport(LibraryElement element) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 while(!queue.isEmpty) { 767 while(!queue.isEmpty) {
741 // TODO(johnniwinther): Find an optimal process order for codegen. 768 // TODO(johnniwinther): Find an optimal process order for codegen.
742 f(queue.removeLast()); 769 f(queue.removeLast());
743 } 770 }
744 } 771 }
745 772
746 void _logSpecificSummary(log(message)) { 773 void _logSpecificSummary(log(message)) {
747 log('Compiled ${generatedCode.length} methods.'); 774 log('Compiled ${generatedCode.length} methods.');
748 } 775 }
749 } 776 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698