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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/closure.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, 5 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 library closureToClassMapper; 5 library closureToClassMapper;
6 6
7 import "elements/elements.dart"; 7 import "elements/elements.dart";
8 import "dart2jslib.dart"; 8 import "dart2jslib.dart";
9 import "dart_types.dart"; 9 import "dart_types.dart";
10 import "scanner/scannerlib.dart" show Token; 10 import "scanner/scannerlib.dart" show Token;
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 ClosureClassMap cached = closureMappingCache[function]; 522 ClosureClassMap cached = closureMappingCache[function];
523 if (!cached.parametersWithSentinel.containsKey(parameter)) { 523 if (!cached.parametersWithSentinel.containsKey(parameter)) {
524 SourceString parameterName = parameter.name; 524 SourceString parameterName = parameter.name;
525 String name = '${parameterName.slowToString()}_check'; 525 String name = '${parameterName.slowToString()}_check';
526 Element newElement = new CheckVariableElement(new SourceString(name), 526 Element newElement = new CheckVariableElement(new SourceString(name),
527 parameter, 527 parameter,
528 enclosing); 528 enclosing);
529 useLocal(newElement); 529 useLocal(newElement);
530 cached.parametersWithSentinel[parameter] = newElement; 530 cached.parametersWithSentinel[parameter] = newElement;
531 } 531 }
532 } else if (node.isTypeTest) {
533 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast);
534 analyzeType(type);
535 } else if (node.isTypeCast) {
536 DartType type = elements.getType(node.arguments.head);
537 analyzeType(type);
532 } 538 }
533 node.visitChildren(this); 539 node.visitChildren(this);
534 } 540 }
535 541
536 visitSendSet(SendSet node) { 542 visitSendSet(SendSet node) {
537 Element element = elements[node]; 543 Element element = elements[node];
538 if (Elements.isLocal(element)) { 544 if (Elements.isLocal(element)) {
539 mutatedVariables.add(element); 545 mutatedVariables.add(element);
540 } 546 }
541 if (Elements.isLocal(element) && 547 if (Elements.isLocal(element) &&
542 element.computeType(compiler).containsTypeVariables) { 548 element.computeType(compiler).containsTypeVariables) {
543 registerNeedsThis(); 549 registerNeedsThis();
544 } 550 }
545 super.visitSendSet(node); 551 super.visitSendSet(node);
546 } 552 }
547 553
548 visitNewExpression(NewExpression node) { 554 visitNewExpression(NewExpression node) {
549 DartType type = elements.getType(node); 555 DartType type = elements.getType(node);
556 analyzeType(type);
557 node.visitChildren(this);
558 }
550 559
551 void analyzeTypeVariables(DartType type) { 560 void analyzeTypeVariables(DartType type) {
552 if (type is TypeVariableType) { 561 type.forEachTypeVariable((TypeVariableType typeVariable) {
553 useLocal(type.element); 562 useLocal(typeVariable.element);
554 // Field initializers are inlined and access the type variable as 563 // Field initializers are inlined and access the type variable as
555 // normal parameters. 564 // normal parameters.
556 if (!outermostElement.isField()) { 565 if (!outermostElement.isField()) {
557 registerNeedsThis(); 566 registerNeedsThis();
558 }
559 } else if (type is InterfaceType) {
560 InterfaceType ifcType = type;
561 for (DartType argument in ifcType.typeArguments) {
562 analyzeTypeVariables(argument);
563 }
564 } 567 }
565 } 568 });
569 }
566 570
571 void analyzeType(DartType type) {
572 // TODO(johnniwinther): Find out why this can be null.
573 if (type == null) return;
567 if (outermostElement.isMember() && 574 if (outermostElement.isMember() &&
568 compiler.backend.needsRti(outermostElement.getEnclosingClass())) { 575 compiler.backend.classNeedsRti(outermostElement.getEnclosingClass())) {
569 if (outermostElement.isConstructor() || outermostElement.isField()) { 576 if (outermostElement.isConstructor() ||
577 outermostElement.isField()) {
570 analyzeTypeVariables(type); 578 analyzeTypeVariables(type);
571 } else if (outermostElement.isInstanceMember()) { 579 } else if (outermostElement.isInstanceMember()) {
572 if (type.containsTypeVariables) { 580 if (type.containsTypeVariables) {
573 registerNeedsThis(); 581 registerNeedsThis();
574 } 582 }
575 } 583 }
576 } 584 }
577
578 node.visitChildren(this);
579 } 585 }
580 586
581 // If variables that are declared in the [node] scope are captured and need 587 // If variables that are declared in the [node] scope are captured and need
582 // to be boxed create a box-element and update the [capturingScopes] in the 588 // to be boxed create a box-element and update the [capturingScopes] in the
583 // current [closureData]. 589 // current [closureData].
584 // The boxed variables are updated in the [capturedVariableMapping]. 590 // The boxed variables are updated in the [capturedVariableMapping].
585 void attachCapturedScopeVariables(Node node) { 591 void attachCapturedScopeVariables(Node node) {
586 Element box = null; 592 Element box = null;
587 Map<Element, Element> scopeMapping = new Map<Element, Element>(); 593 Map<Element, Element> scopeMapping = new Map<Element, Element>();
588 for (Element element in scopeVariables) { 594 for (Element element in scopeVariables) {
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 } 733 }
728 // If we are inside a named closure we have to declare ourselve. For 734 // If we are inside a named closure we have to declare ourselve. For
729 // simplicity we declare the local even if the closure does not have a 735 // simplicity we declare the local even if the closure does not have a
730 // name. 736 // name.
731 // It will simply not be used. 737 // It will simply not be used.
732 if (insideClosure) { 738 if (insideClosure) {
733 declareLocal(element); 739 declareLocal(element);
734 } 740 }
735 741
736 if (currentElement.isFactoryConstructor() && 742 if (currentElement.isFactoryConstructor() &&
737 compiler.backend.needsRti(currentElement.enclosingElement)) { 743 compiler.backend.classNeedsRti(currentElement.enclosingElement)) {
738 // Declare the type parameters in the scope. Generative 744 // Declare the type parameters in the scope. Generative
739 // constructors just use 'this'. 745 // constructors just use 'this'.
740 ClassElement cls = currentElement.enclosingElement; 746 ClassElement cls = currentElement.enclosingElement;
741 cls.typeVariables.forEach((TypeVariableType typeVariable) { 747 cls.typeVariables.forEach((TypeVariableType typeVariable) {
742 declareLocal(typeVariable.element); 748 declareLocal(typeVariable.element);
743 }); 749 });
744 } 750 }
745 751
752 DartType type = element.computeType(compiler);
746 // Compute the function type and check for type variables in return or 753 // Compute the function type and check for type variables in return or
747 // parameter types. 754 // parameter types.
748 if (element.computeType(compiler).containsTypeVariables) { 755 if (type.containsTypeVariables) {
756 registerNeedsThis();
757 }
758 // Ensure that closure that need runtime type information has access to
759 // this of the enclosing class.
760 if (element is FunctionElement &&
761 closureData.thisElement != null &&
762 type.containsTypeVariables &&
763 compiler.backend.methodNeedsRti(element)) {
749 registerNeedsThis(); 764 registerNeedsThis();
750 } 765 }
751 766
752 visitChildren(); 767 visitChildren();
753 }); 768 });
754 769
755 770
756 ClosureClassMap savedClosureData = closureData; 771 ClosureClassMap savedClosureData = closureData;
757 bool savedInsideClosure = insideClosure; 772 bool savedInsideClosure = insideClosure;
758 773
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 } 814 }
800 815
801 visitTryStatement(TryStatement node) { 816 visitTryStatement(TryStatement node) {
802 // TODO(ngeoffray): implement finer grain state. 817 // TODO(ngeoffray): implement finer grain state.
803 bool oldInTryStatement = inTryStatement; 818 bool oldInTryStatement = inTryStatement;
804 inTryStatement = true; 819 inTryStatement = true;
805 node.visitChildren(this); 820 node.visitChildren(this);
806 inTryStatement = oldInTryStatement; 821 inTryStatement = oldInTryStatement;
807 } 822 }
808 } 823 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698