| 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..2c03f2512c2bf68f0684509e931872d7175d606d 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);
|
| }
|
| }
|
|
|
| @@ -1364,7 +1409,7 @@ class FinallyHandler extends ExceptionHandler {
|
| // ------------------------------------------------------------------------
|
| /// Represents the components for Exception handling.
|
| ///
|
| -/// It contains the list of exception handlers, a stack trace and optional
|
| +/// It contains the current of exception handler, a stack trace and optional
|
| /// components, current stacktrace and exception.
|
| class ExceptionComponents {
|
| final ExceptionHandler handler;
|
| @@ -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(
|
| @@ -1517,22 +1562,30 @@ class StatementExecuter
|
|
|
| Configuration visitTryCatch(TryCatch node, ExecConfiguration conf) {
|
| var handler = new CatchHandler(node.catches, conf.environment, conf.state);
|
| - var handlers = new ExceptionComponents(
|
| + var exceptionComponents = new ExceptionComponents(
|
| handler,
|
| conf.state.exceptionComponents.stackTrace,
|
| conf.state.exceptionComponents.currentStackTrace,
|
| conf.state.exceptionComponents.currentException);
|
| - var state = conf.state.withException(handlers);
|
| + var state = conf.state.withException(exceptionComponents);
|
| return new ExecConfiguration(node.body, conf.environment, state);
|
| }
|
|
|
| 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 exceptionComponents = new ExceptionComponents(
|
| + handler,
|
| + conf.state.exceptionComponents.stackTrace,
|
| + conf.state.exceptionComponents.currentStackTrace,
|
| + conf.state.exceptionComponents.currentException);
|
| + var state = new State(labels, exceptionComponents, returnCont, cont);
|
| + return new ExecConfiguration(node.body, conf.environment, state);
|
| }
|
|
|
| Configuration visitVariableDeclaration(
|
|
|