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 current of exception handler, a stack trace and optional |
1368 /// components, current stacktrace and exception. | 1413 /// components, current stacktrace and exception. |
1369 class ExceptionComponents { | 1414 class ExceptionComponents { |
1370 final ExceptionHandler handler; | 1415 final ExceptionHandler handler; |
1371 final StackTrace stackTrace; | 1416 final StackTrace stackTrace; |
1372 | 1417 |
1373 /// Current exception and stack trace. | 1418 /// Current exception and stack trace. |
1374 /// | 1419 /// |
1375 /// Components enabling support for `rethrow` expressions and set only in | 1420 /// Components enabling support for `rethrow` expressions and set only in |
1376 /// catch clauses. | 1421 /// catch clauses. |
1377 final StackTrace currentStackTrace; | 1422 final StackTrace currentStackTrace; |
(...skipping 98 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 13 matching lines...) Expand all Loading... |
1510 if (node.expression == null) { | 1555 if (node.expression == null) { |
1511 return new ValuePassingConfiguration( | 1556 return new ValuePassingConfiguration( |
1512 conf.state.returnContinuation, Value.nullInstance); | 1557 conf.state.returnContinuation, Value.nullInstance); |
1513 } | 1558 } |
1514 return new EvalConfiguration(node.expression, conf.environment, | 1559 return new EvalConfiguration(node.expression, conf.environment, |
1515 conf.state.exceptionComponents, conf.state.returnContinuation); | 1560 conf.state.exceptionComponents, conf.state.returnContinuation); |
1516 } | 1561 } |
1517 | 1562 |
1518 Configuration visitTryCatch(TryCatch node, ExecConfiguration conf) { | 1563 Configuration visitTryCatch(TryCatch node, ExecConfiguration conf) { |
1519 var handler = new CatchHandler(node.catches, conf.environment, conf.state); | 1564 var handler = new CatchHandler(node.catches, conf.environment, conf.state); |
1520 var handlers = new ExceptionComponents( | 1565 var exceptionComponents = 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(exceptionComponents); |
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 exceptionComponents = new ExceptionComponents( |
| 1583 handler, |
| 1584 conf.state.exceptionComponents.stackTrace, |
| 1585 conf.state.exceptionComponents.currentStackTrace, |
| 1586 conf.state.exceptionComponents.currentException); |
| 1587 var state = new State(labels, exceptionComponents, 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 |