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

Side by Side Diff: pkg/kernel/lib/interpreter/interpreter.dart

Issue 2990943002: Add support for super initialziers in constructor initializer list (Closed)
Patch Set: Add comment for index starting at 0 Created 3 years, 4 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
« no previous file with comments | « no previous file | pkg/kernel/test/interpreter/interpreter.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
693 if (constructor.initializers.length == 0 || 713 if (constructor.initializers.length == 0) {
694 constructor.initializers.first is SuperInitializer) {
695 _initializeNullFields(_currentClass, location.value);
696 // TODO(zhivkag): Produce the configuration for executing the super
697 // initializer.
698 return new ForwardConfiguration(continuation, environment); 714 return new ForwardConfiguration(continuation, environment);
699 } 715 }
716
717 if (constructor.initializers.first is SuperInitializer) {
718 // Target constructor is from the superclass `object`.
719 if (_currentClass.superclass.superclass == null) {
720 // TODO(zhivkag): Execute the constructor when support for
721 // native/external functions is added.
722 _initializeNullFields(_currentClass, location.value);
723 return new ForwardConfiguration(continuation, environment);
724 }
725
726 return _createEvalListConfig(constructor.initializers.first);
727 }
728
700 // Otherwise, the next expression from Field or Local initializers will be 729 // Otherwise, the next expression from Field or Local initializers will be
701 // evaluated. 730 // evaluated.
702 Expression expr = (constructor.initializers.first is FieldInitializer) 731 return _createEvalConfig(constructor.initializers.first);
703 ? (constructor.initializers.first as FieldInitializer).value 732 }
704 : (constructor.initializers.first as LocalInitializer)
705 .variable
706 .initializer;
707 733
708 var cont = new InitializerListEK(constructor, 0 /* initializerIndex*/, 734 Configuration _createEvalListConfig(SuperInitializer initializer) {
709 location, environment, continuation); 735 List<InterpreterExpression> args = _getArgumentExpressions(
736 initializer.arguments, initializer.target.function);
737 var cont =
738 new ConstructorInitializerA(initializer.target, location, continuation);
739
740 return new EvalListConfiguration(args, environment, cont);
741 }
742
743 EvalConfiguration _createEvalConfig(Initializer initializer) {
744 Expression expr = (initializer is FieldInitializer)
745 ? initializer.value
746 : (initializer as LocalInitializer).variable.initializer;
747
748 // We start with index = 0 since we are evaluating the expression for the
749 // first initializer in the initializer list.
750 var cont = new InitializerListEK(
751 constructor, 0, location, environment, continuation);
710 return new EvalConfiguration(expr, environment, cont); 752 return new EvalConfiguration(expr, environment, cont);
711 } 753 }
712 } 754 }
713
714 // ------------------------------------------------------------------------ 755 // ------------------------------------------------------------------------
715 // Expression Continuations 756 // Expression Continuations
716 // ------------------------------------------------------------------------ 757 // ------------------------------------------------------------------------
717 758
718 /// Represents an expression continuation. 759 /// Represents an expression continuation.
719 /// 760 ///
720 /// There are various kinds of [ExpressionContinuation]s and their names are 761 /// There are various kinds of [ExpressionContinuation]s and their names are
721 /// suffixed with "EK". 762 /// suffixed with "EK".
722 abstract class ExpressionContinuation extends Continuation { 763 abstract class ExpressionContinuation extends Continuation {
723 Configuration call(Value v); 764 Configuration call(Value v);
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 /// instance with running the constructor. 1029 /// instance with running the constructor.
989 class InitializationEK extends ExpressionContinuation { 1030 class InitializationEK extends ExpressionContinuation {
990 final Constructor constructor; 1031 final Constructor constructor;
991 final Environment environment; 1032 final Environment environment;
992 // TODO(zhivkag): Add components for exception handling support 1033 // TODO(zhivkag): Add components for exception handling support
993 final StatementContinuation continuation; 1034 final StatementContinuation continuation;
994 1035
995 InitializationEK(this.constructor, this.environment, this.continuation); 1036 InitializationEK(this.constructor, this.environment, this.continuation);
996 1037
997 Configuration call(Value value) { 1038 Configuration call(Value value) {
998 if (constructor.enclosingClass.superclass.superclass != null) {
999 throw 'Support for super constructors in not implemented.';
1000 }
1001
1002 if (constructor.initializers.isNotEmpty && 1039 if (constructor.initializers.isNotEmpty &&
1003 !(constructor.initializers.last is SuperInitializer)) { 1040 constructor.initializers.last is RedirectingInitializer) {
1004 throw 'Support for initializers is not implemented.'; 1041 throw 'Support for redirecting initializers is not implemented.';
1005 } 1042 }
1006 1043
1007 // The statement body is captured by the next statement continuation and 1044 // The statement body is captured by the next statement continuation and
1008 // expressions for field initialization are evaluated. 1045 // expressions for field initialization are evaluated.
1009 var ctrEnv = environment.extendWithThis(value); 1046 var ctrEnv = environment.extendWithThis(value);
1010 var bodyCont = 1047 var bodyCont =
1011 new ConstructorBodySK(constructor.function.body, ctrEnv, continuation); 1048 new ConstructorBodySK(constructor.function.body, ctrEnv, continuation);
1012 var initializers = _getFieldInitializers(constructor.enclosingClass); 1049 var initializers = _getFieldInitializers(constructor.enclosingClass);
1013 var fieldsCont = 1050 var fieldsCont =
1014 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
1054 Configuration _createNextConfiguration(Environment env) { 1091 Configuration _createNextConfiguration(Environment env) {
1055 assert(initializerIndex + 1 < constructor.initializers.length); 1092 assert(initializerIndex + 1 < constructor.initializers.length);
1056 Initializer next = constructor.initializers[initializerIndex + 1]; 1093 Initializer next = constructor.initializers[initializerIndex + 1];
1057 if (next is SuperInitializer) { 1094 if (next is SuperInitializer) {
1058 // TODO(zhivkag): Execute constructor of "object" class when support for 1095 // TODO(zhivkag): Execute constructor of "object" class when support for
1059 // native/external functions is added. 1096 // native/external functions is added.
1060 if (_currentClass.superclass.superclass == null) { 1097 if (_currentClass.superclass.superclass == null) {
1061 _initializeNullFields(_currentClass, location.value); 1098 _initializeNullFields(_currentClass, location.value);
1062 return new ForwardConfiguration(continuation, environment); 1099 return new ForwardConfiguration(continuation, environment);
1063 } 1100 }
1064 // TODO(zhivkag): Produce the configuration according to 1101 return _createEvalListConfig(next);
1065 // specification.
1066 throw 'Support for SuperInitializers in not implemented.';
1067 } 1102 }
1068 1103
1069 if (next is RedirectingInitializer) { 1104 if (next is RedirectingInitializer) {
1070 // TODO(zhivkag): Produce the configuration according to 1105 // TODO(zhivkag): Produce the configuration according to
1071 // specification. 1106 // specification.
1072 throw 'Support for RedirectingInitializers is not implemented.'; 1107 throw 'Support for RedirectingInitializers is not implemented.';
1073 } 1108 }
1074 1109
1075 Expression nextExpr = (next is FieldInitializer) 1110 Expression nextExpr = (next is FieldInitializer)
1076 ? next.value 1111 ? next.value
1077 : (next as LocalInitializer).variable.initializer; 1112 : (next as LocalInitializer).variable.initializer;
1078 1113
1079 var cont = withInitializerIndex(initializerIndex + 1); 1114 var cont = withInitializerIndex(initializerIndex + 1);
1080 return new EvalConfiguration(nextExpr, env, cont); 1115 return new EvalConfiguration(nextExpr, env, cont);
1081 } 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 }
1082 } 1126 }
1083 1127
1084 /// Executes statements. 1128 /// Executes statements.
1085 /// 1129 ///
1086 /// Execution of a statement completes in one of the following ways: 1130 /// Execution of a statement completes in one of the following ways:
1087 /// - It completes normally, in which case the execution proceeds to applying 1131 /// - It completes normally, in which case the execution proceeds to applying
1088 /// the next continuation. 1132 /// the next continuation.
1089 /// - 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
1090 /// returned and applied. 1134 /// returned and applied.
1091 /// - 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
1320 if (name.toString() == "==") return equals(arg); 1364 if (name.toString() == "==") return equals(arg);
1321 throw notImplemented(obj: name); 1365 throw notImplemented(obj: name);
1322 } 1366 }
1323 } 1367 }
1324 1368
1325 class ObjectValue extends Value { 1369 class ObjectValue extends Value {
1326 final Class class_; 1370 final Class class_;
1327 final List<Location> fields; 1371 final List<Location> fields;
1328 Object get value => this; 1372 Object get value => this;
1329 1373
1330 ObjectValue(ast.Class classDeclaration) 1374 ObjectValue(this.class_) : fields = new List<Location>(class_.instanceSize) {
1331 : class_ = new Class(classDeclaration.reference),
1332 fields = new List<Location>(classDeclaration.fields.length) {
1333 for (int i = 0; i < fields.length; i++) { 1375 for (int i = 0; i < fields.length; i++) {
1334 // Create fresh locations for each field. 1376 // Create fresh locations for each field.
1335 fields[i] = new Location.empty(); 1377 fields[i] = new Location.empty();
1336 } 1378 }
1337 } 1379 }
1338 } 1380 }
1339 1381
1340 abstract class LiteralValue extends Value { 1382 abstract class LiteralValue extends Value {
1341 Class get class_ => 1383 Class get class_ =>
1342 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
1496 /// Initializes all non initialized fields from the provided class to 1538 /// Initializes all non initialized fields from the provided class to
1497 /// `Value.nullInstance` in the provided value. 1539 /// `Value.nullInstance` in the provided value.
1498 void _initializeNullFields(Class class_, Value value) { 1540 void _initializeNullFields(Class class_, Value value) {
1499 int startIndex = class_.superclass?.instanceSize ?? 0; 1541 int startIndex = class_.superclass?.instanceSize ?? 0;
1500 for (int i = startIndex; i < class_.instanceSize; i++) { 1542 for (int i = startIndex; i < class_.instanceSize; i++) {
1501 if (value.fields[i].value == null) { 1543 if (value.fields[i].value == null) {
1502 value.fields[i].value = Value.nullInstance; 1544 value.fields[i].value = Value.nullInstance;
1503 } 1545 }
1504 } 1546 }
1505 } 1547 }
OLDNEW
« no previous file with comments | « no previous file | pkg/kernel/test/interpreter/interpreter.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698