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 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 |