| 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 |