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