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

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: New check encoding Created 7 years, 9 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 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 ClosureClassMap cached = closureMappingCache[function]; 425 ClosureClassMap cached = closureMappingCache[function];
426 if (!cached.parametersWithSentinel.containsKey(parameter)) { 426 if (!cached.parametersWithSentinel.containsKey(parameter)) {
427 SourceString parameterName = parameter.name; 427 SourceString parameterName = parameter.name;
428 String name = '${parameterName.slowToString()}_check'; 428 String name = '${parameterName.slowToString()}_check';
429 Element newElement = new CheckVariableElement(new SourceString(name), 429 Element newElement = new CheckVariableElement(new SourceString(name),
430 parameter, 430 parameter,
431 enclosing); 431 enclosing);
432 useLocal(newElement); 432 useLocal(newElement);
433 cached.parametersWithSentinel[parameter] = newElement; 433 cached.parametersWithSentinel[parameter] = newElement;
434 } 434 }
435 } else if (node.isOperator) {
436 String operatorString = node.selector.asOperator().source.stringValue;
437 if (operatorString == 'is' || operatorString == 'as') {
karlklose 2013/03/22 13:17:46 I would really like to encapsulate this pattern. I
Johnni Winther 2013/06/12 14:39:10 I looked. They are all slightly different.
438 DartType type = elements.getType(node.arguments.head);
439 analyzeType(type);
440 }
435 } 441 }
436 node.visitChildren(this); 442 node.visitChildren(this);
437 } 443 }
438 444
439 visitSendSet(SendSet node) { 445 visitSendSet(SendSet node) {
440 Element element = elements[node]; 446 Element element = elements[node];
441 if (Elements.isLocal(element)) { 447 if (Elements.isLocal(element)) {
442 mutatedVariables.add(element); 448 mutatedVariables.add(element);
443 } 449 }
444 super.visitSendSet(node); 450 super.visitSendSet(node);
445 } 451 }
446 452
447 visitNewExpression(NewExpression node) { 453 visitNewExpression(NewExpression node) {
448 DartType type = elements.getType(node); 454 DartType type = elements.getType(node);
455 analyzeType(type);
456 node.visitChildren(this);
457 }
449 458
450 bool hasTypeVariable(DartType type) { 459 void analyzeTypeVariables(DartType type) {
451 if (type is TypeVariableType) { 460 if (type is TypeVariableType) {
452 return true; 461 useLocal(type.element);
453 } else if (type is InterfaceType) { 462 } else if (type is InterfaceType) {
454 InterfaceType ifcType = type; 463 InterfaceType ifcType = type;
455 for (DartType argument in ifcType.typeArguments) { 464 for (DartType argument in ifcType.typeArguments) {
456 if (hasTypeVariable(argument)) { 465 analyzeTypeVariables(argument);
457 return true;
458 }
459 }
460 } 466 }
461 return false;
462 } 467 }
468 }
463 469
464 void analyzeTypeVariables(DartType type) { 470 void analyzeType(DartType type) {
465 if (type is TypeVariableType) { 471 if (type == null) return;
karlklose 2013/03/22 13:17:46 How can this happen?
Johnni Winther 2013/06/21 12:19:14 Bad handling of is! Now fixed.
466 useLocal(type.element); 472 if (outermostElement.isMember() &&
467 } else if (type is InterfaceType) { 473 compiler.backend.needsRti(outermostElement.getEnclosingClass())) {
468 InterfaceType ifcType = type; 474 if (outermostElement.isConstructor() ||
469 for (DartType argument in ifcType.typeArguments) { 475 outermostElement.isField()) {
470 analyzeTypeVariables(argument); 476 analyzeTypeVariables(type);
477 } else if (outermostElement.isInstanceMember()) {
478 if (type.containsTypeVariables) {
479 useLocal(closureData.thisElement);
471 } 480 }
472 } 481 }
473 } 482 }
474
475 if (outermostElement.isMember() &&
476 compiler.backend.needsRti(outermostElement.getEnclosingClass())) {
477 if (outermostElement.isConstructor() || outermostElement.isField()) {
478 analyzeTypeVariables(type);
479 } else if (outermostElement.isInstanceMember()) {
480 if (hasTypeVariable(type)) useLocal(closureData.thisElement);
481 }
482 }
483
484 node.visitChildren(this);
485 } 483 }
486 484
487 // If variables that are declared in the [node] scope are captured and need 485 // If variables that are declared in the [node] scope are captured and need
488 // to be boxed create a box-element and update the [capturingScopes] in the 486 // to be boxed create a box-element and update the [capturingScopes] in the
489 // current [closureData]. 487 // current [closureData].
490 // The boxed variables are updated in the [capturedVariableMapping]. 488 // The boxed variables are updated in the [capturedVariableMapping].
491 void attachCapturedScopeVariables(Node node) { 489 void attachCapturedScopeVariables(Node node) {
492 Element box = null; 490 Element box = null;
493 Map<Element, Element> scopeMapping = new Map<Element, Element>(); 491 Map<Element, Element> scopeMapping = new Map<Element, Element>();
494 for (Element element in scopeVariables) { 492 for (Element element in scopeVariables) {
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 if (currentElement.isFactoryConstructor() && 637 if (currentElement.isFactoryConstructor() &&
640 compiler.backend.needsRti(currentElement.enclosingElement)) { 638 compiler.backend.needsRti(currentElement.enclosingElement)) {
641 // Declare the type parameters in the scope. Generative 639 // Declare the type parameters in the scope. Generative
642 // constructors just use 'this'. 640 // constructors just use 'this'.
643 ClassElement cls = currentElement.enclosingElement; 641 ClassElement cls = currentElement.enclosingElement;
644 cls.typeVariables.forEach((TypeVariableType typeVariable) { 642 cls.typeVariables.forEach((TypeVariableType typeVariable) {
645 declareLocal(typeVariable.element); 643 declareLocal(typeVariable.element);
646 }); 644 });
647 } 645 }
648 646
647 // Ensure that closure that need runtime type information has access to
648 // this of the enclosing class.
649 if (closureData.thisElement != null &&
650 compiler.backend.methodNeedsRti(element)) {
651 useLocal(closureData.thisElement);
652 }
653
649 visitChildren(); 654 visitChildren();
650 }); 655 });
651 656
652 657
653 ClosureClassMap savedClosureData = closureData; 658 ClosureClassMap savedClosureData = closureData;
654 bool savedInsideClosure = insideClosure; 659 bool savedInsideClosure = insideClosure;
655 660
656 // Restore old values. 661 // Restore old values.
657 insideClosure = oldInsideClosure; 662 insideClosure = oldInsideClosure;
658 closureData = oldClosureData; 663 closureData = oldClosureData;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 } 701 }
697 702
698 visitTryStatement(TryStatement node) { 703 visitTryStatement(TryStatement node) {
699 // TODO(ngeoffray): implement finer grain state. 704 // TODO(ngeoffray): implement finer grain state.
700 bool oldInTryStatement = inTryStatement; 705 bool oldInTryStatement = inTryStatement;
701 inTryStatement = true; 706 inTryStatement = true;
702 node.visitChildren(this); 707 node.visitChildren(this);
703 inTryStatement = oldInTryStatement; 708 inTryStatement = oldInTryStatement;
704 } 709 }
705 } 710 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698