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 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 InstanceFieldsA( | 683 InstanceFieldsA( |
684 this.constructor, this.location, this.environment, this.continuation) | 684 this.constructor, this.location, this.environment, this.continuation) |
685 : _currentClass = new Class(constructor.enclosingClass.reference); | 685 : _currentClass = new Class(constructor.enclosingClass.reference); |
686 | 686 |
687 Configuration call(List<InterpreterValue> fieldValues) { | 687 Configuration call(List<InterpreterValue> fieldValues) { |
688 for (FieldInitializerValue f in fieldValues) { | 688 for (FieldInitializerValue f in fieldValues) { |
689 // Directly set the field with the corresponding implicit setter. | 689 // Directly set the field with the corresponding implicit setter. |
690 _currentClass.implicitSetters[f.field.name](location.value, f.value); | 690 _currentClass.implicitSetters[f.field.name](location.value, f.value); |
691 } | 691 } |
692 | 692 |
693 // TODO(zhivkag): Execute constructor initializer list before initializing | 693 if (constructor.initializers.length == 0 || |
694 // fields in immediately enclosing class to null. | 694 constructor.initializers.first is SuperInitializer) { |
695 _initializeNullFields(_currentClass, location.value); | 695 _initializeNullFields(_currentClass, location.value); |
696 return new ForwardConfiguration(continuation, environment); | 696 // TODO(zhivkag): Produce the configuration for executing the super |
| 697 // initializer. |
| 698 return new ForwardConfiguration(continuation, environment); |
| 699 } |
| 700 // Otherwise, the next expression from Field or Local initializers will be |
| 701 // evaluated. |
| 702 Expression expr = (constructor.initializers.first is FieldInitializer) |
| 703 ? (constructor.initializers.first as FieldInitializer).value |
| 704 : (constructor.initializers.first as LocalInitializer) |
| 705 .variable |
| 706 .initializer; |
| 707 |
| 708 var cont = new InitializerListEK(constructor, 0 /* initializerIndex*/, |
| 709 location, environment, continuation); |
| 710 return new EvalConfiguration(expr, environment, cont); |
697 } | 711 } |
698 } | 712 } |
699 | 713 |
700 // ------------------------------------------------------------------------ | 714 // ------------------------------------------------------------------------ |
701 // Expression Continuations | 715 // Expression Continuations |
702 // ------------------------------------------------------------------------ | 716 // ------------------------------------------------------------------------ |
703 | 717 |
704 /// Represents an expression continuation. | 718 /// Represents an expression continuation. |
705 /// | 719 /// |
706 /// There are various kinds of [ExpressionContinuation]s and their names are | 720 /// There are various kinds of [ExpressionContinuation]s and their names are |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
996 var bodyCont = | 1010 var bodyCont = |
997 new ConstructorBodySK(constructor.function.body, ctrEnv, continuation); | 1011 new ConstructorBodySK(constructor.function.body, ctrEnv, continuation); |
998 var initializers = _getFieldInitializers(constructor.enclosingClass); | 1012 var initializers = _getFieldInitializers(constructor.enclosingClass); |
999 var fieldsCont = | 1013 var fieldsCont = |
1000 new InstanceFieldsA(constructor, new Location(value), ctrEnv, bodyCont); | 1014 new InstanceFieldsA(constructor, new Location(value), ctrEnv, bodyCont); |
1001 return new EvalListConfiguration( | 1015 return new EvalListConfiguration( |
1002 initializers, new Environment.empty(), fieldsCont); | 1016 initializers, new Environment.empty(), fieldsCont); |
1003 } | 1017 } |
1004 } | 1018 } |
1005 | 1019 |
| 1020 class InitializerListEK extends ExpressionContinuation { |
| 1021 final Constructor constructor; |
| 1022 final int initializerIndex; |
| 1023 final Location location; |
| 1024 final Environment environment; |
| 1025 // TODO(zhivkag): Add componnents for exception handling. |
| 1026 final ConstructorBodySK continuation; |
| 1027 final Class _currentClass; |
| 1028 |
| 1029 InitializerListEK(this.constructor, this.initializerIndex, this.location, |
| 1030 this.environment, this.continuation) |
| 1031 : _currentClass = new Class(constructor.enclosingClass.reference); |
| 1032 |
| 1033 /// Creates a continuation for the evaluation of the initializer at position |
| 1034 /// [index]. |
| 1035 InitializerListEK withInitializerIndex(int index) { |
| 1036 return new InitializerListEK( |
| 1037 constructor, index, location, environment, continuation); |
| 1038 } |
| 1039 |
| 1040 Configuration call(Value value) { |
| 1041 Initializer current = constructor.initializers[initializerIndex]; |
| 1042 if (current is FieldInitializer) { |
| 1043 _currentClass.lookupImplicitSetter(current.field.name)( |
| 1044 location.value, value); |
| 1045 return _createNextConfiguration(environment); |
| 1046 } |
| 1047 if (current is LocalInitializer) { |
| 1048 Environment newEnv = environment.extend(current.variable, value); |
| 1049 return _createNextConfiguration(newEnv); |
| 1050 } |
| 1051 throw "Value can't be applied to initalizer of type ${current.runtimeType}"; |
| 1052 } |
| 1053 |
| 1054 Configuration _createNextConfiguration(Environment env) { |
| 1055 assert(initializerIndex + 1 < constructor.initializers.length); |
| 1056 Initializer next = constructor.initializers[initializerIndex + 1]; |
| 1057 if (next is SuperInitializer) { |
| 1058 // TODO(zhivkag): Execute constructor of "object" class when support for |
| 1059 // native/external functions is added. |
| 1060 if (_currentClass.superclass.superclass == null) { |
| 1061 _initializeNullFields(_currentClass, location.value); |
| 1062 return new ForwardConfiguration(continuation, environment); |
| 1063 } |
| 1064 // TODO(zhivkag): Produce the configuration according to |
| 1065 // specification. |
| 1066 throw 'Support for SuperInitializers in not implemented.'; |
| 1067 } |
| 1068 |
| 1069 if (next is RedirectingInitializer) { |
| 1070 // TODO(zhivkag): Produce the configuration according to |
| 1071 // specification. |
| 1072 throw 'Support for RedirectingInitializers is not implemented.'; |
| 1073 } |
| 1074 |
| 1075 Expression nextExpr = (next is FieldInitializer) |
| 1076 ? next.value |
| 1077 : (next as LocalInitializer).variable.initializer; |
| 1078 |
| 1079 var cont = withInitializerIndex(initializerIndex + 1); |
| 1080 return new EvalConfiguration(nextExpr, env, cont); |
| 1081 } |
| 1082 } |
| 1083 |
1006 /// Executes statements. | 1084 /// Executes statements. |
1007 /// | 1085 /// |
1008 /// Execution of a statement completes in one of the following ways: | 1086 /// Execution of a statement completes in one of the following ways: |
1009 /// - It completes normally, in which case the execution proceeds to applying | 1087 /// - It completes normally, in which case the execution proceeds to applying |
1010 /// the next continuation. | 1088 /// the next continuation. |
1011 /// - It breaks with a label, in which case the corresponding continuation is | 1089 /// - It breaks with a label, in which case the corresponding continuation is |
1012 /// returned and applied. | 1090 /// returned and applied. |
1013 /// - It returns with or without value, in which case the return continuation is | 1091 /// - It returns with or without value, in which case the return continuation is |
1014 /// returned and applied accordingly. | 1092 /// returned and applied accordingly. |
1015 /// - It throws, in which case the handler is returned and applied accordingly. | 1093 /// - It throws, in which case the handler is returned and applied accordingly. |
1016 class StatementExecuter | 1094 class StatementExecuter |
1017 extends StatementVisitor1<Configuration, ExecConfiguration> { | 1095 extends StatementVisitor1<Configuration, ExecConfiguration> { |
1018 Evaluator evaluator = new Evaluator(); | 1096 Evaluator evaluator = new Evaluator(); |
1019 | 1097 |
1020 void trampolinedExecution(Configuration configuration) { | 1098 void trampolinedExecution(Configuration configuration) { |
1021 while (configuration != null) { | 1099 while (configuration != null) { |
1022 configuration = configuration.step(this); | 1100 configuration = configuration.step(this); |
1023 } | 1101 } |
1024 ; | |
1025 } | 1102 } |
1026 | 1103 |
1027 Configuration exec(Statement statement, ExecConfiguration conf) => | 1104 Configuration exec(Statement statement, ExecConfiguration conf) => |
1028 statement.accept1(this, conf); | 1105 statement.accept1(this, conf); |
1029 Configuration eval(Expression expression, EvalConfiguration config) => | 1106 Configuration eval(Expression expression, EvalConfiguration config) => |
1030 evaluator.eval(expression, config); | 1107 evaluator.eval(expression, config); |
1031 Configuration evalList( | 1108 Configuration evalList( |
1032 List<InterpreterExpression> es, Environment env, Continuation cont) => | 1109 List<InterpreterExpression> es, Environment env, Continuation cont) => |
1033 evaluator.evalList(es, env, cont); | 1110 evaluator.evalList(es, env, cont); |
1034 | 1111 |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1419 /// Initializes all non initialized fields from the provided class to | 1496 /// Initializes all non initialized fields from the provided class to |
1420 /// `Value.nullInstance` in the provided value. | 1497 /// `Value.nullInstance` in the provided value. |
1421 void _initializeNullFields(Class class_, Value value) { | 1498 void _initializeNullFields(Class class_, Value value) { |
1422 int startIndex = class_.superclass?.instanceSize ?? 0; | 1499 int startIndex = class_.superclass?.instanceSize ?? 0; |
1423 for (int i = startIndex; i < class_.instanceSize; i++) { | 1500 for (int i = startIndex; i < class_.instanceSize; i++) { |
1424 if (value.fields[i].value == null) { | 1501 if (value.fields[i].value == null) { |
1425 value.fields[i].value = Value.nullInstance; | 1502 value.fields[i].value = Value.nullInstance; |
1426 } | 1503 } |
1427 } | 1504 } |
1428 } | 1505 } |
OLD | NEW |