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 13 matching lines...) Expand all Loading... | |
24 Interpreter(this.program); | 24 Interpreter(this.program); |
25 | 25 |
26 void run() { | 26 void run() { |
27 assert(program.libraries.isEmpty); | 27 assert(program.libraries.isEmpty); |
28 Procedure mainMethod = program.mainMethod; | 28 Procedure mainMethod = program.mainMethod; |
29 | 29 |
30 if (mainMethod == null) return; | 30 if (mainMethod == null) return; |
31 | 31 |
32 Statement statementBlock = mainMethod.function.body; | 32 Statement statementBlock = mainMethod.function.body; |
33 ExecConfiguration configuration = new ExecConfiguration( | 33 ExecConfiguration configuration = new ExecConfiguration( |
34 statementBlock, new Environment.empty(), const State.initial()); | 34 statementBlock, new Environment.empty(), new State.initial()); |
35 visitor.trampolinedExecution(configuration); | 35 visitor.trampolinedExecution(configuration); |
36 } | 36 } |
37 } | 37 } |
38 | 38 |
39 class Location { | 39 class Location { |
40 Value value; | 40 Value value; |
41 | 41 |
42 Location.empty(); | 42 Location.empty(); |
43 Location(this.value); | 43 Location(this.value); |
44 } | 44 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
113 return extend(new VariableDeclaration('this'), v); | 113 return extend(new VariableDeclaration('this'), v); |
114 } | 114 } |
115 } | 115 } |
116 | 116 |
117 /// Evaluate expressions. | 117 /// Evaluate expressions. |
118 class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> { | 118 class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> { |
119 Configuration eval(Expression expr, EvalConfiguration config) => | 119 Configuration eval(Expression expr, EvalConfiguration config) => |
120 expr.accept1(this, config); | 120 expr.accept1(this, config); |
121 | 121 |
122 Configuration evalList(List<InterpreterExpression> list, Environment env, | 122 Configuration evalList(List<InterpreterExpression> list, Environment env, |
123 ApplicationContinuation cont) { | 123 Handlers handlers, ApplicationContinuation cont) { |
124 if (list.isNotEmpty) { | 124 if (list.isNotEmpty) { |
125 return new EvalConfiguration(list.first.expression, env, | 125 return new EvalConfiguration(list.first.expression, env, handlers, |
126 new ExpressionListEK(list.first, list.skip(1), env, cont)); | 126 new ExpressionListEK(list.first, list.skip(1), env, handlers, cont)); |
127 } | 127 } |
128 return new ApplicationConfiguration(cont, <InterpreterValue>[]); | 128 return new ApplicationConfiguration(cont, <InterpreterValue>[]); |
129 } | 129 } |
130 | 130 |
131 Configuration defaultExpression(Expression node, EvalConfiguration config) { | 131 Configuration defaultExpression(Expression node, EvalConfiguration config) { |
132 throw new NotImplemented('Evaluation for expressions of type ' | 132 throw new NotImplemented('Evaluation for expressions of type ' |
133 '${node.runtimeType} is not implemented.'); | 133 '${node.runtimeType} is not implemented.'); |
134 } | 134 } |
135 | 135 |
136 Configuration visitInvalidExpression1( | 136 Configuration visitInvalidExpression1( |
137 InvalidExpression node, EvalConfiguration config) { | 137 InvalidExpression node, EvalConfiguration config) { |
138 throw 'Invalid expression at ${node.location.toString()}'; | 138 throw 'Invalid expression at ${node.location.toString()}'; |
139 } | 139 } |
140 | 140 |
141 Configuration visitVariableGet(VariableGet node, EvalConfiguration config) { | 141 Configuration visitVariableGet(VariableGet node, EvalConfiguration config) { |
142 Value value = config.environment.lookup(node.variable); | 142 Value value = config.environment.lookup(node.variable); |
143 return new ValuePassingConfiguration(config.continuation, value); | 143 return new ValuePassingConfiguration(config.continuation, value); |
144 } | 144 } |
145 | 145 |
146 Configuration visitVariableSet(VariableSet node, EvalConfiguration config) { | 146 Configuration visitVariableSet(VariableSet node, EvalConfiguration config) { |
147 var cont = new VariableSetEK( | 147 var cont = new VariableSetEK( |
148 node.variable, config.environment, config.continuation); | 148 node.variable, config.environment, config.continuation); |
149 return new EvalConfiguration(node.value, config.environment, cont); | 149 return new EvalConfiguration( |
150 node.value, config.environment, config.handlers, cont); | |
150 } | 151 } |
151 | 152 |
152 Configuration visitPropertyGet(PropertyGet node, EvalConfiguration config) { | 153 Configuration visitPropertyGet(PropertyGet node, EvalConfiguration config) { |
153 var cont = new PropertyGetEK(node.name, config.continuation); | 154 var cont = new PropertyGetEK(node.name, config.continuation); |
154 return new EvalConfiguration(node.receiver, config.environment, cont); | 155 return new EvalConfiguration( |
156 node.receiver, config.environment, config.handlers, cont); | |
155 } | 157 } |
156 | 158 |
157 Configuration visitPropertySet(PropertySet node, EvalConfiguration config) { | 159 Configuration visitPropertySet(PropertySet node, EvalConfiguration config) { |
158 var cont = new PropertySetEK( | 160 var cont = new PropertySetEK(node.value, node.name, config.environment, |
159 node.value, node.name, config.environment, config.continuation); | 161 config.handlers, config.continuation); |
160 return new EvalConfiguration(node.receiver, config.environment, cont); | 162 return new EvalConfiguration( |
163 node.receiver, config.environment, config.handlers, cont); | |
161 } | 164 } |
162 | 165 |
163 Configuration visitStaticGet(StaticGet node, EvalConfiguration config) => | 166 Configuration visitStaticGet(StaticGet node, EvalConfiguration config) => |
164 defaultExpression(node, config); | 167 defaultExpression(node, config); |
165 Configuration visitStaticSet(StaticSet node, EvalConfiguration config) => | 168 Configuration visitStaticSet(StaticSet node, EvalConfiguration config) => |
166 defaultExpression(node, config); | 169 defaultExpression(node, config); |
167 | 170 |
168 Configuration visitStaticInvocation( | 171 Configuration visitStaticInvocation( |
169 StaticInvocation node, EvalConfiguration config) { | 172 StaticInvocation node, EvalConfiguration config) { |
170 if ('print' == node.name.toString()) { | 173 if ('print' == node.name.toString()) { |
171 var cont = new PrintEK(config.continuation); | 174 var cont = new PrintEK(config.continuation); |
172 return new EvalConfiguration( | 175 return new EvalConfiguration(node.arguments.positional.first, |
173 node.arguments.positional.first, config.environment, cont); | 176 config.environment, config.handlers, cont); |
174 } else { | 177 } else { |
175 log.info('static-invocation-${node.target.name.toString()}\n'); | 178 log.info('static-invocation-${node.target.name.toString()}\n'); |
176 | 179 |
177 List<InterpreterExpression> args = | 180 List<InterpreterExpression> args = |
178 _getArgumentExpressions(node.arguments, node.target.function); | 181 _getArgumentExpressions(node.arguments, node.target.function); |
179 ApplicationContinuation cont = | 182 ApplicationContinuation cont = new StaticInvocationA( |
180 new StaticInvocationA(node.target.function, config.continuation); | 183 node.target.function, config.handlers, config.continuation); |
181 return new EvalListConfiguration(args, config.environment, cont); | 184 return new EvalListConfiguration( |
185 args, config.environment, config.handlers, cont); | |
182 } | 186 } |
183 } | 187 } |
184 | 188 |
185 Configuration visitMethodInvocation( | 189 Configuration visitMethodInvocation( |
186 MethodInvocation node, EvalConfiguration config) { | 190 MethodInvocation node, EvalConfiguration config) { |
187 // Currently supports only method invocation with <2 arguments and is used | 191 // Currently supports only method invocation with <2 arguments and is used |
188 // to evaluate implemented operators for int, double and String values. | 192 // to evaluate implemented operators for int, double and String values. |
189 var cont = new MethodInvocationEK( | 193 var cont = new MethodInvocationEK(node.arguments, node.name, |
190 node.arguments, node.name, config.environment, config.continuation); | 194 config.environment, config.handlers, config.continuation); |
191 | 195 |
192 return new EvalConfiguration(node.receiver, config.environment, cont); | 196 return new EvalConfiguration( |
197 node.receiver, config.environment, config.handlers, cont); | |
193 } | 198 } |
194 | 199 |
195 Configuration visitConstructorInvocation( | 200 Configuration visitConstructorInvocation( |
196 ConstructorInvocation node, EvalConfiguration config) { | 201 ConstructorInvocation node, EvalConfiguration config) { |
197 ApplicationContinuation cont = | 202 ApplicationContinuation cont = new ConstructorInvocationA( |
198 new ConstructorInvocationA(node.target, config.continuation); | 203 node.target, config.handlers, config.continuation); |
199 var args = _getArgumentExpressions(node.arguments, node.target.function); | 204 var args = _getArgumentExpressions(node.arguments, node.target.function); |
200 | 205 |
201 return new EvalListConfiguration(args, config.environment, cont); | 206 return new EvalListConfiguration( |
207 args, config.environment, config.handlers, cont); | |
202 } | 208 } |
203 | 209 |
204 Configuration visitNot(Not node, EvalConfiguration config) { | 210 Configuration visitNot(Not node, EvalConfiguration config) { |
205 return new EvalConfiguration( | 211 return new EvalConfiguration(node.operand, config.environment, |
206 node.operand, config.environment, new NotEK(config.continuation)); | 212 config.handlers, new NotEK(config.continuation)); |
207 } | 213 } |
208 | 214 |
209 Configuration visitLogicalExpression( | 215 Configuration visitLogicalExpression( |
210 LogicalExpression node, EvalConfiguration config) { | 216 LogicalExpression node, EvalConfiguration config) { |
211 if ('||' == node.operator) { | 217 if ('||' == node.operator) { |
212 var cont = new OrEK(node.right, config.environment, config.continuation); | 218 var cont = new OrEK( |
213 return new EvalConfiguration(node.left, config.environment, cont); | 219 node.right, config.environment, config.handlers, config.continuation); |
220 return new EvalConfiguration( | |
221 node.left, config.environment, config.handlers, cont); | |
214 } else { | 222 } else { |
215 assert('&&' == node.operator); | 223 assert('&&' == node.operator); |
216 var cont = new AndEK(node.right, config.environment, config.continuation); | 224 var cont = new AndEK( |
217 return new EvalConfiguration(node.left, config.environment, cont); | 225 node.right, config.environment, config.handlers, config.continuation); |
226 return new EvalConfiguration( | |
227 node.left, config.environment, config.handlers, cont); | |
218 } | 228 } |
219 } | 229 } |
220 | 230 |
221 Configuration visitConditionalExpression( | 231 Configuration visitConditionalExpression( |
222 ConditionalExpression node, EvalConfiguration config) { | 232 ConditionalExpression node, EvalConfiguration config) { |
223 var cont = new ConditionalEK( | 233 var cont = new ConditionalEK(node.then, node.otherwise, config.environment, |
224 node.then, node.otherwise, config.environment, config.continuation); | 234 config.handlers, config.continuation); |
225 return new EvalConfiguration(node.condition, config.environment, cont); | 235 return new EvalConfiguration( |
236 node.condition, config.environment, config.handlers, cont); | |
226 } | 237 } |
227 | 238 |
228 Configuration visitStringConcatenation( | 239 Configuration visitStringConcatenation( |
229 StringConcatenation node, EvalConfiguration config) { | 240 StringConcatenation node, EvalConfiguration config) { |
230 var cont = new StringConcatenationA(config.continuation); | 241 var cont = new StringConcatenationA(config.continuation); |
231 var expressions = node.expressions | 242 var expressions = node.expressions |
232 .map((Expression e) => new PositionalExpression(e)) | 243 .map((Expression e) => new PositionalExpression(e)) |
233 .toList(); | 244 .toList(); |
234 return new EvalListConfiguration(expressions, config.environment, cont); | 245 return new EvalListConfiguration( |
246 expressions, config.environment, config.handlers, cont); | |
235 } | 247 } |
236 | 248 |
237 Configuration visitThisExpression( | 249 Configuration visitThisExpression( |
238 ThisExpression node, EvalConfiguration config) { | 250 ThisExpression node, EvalConfiguration config) { |
239 return new ValuePassingConfiguration( | 251 return new ValuePassingConfiguration( |
240 config.continuation, config.environment.thisInstance); | 252 config.continuation, config.environment.thisInstance); |
241 } | 253 } |
242 | 254 |
243 // Evaluation of BasicLiterals. | 255 // Evaluation of BasicLiterals. |
244 Configuration visitStringLiteral( | 256 Configuration visitStringLiteral( |
(...skipping 17 matching lines...) Expand all Loading... | |
262 Value value = node.value ? Value.trueInstance : Value.falseInstance; | 274 Value value = node.value ? Value.trueInstance : Value.falseInstance; |
263 return new ValuePassingConfiguration(config.continuation, value); | 275 return new ValuePassingConfiguration(config.continuation, value); |
264 } | 276 } |
265 | 277 |
266 Configuration visitNullLiteral(NullLiteral node, EvalConfiguration config) { | 278 Configuration visitNullLiteral(NullLiteral node, EvalConfiguration config) { |
267 return new ValuePassingConfiguration( | 279 return new ValuePassingConfiguration( |
268 config.continuation, Value.nullInstance); | 280 config.continuation, Value.nullInstance); |
269 } | 281 } |
270 | 282 |
271 Configuration visitLet(Let node, EvalConfiguration config) { | 283 Configuration visitLet(Let node, EvalConfiguration config) { |
272 var letCont = new LetEK( | 284 var letCont = new LetEK(node.variable, node.body, config.environment, |
273 node.variable, node.body, config.environment, config.continuation); | 285 config.handlers, config.continuation); |
274 return new EvalConfiguration( | 286 return new EvalConfiguration(node.variable.initializer, config.environment, |
275 node.variable.initializer, config.environment, letCont); | 287 config.handlers, letCont); |
276 } | 288 } |
277 } | 289 } |
278 | 290 |
279 /// Represents a state for statement execution. | 291 /// Represents a state for statement execution. |
280 class State { | 292 class State { |
281 final Label labels; | 293 final Label labels; |
282 // TODO: Add switch labels. | 294 // TODO: Add switch labels. |
283 // TODO: Add component for exception support. | 295 final Handlers handlers; |
284 final ExpressionContinuation returnContinuation; | 296 final ExpressionContinuation returnContinuation; |
285 final StatementContinuation continuation; | 297 final StatementContinuation continuation; |
286 | 298 |
287 State(this.labels, this.returnContinuation, this.continuation); | 299 State(this.labels, this.handlers, this.returnContinuation, this.continuation); |
288 | 300 |
289 const State.initial() | 301 State.initial() |
290 : labels = null, | 302 : labels = null, |
303 handlers = new Handlers.initial(), | |
291 returnContinuation = null, | 304 returnContinuation = null, |
292 continuation = null; | 305 continuation = null; |
293 | 306 |
294 State withBreak(Statement stmt, Environment env) { | 307 State withBreak(Statement stmt, Environment env) { |
295 Label breakLabels = new Label(stmt, env, continuation, labels); | 308 Label breakLabels = new Label(stmt, env, continuation, labels); |
296 return new State(breakLabels, returnContinuation, continuation); | 309 return new State(breakLabels, handlers, returnContinuation, continuation); |
297 } | 310 } |
298 | 311 |
299 State withReturnContinuation(ExpressionContinuation returnCont) { | 312 State withReturnContinuation(ExpressionContinuation returnCont) { |
300 return new State(labels, returnCont, continuation); | 313 return new State(labels, handlers, returnCont, continuation); |
301 } | 314 } |
302 | 315 |
303 State withContinuation(StatementContinuation cont) { | 316 State withContinuation(StatementContinuation cont) { |
304 return new State(labels, returnContinuation, cont); | 317 return new State(labels, handlers, returnContinuation, cont); |
318 } | |
319 | |
320 State withException(Handlers state) { | |
321 return new State(labels, state, returnContinuation, continuation); | |
305 } | 322 } |
306 | 323 |
307 Label lookupLabel(LabeledStatement s) { | 324 Label lookupLabel(LabeledStatement s) { |
308 assert(labels != null); | 325 assert(labels != null); |
309 return labels.lookupLabel(s); | 326 return labels.lookupLabel(s); |
310 } | 327 } |
311 } | 328 } |
312 | 329 |
313 /// Represents a labeled statement, the corresponding continuation and the | 330 /// Represents a labeled statement, the corresponding continuation and the |
314 /// enclosing label. | 331 /// enclosing label. |
(...skipping 22 matching lines...) Expand all Loading... | |
337 Configuration step(StatementExecuter executer); | 354 Configuration step(StatementExecuter executer); |
338 } | 355 } |
339 | 356 |
340 /// Configuration for evaluating an [Expression]. | 357 /// Configuration for evaluating an [Expression]. |
341 class EvalConfiguration extends Configuration { | 358 class EvalConfiguration extends Configuration { |
342 final Expression expression; | 359 final Expression expression; |
343 | 360 |
344 /// Environment in which the expression is evaluated. | 361 /// Environment in which the expression is evaluated. |
345 final Environment environment; | 362 final Environment environment; |
346 | 363 |
364 /// Exception handlers. | |
365 final Handlers handlers; | |
366 | |
347 /// Next continuation to be applied. | 367 /// Next continuation to be applied. |
348 final Continuation continuation; | 368 final Continuation continuation; |
349 | 369 |
350 EvalConfiguration(this.expression, this.environment, this.continuation); | 370 EvalConfiguration( |
371 this.expression, this.environment, this.handlers, this.continuation); | |
351 | 372 |
352 Configuration step(StatementExecuter executer) => | 373 Configuration step(StatementExecuter executer) => |
353 executer.eval(expression, this); | 374 executer.eval(expression, this); |
354 } | 375 } |
355 | 376 |
356 /// Configuration for evaluating a `List<InterpreterExpression>`. | 377 /// Configuration for evaluating a `List<InterpreterExpression>`. |
357 class EvalListConfiguration extends Configuration { | 378 class EvalListConfiguration extends Configuration { |
358 final List<InterpreterExpression> expressions; | 379 final List<InterpreterExpression> expressions; |
359 final Environment environment; | 380 final Environment environment; |
381 final Handlers handlers; | |
360 final ApplicationContinuation continuation; | 382 final ApplicationContinuation continuation; |
361 | 383 |
362 EvalListConfiguration(this.expressions, this.environment, this.continuation); | 384 EvalListConfiguration( |
385 this.expressions, this.environment, this.handlers, this.continuation); | |
363 | 386 |
364 Configuration step(StatementExecuter executer) => | 387 Configuration step(StatementExecuter executer) => |
365 executer.evalList(expressions, environment, continuation); | 388 executer.evalList(expressions, environment, handlers, continuation); |
366 } | 389 } |
367 | 390 |
368 /// Configuration for execution of a [Statement]. | 391 /// Configuration for execution of a [Statement]. |
369 class ExecConfiguration extends Configuration { | 392 class ExecConfiguration extends Configuration { |
370 final Statement currentStatement; | 393 final Statement currentStatement; |
371 final Environment environment; | 394 final Environment environment; |
372 final State state; | 395 final State state; |
373 | 396 |
374 ExecConfiguration(this.currentStatement, this.environment, this.state); | 397 ExecConfiguration(this.currentStatement, this.environment, this.state); |
375 | 398 |
(...skipping 25 matching lines...) Expand all Loading... | |
401 /// `List<InterpreterValue>`. | 424 /// `List<InterpreterValue>`. |
402 class ApplicationConfiguration extends Configuration { | 425 class ApplicationConfiguration extends Configuration { |
403 final ApplicationContinuation continuation; | 426 final ApplicationContinuation continuation; |
404 final List<InterpreterValue> values; | 427 final List<InterpreterValue> values; |
405 | 428 |
406 ApplicationConfiguration(this.continuation, this.values); | 429 ApplicationConfiguration(this.continuation, this.values); |
407 | 430 |
408 Configuration step(StatementExecuter _) => continuation(values); | 431 Configuration step(StatementExecuter _) => continuation(values); |
409 } | 432 } |
410 | 433 |
434 class ThrowConfiguration extends Configuration { | |
435 final ExceptionHandler handler; | |
436 final Value exception; | |
437 final StackTrace stacktrace; | |
438 | |
439 ThrowConfiguration(this.handler, this.exception, this.stacktrace); | |
440 | |
441 Configuration step(StatementExecuter _) => handler(exception, stacktrace); | |
442 } | |
443 | |
411 // ------------------------------------------------------------------------ | 444 // ------------------------------------------------------------------------ |
412 // Interpreter Expressions and Values | 445 // Interpreter Expressions and Values |
413 // ------------------------------------------------------------------------ | 446 // ------------------------------------------------------------------------ |
414 | 447 |
415 abstract class InterpreterExpression { | 448 abstract class InterpreterExpression { |
416 Expression get expression; | 449 Expression get expression; |
417 | 450 |
418 InterpreterValue assignValue(Value v); | 451 InterpreterValue assignValue(Value v); |
419 } | 452 } |
420 | 453 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
522 final Expression condition; | 555 final Expression condition; |
523 final Statement body; | 556 final Statement body; |
524 final Environment enclosingEnv; | 557 final Environment enclosingEnv; |
525 final State state; | 558 final State state; |
526 | 559 |
527 WhileConditionSK(this.condition, this.body, this.enclosingEnv, this.state); | 560 WhileConditionSK(this.condition, this.body, this.enclosingEnv, this.state); |
528 | 561 |
529 Configuration call(Environment _) { | 562 Configuration call(Environment _) { |
530 // Evaluate the condition for the while loop execution. | 563 // Evaluate the condition for the while loop execution. |
531 var cont = new WhileConditionEK(condition, body, enclosingEnv, state); | 564 var cont = new WhileConditionEK(condition, body, enclosingEnv, state); |
532 return new EvalConfiguration(condition, enclosingEnv, cont); | 565 return new EvalConfiguration(condition, enclosingEnv, state.handlers, cont); |
533 } | 566 } |
534 } | 567 } |
535 | 568 |
536 /// Applies the expression continuation to the provided value. | 569 /// Applies the expression continuation to the provided value. |
537 class NewSK extends StatementContinuation { | 570 class NewSK extends StatementContinuation { |
538 final ExpressionContinuation continuation; | 571 final ExpressionContinuation continuation; |
539 final Location location; | 572 final Location location; |
540 | 573 |
541 NewSK(this.continuation, this.location); | 574 NewSK(this.continuation, this.location); |
542 | 575 |
543 Configuration call(Environment _) => | 576 Configuration call(Environment _) => |
544 new ValuePassingConfiguration(continuation, location.value); | 577 new ValuePassingConfiguration(continuation, location.value); |
545 } | 578 } |
546 | 579 |
547 class ConstructorBodySK extends StatementContinuation { | 580 class ConstructorBodySK extends StatementContinuation { |
548 final Statement body; | 581 final Statement body; |
549 final Environment environment; | 582 final Environment environment; |
550 // TODO(zhivkag): Add component for exception handler. | 583 final Handlers handlers; |
551 final StatementContinuation continuation; | 584 final StatementContinuation continuation; |
552 | 585 |
553 ConstructorBodySK(this.body, this.environment, this.continuation); | 586 ConstructorBodySK( |
587 this.body, this.environment, this.handlers, this.continuation); | |
554 | 588 |
555 Configuration call(Environment _) { | 589 Configuration call(Environment _) { |
556 return new ExecConfiguration( | 590 return new ExecConfiguration( |
557 body, environment, new State(null, null, continuation)); | 591 body, environment, new State(null, handlers, null, continuation)); |
558 } | 592 } |
559 } | 593 } |
560 | 594 |
561 // ------------------------------------------------------------------------ | 595 // ------------------------------------------------------------------------ |
562 // Application Continuations | 596 // Application Continuations |
563 // ------------------------------------------------------------------------ | 597 // ------------------------------------------------------------------------ |
564 | 598 |
565 /// Represents the continuation called after the evaluation of argument | 599 /// Represents the continuation called after the evaluation of argument |
566 /// expressions. | 600 /// expressions. |
567 /// | 601 /// |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
627 result.write(v.value.value); | 661 result.write(v.value.value); |
628 } | 662 } |
629 return new ValuePassingConfiguration( | 663 return new ValuePassingConfiguration( |
630 continuation, new StringValue(result.toString())); | 664 continuation, new StringValue(result.toString())); |
631 } | 665 } |
632 } | 666 } |
633 | 667 |
634 /// Represents the application continuation for static invocation. | 668 /// Represents the application continuation for static invocation. |
635 class StaticInvocationA extends ApplicationContinuation { | 669 class StaticInvocationA extends ApplicationContinuation { |
636 final FunctionNode function; | 670 final FunctionNode function; |
671 final Handlers handlers; | |
637 final ExpressionContinuation continuation; | 672 final ExpressionContinuation continuation; |
638 | 673 |
639 StaticInvocationA(this.function, this.continuation); | 674 StaticInvocationA(this.function, this.handlers, this.continuation); |
640 | 675 |
641 Configuration call(List<InterpreterValue> argValues) { | 676 Configuration call(List<InterpreterValue> argValues) { |
642 Environment functionEnv = | 677 Environment functionEnv = |
643 ApplicationContinuation.createEnvironment(function, argValues); | 678 ApplicationContinuation.createEnvironment(function, argValues); |
644 State bodyState = new State( | 679 State bodyState = new State(null, handlers, continuation, |
645 null, continuation, new ExitSK(continuation, Value.nullInstance)); | 680 new ExitSK(continuation, Value.nullInstance)); |
646 | 681 |
647 return new ExecConfiguration(function.body, functionEnv, bodyState); | 682 return new ExecConfiguration(function.body, functionEnv, bodyState); |
648 } | 683 } |
649 } | 684 } |
650 | 685 |
651 /// Represents the application continuation for constructor invocation applied | 686 /// Represents the application continuation for constructor invocation applied |
652 /// on the list of evaluated arguments when a constructor is invoked with new. | 687 /// on the list of evaluated arguments when a constructor is invoked with new. |
653 /// | 688 /// |
654 /// It creates the newly allocated object instance. | 689 /// It creates the newly allocated object instance. |
655 class ConstructorInvocationA extends ApplicationContinuation { | 690 class ConstructorInvocationA extends ApplicationContinuation { |
656 final Constructor constructor; | 691 final Constructor constructor; |
692 final Handlers handlers; | |
657 final ExpressionContinuation continuation; | 693 final ExpressionContinuation continuation; |
658 | 694 |
659 ConstructorInvocationA(this.constructor, this.continuation); | 695 ConstructorInvocationA(this.constructor, this.handlers, this.continuation); |
660 | 696 |
661 Configuration call(List<InterpreterValue> argValues) { | 697 Configuration call(List<InterpreterValue> argValues) { |
662 Environment ctrEnv = ApplicationContinuation.createEnvironment( | 698 Environment ctrEnv = ApplicationContinuation.createEnvironment( |
663 constructor.function, argValues); | 699 constructor.function, argValues); |
664 var class_ = new Class(constructor.enclosingClass.reference); | 700 var class_ = new Class(constructor.enclosingClass.reference); |
665 var newObject = new ObjectValue(class_); | 701 var newObject = new ObjectValue(class_); |
666 var cont = new InitializationEK( | 702 var cont = new InitializationEK(constructor, ctrEnv, handlers, |
667 constructor, ctrEnv, new NewSK(continuation, new Location(newObject))); | 703 new NewSK(continuation, new Location(newObject))); |
668 | 704 |
669 return new ValuePassingConfiguration(cont, newObject); | 705 return new ValuePassingConfiguration(cont, newObject); |
670 } | 706 } |
671 } | 707 } |
672 | 708 |
673 /// Represents the application continuation for constructor invocation applied | 709 /// Represents the application continuation for constructor invocation applied |
674 /// on the list of evaluated arguments when a constructor is invoked in a | 710 /// on the list of evaluated arguments when a constructor is invoked in a |
675 /// constructor initializer list with a [RedirectingInitializer] or | 711 /// constructor initializer list with a [RedirectingInitializer] or |
676 /// [SuperInitializer]. | 712 /// [SuperInitializer]. |
677 class ConstructorInitializerA extends ApplicationContinuation { | 713 class ConstructorInitializerA extends ApplicationContinuation { |
678 final Constructor constructor; | 714 final Constructor constructor; |
679 final Location location; | 715 final Location location; |
716 final Handlers handlers; | |
680 final ConstructorBodySK continuation; | 717 final ConstructorBodySK continuation; |
681 | 718 |
682 ConstructorInitializerA(this.constructor, this.location, this.continuation); | 719 ConstructorInitializerA( |
720 this.constructor, this.location, this.handlers, this.continuation); | |
683 | 721 |
684 Configuration call(List<InterpreterValue> vs) { | 722 Configuration call(List<InterpreterValue> vs) { |
685 Environment ctrEnv = | 723 Environment ctrEnv = |
686 ApplicationContinuation.createEnvironment(constructor.function, vs); | 724 ApplicationContinuation.createEnvironment(constructor.function, vs); |
687 var cont = new InitializationEK(constructor, ctrEnv, continuation); | 725 var cont = |
726 new InitializationEK(constructor, ctrEnv, handlers, continuation); | |
688 | 727 |
689 return new ValuePassingConfiguration(cont, location.value); | 728 return new ValuePassingConfiguration(cont, location.value); |
690 } | 729 } |
691 } | 730 } |
692 | 731 |
693 /// Represents the application continuation applied on the list of evaluated | 732 /// Represents the application continuation applied on the list of evaluated |
694 /// field initializer expressions. | 733 /// field initializer expressions. |
695 class InstanceFieldsA extends ApplicationContinuation { | 734 class InstanceFieldsA extends ApplicationContinuation { |
696 final Constructor constructor; | 735 final Constructor constructor; |
697 final Location location; | 736 final Location location; |
698 final Environment environment; | 737 final Environment environment; |
738 final Handlers handlers; | |
699 final ConstructorBodySK continuation; | 739 final ConstructorBodySK continuation; |
700 | 740 |
701 final Class _currentClass; | 741 final Class _currentClass; |
702 | 742 |
703 InstanceFieldsA( | 743 InstanceFieldsA(this.constructor, this.location, this.environment, |
704 this.constructor, this.location, this.environment, this.continuation) | 744 this.handlers, this.continuation) |
705 : _currentClass = new Class(constructor.enclosingClass.reference); | 745 : _currentClass = new Class(constructor.enclosingClass.reference); |
706 | 746 |
707 Configuration call(List<InterpreterValue> fieldValues) { | 747 Configuration call(List<InterpreterValue> fieldValues) { |
708 for (FieldInitializerValue f in fieldValues) { | 748 for (FieldInitializerValue f in fieldValues) { |
709 // Directly set the field with the corresponding implicit setter. | 749 // Directly set the field with the corresponding implicit setter. |
710 _currentClass.implicitSetters[f.field.name](location.value, f.value); | 750 _currentClass.implicitSetters[f.field.name](location.value, f.value); |
711 } | 751 } |
712 | 752 |
713 if (constructor.initializers.length == 0) { | 753 if (constructor.initializers.length == 0) { |
714 // This can happen when initializing fields of Ctr with empty initializer | 754 // This can happen when initializing fields of Ctr with empty initializer |
(...skipping 14 matching lines...) Expand all Loading... | |
729 } | 769 } |
730 | 770 |
731 // Otherwise, the next expression from Field or Local initializers will be | 771 // Otherwise, the next expression from Field or Local initializers will be |
732 // evaluated. | 772 // evaluated. |
733 return _createEvalConfig(constructor.initializers.first); | 773 return _createEvalConfig(constructor.initializers.first); |
734 } | 774 } |
735 | 775 |
736 Configuration _createEvalListConfig(SuperInitializer initializer) { | 776 Configuration _createEvalListConfig(SuperInitializer initializer) { |
737 List<InterpreterExpression> args = _getArgumentExpressions( | 777 List<InterpreterExpression> args = _getArgumentExpressions( |
738 initializer.arguments, initializer.target.function); | 778 initializer.arguments, initializer.target.function); |
739 var cont = | 779 var cont = new ConstructorInitializerA( |
740 new ConstructorInitializerA(initializer.target, location, continuation); | 780 initializer.target, location, handlers, continuation); |
741 | 781 |
742 return new EvalListConfiguration(args, environment, cont); | 782 return new EvalListConfiguration(args, environment, handlers, cont); |
743 } | 783 } |
744 | 784 |
745 EvalConfiguration _createEvalConfig(Initializer initializer) { | 785 EvalConfiguration _createEvalConfig(Initializer initializer) { |
746 Expression expr = (initializer is FieldInitializer) | 786 Expression expr = (initializer is FieldInitializer) |
747 ? initializer.value | 787 ? initializer.value |
748 : (initializer as LocalInitializer).variable.initializer; | 788 : (initializer as LocalInitializer).variable.initializer; |
749 | 789 |
750 // We start with index = 0 since we are evaluating the expression for the | 790 // We start with index = 0 since we are evaluating the expression for the |
751 // first initializer in the initializer list. | 791 // first initializer in the initializer list. |
752 var cont = new InitializerListEK( | 792 var cont = new InitializerListEK( |
753 constructor, 0, location, environment, continuation); | 793 constructor, 0, location, environment, handlers, continuation); |
754 return new EvalConfiguration(expr, environment, cont); | 794 return new EvalConfiguration(expr, environment, handlers, cont); |
755 } | 795 } |
756 } | 796 } |
757 // ------------------------------------------------------------------------ | 797 // ------------------------------------------------------------------------ |
758 // Expression Continuations | 798 // Expression Continuations |
759 // ------------------------------------------------------------------------ | 799 // ------------------------------------------------------------------------ |
760 | 800 |
761 /// Represents an expression continuation. | 801 /// Represents an expression continuation. |
762 /// | 802 /// |
763 /// There are various kinds of [ExpressionContinuation]s and their names are | 803 /// There are various kinds of [ExpressionContinuation]s and their names are |
764 /// suffixed with "EK". | 804 /// suffixed with "EK". |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
800 Configuration call(Value receiver) { | 840 Configuration call(Value receiver) { |
801 Value propertyValue = receiver.class_.lookupImplicitGetter(name)(receiver); | 841 Value propertyValue = receiver.class_.lookupImplicitGetter(name)(receiver); |
802 return new ValuePassingConfiguration(continuation, propertyValue); | 842 return new ValuePassingConfiguration(continuation, propertyValue); |
803 } | 843 } |
804 } | 844 } |
805 | 845 |
806 class PropertySetEK extends ExpressionContinuation { | 846 class PropertySetEK extends ExpressionContinuation { |
807 final Expression value; | 847 final Expression value; |
808 final Name setterName; | 848 final Name setterName; |
809 final Environment environment; | 849 final Environment environment; |
850 final Handlers handlers; | |
810 final ExpressionContinuation continuation; | 851 final ExpressionContinuation continuation; |
811 | 852 |
812 PropertySetEK( | 853 PropertySetEK(this.value, this.setterName, this.environment, this.handlers, |
813 this.value, this.setterName, this.environment, this.continuation); | 854 this.continuation); |
814 | 855 |
815 Configuration call(Value receiver) { | 856 Configuration call(Value receiver) { |
816 var cont = new SetterEK(receiver, setterName, continuation); | 857 var cont = new SetterEK(receiver, setterName, continuation); |
817 return new EvalConfiguration(value, environment, cont); | 858 return new EvalConfiguration(value, environment, handlers, cont); |
818 } | 859 } |
819 } | 860 } |
820 | 861 |
821 class SetterEK extends ExpressionContinuation { | 862 class SetterEK extends ExpressionContinuation { |
822 final Value receiver; | 863 final Value receiver; |
823 final Name name; | 864 final Name name; |
824 final ExpressionContinuation continuation; | 865 final ExpressionContinuation continuation; |
825 | 866 |
826 SetterEK(this.receiver, this.name, this.continuation); | 867 SetterEK(this.receiver, this.name, this.continuation); |
827 | 868 |
828 Configuration call(Value v) { | 869 Configuration call(Value v) { |
829 Setter setter = receiver.class_.lookupImplicitSetter(name); | 870 Setter setter = receiver.class_.lookupImplicitSetter(name); |
830 setter(receiver, v); | 871 setter(receiver, v); |
831 return new ValuePassingConfiguration(continuation, v); | 872 return new ValuePassingConfiguration(continuation, v); |
832 } | 873 } |
833 } | 874 } |
834 | 875 |
835 /// Represents a continuation to be called after the evaluation of an actual | 876 /// Represents a continuation to be called after the evaluation of an actual |
836 /// argument for function invocation. | 877 /// argument for function invocation. |
837 class ExpressionListEK extends ExpressionContinuation { | 878 class ExpressionListEK extends ExpressionContinuation { |
838 final InterpreterExpression currentExpression; | 879 final InterpreterExpression currentExpression; |
839 final List<InterpreterExpression> expressions; | 880 final List<InterpreterExpression> expressions; |
840 final Environment environment; | 881 final Environment environment; |
882 final Handlers handlers; | |
841 final ApplicationContinuation applicationContinuation; | 883 final ApplicationContinuation applicationContinuation; |
842 | 884 |
843 ExpressionListEK(this.currentExpression, this.expressions, this.environment, | 885 ExpressionListEK(this.currentExpression, this.expressions, this.environment, |
844 this.applicationContinuation); | 886 this.handlers, this.applicationContinuation); |
845 | 887 |
846 Configuration call(Value v) { | 888 Configuration call(Value v) { |
847 ValueA app = | 889 ValueA app = |
848 new ValueA(currentExpression.assignValue(v), applicationContinuation); | 890 new ValueA(currentExpression.assignValue(v), applicationContinuation); |
849 return new EvalListConfiguration(expressions, environment, app); | 891 return new EvalListConfiguration(expressions, environment, handlers, app); |
850 } | 892 } |
851 } | 893 } |
852 | 894 |
853 class MethodInvocationEK extends ExpressionContinuation { | 895 class MethodInvocationEK extends ExpressionContinuation { |
854 final Arguments arguments; | 896 final Arguments arguments; |
855 final Name methodName; | 897 final Name methodName; |
856 final Environment environment; | 898 final Environment environment; |
899 final Handlers handlers; | |
857 final ExpressionContinuation continuation; | 900 final ExpressionContinuation continuation; |
858 | 901 |
859 MethodInvocationEK( | 902 MethodInvocationEK(this.arguments, this.methodName, this.environment, |
860 this.arguments, this.methodName, this.environment, this.continuation); | 903 this.handlers, this.continuation); |
861 | 904 |
862 Configuration call(Value receiver) { | 905 Configuration call(Value receiver) { |
863 if (arguments.positional.isEmpty) { | 906 if (arguments.positional.isEmpty) { |
864 Value returnValue = receiver.invokeMethod(methodName); | 907 Value returnValue = receiver.invokeMethod(methodName); |
865 return new ValuePassingConfiguration(continuation, returnValue); | 908 return new ValuePassingConfiguration(continuation, returnValue); |
866 } | 909 } |
867 var cont = new ArgumentsEK( | 910 var cont = new ArgumentsEK( |
868 receiver, methodName, arguments, environment, continuation); | 911 receiver, methodName, arguments, environment, continuation); |
869 | 912 |
870 return new EvalConfiguration(arguments.positional.first, environment, cont); | 913 return new EvalConfiguration( |
914 arguments.positional.first, environment, handlers, cont); | |
871 } | 915 } |
872 } | 916 } |
873 | 917 |
874 class ArgumentsEK extends ExpressionContinuation { | 918 class ArgumentsEK extends ExpressionContinuation { |
875 final Value receiver; | 919 final Value receiver; |
876 final Name methodName; | 920 final Name methodName; |
877 final Arguments arguments; | 921 final Arguments arguments; |
878 final Environment environment; | 922 final Environment environment; |
879 final ExpressionContinuation continuation; | 923 final ExpressionContinuation continuation; |
880 | 924 |
(...skipping 30 matching lines...) Expand all Loading... | |
911 Value notValue = identical(Value.trueInstance, value) | 955 Value notValue = identical(Value.trueInstance, value) |
912 ? Value.falseInstance | 956 ? Value.falseInstance |
913 : Value.trueInstance; | 957 : Value.trueInstance; |
914 return new ValuePassingConfiguration(continuation, notValue); | 958 return new ValuePassingConfiguration(continuation, notValue); |
915 } | 959 } |
916 } | 960 } |
917 | 961 |
918 class OrEK extends ExpressionContinuation { | 962 class OrEK extends ExpressionContinuation { |
919 final Expression right; | 963 final Expression right; |
920 final Environment environment; | 964 final Environment environment; |
965 final Handlers handlers; | |
921 final ExpressionContinuation continuation; | 966 final ExpressionContinuation continuation; |
922 | 967 |
923 OrEK(this.right, this.environment, this.continuation); | 968 OrEK(this.right, this.environment, this.handlers, this.continuation); |
924 | 969 |
925 Configuration call(Value left) { | 970 Configuration call(Value left) { |
926 return identical(Value.trueInstance, left) | 971 return identical(Value.trueInstance, left) |
927 ? new ValuePassingConfiguration(continuation, Value.trueInstance) | 972 ? new ValuePassingConfiguration(continuation, Value.trueInstance) |
928 : new EvalConfiguration(right, environment, continuation); | 973 : new EvalConfiguration(right, environment, handlers, continuation); |
929 } | 974 } |
930 } | 975 } |
931 | 976 |
932 class AndEK extends ExpressionContinuation { | 977 class AndEK extends ExpressionContinuation { |
933 final Expression right; | 978 final Expression right; |
934 final Environment environment; | 979 final Environment environment; |
980 final Handlers handlers; | |
935 final ExpressionContinuation continuation; | 981 final ExpressionContinuation continuation; |
936 | 982 |
937 AndEK(this.right, this.environment, this.continuation); | 983 AndEK(this.right, this.environment, this.handlers, this.continuation); |
938 | 984 |
939 Configuration call(Value left) { | 985 Configuration call(Value left) { |
940 return identical(Value.falseInstance, left) | 986 return identical(Value.falseInstance, left) |
941 ? new ValuePassingConfiguration(continuation, Value.falseInstance) | 987 ? new ValuePassingConfiguration(continuation, Value.falseInstance) |
942 : new EvalConfiguration(right, environment, continuation); | 988 : new EvalConfiguration(right, environment, handlers, continuation); |
943 } | 989 } |
944 } | 990 } |
945 | 991 |
946 class ConditionalEK extends ExpressionContinuation { | 992 class ConditionalEK extends ExpressionContinuation { |
947 final Expression then; | 993 final Expression then; |
948 final Expression otherwise; | 994 final Expression otherwise; |
949 final Environment environment; | 995 final Environment environment; |
996 final Handlers handlers; | |
950 final ExpressionContinuation continuation; | 997 final ExpressionContinuation continuation; |
951 | 998 |
952 ConditionalEK(this.then, this.otherwise, this.environment, this.continuation); | 999 ConditionalEK(this.then, this.otherwise, this.environment, this.handlers, |
1000 this.continuation); | |
953 | 1001 |
954 Configuration call(Value value) { | 1002 Configuration call(Value value) { |
955 return identical(Value.trueInstance, value) | 1003 return identical(Value.trueInstance, value) |
956 ? new EvalConfiguration(then, environment, continuation) | 1004 ? new EvalConfiguration(then, environment, handlers, continuation) |
957 : new EvalConfiguration(otherwise, environment, continuation); | 1005 : new EvalConfiguration(otherwise, environment, handlers, continuation); |
958 } | 1006 } |
959 } | 1007 } |
960 | 1008 |
961 class LetEK extends ExpressionContinuation { | 1009 class LetEK extends ExpressionContinuation { |
962 final VariableDeclaration variable; | 1010 final VariableDeclaration variable; |
963 final Expression letBody; | 1011 final Expression letBody; |
964 final Environment environment; | 1012 final Environment environment; |
1013 final Handlers handlers; | |
965 final ExpressionContinuation continuation; | 1014 final ExpressionContinuation continuation; |
966 | 1015 |
967 LetEK(this.variable, this.letBody, this.environment, this.continuation); | 1016 LetEK(this.variable, this.letBody, this.environment, this.handlers, |
1017 this.continuation); | |
968 | 1018 |
969 Configuration call(Value value) { | 1019 Configuration call(Value value) { |
970 var letEnv = new Environment(environment); | 1020 var letEnv = new Environment(environment); |
971 letEnv.extend(variable, value); | 1021 letEnv.extend(variable, value); |
972 return new EvalConfiguration(letBody, letEnv, continuation); | 1022 return new EvalConfiguration(letBody, letEnv, handlers, continuation); |
973 } | 1023 } |
974 } | 1024 } |
975 | 1025 |
976 /// Represents the continuation for the condition expression in [WhileStatement] . | 1026 /// Represents the continuation for the condition expression in [WhileStatement] . |
977 class WhileConditionEK extends ExpressionContinuation { | 1027 class WhileConditionEK extends ExpressionContinuation { |
978 final Expression condition; | 1028 final Expression condition; |
979 final Statement body; | 1029 final Statement body; |
980 final Environment enclosingEnv; | 1030 final Environment enclosingEnv; |
981 final State state; | 1031 final State state; |
982 | 1032 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1025 return new ForwardConfiguration( | 1075 return new ForwardConfiguration( |
1026 continuation, environment.extend(variable, v)); | 1076 continuation, environment.extend(variable, v)); |
1027 } | 1077 } |
1028 } | 1078 } |
1029 | 1079 |
1030 /// Expression continuation that further initializes the newly allocated object | 1080 /// Expression continuation that further initializes the newly allocated object |
1031 /// instance with running the constructor. | 1081 /// instance with running the constructor. |
1032 class InitializationEK extends ExpressionContinuation { | 1082 class InitializationEK extends ExpressionContinuation { |
1033 final Constructor constructor; | 1083 final Constructor constructor; |
1034 final Environment environment; | 1084 final Environment environment; |
1035 // TODO(zhivkag): Add components for exception handling support | 1085 final Handlers handlers; |
1036 final StatementContinuation continuation; | 1086 final StatementContinuation continuation; |
1037 | 1087 |
1038 InitializationEK(this.constructor, this.environment, this.continuation); | 1088 InitializationEK( |
1089 this.constructor, this.environment, this.handlers, this.continuation); | |
1039 | 1090 |
1040 Configuration call(Value value) { | 1091 Configuration call(Value value) { |
1041 Location location = new Location(value); | 1092 Location location = new Location(value); |
1042 | 1093 |
1043 if (constructor.initializers.isNotEmpty && | 1094 if (constructor.initializers.isNotEmpty && |
1044 constructor.initializers.last is RedirectingInitializer) { | 1095 constructor.initializers.last is RedirectingInitializer) { |
1045 return _createRedirectingInitializerConfig( | 1096 return _createRedirectingInitializerConfig( |
1046 constructor.initializers.first, location); | 1097 constructor.initializers.first, location); |
1047 } | 1098 } |
1048 // The statement body is captured by the next statement continuation and | 1099 // The statement body is captured by the next statement continuation and |
1049 // expressions for field initialization are evaluated. | 1100 // expressions for field initialization are evaluated. |
1050 var ctrEnv = environment.extendWithThis(value); | 1101 var ctrEnv = environment.extendWithThis(value); |
1051 var bodyCont = | 1102 var bodyCont = new ConstructorBodySK( |
1052 new ConstructorBodySK(constructor.function.body, ctrEnv, continuation); | 1103 constructor.function.body, ctrEnv, handlers, continuation); |
1053 var initializers = _getFieldInitializers(constructor.enclosingClass); | 1104 var initializers = _getFieldInitializers(constructor.enclosingClass); |
1054 var fieldsCont = | 1105 var fieldsCont = |
1055 new InstanceFieldsA(constructor, location, ctrEnv, bodyCont); | 1106 new InstanceFieldsA(constructor, location, ctrEnv, handlers, bodyCont); |
1056 return new EvalListConfiguration( | 1107 return new EvalListConfiguration( |
1057 initializers, new Environment.empty(), fieldsCont); | 1108 initializers, new Environment.empty(), handlers, fieldsCont); |
1058 } | 1109 } |
1059 | 1110 |
1060 /// Creates the next configuration to further initializer the value for | 1111 /// Creates the next configuration to further initializer the value for |
1061 /// redirecting constructors. | 1112 /// redirecting constructors. |
1062 Configuration _createRedirectingInitializerConfig( | 1113 Configuration _createRedirectingInitializerConfig( |
1063 Initializer initializer, Location location) { | 1114 Initializer initializer, Location location) { |
1064 Initializer current = constructor.initializers.first; | 1115 Initializer current = constructor.initializers.first; |
1065 if (current is RedirectingInitializer) { | 1116 if (current is RedirectingInitializer) { |
1066 // eval list of args with current env | 1117 // eval list of args with current env |
1067 List<InterpreterExpression> exprs = | 1118 List<InterpreterExpression> exprs = |
1068 _getArgumentExpressions(current.arguments, current.target.function); | 1119 _getArgumentExpressions(current.arguments, current.target.function); |
1069 var cont = | 1120 var cont = new ConstructorInitializerA( |
1070 new ConstructorInitializerA(current.target, location, continuation); | 1121 current.target, location, handlers, continuation); |
1071 return new EvalListConfiguration(exprs, environment, cont); | 1122 return new EvalListConfiguration(exprs, environment, handlers, cont); |
1072 } | 1123 } |
1073 Expression expr = (current is FieldInitializer) | 1124 Expression expr = (current is FieldInitializer) |
1074 ? current.value | 1125 ? current.value |
1075 : (current as LocalInitializer).variable.initializer; | 1126 : (current as LocalInitializer).variable.initializer; |
1076 | 1127 |
1077 var cont = new InitializerListEK(constructor, 0 /* initializerIndex*/, | 1128 var cont = new InitializerListEK(constructor, 0 /* initializerIndex*/, |
1078 location, environment, continuation); | 1129 location, environment, handlers, continuation); |
1079 return new EvalConfiguration(expr, environment, cont); | 1130 return new EvalConfiguration(expr, environment, handlers, cont); |
1080 } | 1131 } |
1081 } | 1132 } |
1082 | 1133 |
1083 class InitializerListEK extends ExpressionContinuation { | 1134 class InitializerListEK extends ExpressionContinuation { |
1084 final Constructor constructor; | 1135 final Constructor constructor; |
1085 final int initializerIndex; | 1136 final int initializerIndex; |
1086 final Location location; | 1137 final Location location; |
1087 final Environment environment; | 1138 final Environment environment; |
1088 // TODO(zhivkag): Add componnents for exception handling. | 1139 final Handlers handlers; |
1089 final ConstructorBodySK continuation; | 1140 final ConstructorBodySK continuation; |
1141 | |
1090 final Class _currentClass; | 1142 final Class _currentClass; |
1091 | 1143 |
1092 InitializerListEK(this.constructor, this.initializerIndex, this.location, | 1144 InitializerListEK(this.constructor, this.initializerIndex, this.location, |
1093 this.environment, this.continuation) | 1145 this.environment, this.handlers, this.continuation) |
1094 : _currentClass = new Class(constructor.enclosingClass.reference); | 1146 : _currentClass = new Class(constructor.enclosingClass.reference); |
1095 | 1147 |
1096 /// Creates a continuation for the evaluation of the initializer at position | 1148 /// Creates a continuation for the evaluation of the initializer at position |
1097 /// [index]. | 1149 /// [index]. |
1098 InitializerListEK withInitializerIndex(int index) { | 1150 InitializerListEK withInitializerIndex(int index) { |
1099 return new InitializerListEK( | 1151 return new InitializerListEK( |
1100 constructor, index, location, environment, continuation); | 1152 constructor, index, location, environment, handlers, continuation); |
1101 } | 1153 } |
1102 | 1154 |
1103 Configuration call(Value value) { | 1155 Configuration call(Value value) { |
1104 Initializer current = constructor.initializers[initializerIndex]; | 1156 Initializer current = constructor.initializers[initializerIndex]; |
1105 if (current is FieldInitializer) { | 1157 if (current is FieldInitializer) { |
1106 _currentClass.lookupImplicitSetter(current.field.name)( | 1158 _currentClass.lookupImplicitSetter(current.field.name)( |
1107 location.value, value); | 1159 location.value, value); |
1108 return _createNextConfiguration(environment); | 1160 return _createNextConfiguration(environment); |
1109 } | 1161 } |
1110 if (current is LocalInitializer) { | 1162 if (current is LocalInitializer) { |
(...skipping 18 matching lines...) Expand all Loading... | |
1129 | 1181 |
1130 if (next is RedirectingInitializer) { | 1182 if (next is RedirectingInitializer) { |
1131 return _createEvalListConfig(next.arguments, next.target, env); | 1183 return _createEvalListConfig(next.arguments, next.target, env); |
1132 } | 1184 } |
1133 | 1185 |
1134 Expression nextExpr = (next is FieldInitializer) | 1186 Expression nextExpr = (next is FieldInitializer) |
1135 ? next.value | 1187 ? next.value |
1136 : (next as LocalInitializer).variable.initializer; | 1188 : (next as LocalInitializer).variable.initializer; |
1137 | 1189 |
1138 var cont = withInitializerIndex(initializerIndex + 1); | 1190 var cont = withInitializerIndex(initializerIndex + 1); |
1139 return new EvalConfiguration(nextExpr, env, cont); | 1191 return new EvalConfiguration(nextExpr, env, handlers, cont); |
1140 } | 1192 } |
1141 | 1193 |
1142 Configuration _createEvalListConfig( | 1194 Configuration _createEvalListConfig( |
1143 Arguments args, Constructor ctr, Environment env) { | 1195 Arguments args, Constructor ctr, Environment env) { |
1144 List<InterpreterExpression> exprs = | 1196 List<InterpreterExpression> exprs = |
1145 _getArgumentExpressions(args, ctr.function); | 1197 _getArgumentExpressions(args, ctr.function); |
1146 var cont = new ConstructorInitializerA(ctr, location, continuation); | 1198 var cont = |
1147 return new EvalListConfiguration(exprs, env, cont); | 1199 new ConstructorInitializerA(ctr, location, handlers, continuation); |
1200 return new EvalListConfiguration(exprs, env, handlers, cont); | |
1148 } | 1201 } |
1149 } | 1202 } |
1150 | 1203 |
1204 // ------------------------------------------------------------------------ | |
1205 // Exceptions Handlers | |
1206 // ------------------------------------------------------------------------ | |
1207 | |
1208 abstract class ExceptionHandler extends Continuation { | |
1209 ExceptionHandler get nextHandler; | |
1210 | |
1211 Configuration call(Value exception, StackTrace stacktrace); | |
1212 } | |
1213 | |
1214 // ------------------------------------------------------------------------ | |
1215 // Exceptions | |
1216 // ------------------------------------------------------------------------ | |
1217 /// Represents the components for Exception handling. | |
1218 /// | |
1219 /// It contains the list of exception handlers, a stack trace and optional | |
1220 /// components, current stacktrace and exception. | |
1221 class Handlers { | |
Dmitry Stefantsov
2017/08/03 08:45:17
I get it that [Handlers] contains all the informat
| |
1222 final ExceptionHandler handler; | |
1223 final StackTrace stackTrace; | |
1224 | |
1225 /// Current exception and stack trace. | |
1226 /// | |
1227 /// Components enabling support for `rethrow` expressions and set only in | |
1228 /// catch clauses. | |
1229 final StackTrace currentStackTrace; | |
1230 final Value currentException; | |
1231 | |
1232 Handlers(this.handler, this.stackTrace, this.currentStackTrace, | |
1233 this.currentException); | |
1234 | |
1235 // TODO(zhivkag): Add a top level handler for initial exception state. | |
1236 Handlers.initial() | |
1237 : handler = null, | |
1238 stackTrace = null, | |
1239 currentStackTrace = null, | |
1240 currentException = null; | |
1241 } | |
1242 | |
1243 class StackTrace { | |
1244 final Expression expression; | |
1245 final StackTrace stackTrace; | |
1246 | |
1247 StackTrace(this.expression, this.stackTrace); | |
1248 } | |
1249 | |
1151 /// Executes statements. | 1250 /// Executes statements. |
1152 /// | 1251 /// |
1153 /// Execution of a statement completes in one of the following ways: | 1252 /// Execution of a statement completes in one of the following ways: |
1154 /// - It completes normally, in which case the execution proceeds to applying | 1253 /// - It completes normally, in which case the execution proceeds to applying |
1155 /// the next continuation. | 1254 /// the next continuation. |
1156 /// - It breaks with a label, in which case the corresponding continuation is | 1255 /// - It breaks with a label, in which case the corresponding continuation is |
1157 /// returned and applied. | 1256 /// returned and applied. |
1158 /// - It returns with or without value, in which case the return continuation is | 1257 /// - It returns with or without value, in which case the return continuation is |
1159 /// returned and applied accordingly. | 1258 /// returned and applied accordingly. |
1160 /// - It throws, in which case the handler is returned and applied accordingly. | 1259 /// - It throws, in which case the handler is returned and applied accordingly. |
1161 class StatementExecuter | 1260 class StatementExecuter |
1162 extends StatementVisitor1<Configuration, ExecConfiguration> { | 1261 extends StatementVisitor1<Configuration, ExecConfiguration> { |
1163 Evaluator evaluator = new Evaluator(); | 1262 Evaluator evaluator = new Evaluator(); |
1164 | 1263 |
1165 void trampolinedExecution(Configuration configuration) { | 1264 void trampolinedExecution(Configuration configuration) { |
1166 while (configuration != null) { | 1265 while (configuration != null) { |
1167 configuration = configuration.step(this); | 1266 configuration = configuration.step(this); |
1168 } | 1267 } |
1169 } | 1268 } |
1170 | 1269 |
1171 Configuration exec(Statement statement, ExecConfiguration conf) => | 1270 Configuration exec(Statement statement, ExecConfiguration conf) => |
1172 statement.accept1(this, conf); | 1271 statement.accept1(this, conf); |
1173 Configuration eval(Expression expression, EvalConfiguration config) => | 1272 Configuration eval(Expression expression, EvalConfiguration config) => |
1174 evaluator.eval(expression, config); | 1273 evaluator.eval(expression, config); |
1175 Configuration evalList( | 1274 Configuration evalList(List<InterpreterExpression> es, Environment env, |
1176 List<InterpreterExpression> es, Environment env, Continuation cont) => | 1275 Handlers handlers, Continuation cont) => |
1177 evaluator.evalList(es, env, cont); | 1276 evaluator.evalList(es, env, handlers, cont); |
1178 | 1277 |
1179 Configuration defaultStatement(Statement node, ExecConfiguration conf) { | 1278 Configuration defaultStatement(Statement node, ExecConfiguration conf) { |
1180 throw notImplemented( | 1279 throw notImplemented( |
1181 m: "Execution is not implemented for statement:\n$node "); | 1280 m: "Execution is not implemented for statement:\n$node "); |
1182 } | 1281 } |
1183 | 1282 |
1184 Configuration visitInvalidStatement( | 1283 Configuration visitInvalidStatement( |
1185 InvalidStatement node, ExecConfiguration conf) { | 1284 InvalidStatement node, ExecConfiguration conf) { |
1186 throw "Invalid statement at ${node.location}"; | 1285 throw "Invalid statement at ${node.location}"; |
1187 } | 1286 } |
1188 | 1287 |
1189 Configuration visitExpressionStatement( | 1288 Configuration visitExpressionStatement( |
1190 ExpressionStatement node, ExecConfiguration conf) { | 1289 ExpressionStatement node, ExecConfiguration conf) { |
1191 var cont = new ExpressionEK(conf.state.continuation, conf.environment); | 1290 var cont = new ExpressionEK(conf.state.continuation, conf.environment); |
1192 return new EvalConfiguration(node.expression, conf.environment, cont); | 1291 return new EvalConfiguration( |
1292 node.expression, conf.environment, conf.state.handlers, cont); | |
1193 } | 1293 } |
1194 | 1294 |
1195 Configuration visitBlock(Block node, ExecConfiguration conf) { | 1295 Configuration visitBlock(Block node, ExecConfiguration conf) { |
1196 if (node.statements.isEmpty) { | 1296 if (node.statements.isEmpty) { |
1197 return new ForwardConfiguration( | 1297 return new ForwardConfiguration( |
1198 conf.state.continuation, conf.environment); | 1298 conf.state.continuation, conf.environment); |
1199 } | 1299 } |
1200 | 1300 |
1201 var env = new Environment(conf.environment); | 1301 var env = new Environment(conf.environment); |
1202 var cont = new BlockSK.fromConfig(node.statements.skip(1).toList(), conf); | 1302 var cont = new BlockSK.fromConfig(node.statements.skip(1).toList(), conf); |
1203 return new ExecConfiguration( | 1303 return new ExecConfiguration( |
1204 node.statements.first, env, conf.state.withContinuation(cont)); | 1304 node.statements.first, env, conf.state.withContinuation(cont)); |
1205 } | 1305 } |
1206 | 1306 |
1207 Configuration visitEmptyStatement( | 1307 Configuration visitEmptyStatement( |
1208 EmptyStatement node, ExecConfiguration conf) { | 1308 EmptyStatement node, ExecConfiguration conf) { |
1209 return new ForwardConfiguration(conf.state.continuation, conf.environment); | 1309 return new ForwardConfiguration(conf.state.continuation, conf.environment); |
1210 } | 1310 } |
1211 | 1311 |
1212 Configuration visitIfStatement(IfStatement node, ExecConfiguration conf) { | 1312 Configuration visitIfStatement(IfStatement node, ExecConfiguration conf) { |
1213 var cont = new IfConditionEK( | 1313 var cont = new IfConditionEK( |
1214 node.then, node.otherwise, conf.environment, conf.state); | 1314 node.then, node.otherwise, conf.environment, conf.state); |
1215 | 1315 |
1216 return new EvalConfiguration(node.condition, conf.environment, cont); | 1316 return new EvalConfiguration( |
1317 node.condition, conf.environment, conf.state.handlers, cont); | |
1217 } | 1318 } |
1218 | 1319 |
1219 Configuration visitLabeledStatement( | 1320 Configuration visitLabeledStatement( |
1220 LabeledStatement node, ExecConfiguration conf) { | 1321 LabeledStatement node, ExecConfiguration conf) { |
1221 return new ExecConfiguration(node.body, conf.environment, | 1322 return new ExecConfiguration(node.body, conf.environment, |
1222 conf.state.withBreak(node, conf.environment)); | 1323 conf.state.withBreak(node, conf.environment)); |
1223 } | 1324 } |
1224 | 1325 |
1225 Configuration visitBreakStatement( | 1326 Configuration visitBreakStatement( |
1226 BreakStatement node, ExecConfiguration conf) { | 1327 BreakStatement node, ExecConfiguration conf) { |
1227 Label l = conf.state.lookupLabel(node.target); | 1328 Label l = conf.state.lookupLabel(node.target); |
1228 return new ForwardConfiguration(l.continuation, l.environment); | 1329 return new ForwardConfiguration(l.continuation, l.environment); |
1229 } | 1330 } |
1230 | 1331 |
1231 Configuration visitWhileStatement( | 1332 Configuration visitWhileStatement( |
1232 WhileStatement node, ExecConfiguration conf) { | 1333 WhileStatement node, ExecConfiguration conf) { |
1233 var cont = new WhileConditionEK( | 1334 var cont = new WhileConditionEK( |
1234 node.condition, node.body, conf.environment, conf.state); | 1335 node.condition, node.body, conf.environment, conf.state); |
1235 | 1336 |
1236 return new EvalConfiguration(node.condition, conf.environment, cont); | 1337 return new EvalConfiguration( |
1338 node.condition, conf.environment, conf.state.handlers, cont); | |
1237 } | 1339 } |
1238 | 1340 |
1239 Configuration visitDoStatement(DoStatement node, ExecConfiguration conf) { | 1341 Configuration visitDoStatement(DoStatement node, ExecConfiguration conf) { |
1240 var cont = new WhileConditionSK( | 1342 var cont = new WhileConditionSK( |
1241 node.condition, node.body, conf.environment, conf.state); | 1343 node.condition, node.body, conf.environment, conf.state); |
1242 | 1344 |
1243 return new ExecConfiguration( | 1345 return new ExecConfiguration( |
1244 node.body, conf.environment, conf.state.withContinuation(cont)); | 1346 node.body, conf.environment, conf.state.withContinuation(cont)); |
1245 } | 1347 } |
1246 | 1348 |
1247 Configuration visitReturnStatement( | 1349 Configuration visitReturnStatement( |
1248 ReturnStatement node, ExecConfiguration conf) { | 1350 ReturnStatement node, ExecConfiguration conf) { |
1249 assert(conf.state.returnContinuation != null); | 1351 assert(conf.state.returnContinuation != null); |
1250 log.info('return\n'); | 1352 log.info('return\n'); |
1251 if (node.expression == null) { | 1353 if (node.expression == null) { |
1252 return new ValuePassingConfiguration( | 1354 return new ValuePassingConfiguration( |
1253 conf.state.returnContinuation, Value.nullInstance); | 1355 conf.state.returnContinuation, Value.nullInstance); |
1254 } | 1356 } |
1255 | 1357 return new EvalConfiguration(node.expression, conf.environment, |
1256 return new EvalConfiguration( | 1358 conf.state.handlers, conf.state.returnContinuation); |
1257 node.expression, conf.environment, conf.state.returnContinuation); | |
1258 } | 1359 } |
1259 | 1360 |
1260 Configuration visitVariableDeclaration( | 1361 Configuration visitVariableDeclaration( |
1261 VariableDeclaration node, ExecConfiguration conf) { | 1362 VariableDeclaration node, ExecConfiguration conf) { |
1262 if (node.initializer != null) { | 1363 if (node.initializer != null) { |
1263 var cont = new VariableInitializerEK( | 1364 var cont = new VariableInitializerEK( |
1264 node, conf.environment, conf.state.continuation); | 1365 node, conf.environment, conf.state.continuation); |
1265 return new EvalConfiguration(node.initializer, conf.environment, cont); | 1366 return new EvalConfiguration( |
1367 node.initializer, conf.environment, conf.state.handlers, cont); | |
1266 } | 1368 } |
1267 return new ForwardConfiguration(conf.state.continuation, | 1369 return new ForwardConfiguration(conf.state.continuation, |
1268 conf.environment.extend(node, Value.nullInstance)); | 1370 conf.environment.extend(node, Value.nullInstance)); |
1269 } | 1371 } |
1270 } | 1372 } |
1271 | 1373 |
1272 // ------------------------------------------------------------------------ | 1374 // ------------------------------------------------------------------------ |
1273 // VALUES | 1375 // VALUES |
1274 // ------------------------------------------------------------------------ | 1376 // ------------------------------------------------------------------------ |
1275 | 1377 |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1561 /// Initializes all non initialized fields from the provided class to | 1663 /// Initializes all non initialized fields from the provided class to |
1562 /// `Value.nullInstance` in the provided value. | 1664 /// `Value.nullInstance` in the provided value. |
1563 void _initializeNullFields(Class class_, Value value) { | 1665 void _initializeNullFields(Class class_, Value value) { |
1564 int startIndex = class_.superclass?.instanceSize ?? 0; | 1666 int startIndex = class_.superclass?.instanceSize ?? 0; |
1565 for (int i = startIndex; i < class_.instanceSize; i++) { | 1667 for (int i = startIndex; i < class_.instanceSize; i++) { |
1566 if (value.fields[i].value == null) { | 1668 if (value.fields[i].value == null) { |
1567 value.fields[i].value = Value.nullInstance; | 1669 value.fields[i].value = Value.nullInstance; |
1568 } | 1670 } |
1569 } | 1671 } |
1570 } | 1672 } |
OLD | NEW |