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 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
310 State(this.labels, this.exceptionComponents, this.returnContinuation, | 310 State(this.labels, this.exceptionComponents, this.returnContinuation, |
311 this.continuation); | 311 this.continuation); |
312 | 312 |
313 State.initial() | 313 State.initial() |
314 : labels = null, | 314 : labels = null, |
315 exceptionComponents = new ExceptionComponents.initial(), | 315 exceptionComponents = new ExceptionComponents.initial(), |
316 returnContinuation = null, | 316 returnContinuation = null, |
317 continuation = null; | 317 continuation = null; |
318 | 318 |
319 State withBreak(Statement stmt, Environment env) { | 319 State withBreak(Statement stmt, Environment env) { |
320 Label breakLabels = new Label(stmt, env, continuation, labels); | 320 var cont = new BreakBK(continuation, env); |
321 Label breakLabels = new Label(stmt, cont, labels); | |
321 return new State( | 322 return new State( |
322 breakLabels, exceptionComponents, returnContinuation, continuation); | 323 breakLabels, exceptionComponents, returnContinuation, continuation); |
323 } | 324 } |
324 | 325 |
325 State withReturnContinuation(ExpressionContinuation returnCont) { | 326 State withReturnContinuation(ExpressionContinuation returnCont) { |
326 return new State(labels, exceptionComponents, returnCont, continuation); | 327 return new State(labels, exceptionComponents, returnCont, continuation); |
327 } | 328 } |
328 | 329 |
329 State withContinuation(StatementContinuation cont) { | 330 State withContinuation(StatementContinuation cont) { |
330 return new State(labels, exceptionComponents, returnContinuation, cont); | 331 return new State(labels, exceptionComponents, returnContinuation, cont); |
331 } | 332 } |
332 | 333 |
333 State withException(ExceptionComponents ecs) { | 334 State withException(ExceptionComponents ecs) { |
334 return new State(labels, ecs, returnContinuation, continuation); | 335 return new State(labels, ecs, returnContinuation, continuation); |
335 } | 336 } |
336 | 337 |
337 Label lookupLabel(LabeledStatement s) { | 338 Label lookupLabel(LabeledStatement s) { |
338 assert(labels != null); | 339 assert(labels != null); |
339 return labels.lookupLabel(s); | 340 return labels.lookupLabel(s); |
340 } | 341 } |
341 } | 342 } |
342 | 343 |
343 /// Represents a labeled statement, the corresponding continuation and the | 344 /// Represents a labeled statement, the corresponding continuation and the |
344 /// enclosing label. | 345 /// enclosing label. |
345 class Label { | 346 class Label { |
346 final LabeledStatement statement; | 347 final LabeledStatement statement; |
347 final Environment environment; | 348 final BreakContinuation continuation; |
348 final StatementContinuation continuation; | |
349 final Label enclosingLabel; | 349 final Label enclosingLabel; |
350 | 350 |
351 Label( | 351 Label(this.statement, this.continuation, this.enclosingLabel); |
352 this.statement, this.environment, this.continuation, this.enclosingLabel); | |
353 | 352 |
354 Label lookupLabel(LabeledStatement s) { | 353 Label lookupLabel(LabeledStatement s) { |
355 if (identical(s, statement)) return this; | 354 if (identical(s, statement)) return this; |
356 assert(enclosingLabel != null); | 355 assert(enclosingLabel != null); |
357 return enclosingLabel.lookupLabel(s); | 356 return enclosingLabel.lookupLabel(s); |
358 } | 357 } |
358 | |
359 // Recursively install finally break to all labels. | |
360 Label withFinalizer(Statement finalizer, Environment env, State state) { | |
361 var label = enclosingLabel?.withFinalizer(finalizer, env, state); | |
362 var finallyCont = new FinallyBK(finalizer, env, state, continuation); | |
363 return new Label(statement, finallyCont, label); | |
364 } | |
359 } | 365 } |
360 | 366 |
361 // ------------------------------------------------------------------------ | 367 // ------------------------------------------------------------------------ |
362 // Configurations | 368 // Configurations |
363 // ------------------------------------------------------------------------ | 369 // ------------------------------------------------------------------------ |
364 | 370 |
365 abstract class Configuration { | 371 abstract class Configuration { |
366 /// Executes the current and returns the next configuration. | 372 /// Executes the current and returns the next configuration. |
367 Configuration step(StatementExecuter executer); | 373 Configuration step(StatementExecuter executer); |
368 } | 374 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
449 class ThrowConfiguration extends Configuration { | 455 class ThrowConfiguration extends Configuration { |
450 final ExceptionHandler handler; | 456 final ExceptionHandler handler; |
451 final Value exception; | 457 final Value exception; |
452 final StackTrace stacktrace; | 458 final StackTrace stacktrace; |
453 | 459 |
454 ThrowConfiguration(this.handler, this.exception, this.stacktrace); | 460 ThrowConfiguration(this.handler, this.exception, this.stacktrace); |
455 | 461 |
456 Configuration step(StatementExecuter _) => handler(exception, stacktrace); | 462 Configuration step(StatementExecuter _) => handler(exception, stacktrace); |
457 } | 463 } |
458 | 464 |
465 class BreakConfiguration extends Configuration { | |
466 final BreakContinuation continuation; | |
467 | |
468 BreakConfiguration(this.continuation); | |
469 | |
470 Configuration step(StatementExecuter _) => continuation(); | |
471 } | |
472 | |
473 abstract class BreakContinuation extends Continuation { | |
474 Configuration call(); | |
475 } | |
476 | |
477 class BreakBK extends BreakContinuation { | |
478 final StatementContinuation continuation; | |
479 final Environment environment; | |
480 | |
481 BreakBK(this.continuation, this.environment); | |
482 | |
483 Configuration call() => new ForwardConfiguration(continuation, environment); | |
484 } | |
485 | |
486 class FinallyBK extends BreakContinuation { | |
487 final Statement finalizer; | |
488 final Environment environment; | |
489 final State state; | |
490 final BreakContinuation continuation; | |
491 | |
492 FinallyBK(this.finalizer, this.environment, this.state, this.continuation); | |
493 | |
494 Configuration call() { | |
495 var cont = new BreakSK(continuation); | |
496 return new ExecConfiguration( | |
497 finalizer, environment, state.withContinuation(cont)); | |
498 } | |
499 } | |
500 | |
501 class BreakSK extends StatementContinuation { | |
502 final BreakContinuation continuation; | |
503 | |
504 BreakSK(this.continuation); | |
505 | |
506 Configuration call(Environment _) => new BreakConfiguration(continuation); | |
507 } | |
508 | |
459 // ------------------------------------------------------------------------ | 509 // ------------------------------------------------------------------------ |
460 // Interpreter Expressions and Values | 510 // Interpreter Expressions and Values |
461 // ------------------------------------------------------------------------ | 511 // ------------------------------------------------------------------------ |
462 | 512 |
463 abstract class InterpreterExpression { | 513 abstract class InterpreterExpression { |
464 Expression get expression; | 514 Expression get expression; |
465 | 515 |
466 InterpreterValue assignValue(Value v); | 516 InterpreterValue assignValue(Value v); |
467 } | 517 } |
468 | 518 |
(...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1334 } | 1384 } |
1335 | 1385 |
1336 /// Represents the handler that executes the corresponding finalizer before | 1386 /// Represents the handler that executes the corresponding finalizer before |
1337 /// applying the next handler to the given exception. | 1387 /// applying the next handler to the given exception. |
1338 /// | 1388 /// |
1339 /// Applying the next handler to the given exception is supported with adding | 1389 /// Applying the next handler to the given exception is supported with adding |
1340 /// [RethrowSK] as next statement continuation. | 1390 /// [RethrowSK] as next statement continuation. |
1341 class FinallyHandler extends ExceptionHandler { | 1391 class FinallyHandler extends ExceptionHandler { |
1342 final Statement finallyStatement; | 1392 final Statement finallyStatement; |
1343 final Environment environment; | 1393 final Environment environment; |
1344 final Label labels; | 1394 final State state; |
1345 final ExceptionComponents exceptionComponents; | |
1346 final ExpressionContinuation expressionContinuation; | |
1347 | 1395 |
1348 FinallyHandler(this.finallyStatement, this.environment, this.labels, | 1396 FinallyHandler(this.finallyStatement, this.environment, this.state); |
1349 this.exceptionComponents, this.expressionContinuation); | |
1350 | |
1351 Configuration call(Value exception, StackTrace stackTrace) { | 1397 Configuration call(Value exception, StackTrace stackTrace) { |
1352 // A finally handler can't handle an exception, only execute the | 1398 // A finally handler can't handle an exception, only execute the |
1353 // corresponding finally statement and rethrow. | 1399 // corresponding finally statement and rethrow. |
1354 var cont = | 1400 var cont = |
1355 new RethrowSK(exceptionComponents.handler, exception, stackTrace); | 1401 new RethrowSK(state.exceptionComponents.handler, exception, stackTrace); |
1356 var state = | 1402 var newState = state.withContinuation(cont); |
1357 new State(labels, exceptionComponents, expressionContinuation, cont); | 1403 return new ExecConfiguration(finallyStatement, environment, newState); |
1358 return new ExecConfiguration(finallyStatement, environment, state); | |
1359 } | 1404 } |
1360 } | 1405 } |
1361 | 1406 |
1362 // ------------------------------------------------------------------------ | 1407 // ------------------------------------------------------------------------ |
1363 // Exceptions | 1408 // Exceptions |
1364 // ------------------------------------------------------------------------ | 1409 // ------------------------------------------------------------------------ |
1365 /// Represents the components for Exception handling. | 1410 /// Represents the components for Exception handling. |
1366 /// | 1411 /// |
1367 /// It contains the list of exception handlers, a stack trace and optional | 1412 /// It contains the list of exception handlers, a stack trace and optional |
1368 /// components, current stacktrace and exception. | 1413 /// components, current stacktrace and exception. |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1476 | 1521 |
1477 Configuration visitLabeledStatement( | 1522 Configuration visitLabeledStatement( |
1478 LabeledStatement node, ExecConfiguration conf) { | 1523 LabeledStatement node, ExecConfiguration conf) { |
1479 return new ExecConfiguration(node.body, conf.environment, | 1524 return new ExecConfiguration(node.body, conf.environment, |
1480 conf.state.withBreak(node, conf.environment)); | 1525 conf.state.withBreak(node, conf.environment)); |
1481 } | 1526 } |
1482 | 1527 |
1483 Configuration visitBreakStatement( | 1528 Configuration visitBreakStatement( |
1484 BreakStatement node, ExecConfiguration conf) { | 1529 BreakStatement node, ExecConfiguration conf) { |
1485 Label l = conf.state.lookupLabel(node.target); | 1530 Label l = conf.state.lookupLabel(node.target); |
1486 return new ForwardConfiguration(l.continuation, l.environment); | 1531 return new BreakConfiguration(l.continuation); |
1487 } | 1532 } |
1488 | 1533 |
1489 Configuration visitWhileStatement( | 1534 Configuration visitWhileStatement( |
1490 WhileStatement node, ExecConfiguration conf) { | 1535 WhileStatement node, ExecConfiguration conf) { |
1491 var cont = new WhileConditionEK( | 1536 var cont = new WhileConditionEK( |
1492 node.condition, node.body, conf.environment, conf.state); | 1537 node.condition, node.body, conf.environment, conf.state); |
1493 | 1538 |
1494 return new EvalConfiguration( | 1539 return new EvalConfiguration( |
1495 node.condition, conf.environment, conf.state.exceptionComponents, cont); | 1540 node.condition, conf.environment, conf.state.exceptionComponents, cont); |
1496 } | 1541 } |
(...skipping 23 matching lines...) Expand all Loading... | |
1520 var handlers = new ExceptionComponents( | 1565 var handlers = new ExceptionComponents( |
1521 handler, | 1566 handler, |
1522 conf.state.exceptionComponents.stackTrace, | 1567 conf.state.exceptionComponents.stackTrace, |
1523 conf.state.exceptionComponents.currentStackTrace, | 1568 conf.state.exceptionComponents.currentStackTrace, |
1524 conf.state.exceptionComponents.currentException); | 1569 conf.state.exceptionComponents.currentException); |
1525 var state = conf.state.withException(handlers); | 1570 var state = conf.state.withException(handlers); |
1526 return new ExecConfiguration(node.body, conf.environment, state); | 1571 return new ExecConfiguration(node.body, conf.environment, state); |
1527 } | 1572 } |
1528 | 1573 |
1529 Configuration visitTryFinally(TryFinally node, ExecConfiguration conf) { | 1574 Configuration visitTryFinally(TryFinally node, ExecConfiguration conf) { |
1530 // TODO(zhivkag): Add FinallyBreak to break labels. | |
1531 var cont = new FinallySK(node.finalizer, conf.environment, conf.state); | 1575 var cont = new FinallySK(node.finalizer, conf.environment, conf.state); |
1532 var returnCont = | 1576 var returnCont = |
1533 new FinallyReturnEK(node.finalizer, conf.environment, conf.state); | 1577 new FinallyReturnEK(node.finalizer, conf.environment, conf.state); |
1534 return new ExecConfiguration(node.body, conf.environment, | 1578 var labels = conf.state.labels |
1535 conf.state.withContinuation(cont).withReturnContinuation(returnCont)); | 1579 ?.withFinalizer(node.finalizer, conf.environment, conf.state); |
1580 var handler = | |
1581 new FinallyHandler(node.finalizer, conf.environment, conf.state); | |
1582 var handlers = new ExceptionComponents( | |
Dmitry Stefantsov
2017/08/03 13:38:03
Consider renaming [handlers].
zhivkag
2017/08/03 14:13:30
Done.
| |
1583 handler, | |
1584 conf.state.exceptionComponents.stackTrace, | |
1585 conf.state.exceptionComponents.currentStackTrace, | |
1586 conf.state.exceptionComponents.currentException); | |
1587 var state = new State(labels, handlers, returnCont, cont); | |
1588 return new ExecConfiguration(node.body, conf.environment, state); | |
1536 } | 1589 } |
1537 | 1590 |
1538 Configuration visitVariableDeclaration( | 1591 Configuration visitVariableDeclaration( |
1539 VariableDeclaration node, ExecConfiguration conf) { | 1592 VariableDeclaration node, ExecConfiguration conf) { |
1540 if (node.initializer != null) { | 1593 if (node.initializer != null) { |
1541 var cont = new VariableInitializerEK( | 1594 var cont = new VariableInitializerEK( |
1542 node, conf.environment, conf.state.continuation); | 1595 node, conf.environment, conf.state.continuation); |
1543 return new EvalConfiguration(node.initializer, conf.environment, | 1596 return new EvalConfiguration(node.initializer, conf.environment, |
1544 conf.state.exceptionComponents, cont); | 1597 conf.state.exceptionComponents, cont); |
1545 } | 1598 } |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1840 /// Initializes all non initialized fields from the provided class to | 1893 /// Initializes all non initialized fields from the provided class to |
1841 /// `Value.nullInstance` in the provided value. | 1894 /// `Value.nullInstance` in the provided value. |
1842 void _initializeNullFields(Class class_, Value value) { | 1895 void _initializeNullFields(Class class_, Value value) { |
1843 int startIndex = class_.superclass?.instanceSize ?? 0; | 1896 int startIndex = class_.superclass?.instanceSize ?? 0; |
1844 for (int i = startIndex; i < class_.instanceSize; i++) { | 1897 for (int i = startIndex; i < class_.instanceSize; i++) { |
1845 if (value.fields[i].value == null) { | 1898 if (value.fields[i].value == null) { |
1846 value.fields[i].value = Value.nullInstance; | 1899 value.fields[i].value = Value.nullInstance; |
1847 } | 1900 } |
1848 } | 1901 } |
1849 } | 1902 } |
OLD | NEW |