OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 library kernel.interpreter; | 4 library kernel.interpreter; |
5 | 5 |
6 import '../ast.dart'; | 6 import '../ast.dart'; |
7 import '../ast.dart' as ast show Class; | 7 import '../ast.dart' as ast show Class; |
8 | 8 |
9 import '../log.dart'; | 9 import '../log.dart'; |
10 export '../log.dart'; | 10 export '../log.dart'; |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 | 169 |
170 Configuration visitConstructorInvocation( | 170 Configuration visitConstructorInvocation( |
171 ConstructorInvocation node, ExpressionConfiguration config) { | 171 ConstructorInvocation node, ExpressionConfiguration config) { |
172 // Currently, the bodies of the constructors are not executed. | 172 // Currently, the bodies of the constructors are not executed. |
173 // Currently initializer list is executed only for redirecting | 173 // Currently initializer list is executed only for redirecting |
174 // constructors. | 174 // constructors. |
175 if (node.target.function.body is! EmptyStatement) { | 175 if (node.target.function.body is! EmptyStatement) { |
176 throw 'Execution for body of constructor is not implemented.'; | 176 throw 'Execution for body of constructor is not implemented.'; |
177 } | 177 } |
178 | 178 |
179 var class_ = new Class(node.target.enclosingClass.reference); | 179 ApplicationContinuation cont = |
180 var newObject = | 180 new ConstructorInvocationApplication(node.target, config.continuation); |
181 new ObjectValue(class_, new List<Value>(class_.instanceSize)); | |
182 | |
183 ApplicationContinuation cont = new ConstructorInvocationApplication( | |
184 newObject, node.target, config.continuation); | |
185 | 181 |
186 var args = | 182 var args = |
187 _createArgumentExpressionList(node.arguments, node.target.function); | 183 _createArgumentExpressionList(node.arguments, node.target.function); |
188 | 184 |
189 return new ExpressionListConfiguration(args, config.environment, cont); | 185 return new ExpressionListConfiguration(args, config.environment, cont); |
190 } | 186 } |
191 | 187 |
192 Configuration visitNot(Not node, ExpressionConfiguration config) { | 188 Configuration visitNot(Not node, ExpressionConfiguration config) { |
193 return new ExpressionConfiguration(node.operand, config.environment, | 189 return new ExpressionConfiguration(node.operand, config.environment, |
194 new NotContinuation(config.continuation)); | 190 new NotContinuation(config.continuation)); |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 .withExpressionContinuation(continuation) | 514 .withExpressionContinuation(continuation) |
519 .withConfiguration(new ExitConfiguration(continuation)) | 515 .withConfiguration(new ExitConfiguration(continuation)) |
520 .withEnvironment(functionEnv); | 516 .withEnvironment(functionEnv); |
521 return new StatementConfiguration(function.body, bodyState); | 517 return new StatementConfiguration(function.body, bodyState); |
522 } | 518 } |
523 } | 519 } |
524 | 520 |
525 /// Represents the application continuation for constructor invocation applied | 521 /// Represents the application continuation for constructor invocation applied |
526 /// on the list of evaluated arguments. | 522 /// on the list of evaluated arguments. |
527 class ConstructorInvocationApplication extends ApplicationContinuation { | 523 class ConstructorInvocationApplication extends ApplicationContinuation { |
528 final ObjectValue newObject; | |
529 final Constructor constructor; | 524 final Constructor constructor; |
530 final ExpressionContinuation expressionContinuation; | 525 final ExpressionContinuation continuation; |
531 | 526 |
532 ConstructorInvocationApplication( | 527 ConstructorInvocationApplication(this.constructor, this.continuation); |
533 this.newObject, this.constructor, this.expressionContinuation); | |
534 | 528 |
535 Configuration call(List<InterpreterValue> argValues) { | 529 Configuration call(List<InterpreterValue> argValues) { |
536 Environment ctrEnv = ApplicationContinuation.createEnvironment( | 530 Environment ctrEnv = ApplicationContinuation.createEnvironment( |
537 constructor.function, argValues); | 531 constructor.function, argValues); |
538 | 532 |
| 533 var class_ = new Class(constructor.enclosingClass.reference); |
| 534 var newObject = |
| 535 new ObjectValue(class_, new List<Value>(class_.instanceSize)); |
| 536 |
| 537 var cont = |
| 538 new ObjectInitializationContinuation(constructor, ctrEnv, continuation); |
| 539 |
| 540 return new ContinuationConfiguration(cont, newObject); |
| 541 } |
| 542 } |
| 543 |
| 544 /// Represents the application continuation for redirecting constructor |
| 545 /// invocation applied on the list of evaluated arguments. |
| 546 class RedirectingConstructorApplication extends ApplicationContinuation { |
| 547 final ObjectValue newObject; |
| 548 final Constructor constructor; |
| 549 final ExpressionContinuation continuation; |
| 550 |
| 551 RedirectingConstructorApplication( |
| 552 this.newObject, this.constructor, this.continuation); |
| 553 |
| 554 Configuration call(List<InterpreterValue> argValues) { |
| 555 Environment ctrEnv = ApplicationContinuation.createEnvironment( |
| 556 constructor.function, argValues); |
| 557 var cont = |
| 558 new ObjectInitializationContinuation(constructor, ctrEnv, continuation); |
| 559 return new ContinuationConfiguration(cont, newObject); |
| 560 } |
| 561 } |
| 562 |
| 563 /// Represents the application continuation for super constructor |
| 564 /// invocation applied on the list of evaluated arguments. |
| 565 class SuperConstructorApplication extends ApplicationContinuation { |
| 566 final ObjectValue newObject; |
| 567 final Constructor constructor; |
| 568 // TODO: remember to execute body of previous ctr. |
| 569 final ExpressionContinuation continuation; |
| 570 |
| 571 SuperConstructorApplication( |
| 572 this.newObject, this.constructor, this.continuation); |
| 573 |
| 574 Configuration call(List<InterpreterValue> argValues) { |
| 575 Environment ctrEnv = ApplicationContinuation.createEnvironment( |
| 576 constructor.function, argValues); |
| 577 var cont = |
| 578 new ObjectInitializationContinuation(constructor, ctrEnv, continuation); |
| 579 return new ContinuationConfiguration(cont, newObject); |
| 580 } |
| 581 } |
| 582 |
| 583 class ObjectInitializationContinuation extends ExpressionContinuation { |
| 584 final Constructor constructor; |
| 585 final Environment environment; |
| 586 final ExpressionContinuation continuation; |
| 587 |
| 588 ObjectInitializationContinuation( |
| 589 this.constructor, this.environment, this.continuation); |
| 590 |
| 591 Configuration call(Value v) { |
539 if (constructor.initializers.isNotEmpty && | 592 if (constructor.initializers.isNotEmpty && |
540 constructor.initializers.last is RedirectingInitializer) { | 593 constructor.initializers.last is RedirectingInitializer) { |
541 // Constructor is redirecting. | 594 // Constructor is redirecting. |
542 Initializer initializer = constructor.initializers.first; | 595 Initializer initializer = constructor.initializers.first; |
543 if (initializer is RedirectingInitializer) { | 596 if (initializer is RedirectingInitializer) { |
544 var app = new ConstructorInvocationApplication( | 597 var app = new RedirectingConstructorApplication( |
545 newObject, initializer.target, expressionContinuation); | 598 v, initializer.target, continuation); |
546 var args = _createArgumentExpressionList( | 599 var args = _createArgumentExpressionList( |
547 initializer.arguments, initializer.target.function); | 600 initializer.arguments, initializer.target.function); |
548 | 601 |
549 return new ExpressionListConfiguration(args, ctrEnv, app); | 602 return new ExpressionListConfiguration(args, environment, app); |
550 } | 603 } |
551 // Redirecting initializer is not the only initializer. | 604 // Redirecting initializer is not the only initializer. |
552 for (Initializer i in constructor.initializers.reversed.skip(1)) { | 605 for (Initializer i in constructor.initializers.reversed.skip(1)) { |
553 assert(i is LocalInitializer); | 606 assert(i is LocalInitializer); |
554 } | 607 } |
555 var class_ = new Class(constructor.enclosingClass.reference); | 608 var class_ = new Class(constructor.enclosingClass.reference); |
556 var cont = new InitializerContinuation(newObject, class_, ctrEnv, | 609 var cont = new InitializerContinuation( |
557 constructor.initializers, expressionContinuation); | 610 v, class_, environment, constructor.initializers, continuation); |
558 return new ExpressionConfiguration( | 611 return new ExpressionConfiguration( |
559 (initializer as LocalInitializer).variable.initializer, ctrEnv, cont); | 612 (initializer as LocalInitializer).variable.initializer, |
| 613 environment, |
| 614 cont); |
560 } | 615 } |
561 | 616 |
562 // Initialize fields in immediately enclosing class. | 617 // Initialize fields in immediately enclosing class. |
563 var cont = new InstanceFieldsApplication( | 618 var cont = new InstanceFieldsApplication( |
564 newObject, constructor, ctrEnv, expressionContinuation); | 619 v, constructor, environment, continuation); |
565 var fieldExpressions = _createInstanceInitializers(constructor); | 620 var fieldExpressions = _createInstanceInitializers(constructor); |
566 | 621 |
567 return new ExpressionListConfiguration(fieldExpressions, ctrEnv, cont); | 622 return new ExpressionListConfiguration( |
| 623 fieldExpressions, new Environment.empty(), cont); |
568 } | 624 } |
569 | 625 |
570 /// Creates a list of expressions for instance field initializers in | 626 /// Creates a list of expressions for instance field initializers in |
571 /// immediately enclosing class. | 627 /// immediately enclosing class. |
572 static List<InterpreterExpression> _createInstanceInitializers( | 628 static List<InterpreterExpression> _createInstanceInitializers( |
573 Constructor ctr) { | 629 Constructor ctr) { |
574 Class currentClass = new Class(ctr.enclosingClass.reference); | 630 Class currentClass = new Class(ctr.enclosingClass.reference); |
575 List<InterpreterExpression> es = <InterpreterExpression>[]; | 631 List<InterpreterExpression> es = <InterpreterExpression>[]; |
576 | 632 |
577 for (int i = currentClass.superclass?.instanceSize ?? 0; | 633 for (int i = currentClass.superclass?.instanceSize ?? 0; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
610 _initializeNullFields(_currentClass, newObject); | 666 _initializeNullFields(_currentClass, newObject); |
611 return new ContinuationConfiguration(expressionContinuation, newObject); | 667 return new ContinuationConfiguration(expressionContinuation, newObject); |
612 } | 668 } |
613 | 669 |
614 if (constructor.initializers.first is SuperInitializer) { | 670 if (constructor.initializers.first is SuperInitializer) { |
615 // SuperInitializer appears last in the initializer list. | 671 // SuperInitializer appears last in the initializer list. |
616 assert(constructor.initializers.length == 1); | 672 assert(constructor.initializers.length == 1); |
617 SuperInitializer current = constructor.initializers.first; | 673 SuperInitializer current = constructor.initializers.first; |
618 var args = _createArgumentExpressionList( | 674 var args = _createArgumentExpressionList( |
619 current.arguments, current.target.function); | 675 current.arguments, current.target.function); |
620 var superApp = new ConstructorInvocationApplication( | 676 var superApp = new SuperConstructorApplication( |
621 newObject, current.target, expressionContinuation); | 677 newObject, current.target, expressionContinuation); |
622 _initializeNullFields(_currentClass, newObject); | 678 _initializeNullFields(_currentClass, newObject); |
623 return new ExpressionListConfiguration(args, environment, superApp); | 679 return new ExpressionListConfiguration(args, environment, superApp); |
624 } | 680 } |
625 | 681 |
626 Class class_ = new Class(constructor.enclosingClass.reference); | 682 Class class_ = new Class(constructor.enclosingClass.reference); |
627 Environment initEnv = new Environment(environment); | 683 Environment initEnv = new Environment(environment); |
628 | 684 |
629 var cont = new InitializerContinuation(newObject, class_, initEnv, | 685 var cont = new InitializerContinuation(newObject, class_, initEnv, |
630 constructor.initializers, expressionContinuation); | 686 constructor.initializers, expressionContinuation); |
(...skipping 28 matching lines...) Expand all Loading... |
659 // todo: return configuration for body of ctr. | 715 // todo: return configuration for body of ctr. |
660 _initializeNullFields(currentClass, newObject); | 716 _initializeNullFields(currentClass, newObject); |
661 return new ContinuationConfiguration(continuation, newObject); | 717 return new ContinuationConfiguration(continuation, newObject); |
662 } | 718 } |
663 | 719 |
664 Initializer next = initializers[1]; | 720 Initializer next = initializers[1]; |
665 | 721 |
666 if (next is RedirectingInitializer) { | 722 if (next is RedirectingInitializer) { |
667 // RedirectingInitializer appears last in the initializer list. | 723 // RedirectingInitializer appears last in the initializer list. |
668 assert(initializers.length == 2); | 724 assert(initializers.length == 2); |
669 var cont = new ConstructorInvocationApplication( | 725 var cont = new RedirectingConstructorApplication( |
670 newObject, next.target, continuation); | 726 newObject, next.target, continuation); |
671 var args = | 727 var args = |
672 _createArgumentExpressionList(next.arguments, next.target.function); | 728 _createArgumentExpressionList(next.arguments, next.target.function); |
673 return new ExpressionListConfiguration( | 729 return new ExpressionListConfiguration( |
674 args, initializerEnvironment, cont); | 730 args, initializerEnvironment, cont); |
675 } | 731 } |
676 | 732 |
677 if (next is SuperInitializer) { | 733 if (next is SuperInitializer) { |
678 // SuperInitializer appears last in the initializer list. | 734 // SuperInitializer appears last in the initializer list. |
679 assert(initializers.length == 2); | 735 assert(initializers.length == 2); |
680 var args = | 736 var args = |
681 _createArgumentExpressionList(next.arguments, next.target.function); | 737 _createArgumentExpressionList(next.arguments, next.target.function); |
682 var superApp = new ConstructorInvocationApplication( | 738 var superApp = |
683 newObject, next.target, continuation); | 739 new SuperConstructorApplication(newObject, next.target, continuation); |
684 _initializeNullFields(currentClass, newObject); | 740 _initializeNullFields(currentClass, newObject); |
685 return new ExpressionListConfiguration( | 741 return new ExpressionListConfiguration( |
686 args, initializerEnvironment, superApp); | 742 args, initializerEnvironment, superApp); |
687 } | 743 } |
688 | 744 |
689 var cont = new InitializerContinuation(newObject, currentClass, | 745 var cont = new InitializerContinuation(newObject, currentClass, |
690 initializerEnvironment, initializers.skip(1).toList(), continuation); | 746 initializerEnvironment, initializers.skip(1).toList(), continuation); |
691 return new ExpressionConfiguration( | 747 return new ExpressionConfiguration( |
692 _getExpression(next), initializerEnvironment, cont); | 748 _getExpression(next), initializerEnvironment, cont); |
693 } | 749 } |
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1397 void _initializeNullFields(Class class_, ObjectValue newObject) { | 1453 void _initializeNullFields(Class class_, ObjectValue newObject) { |
1398 int superClassSize = class_.superclass?.instanceSize ?? 0; | 1454 int superClassSize = class_.superclass?.instanceSize ?? 0; |
1399 for (int i = superClassSize; i < class_.instanceSize; i++) { | 1455 for (int i = superClassSize; i < class_.instanceSize; i++) { |
1400 Field field = class_.instanceFields[i]; | 1456 Field field = class_.instanceFields[i]; |
1401 if (class_.getProperty(newObject, field) == null) { | 1457 if (class_.getProperty(newObject, field) == null) { |
1402 assert(field.initializer == null); | 1458 assert(field.initializer == null); |
1403 class_.setProperty(newObject, field, Value.nullInstance); | 1459 class_.setProperty(newObject, field, Value.nullInstance); |
1404 } | 1460 } |
1405 } | 1461 } |
1406 } | 1462 } |
OLD | NEW |