Chromium Code Reviews| Index: pkg/kernel/lib/interpreter/interpreter.dart |
| diff --git a/pkg/kernel/lib/interpreter/interpreter.dart b/pkg/kernel/lib/interpreter/interpreter.dart |
| index 6d88dd25abc92be2a0b161ffcc51b96aa29f8bf9..50415b3d315389ef2f4521f2b919b323322701c9 100644 |
| --- a/pkg/kernel/lib/interpreter/interpreter.dart |
| +++ b/pkg/kernel/lib/interpreter/interpreter.dart |
| @@ -317,7 +317,8 @@ class State { |
| continuation = null; |
| State withBreak(Statement stmt, Environment env) { |
| - Label breakLabels = new Label(stmt, env, continuation, labels); |
| + var cont = new BreakBK(continuation, env); |
| + Label breakLabels = new Label(stmt, cont, labels); |
| return new State( |
| breakLabels, exceptionComponents, returnContinuation, continuation); |
| } |
| @@ -344,18 +345,23 @@ class State { |
| /// enclosing label. |
| class Label { |
| final LabeledStatement statement; |
| - final Environment environment; |
| - final StatementContinuation continuation; |
| + final BreakContinuation continuation; |
| final Label enclosingLabel; |
| - Label( |
| - this.statement, this.environment, this.continuation, this.enclosingLabel); |
| + Label(this.statement, this.continuation, this.enclosingLabel); |
| Label lookupLabel(LabeledStatement s) { |
| if (identical(s, statement)) return this; |
| assert(enclosingLabel != null); |
| return enclosingLabel.lookupLabel(s); |
| } |
| + |
| + // Recursively install finally break to all labels. |
| + Label withFinalizer(Statement finalizer, Environment env, State state) { |
| + var label = enclosingLabel?.withFinalizer(finalizer, env, state); |
| + var finallyCont = new FinallyBK(finalizer, env, state, continuation); |
| + return new Label(statement, finallyCont, label); |
| + } |
| } |
| // ------------------------------------------------------------------------ |
| @@ -456,6 +462,50 @@ class ThrowConfiguration extends Configuration { |
| Configuration step(StatementExecuter _) => handler(exception, stacktrace); |
| } |
| +class BreakConfiguration extends Configuration { |
| + final BreakContinuation continuation; |
| + |
| + BreakConfiguration(this.continuation); |
| + |
| + Configuration step(StatementExecuter _) => continuation(); |
| +} |
| + |
| +abstract class BreakContinuation extends Continuation { |
| + Configuration call(); |
| +} |
| + |
| +class BreakBK extends BreakContinuation { |
| + final StatementContinuation continuation; |
| + final Environment environment; |
| + |
| + BreakBK(this.continuation, this.environment); |
| + |
| + Configuration call() => new ForwardConfiguration(continuation, environment); |
| +} |
| + |
| +class FinallyBK extends BreakContinuation { |
| + final Statement finalizer; |
| + final Environment environment; |
| + final State state; |
| + final BreakContinuation continuation; |
| + |
| + FinallyBK(this.finalizer, this.environment, this.state, this.continuation); |
| + |
| + Configuration call() { |
| + var cont = new BreakSK(continuation); |
| + return new ExecConfiguration( |
| + finalizer, environment, state.withContinuation(cont)); |
| + } |
| +} |
| + |
| +class BreakSK extends StatementContinuation { |
| + final BreakContinuation continuation; |
| + |
| + BreakSK(this.continuation); |
| + |
| + Configuration call(Environment _) => new BreakConfiguration(continuation); |
| +} |
| + |
| // ------------------------------------------------------------------------ |
| // Interpreter Expressions and Values |
| // ------------------------------------------------------------------------ |
| @@ -1341,21 +1391,16 @@ class CatchHandler extends ExceptionHandler { |
| class FinallyHandler extends ExceptionHandler { |
| final Statement finallyStatement; |
| final Environment environment; |
| - final Label labels; |
| - final ExceptionComponents exceptionComponents; |
| - final ExpressionContinuation expressionContinuation; |
| - |
| - FinallyHandler(this.finallyStatement, this.environment, this.labels, |
| - this.exceptionComponents, this.expressionContinuation); |
| + final State state; |
| + FinallyHandler(this.finallyStatement, this.environment, this.state); |
| Configuration call(Value exception, StackTrace stackTrace) { |
| // A finally handler can't handle an exception, only execute the |
| // corresponding finally statement and rethrow. |
| var cont = |
| - new RethrowSK(exceptionComponents.handler, exception, stackTrace); |
| - var state = |
| - new State(labels, exceptionComponents, expressionContinuation, cont); |
| - return new ExecConfiguration(finallyStatement, environment, state); |
| + new RethrowSK(state.exceptionComponents.handler, exception, stackTrace); |
| + var newState = state.withContinuation(cont); |
| + return new ExecConfiguration(finallyStatement, environment, newState); |
| } |
| } |
| @@ -1483,7 +1528,7 @@ class StatementExecuter |
| Configuration visitBreakStatement( |
| BreakStatement node, ExecConfiguration conf) { |
| Label l = conf.state.lookupLabel(node.target); |
| - return new ForwardConfiguration(l.continuation, l.environment); |
| + return new BreakConfiguration(l.continuation); |
| } |
| Configuration visitWhileStatement( |
| @@ -1527,12 +1572,20 @@ class StatementExecuter |
| } |
| Configuration visitTryFinally(TryFinally node, ExecConfiguration conf) { |
| - // TODO(zhivkag): Add FinallyBreak to break labels. |
| var cont = new FinallySK(node.finalizer, conf.environment, conf.state); |
| var returnCont = |
| new FinallyReturnEK(node.finalizer, conf.environment, conf.state); |
| - return new ExecConfiguration(node.body, conf.environment, |
| - conf.state.withContinuation(cont).withReturnContinuation(returnCont)); |
| + var labels = conf.state.labels |
| + ?.withFinalizer(node.finalizer, conf.environment, conf.state); |
| + var handler = |
| + new FinallyHandler(node.finalizer, conf.environment, conf.state); |
| + var handlers = new ExceptionComponents( |
|
Dmitry Stefantsov
2017/08/03 13:38:03
Consider renaming [handlers].
zhivkag
2017/08/03 14:13:30
Done.
|
| + handler, |
| + conf.state.exceptionComponents.stackTrace, |
| + conf.state.exceptionComponents.currentStackTrace, |
| + conf.state.exceptionComponents.currentException); |
| + var state = new State(labels, handlers, returnCont, cont); |
| + return new ExecConfiguration(node.body, conf.environment, state); |
| } |
| Configuration visitVariableDeclaration( |