Chromium Code Reviews| 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 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 var class_ = new Class(node.target.enclosingClass.reference); |
| 180 var newObject = | 180 var newObject = |
| 181 new ObjectValue(class_, new List<Value>(class_.instanceSize)); | 181 new ObjectValue(class_, new List<Value>(class_.instanceSize)); |
| 182 | |
| 182 ApplicationContinuation cont = new ConstructorInvocationApplication( | 183 ApplicationContinuation cont = new ConstructorInvocationApplication( |
| 183 newObject, node.target, config.continuation); | 184 newObject, node.target, config.continuation); |
| 184 | 185 |
| 185 var args = | 186 var args = |
| 186 _createArgumentExpressionList(node.arguments, node.target.function); | 187 _createArgumentExpressionList(node.arguments, node.target.function); |
| 187 | 188 |
| 188 return new ExpressionListConfiguration(args, config.environment, cont); | 189 return new ExpressionListConfiguration(args, config.environment, cont); |
| 189 } | 190 } |
| 190 | 191 |
| 191 Configuration visitNot(Not node, ExpressionConfiguration config) { | 192 Configuration visitNot(Not node, ExpressionConfiguration config) { |
| (...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 596 | 597 |
| 597 InstanceFieldsApplication(this.newObject, this.constructor, this.environment, | 598 InstanceFieldsApplication(this.newObject, this.constructor, this.environment, |
| 598 this.expressionContinuation) | 599 this.expressionContinuation) |
| 599 : _currentClass = new Class(constructor.enclosingClass.reference); | 600 : _currentClass = new Class(constructor.enclosingClass.reference); |
| 600 | 601 |
| 601 Configuration call(List<InterpreterValue> fieldValues) { | 602 Configuration call(List<InterpreterValue> fieldValues) { |
| 602 for (FieldInitializerValue current in fieldValues.reversed) { | 603 for (FieldInitializerValue current in fieldValues.reversed) { |
| 603 _currentClass.setProperty(newObject, current.field, current.value); | 604 _currentClass.setProperty(newObject, current.field, current.value); |
| 604 } | 605 } |
| 605 | 606 |
| 606 if (constructor.initializers.isEmpty || | 607 if (constructor.initializers.isEmpty) { |
| 607 constructor.initializers.first is SuperInitializer) { | |
| 608 // todo: eval super args or constructor body configuration. | |
| 609 return new ContinuationConfiguration(expressionContinuation, newObject); | 608 return new ContinuationConfiguration(expressionContinuation, newObject); |
| 610 } | 609 } |
| 611 | 610 |
| 611 if (constructor.initializers.first is SuperInitializer) { | |
| 612 // SuperInitializer appears last in the initializer list. | |
| 613 assert(constructor.initializers.length == 1); | |
| 614 SuperInitializer current = constructor.initializers.first; | |
| 615 var args = _createArgumentExpressionList( | |
| 616 current.arguments, current.target.function); | |
| 617 var superApp = new ConstructorInvocationApplication( | |
| 618 newObject, current.target, expressionContinuation); | |
| 619 _initializeNullFields(_currentClass, newObject); | |
| 620 return new ExpressionListConfiguration(args, environment, superApp); | |
| 621 } | |
| 622 | |
| 612 Class class_ = new Class(constructor.enclosingClass.reference); | 623 Class class_ = new Class(constructor.enclosingClass.reference); |
| 613 Environment initEnv = new Environment(environment); | 624 Environment initEnv = new Environment(environment); |
| 614 | 625 |
| 615 var cont = new InitializerContinuation(newObject, class_, initEnv, | 626 var cont = new InitializerContinuation(newObject, class_, initEnv, |
| 616 constructor.initializers, expressionContinuation); | 627 constructor.initializers, expressionContinuation); |
| 617 return new ExpressionConfiguration( | 628 return new ExpressionConfiguration( |
| 618 _getExpression(constructor.initializers.first), initEnv, cont); | 629 _getExpression(constructor.initializers.first), initEnv, cont); |
| 619 } | 630 } |
| 620 } | 631 } |
| 621 | 632 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 636 if (current is FieldInitializer) { | 647 if (current is FieldInitializer) { |
| 637 currentClass.setProperty(newObject, current.field, v); | 648 currentClass.setProperty(newObject, current.field, v); |
| 638 } else if (current is LocalInitializer) { | 649 } else if (current is LocalInitializer) { |
| 639 initializerEnvironment.expand(current.variable, v); | 650 initializerEnvironment.expand(current.variable, v); |
| 640 } else { | 651 } else { |
| 641 throw 'Assigning value $v to ${current.runtimeType}'; | 652 throw 'Assigning value $v to ${current.runtimeType}'; |
| 642 } | 653 } |
| 643 | 654 |
| 644 if (initializers.length <= 1) { | 655 if (initializers.length <= 1) { |
| 645 // todo: return configuration for body of ctr. | 656 // todo: return configuration for body of ctr. |
| 646 return new ContinuationConfiguration(continuation, newObject); | 657 return new ContinuationConfiguration(continuation, newObject); |
|
Dmitry Stefantsov
2017/05/15 11:48:23
Should we call "_initializeNullFields" here before
zhivkag
2017/05/15 11:58:14
Yes, thanks! Done.
| |
| 647 } | 658 } |
| 648 | 659 |
| 649 Initializer next = initializers[1]; | 660 Initializer next = initializers[1]; |
| 650 | 661 |
| 651 if (next is RedirectingInitializer) { | 662 if (next is RedirectingInitializer) { |
| 663 // RedirectingInitializer appears last in the initializer list. | |
| 664 assert(initializers.length == 2); | |
| 652 var cont = new ConstructorInvocationApplication( | 665 var cont = new ConstructorInvocationApplication( |
| 653 newObject, next.target, continuation); | 666 newObject, next.target, continuation); |
| 654 var args = | 667 var args = |
| 655 _createArgumentExpressionList(next.arguments, next.target.function); | 668 _createArgumentExpressionList(next.arguments, next.target.function); |
| 656 return new ExpressionListConfiguration( | 669 return new ExpressionListConfiguration( |
| 657 args, initializerEnvironment, cont); | 670 args, initializerEnvironment, cont); |
| 658 } | 671 } |
| 659 | 672 |
| 660 if (next is SuperInitializer) { | 673 if (next is SuperInitializer) { |
| 661 // todo: eval args for super. | 674 // SuperInitializer appears last in the initializer list. |
| 662 if (currentClass.superclass.superclass != null) { | 675 assert(initializers.length == 2); |
| 663 throw 'Super initializer invocation is not supported.'; | 676 var args = |
| 664 } | 677 _createArgumentExpressionList(next.arguments, next.target.function); |
| 665 return new ContinuationConfiguration(continuation, newObject); | 678 var superApp = new ConstructorInvocationApplication( |
| 679 newObject, next.target, continuation); | |
| 680 _initializeNullFields(currentClass, newObject); | |
| 681 return new ExpressionListConfiguration( | |
| 682 args, initializerEnvironment, superApp); | |
| 666 } | 683 } |
| 667 | 684 |
| 668 var cont = new InitializerContinuation(newObject, currentClass, | 685 var cont = new InitializerContinuation(newObject, currentClass, |
| 669 initializerEnvironment, initializers.skip(1).toList(), continuation); | 686 initializerEnvironment, initializers.skip(1).toList(), continuation); |
| 670 return new ExpressionConfiguration( | 687 return new ExpressionConfiguration( |
| 671 _getExpression(next), initializerEnvironment, cont); | 688 _getExpression(next), initializerEnvironment, cont); |
| 672 } | 689 } |
| 673 } | 690 } |
| 674 | 691 |
| 675 /// Represents the application continuation called after the evaluation of all | 692 /// Represents the application continuation called after the evaluation of all |
| (...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1377 Expression _getExpression(Initializer initializer) { | 1394 Expression _getExpression(Initializer initializer) { |
| 1378 if (initializer is FieldInitializer) { | 1395 if (initializer is FieldInitializer) { |
| 1379 return initializer.value; | 1396 return initializer.value; |
| 1380 } | 1397 } |
| 1381 if (initializer is LocalInitializer) { | 1398 if (initializer is LocalInitializer) { |
| 1382 return initializer.variable.initializer; | 1399 return initializer.variable.initializer; |
| 1383 } | 1400 } |
| 1384 | 1401 |
| 1385 throw '${initializer.runtimeType} has no epxression.'; | 1402 throw '${initializer.runtimeType} has no epxression.'; |
| 1386 } | 1403 } |
| 1404 | |
| 1405 /// Initializes all non initialized fields in given class with | |
| 1406 /// [Value.nullInstance]. | |
| 1407 void _initializeNullFields(Class class_, ObjectValue newObject) { | |
| 1408 int superClassSize = class_.superclass?.instanceSize ?? 0; | |
| 1409 for (int i = superClassSize; i < class_.instanceSize; i++) { | |
| 1410 Field field = class_.instanceFields[i]; | |
| 1411 if (class_.getProperty(newObject, field) == null) { | |
| 1412 assert(field.initializer == null); | |
| 1413 class_.setProperty(newObject, field, Value.nullInstance); | |
| 1414 } | |
| 1415 } | |
| 1416 } | |
| OLD | NEW |