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 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 654 /// It creates the newly allocated object instance. | 654 /// It creates the newly allocated object instance. |
| 655 class ConstructorInvocationA extends ApplicationContinuation { | 655 class ConstructorInvocationA extends ApplicationContinuation { |
| 656 final Constructor constructor; | 656 final Constructor constructor; |
| 657 final ExpressionContinuation continuation; | 657 final ExpressionContinuation continuation; |
| 658 | 658 |
| 659 ConstructorInvocationA(this.constructor, this.continuation); | 659 ConstructorInvocationA(this.constructor, this.continuation); |
| 660 | 660 |
| 661 Configuration call(List<InterpreterValue> argValues) { | 661 Configuration call(List<InterpreterValue> argValues) { |
| 662 Environment ctrEnv = ApplicationContinuation.createEnvironment( | 662 Environment ctrEnv = ApplicationContinuation.createEnvironment( |
| 663 constructor.function, argValues); | 663 constructor.function, argValues); |
| 664 | 664 var class_ = new Class(constructor.enclosingClass.reference); |
| 665 var newObject = new ObjectValue(constructor.enclosingClass); | 665 var newObject = new ObjectValue(class_); |
| 666 var cont = new InitializationEK( | 666 var cont = new InitializationEK( |
| 667 constructor, ctrEnv, new NewSK(continuation, new Location(newObject))); | 667 constructor, ctrEnv, new NewSK(continuation, new Location(newObject))); |
| 668 | 668 |
| 669 return new ValuePassingConfiguration(cont, newObject); | 669 return new ValuePassingConfiguration(cont, newObject); |
| 670 } | 670 } |
| 671 } | 671 } |
| 672 | 672 |
| 673 /// Represents the application continuation for constructor invocation applied | |
| 674 /// on the list of evaluated arguments when a constructor is invoked in a | |
| 675 /// constructor initializer list with a [RedirectingInitializer] or | |
| 676 /// [SuperInitializer]. | |
| 677 class ConstructorInitializerA extends ApplicationContinuation { | |
| 678 final Constructor constructor; | |
| 679 final Location location; | |
| 680 final ConstructorBodySK continuation; | |
| 681 | |
| 682 ConstructorInitializerA(this.constructor, this.location, this.continuation); | |
| 683 | |
| 684 Configuration call(List<InterpreterValue> vs) { | |
| 685 Environment ctrEnv = | |
| 686 ApplicationContinuation.createEnvironment(constructor.function, vs); | |
| 687 var cont = new InitializationEK(constructor, ctrEnv, continuation); | |
| 688 | |
| 689 return new ValuePassingConfiguration(cont, location.value); | |
| 690 } | |
| 691 } | |
| 692 | |
| 673 /// Represents the application continuation applied on the list of evaluated | 693 /// Represents the application continuation applied on the list of evaluated |
| 674 /// field initializer expressions. | 694 /// field initializer expressions. |
| 675 class InstanceFieldsA extends ApplicationContinuation { | 695 class InstanceFieldsA extends ApplicationContinuation { |
| 676 final Constructor constructor; | 696 final Constructor constructor; |
| 677 final Location location; | 697 final Location location; |
| 678 final Environment environment; | 698 final Environment environment; |
| 679 final ConstructorBodySK continuation; | 699 final ConstructorBodySK continuation; |
| 680 | 700 |
| 681 final Class _currentClass; | 701 final Class _currentClass; |
| 682 | 702 |
| 683 InstanceFieldsA( | 703 InstanceFieldsA( |
| 684 this.constructor, this.location, this.environment, this.continuation) | 704 this.constructor, this.location, this.environment, this.continuation) |
| 685 : _currentClass = new Class(constructor.enclosingClass.reference); | 705 : _currentClass = new Class(constructor.enclosingClass.reference); |
| 686 | 706 |
| 687 Configuration call(List<InterpreterValue> fieldValues) { | 707 Configuration call(List<InterpreterValue> fieldValues) { |
| 688 for (FieldInitializerValue f in fieldValues) { | 708 for (FieldInitializerValue f in fieldValues) { |
| 689 // Directly set the field with the corresponding implicit setter. | 709 // Directly set the field with the corresponding implicit setter. |
| 690 _currentClass.implicitSetters[f.field.name](location.value, f.value); | 710 _currentClass.implicitSetters[f.field.name](location.value, f.value); |
| 691 } | 711 } |
| 692 | 712 |
| 713 if (constructor.initializers.length == 0) { | |
| 714 return new ForwardConfiguration(continuation, environment); | |
| 715 } | |
| 716 | |
| 693 // The first initializer is either an initializer with expression | 717 // The first initializer is either an initializer with expression |
| 694 // (i.e., Field or Local initializer) or a Super initializer. | 718 // (i.e., Field or Local initializer) or a Super initializer. |
|
Dmitry Stefantsov
2017/08/02 15:05:49
Please, see if the changes from the previous updat
zhivkag
2017/08/02 15:25:39
Done.
| |
| 695 if (constructor.initializers.length == 0 || | 719 if (constructor.initializers.first is SuperInitializer) { |
| 696 constructor.initializers.first is SuperInitializer) { | 720 // Target constructor is from the superclass `object`. |
| 697 _initializeNullFields(_currentClass, location.value); | 721 if (_currentClass.superclass.superclass == null) { |
| 698 // TODO(zhivkag): Produce the configuration for executing the super | 722 // TODO(zhivkag): Execute the constructor when support for |
| 699 // initializer. | 723 // native/external functions is added. |
| 700 return new ForwardConfiguration(continuation, environment); | 724 _initializeNullFields(_currentClass, location.value); |
| 725 return new ForwardConfiguration(continuation, environment); | |
| 726 } | |
| 727 | |
| 728 return _createEvalListConfig(constructor.initializers.first); | |
| 701 } | 729 } |
| 730 | |
| 702 // Otherwise, the next expression from Field or Local initializers will be | 731 // Otherwise, the next expression from Field or Local initializers will be |
| 703 // evaluated. | 732 // evaluated. |
| 704 Expression expr = (constructor.initializers.first is FieldInitializer) | 733 return _createEvalConfig(constructor.initializers.first); |
| 705 ? (constructor.initializers.first as FieldInitializer).value | 734 } |
| 706 : (constructor.initializers.first as LocalInitializer) | 735 |
| 707 .variable | 736 Configuration _createEvalListConfig(SuperInitializer initializer) { |
| 708 .initializer; | 737 List<InterpreterExpression> args = _getArgumentExpressions( |
| 738 initializer.arguments, initializer.target.function); | |
| 739 var cont = | |
| 740 new ConstructorInitializerA(initializer.target, location, continuation); | |
| 741 | |
| 742 return new EvalListConfiguration(args, environment, cont); | |
| 743 } | |
| 744 | |
| 745 EvalConfiguration _createEvalConfig(Initializer initializer) { | |
| 746 Expression expr = (initializer is FieldInitializer) | |
| 747 ? initializer.value | |
| 748 : (initializer as LocalInitializer).variable.initializer; | |
| 709 | 749 |
| 710 var cont = new InitializerListEK(constructor, 0 /* initializerIndex*/, | 750 var cont = new InitializerListEK(constructor, 0 /* initializerIndex*/, |
|
Dmitry Stefantsov
2017/08/02 15:05:49
How about putting this in-line comment to its own
zhivkag
2017/08/02 15:25:39
Done.
| |
| 711 location, environment, continuation); | 751 location, environment, continuation); |
| 712 return new EvalConfiguration(expr, environment, cont); | 752 return new EvalConfiguration(expr, environment, cont); |
| 713 } | 753 } |
| 714 } | 754 } |
| 715 | |
| 716 // ------------------------------------------------------------------------ | 755 // ------------------------------------------------------------------------ |
| 717 // Expression Continuations | 756 // Expression Continuations |
| 718 // ------------------------------------------------------------------------ | 757 // ------------------------------------------------------------------------ |
| 719 | 758 |
| 720 /// Represents an expression continuation. | 759 /// Represents an expression continuation. |
| 721 /// | 760 /// |
| 722 /// There are various kinds of [ExpressionContinuation]s and their names are | 761 /// There are various kinds of [ExpressionContinuation]s and their names are |
| 723 /// suffixed with "EK". | 762 /// suffixed with "EK". |
| 724 abstract class ExpressionContinuation extends Continuation { | 763 abstract class ExpressionContinuation extends Continuation { |
| 725 Configuration call(Value v); | 764 Configuration call(Value v); |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 990 /// instance with running the constructor. | 1029 /// instance with running the constructor. |
| 991 class InitializationEK extends ExpressionContinuation { | 1030 class InitializationEK extends ExpressionContinuation { |
| 992 final Constructor constructor; | 1031 final Constructor constructor; |
| 993 final Environment environment; | 1032 final Environment environment; |
| 994 // TODO(zhivkag): Add components for exception handling support | 1033 // TODO(zhivkag): Add components for exception handling support |
| 995 final StatementContinuation continuation; | 1034 final StatementContinuation continuation; |
| 996 | 1035 |
| 997 InitializationEK(this.constructor, this.environment, this.continuation); | 1036 InitializationEK(this.constructor, this.environment, this.continuation); |
| 998 | 1037 |
| 999 Configuration call(Value value) { | 1038 Configuration call(Value value) { |
| 1000 if (constructor.enclosingClass.superclass.superclass != null) { | |
| 1001 throw 'Support for super constructors in not implemented.'; | |
| 1002 } | |
| 1003 | |
| 1004 if (constructor.initializers.isNotEmpty && | 1039 if (constructor.initializers.isNotEmpty && |
| 1005 !(constructor.initializers.last is SuperInitializer)) { | 1040 constructor.initializers.last is RedirectingInitializer) { |
| 1006 throw 'Support for initializers is not implemented.'; | 1041 throw 'Support for redirecting initializers is not implemented.'; |
| 1007 } | 1042 } |
| 1008 | 1043 |
| 1009 // The statement body is captured by the next statement continuation and | 1044 // The statement body is captured by the next statement continuation and |
| 1010 // expressions for field initialization are evaluated. | 1045 // expressions for field initialization are evaluated. |
| 1011 var ctrEnv = environment.extendWithThis(value); | 1046 var ctrEnv = environment.extendWithThis(value); |
| 1012 var bodyCont = | 1047 var bodyCont = |
| 1013 new ConstructorBodySK(constructor.function.body, ctrEnv, continuation); | 1048 new ConstructorBodySK(constructor.function.body, ctrEnv, continuation); |
| 1014 var initializers = _getFieldInitializers(constructor.enclosingClass); | 1049 var initializers = _getFieldInitializers(constructor.enclosingClass); |
| 1015 var fieldsCont = | 1050 var fieldsCont = |
| 1016 new InstanceFieldsA(constructor, new Location(value), ctrEnv, bodyCont); | 1051 new InstanceFieldsA(constructor, new Location(value), ctrEnv, bodyCont); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1056 Configuration _createNextConfiguration(Environment env) { | 1091 Configuration _createNextConfiguration(Environment env) { |
| 1057 assert(initializerIndex + 1 < constructor.initializers.length); | 1092 assert(initializerIndex + 1 < constructor.initializers.length); |
| 1058 Initializer next = constructor.initializers[initializerIndex + 1]; | 1093 Initializer next = constructor.initializers[initializerIndex + 1]; |
| 1059 if (next is SuperInitializer) { | 1094 if (next is SuperInitializer) { |
| 1060 // TODO(zhivkag): Execute `object` constructor when support for | 1095 // TODO(zhivkag): Execute `object` constructor when support for |
| 1061 // native/external functions is added. | 1096 // native/external functions is added. |
| 1062 if (_currentClass.superclass.superclass == null) { | 1097 if (_currentClass.superclass.superclass == null) { |
| 1063 _initializeNullFields(_currentClass, location.value); | 1098 _initializeNullFields(_currentClass, location.value); |
| 1064 return new ForwardConfiguration(continuation, environment); | 1099 return new ForwardConfiguration(continuation, environment); |
| 1065 } | 1100 } |
| 1066 // TODO(zhivkag): Produce the configuration according to | 1101 return _createEvalListConfig(next); |
| 1067 // specification. | |
| 1068 throw 'Support for SuperInitializers in not implemented.'; | |
| 1069 } | 1102 } |
| 1070 | 1103 |
| 1071 if (next is RedirectingInitializer) { | 1104 if (next is RedirectingInitializer) { |
| 1072 // TODO(zhivkag): Produce the configuration according to | 1105 // TODO(zhivkag): Produce the configuration according to |
| 1073 // specification. | 1106 // specification. |
| 1074 throw 'Support for RedirectingInitializers is not implemented.'; | 1107 throw 'Support for RedirectingInitializers is not implemented.'; |
| 1075 } | 1108 } |
| 1076 | 1109 |
| 1077 Expression nextExpr = (next is FieldInitializer) | 1110 Expression nextExpr = (next is FieldInitializer) |
| 1078 ? next.value | 1111 ? next.value |
| 1079 : (next as LocalInitializer).variable.initializer; | 1112 : (next as LocalInitializer).variable.initializer; |
| 1080 | 1113 |
| 1081 var cont = withInitializerIndex(initializerIndex + 1); | 1114 var cont = withInitializerIndex(initializerIndex + 1); |
| 1082 return new EvalConfiguration(nextExpr, env, cont); | 1115 return new EvalConfiguration(nextExpr, env, cont); |
| 1083 } | 1116 } |
| 1117 | |
| 1118 Configuration _createEvalListConfig(SuperInitializer initializer) { | |
| 1119 List<InterpreterExpression> args = _getArgumentExpressions( | |
| 1120 initializer.arguments, initializer.target.function); | |
| 1121 var cont = | |
| 1122 new ConstructorInitializerA(initializer.target, location, continuation); | |
| 1123 | |
| 1124 return new EvalListConfiguration(args, environment, cont); | |
| 1125 } | |
| 1084 } | 1126 } |
| 1085 | 1127 |
| 1086 /// Executes statements. | 1128 /// Executes statements. |
| 1087 /// | 1129 /// |
| 1088 /// Execution of a statement completes in one of the following ways: | 1130 /// Execution of a statement completes in one of the following ways: |
| 1089 /// - It completes normally, in which case the execution proceeds to applying | 1131 /// - It completes normally, in which case the execution proceeds to applying |
| 1090 /// the next continuation. | 1132 /// the next continuation. |
| 1091 /// - It breaks with a label, in which case the corresponding continuation is | 1133 /// - It breaks with a label, in which case the corresponding continuation is |
| 1092 /// returned and applied. | 1134 /// returned and applied. |
| 1093 /// - It returns with or without value, in which case the return continuation is | 1135 /// - It returns with or without value, in which case the return continuation is |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1322 if (name.toString() == "==") return equals(arg); | 1364 if (name.toString() == "==") return equals(arg); |
| 1323 throw notImplemented(obj: name); | 1365 throw notImplemented(obj: name); |
| 1324 } | 1366 } |
| 1325 } | 1367 } |
| 1326 | 1368 |
| 1327 class ObjectValue extends Value { | 1369 class ObjectValue extends Value { |
| 1328 final Class class_; | 1370 final Class class_; |
| 1329 final List<Location> fields; | 1371 final List<Location> fields; |
| 1330 Object get value => this; | 1372 Object get value => this; |
| 1331 | 1373 |
| 1332 ObjectValue(ast.Class classDeclaration) | 1374 ObjectValue(this.class_) : fields = new List<Location>(class_.instanceSize) { |
| 1333 : class_ = new Class(classDeclaration.reference), | |
| 1334 fields = new List<Location>(classDeclaration.fields.length) { | |
| 1335 for (int i = 0; i < fields.length; i++) { | 1375 for (int i = 0; i < fields.length; i++) { |
| 1336 // Create fresh locations for each field. | 1376 // Create fresh locations for each field. |
| 1337 fields[i] = new Location.empty(); | 1377 fields[i] = new Location.empty(); |
| 1338 } | 1378 } |
| 1339 } | 1379 } |
| 1340 } | 1380 } |
| 1341 | 1381 |
| 1342 abstract class LiteralValue extends Value { | 1382 abstract class LiteralValue extends Value { |
| 1343 Class get class_ => | 1383 Class get class_ => |
| 1344 notImplemented(m: "Loading class for literal is not implemented."); | 1384 notImplemented(m: "Loading class for literal is not implemented."); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1498 /// Initializes all non initialized fields from the provided class to | 1538 /// Initializes all non initialized fields from the provided class to |
| 1499 /// `Value.nullInstance` in the provided value. | 1539 /// `Value.nullInstance` in the provided value. |
| 1500 void _initializeNullFields(Class class_, Value value) { | 1540 void _initializeNullFields(Class class_, Value value) { |
| 1501 int startIndex = class_.superclass?.instanceSize ?? 0; | 1541 int startIndex = class_.superclass?.instanceSize ?? 0; |
| 1502 for (int i = startIndex; i < class_.instanceSize; i++) { | 1542 for (int i = startIndex; i < class_.instanceSize; i++) { |
| 1503 if (value.fields[i].value == null) { | 1543 if (value.fields[i].value == null) { |
| 1504 value.fields[i].value = Value.nullInstance; | 1544 value.fields[i].value = Value.nullInstance; |
| 1505 } | 1545 } |
| 1506 } | 1546 } |
| 1507 } | 1547 } |
| OLD | NEW |