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

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

Issue 2997563002: Implement support for static accessors (Closed)
Patch Set: Remove dill 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/testcases/interpreter/function_expressions_test.dart » ('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';
11 11
12 class NotImplemented { 12 class NotImplemented {
13 String message; 13 String message;
14 14
15 NotImplemented(this.message); 15 NotImplemented(this.message);
16 16
17 String toString() => message; 17 String toString() => message;
18 } 18 }
19 19
20 class Interpreter { 20 class Interpreter {
21 Program program; 21 Program program;
22 StatementExecuter visitor = new StatementExecuter(); 22 StatementExecuter visitor = new StatementExecuter();
23 23
24 // The execution of the program starts with empty main environment.
25 static MainEnvironment mainEnvironment =
26 new MainEnvironment(<Member, Location>{});
27
24 Interpreter(this.program); 28 Interpreter(this.program);
25 29
26 void run() { 30 void run() {
27 assert(program.libraries.isEmpty); 31 assert(program.libraries.isEmpty);
28 Procedure mainMethod = program.mainMethod; 32 Procedure mainMethod = program.mainMethod;
29 33
30 if (mainMethod == null) return; 34 if (mainMethod == null) return;
31 35
32 Statement statementBlock = mainMethod.function.body; 36 Statement statementBlock = mainMethod.function.body;
33 ExecConfiguration configuration = new ExecConfiguration( 37 ExecConfiguration configuration = new ExecConfiguration(
34 statementBlock, new Environment.empty(), new State.initial()); 38 statementBlock, new Environment.empty(), new State.initial());
35 visitor.trampolinedExecution(configuration); 39 visitor.trampolinedExecution(configuration);
36 } 40 }
37 } 41 }
38 42
39 class Location { 43 class Location {
40 Value value; 44 Value value;
41 45
42 Location.empty(); 46 Location.empty();
43 Location(this.value); 47 Location(this.value);
44 } 48 }
45 49
46 class Binding { 50 class Binding {
47 final VariableDeclaration variable; 51 final VariableDeclaration variable;
48 final Location location; 52 final Location location;
49 53
50 Binding(this.variable, this.location); 54 Binding(this.variable, this.location);
51 } 55 }
52 56
57 /// Represents the top level environment that binds previously accessed or set
58 /// static fields to the location that stores their value.
59 class MainEnvironment {
60 final Map<Member, Location> _staticFields;
61
62 MainEnvironment(this._staticFields);
63
64 bool contains(Member member) => _staticFields[member] != null;
65
66 Value lookup(Member member) {
67 assert(contains(member));
68 return _staticFields[member].value;
69 }
70
71 void updateStore(Member member, Value value) {
72 assert(contains(member));
73 _staticFields[member].value = value;
74 }
75
76 MainEnvironment extend(Member member, Value value) {
77 var newMap = new Map<Member, Location>.from(_staticFields);
78 newMap[member] = new Location(value);
79 return new MainEnvironment(newMap);
80 }
81 }
82
53 class Environment { 83 class Environment {
54 final List<Binding> bindings = <Binding>[]; 84 final List<Binding> bindings = <Binding>[];
55 final Environment parent; 85 final Environment parent;
56 86
57 Value get thisInstance { 87 Value get thisInstance {
58 return containsThis() 88 return containsThis()
59 ? lookupThis().value 89 ? lookupThis().value
60 : throw "Invalid reference to 'this' expression"; 90 : throw "Invalid reference to 'this' expression";
61 } 91 }
62 92
(...skipping 27 matching lines...) Expand all
90 for (Binding b in bindings) { 120 for (Binding b in bindings) {
91 if (identical(b.variable.name, 'this')) return b.location; 121 if (identical(b.variable.name, 'this')) return b.location;
92 } 122 }
93 return parent.lookupThis(); 123 return parent.lookupThis();
94 } 124 }
95 125
96 Value lookup(VariableDeclaration variable) { 126 Value lookup(VariableDeclaration variable) {
97 return lookupBinding(variable).location.value; 127 return lookupBinding(variable).location.value;
98 } 128 }
99 129
100 void assign(VariableDeclaration variable, Value value) { 130 void updateStore(VariableDeclaration variable, Value value) {
101 assert(contains(variable)); 131 assert(contains(variable));
102 lookupBinding(variable).location.value = value; 132 lookupBinding(variable).location.value = value;
103 } 133 }
104 134
105 Environment extend(VariableDeclaration variable, Value value) { 135 Environment extend(VariableDeclaration variable, Value value) {
106 assert(!contains(variable)); 136 assert(!contains(variable));
107 return new Environment(this) 137 return new Environment(this)
108 ..bindings.add(new Binding(variable, new Location(value))); 138 ..bindings.add(new Binding(variable, new Location(value)));
109 } 139 }
110 140
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 node.receiver, config.environment, config.exceptionComponents, cont); 190 node.receiver, config.environment, config.exceptionComponents, cont);
161 } 191 }
162 192
163 Configuration visitPropertySet(PropertySet node, EvalConfiguration config) { 193 Configuration visitPropertySet(PropertySet node, EvalConfiguration config) {
164 var cont = new PropertySetEK(node.value, node.name, config.environment, 194 var cont = new PropertySetEK(node.value, node.name, config.environment,
165 config.exceptionComponents, config.continuation); 195 config.exceptionComponents, config.continuation);
166 return new EvalConfiguration( 196 return new EvalConfiguration(
167 node.receiver, config.environment, config.exceptionComponents, cont); 197 node.receiver, config.environment, config.exceptionComponents, cont);
168 } 198 }
169 199
170 Configuration visitStaticGet(StaticGet node, EvalConfiguration config) => 200 Configuration visitStaticGet(StaticGet node, EvalConfiguration config) {
171 defaultExpression(node, config); 201 Member member = node.target;
172 Configuration visitStaticSet(StaticSet node, EvalConfiguration config) => 202
173 defaultExpression(node, config); 203 if (member is Procedure && !member.isAccessor) {
204 // Create a closure for the method tear off.
205 var v = new FunctionValue(member.function, new Environment.empty());
206 return new ValuePassingConfiguration(config.continuation, v);
207 }
208
209 if (member is Procedure && member.isGetter) {
210 // Execute the body of the getter.
211 var state = new State.initial()
212 .withReturnContinuation(config.continuation)
213 .withContinuation(new ExitSK(config.continuation, Value.nullInstance))
214 .withException(config.exceptionComponents);
215 return new ExecConfiguration(
216 member.function.body, new Environment.empty(), state);
217 }
218
219 assert(member is Field);
220 if (Interpreter.mainEnvironment.contains(member)) {
221 // Read the value for the member in the main environment.
222 return new ValuePassingConfiguration(
223 config.continuation, Interpreter.mainEnvironment.lookup(member));
224 }
225
226 // Otherwise, the static field is accessed for the first time.
227 // We extend the main environment with a new binding.
228 Interpreter.mainEnvironment =
229 Interpreter.mainEnvironment.extend(member, Value.nullInstance);
230
231 if ((member as Field).initializer == null) {
232 return new ValuePassingConfiguration(
233 config.continuation, Value.nullInstance);
234 }
235
236 // The initializer expression is evaluated otherwise.
237 var cont = new StaticSetEK(member, config.continuation);
238 return new EvalConfiguration((member as Field).initializer,
239 new Environment.empty(), config.exceptionComponents, cont);
240 }
241
242 Configuration visitStaticSet(StaticSet node, EvalConfiguration config) {
243 Member member = node.target;
244 ExpressionContinuation cont;
245
246 if (member is Procedure) {
247 assert(member.isSetter);
248 cont = new StaticSetterEK(
249 member.function, config.exceptionComponents, config.continuation);
250 } else {
251 assert(member is Field);
252 cont = new StaticSetEK(member, config.continuation);
253 }
254
255 return new EvalConfiguration(
256 node.value, config.environment, config.exceptionComponents, cont);
257 }
174 258
175 Configuration visitStaticInvocation( 259 Configuration visitStaticInvocation(
176 StaticInvocation node, EvalConfiguration config) { 260 StaticInvocation node, EvalConfiguration config) {
177 if ('print' == node.name.toString()) { 261 if ('print' == node.name.toString()) {
178 var cont = new PrintEK(config.continuation); 262 var cont = new PrintEK(config.continuation);
179 return new EvalConfiguration(node.arguments.positional.first, 263 return new EvalConfiguration(node.arguments.positional.first,
180 config.environment, config.exceptionComponents, cont); 264 config.environment, config.exceptionComponents, cont);
181 } else { 265 } else {
182 log.info('static-invocation-${node.target.name.toString()}\n'); 266 log.info('static-invocation-${node.target.name.toString()}\n');
183 267
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 config.continuation, config.environment.thisInstance); 340 config.continuation, config.environment.thisInstance);
257 } 341 }
258 342
259 Configuration visitThrow(Throw node, EvalConfiguration config) { 343 Configuration visitThrow(Throw node, EvalConfiguration config) {
260 var cont = new ThrowEK(config.exceptionComponents); 344 var cont = new ThrowEK(config.exceptionComponents);
261 345
262 return new EvalConfiguration( 346 return new EvalConfiguration(
263 node.expression, config.environment, config.exceptionComponents, cont); 347 node.expression, config.environment, config.exceptionComponents, cont);
264 } 348 }
265 349
350 Configuration visitFunctionExpression(
351 FunctionExpression node, EvalConfiguration config) {
352 var val = new FunctionValue(node.function, config.environment);
353 return new ValuePassingConfiguration(config.continuation, val);
354 }
355
266 // Evaluation of BasicLiterals. 356 // Evaluation of BasicLiterals.
267 Configuration visitStringLiteral( 357 Configuration visitStringLiteral(
268 StringLiteral node, EvalConfiguration config) { 358 StringLiteral node, EvalConfiguration config) {
269 return new ValuePassingConfiguration( 359 return new ValuePassingConfiguration(
270 config.continuation, new StringValue(node.value)); 360 config.continuation, new StringValue(node.value));
271 } 361 }
272 362
273 Configuration visitIntLiteral(IntLiteral node, EvalConfiguration config) { 363 Configuration visitIntLiteral(IntLiteral node, EvalConfiguration config) {
274 return new ValuePassingConfiguration( 364 return new ValuePassingConfiguration(
275 config.continuation, new IntValue(node.value)); 365 config.continuation, new IntValue(node.value));
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 } 498 }
409 499
410 /// Configuration for execution of a [Statement]. 500 /// Configuration for execution of a [Statement].
411 class ExecConfiguration extends Configuration { 501 class ExecConfiguration extends Configuration {
412 final Statement currentStatement; 502 final Statement currentStatement;
413 final Environment environment; 503 final Environment environment;
414 final State state; 504 final State state;
415 505
416 ExecConfiguration(this.currentStatement, this.environment, this.state); 506 ExecConfiguration(this.currentStatement, this.environment, this.state);
417 507
418 Configuration step(StatementExecuter executer) => 508 Configuration step(StatementExecuter executer) {
419 executer.exec(currentStatement, this); 509 return executer.exec(currentStatement, this);
510 }
420 } 511 }
421 512
422 /// Configuration for applying a [StatementContinuation] to an [Environment]. 513 /// Configuration for applying a [StatementContinuation] to an [Environment].
423 class ForwardConfiguration extends Configuration { 514 class ForwardConfiguration extends Configuration {
424 final StatementContinuation continuation; 515 final StatementContinuation continuation;
425 final Environment environment; 516 final Environment environment;
426 517
427 ForwardConfiguration(this.continuation, this.environment); 518 ForwardConfiguration(this.continuation, this.environment);
428 519
429 Configuration step(StatementExecuter _) => continuation?.call(environment); 520 Configuration step(StatementExecuter _) => continuation?.call(environment);
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 ? initializer.value 976 ? initializer.value
886 : (initializer as LocalInitializer).variable.initializer; 977 : (initializer as LocalInitializer).variable.initializer;
887 978
888 // We start with index = 0 since we are evaluating the expression for the 979 // We start with index = 0 since we are evaluating the expression for the
889 // first initializer in the initializer list. 980 // first initializer in the initializer list.
890 var cont = new InitializerListEK(constructor, 0, location, environment, 981 var cont = new InitializerListEK(constructor, 0, location, environment,
891 exceptionComponents, continuation); 982 exceptionComponents, continuation);
892 return new EvalConfiguration(expr, environment, exceptionComponents, cont); 983 return new EvalConfiguration(expr, environment, exceptionComponents, cont);
893 } 984 }
894 } 985 }
986
987 class FunctionValueA extends ApplicationContinuation {
988 final FunctionValue receiver;
989 final ExceptionComponents exceptionComponents;
990 final ExpressionContinuation returnContinuation;
991
992 FunctionValueA(
993 this.receiver, this.exceptionComponents, this.returnContinuation);
994
995 Configuration call(List<InterpreterValue> vs) {
996 Environment env = ApplicationContinuation.createEnvironment(
997 receiver.function, vs, receiver.environment);
998 var scont = new ExitSK(returnContinuation, Value.nullInstance);
999 var state = new State(null, exceptionComponents, returnContinuation, scont);
1000 return new ExecConfiguration(receiver.function.body, env, state);
1001 }
1002 }
1003
895 // ------------------------------------------------------------------------ 1004 // ------------------------------------------------------------------------
896 // Expression Continuations 1005 // Expression Continuations
897 // ------------------------------------------------------------------------ 1006 // ------------------------------------------------------------------------
898 1007
899 /// Represents an expression continuation. 1008 /// Represents an expression continuation.
900 /// 1009 ///
901 /// There are various kinds of [ExpressionContinuation]s and their names are 1010 /// There are various kinds of [ExpressionContinuation]s and their names are
902 /// suffixed with "EK". 1011 /// suffixed with "EK".
903 abstract class ExpressionContinuation extends Continuation { 1012 abstract class ExpressionContinuation extends Continuation {
904 Configuration call(Value v); 1013 Configuration call(Value v);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 1073
965 SetterEK(this.receiver, this.name, this.continuation); 1074 SetterEK(this.receiver, this.name, this.continuation);
966 1075
967 Configuration call(Value v) { 1076 Configuration call(Value v) {
968 Setter setter = receiver.class_.lookupImplicitSetter(name); 1077 Setter setter = receiver.class_.lookupImplicitSetter(name);
969 setter(receiver, v); 1078 setter(receiver, v);
970 return new ValuePassingConfiguration(continuation, v); 1079 return new ValuePassingConfiguration(continuation, v);
971 } 1080 }
972 } 1081 }
973 1082
1083 class StaticSetEK extends ExpressionContinuation {
1084 final Member member;
1085 final ExpressionContinuation continuation;
1086
1087 StaticSetEK(this.member, this.continuation);
1088
1089 Configuration call(Value v) {
1090 if (Interpreter.mainEnvironment.contains(member)) {
1091 Interpreter.mainEnvironment.updateStore(member, v);
1092 } else {
1093 Interpreter.mainEnvironment =
1094 Interpreter.mainEnvironment.extend(member, v);
1095 }
1096 return new ValuePassingConfiguration(continuation, v);
1097 }
1098 }
1099
1100 class StaticSetterEK extends ExpressionContinuation {
1101 final FunctionNode setter;
1102 final ExceptionComponents exceptionComponents;
1103 final ExpressionContinuation expressionContinuation;
1104
1105 StaticSetterEK(
1106 this.setter, this.exceptionComponents, this.expressionContinuation);
1107
1108 Configuration call(Value v) {
1109 VariableDeclaration arg = setter.positionalParameters.first;
1110 var env = new Environment.empty().extend(arg, v);
1111 var state = new State.initial()
1112 .withException(exceptionComponents)
1113 .withReturnContinuation(expressionContinuation)
1114 .withContinuation(
1115 new ExitSK(expressionContinuation, Value.nullInstance));
1116
1117 return new ExecConfiguration(setter.body, env, state);
1118 }
1119 }
1120
974 /// Represents a continuation to be called after the evaluation of an actual 1121 /// Represents a continuation to be called after the evaluation of an actual
975 /// argument for function invocation. 1122 /// argument for function invocation.
976 class ExpressionListEK extends ExpressionContinuation { 1123 class ExpressionListEK extends ExpressionContinuation {
977 final InterpreterExpression currentExpression; 1124 final InterpreterExpression currentExpression;
978 final List<InterpreterExpression> expressions; 1125 final List<InterpreterExpression> expressions;
979 final Environment environment; 1126 final Environment environment;
980 final ExceptionComponents exceptionComponents; 1127 final ExceptionComponents exceptionComponents;
981 final ApplicationContinuation applicationContinuation; 1128 final ApplicationContinuation applicationContinuation;
982 1129
983 ExpressionListEK(this.currentExpression, this.expressions, this.environment, 1130 ExpressionListEK(this.currentExpression, this.expressions, this.environment,
(...skipping 11 matching lines...) Expand all
995 final Arguments arguments; 1142 final Arguments arguments;
996 final Name methodName; 1143 final Name methodName;
997 final Environment environment; 1144 final Environment environment;
998 final ExceptionComponents exceptionComponents; 1145 final ExceptionComponents exceptionComponents;
999 final ExpressionContinuation continuation; 1146 final ExpressionContinuation continuation;
1000 1147
1001 MethodInvocationEK(this.arguments, this.methodName, this.environment, 1148 MethodInvocationEK(this.arguments, this.methodName, this.environment,
1002 this.exceptionComponents, this.continuation); 1149 this.exceptionComponents, this.continuation);
1003 1150
1004 Configuration call(Value receiver) { 1151 Configuration call(Value receiver) {
1152 if (receiver is FunctionValue) {
1153 // TODO(zhivkag): use method lookup instead.
1154 assert(methodName.toString() == 'call');
1155 var args = _getArgumentExpressions(arguments, receiver.function);
1156 var acont =
1157 new FunctionValueA(receiver, exceptionComponents, continuation);
1158 return new EvalListConfiguration(
1159 args, environment, exceptionComponents, acont);
1160 }
1161
1005 if (arguments.positional.isEmpty) { 1162 if (arguments.positional.isEmpty) {
1006 Value returnValue = receiver.invokeMethod(methodName); 1163 Value returnValue = receiver.invokeMethod(methodName);
1007 return new ValuePassingConfiguration(continuation, returnValue); 1164 return new ValuePassingConfiguration(continuation, returnValue);
1008 } 1165 }
1009 var cont = new ArgumentsEK( 1166 var cont = new ArgumentsEK(
1010 receiver, methodName, arguments, environment, continuation); 1167 receiver, methodName, arguments, environment, continuation);
1011 1168
1012 return new EvalConfiguration( 1169 return new EvalConfiguration(
1013 arguments.positional.first, environment, exceptionComponents, cont); 1170 arguments.positional.first, environment, exceptionComponents, cont);
1014 } 1171 }
(...skipping 18 matching lines...) Expand all
1033 } 1190 }
1034 1191
1035 class VariableSetEK extends ExpressionContinuation { 1192 class VariableSetEK extends ExpressionContinuation {
1036 final VariableDeclaration variable; 1193 final VariableDeclaration variable;
1037 final Environment environment; 1194 final Environment environment;
1038 final ExpressionContinuation continuation; 1195 final ExpressionContinuation continuation;
1039 1196
1040 VariableSetEK(this.variable, this.environment, this.continuation); 1197 VariableSetEK(this.variable, this.environment, this.continuation);
1041 1198
1042 Configuration call(Value value) { 1199 Configuration call(Value value) {
1043 environment.assign(variable, value); 1200 environment.updateStore(variable, value);
1044 return new ValuePassingConfiguration(continuation, value); 1201 return new ValuePassingConfiguration(continuation, value);
1045 } 1202 }
1046 } 1203 }
1047 1204
1048 class NotEK extends ExpressionContinuation { 1205 class NotEK extends ExpressionContinuation {
1049 final ExpressionContinuation continuation; 1206 final ExpressionContinuation continuation;
1050 1207
1051 NotEK(this.continuation); 1208 NotEK(this.continuation);
1052 1209
1053 Configuration call(Value value) { 1210 Configuration call(Value value) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1115 final VariableDeclaration variable; 1272 final VariableDeclaration variable;
1116 final Expression letBody; 1273 final Expression letBody;
1117 final Environment environment; 1274 final Environment environment;
1118 final ExceptionComponents exceptionComponents; 1275 final ExceptionComponents exceptionComponents;
1119 final ExpressionContinuation continuation; 1276 final ExpressionContinuation continuation;
1120 1277
1121 LetEK(this.variable, this.letBody, this.environment, this.exceptionComponents, 1278 LetEK(this.variable, this.letBody, this.environment, this.exceptionComponents,
1122 this.continuation); 1279 this.continuation);
1123 1280
1124 Configuration call(Value value) { 1281 Configuration call(Value value) {
1125 var letEnv = new Environment(environment); 1282 var letEnv = environment.extend(variable, value);
1126 letEnv.extend(variable, value);
1127 return new EvalConfiguration( 1283 return new EvalConfiguration(
1128 letBody, letEnv, exceptionComponents, continuation); 1284 letBody, letEnv, exceptionComponents, continuation);
1129 } 1285 }
1130 } 1286 }
1131 1287
1132 /// Represents the continuation for the condition expression in [WhileStatement] . 1288 /// Represents the continuation for the condition expression in [WhileStatement] .
1133 class WhileConditionEK extends ExpressionContinuation { 1289 class WhileConditionEK extends ExpressionContinuation {
1134 final Expression condition; 1290 final Expression condition;
1135 final Statement body; 1291 final Statement body;
1136 final Environment enclosingEnv; 1292 final Environment enclosingEnv;
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
1493 return new EvalConfiguration(node.expression, conf.environment, 1649 return new EvalConfiguration(node.expression, conf.environment,
1494 conf.state.exceptionComponents, cont); 1650 conf.state.exceptionComponents, cont);
1495 } 1651 }
1496 1652
1497 Configuration visitBlock(Block node, ExecConfiguration conf) { 1653 Configuration visitBlock(Block node, ExecConfiguration conf) {
1498 if (node.statements.isEmpty) { 1654 if (node.statements.isEmpty) {
1499 return new ForwardConfiguration( 1655 return new ForwardConfiguration(
1500 conf.state.continuation, conf.environment); 1656 conf.state.continuation, conf.environment);
1501 } 1657 }
1502 1658
1503 var env = new Environment(conf.environment);
1504 var cont = new BlockSK.fromConfig(node.statements.skip(1).toList(), conf); 1659 var cont = new BlockSK.fromConfig(node.statements.skip(1).toList(), conf);
1505 return new ExecConfiguration( 1660 return new ExecConfiguration(node.statements.first, conf.environment,
1506 node.statements.first, env, conf.state.withContinuation(cont)); 1661 conf.state.withContinuation(cont));
1507 } 1662 }
1508 1663
1509 Configuration visitEmptyStatement( 1664 Configuration visitEmptyStatement(
1510 EmptyStatement node, ExecConfiguration conf) { 1665 EmptyStatement node, ExecConfiguration conf) {
1511 return new ForwardConfiguration(conf.state.continuation, conf.environment); 1666 return new ForwardConfiguration(conf.state.continuation, conf.environment);
1512 } 1667 }
1513 1668
1514 Configuration visitIfStatement(IfStatement node, ExecConfiguration conf) { 1669 Configuration visitIfStatement(IfStatement node, ExecConfiguration conf) {
1515 var cont = new IfConditionEK( 1670 var cont = new IfConditionEK(
1516 node.then, node.otherwise, conf.environment, conf.state); 1671 node.then, node.otherwise, conf.environment, conf.state);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1592 VariableDeclaration node, ExecConfiguration conf) { 1747 VariableDeclaration node, ExecConfiguration conf) {
1593 if (node.initializer != null) { 1748 if (node.initializer != null) {
1594 var cont = new VariableInitializerEK( 1749 var cont = new VariableInitializerEK(
1595 node, conf.environment, conf.state.continuation); 1750 node, conf.environment, conf.state.continuation);
1596 return new EvalConfiguration(node.initializer, conf.environment, 1751 return new EvalConfiguration(node.initializer, conf.environment,
1597 conf.state.exceptionComponents, cont); 1752 conf.state.exceptionComponents, cont);
1598 } 1753 }
1599 return new ForwardConfiguration(conf.state.continuation, 1754 return new ForwardConfiguration(conf.state.continuation,
1600 conf.environment.extend(node, Value.nullInstance)); 1755 conf.environment.extend(node, Value.nullInstance));
1601 } 1756 }
1757
1758 Configuration visitFunctionDeclaration(
1759 FunctionDeclaration node, ExecConfiguration conf) {
1760 var newEnv = conf.environment.extend(node.variable, Value.nullInstance);
1761 var fun = new FunctionValue(node.function, newEnv);
1762 newEnv.updateStore(node.variable, fun);
1763 return new ForwardConfiguration(conf.state.continuation, newEnv);
1764 }
1602 } 1765 }
1603 1766
1604 // ------------------------------------------------------------------------ 1767 // ------------------------------------------------------------------------
1605 // VALUES 1768 // VALUES
1606 // ------------------------------------------------------------------------ 1769 // ------------------------------------------------------------------------
1607 1770
1608 typedef Value Getter(Value receiver); 1771 typedef Value Getter(Value receiver);
1609 typedef void Setter(Value receiver, Value value); 1772 typedef void Setter(Value receiver, Value value);
1610 1773
1611 class Class { 1774 class Class {
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1727 Object get value => this; 1890 Object get value => this;
1728 1891
1729 ObjectValue(this.class_) : fields = new List<Location>(class_.instanceSize) { 1892 ObjectValue(this.class_) : fields = new List<Location>(class_.instanceSize) {
1730 for (int i = 0; i < fields.length; i++) { 1893 for (int i = 0; i < fields.length; i++) {
1731 // Create fresh locations for each field. 1894 // Create fresh locations for each field.
1732 fields[i] = new Location.empty(); 1895 fields[i] = new Location.empty();
1733 } 1896 }
1734 } 1897 }
1735 } 1898 }
1736 1899
1900 class FunctionValue extends Value {
1901 Class get class_ => throw 'Class for FunctionValue is not defined';
1902 List<Location> get fields => throw 'FunctionValue has no fields.';
1903
1904 FunctionValue get value => this;
1905
1906 final FunctionNode function;
1907 final Environment environment;
1908
1909 FunctionValue(this.function, this.environment);
1910 }
1911
1737 abstract class LiteralValue extends Value { 1912 abstract class LiteralValue extends Value {
1738 Class get class_ => 1913 Class get class_ =>
1739 notImplemented(m: "Loading class for literal is not implemented."); 1914 notImplemented(m: "Loading class for literal is not implemented.");
1740 List<Location> get fields => 1915 List<Location> get fields =>
1741 notImplemented(m: "Literal value does not have fields"); 1916 notImplemented(m: "Literal value does not have fields");
1742 1917
1743 const LiteralValue(); 1918 const LiteralValue();
1744 } 1919 }
1745 1920
1746 class StringValue extends LiteralValue { 1921 class StringValue extends LiteralValue {
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1893 /// Initializes all non initialized fields from the provided class to 2068 /// Initializes all non initialized fields from the provided class to
1894 /// `Value.nullInstance` in the provided value. 2069 /// `Value.nullInstance` in the provided value.
1895 void _initializeNullFields(Class class_, Value value) { 2070 void _initializeNullFields(Class class_, Value value) {
1896 int startIndex = class_.superclass?.instanceSize ?? 0; 2071 int startIndex = class_.superclass?.instanceSize ?? 0;
1897 for (int i = startIndex; i < class_.instanceSize; i++) { 2072 for (int i = startIndex; i < class_.instanceSize; i++) {
1898 if (value.fields[i].value == null) { 2073 if (value.fields[i].value == null) {
1899 value.fields[i].value = Value.nullInstance; 2074 value.fields[i].value = Value.nullInstance;
1900 } 2075 }
1901 } 2076 }
1902 } 2077 }
OLDNEW
« no previous file with comments | « no previous file | pkg/kernel/testcases/interpreter/function_expressions_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698