Index: pkg/kernel/lib/interpreter/interpreter.dart |
diff --git a/pkg/kernel/lib/interpreter/interpreter.dart b/pkg/kernel/lib/interpreter/interpreter.dart |
index 0bb5af1d3a6d0a4171d839e6a3edb48fded1faaf..1e35f21c01145f06d989e57fb819514af26bada4 100644 |
--- a/pkg/kernel/lib/interpreter/interpreter.dart |
+++ b/pkg/kernel/lib/interpreter/interpreter.dart |
@@ -31,7 +31,7 @@ class Interpreter { |
Statement statementBlock = mainMethod.function.body; |
ExecConfiguration configuration = new ExecConfiguration( |
- statementBlock, new Environment.empty(), const State.initial()); |
+ statementBlock, new Environment.empty(), new State.initial()); |
visitor.trampolinedExecution(configuration); |
} |
} |
@@ -120,10 +120,14 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> { |
expr.accept1(this, config); |
Configuration evalList(List<InterpreterExpression> list, Environment env, |
- ApplicationContinuation cont) { |
+ ExceptionComponents exceptionComponents, ApplicationContinuation cont) { |
if (list.isNotEmpty) { |
- return new EvalConfiguration(list.first.expression, env, |
- new ExpressionListEK(list.first, list.skip(1), env, cont)); |
+ return new EvalConfiguration( |
+ list.first.expression, |
+ env, |
+ exceptionComponents, |
+ new ExpressionListEK( |
+ list.first, list.skip(1), env, exceptionComponents, cont)); |
} |
return new ApplicationConfiguration(cont, <InterpreterValue>[]); |
} |
@@ -146,18 +150,21 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> { |
Configuration visitVariableSet(VariableSet node, EvalConfiguration config) { |
var cont = new VariableSetEK( |
node.variable, config.environment, config.continuation); |
- return new EvalConfiguration(node.value, config.environment, cont); |
+ return new EvalConfiguration( |
+ node.value, config.environment, config.exceptionComponents, cont); |
} |
Configuration visitPropertyGet(PropertyGet node, EvalConfiguration config) { |
var cont = new PropertyGetEK(node.name, config.continuation); |
- return new EvalConfiguration(node.receiver, config.environment, cont); |
+ return new EvalConfiguration( |
+ node.receiver, config.environment, config.exceptionComponents, cont); |
} |
Configuration visitPropertySet(PropertySet node, EvalConfiguration config) { |
- var cont = new PropertySetEK( |
- node.value, node.name, config.environment, config.continuation); |
- return new EvalConfiguration(node.receiver, config.environment, cont); |
+ var cont = new PropertySetEK(node.value, node.name, config.environment, |
+ config.exceptionComponents, config.continuation); |
+ return new EvalConfiguration( |
+ node.receiver, config.environment, config.exceptionComponents, cont); |
} |
Configuration visitStaticGet(StaticGet node, EvalConfiguration config) => |
@@ -169,16 +176,17 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> { |
StaticInvocation node, EvalConfiguration config) { |
if ('print' == node.name.toString()) { |
var cont = new PrintEK(config.continuation); |
- return new EvalConfiguration( |
- node.arguments.positional.first, config.environment, cont); |
+ return new EvalConfiguration(node.arguments.positional.first, |
+ config.environment, config.exceptionComponents, cont); |
} else { |
log.info('static-invocation-${node.target.name.toString()}\n'); |
List<InterpreterExpression> args = |
_getArgumentExpressions(node.arguments, node.target.function); |
- ApplicationContinuation cont = |
- new StaticInvocationA(node.target.function, config.continuation); |
- return new EvalListConfiguration(args, config.environment, cont); |
+ ApplicationContinuation cont = new StaticInvocationA(node.target.function, |
+ config.exceptionComponents, config.continuation); |
+ return new EvalListConfiguration( |
+ args, config.environment, config.exceptionComponents, cont); |
} |
} |
@@ -186,43 +194,50 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> { |
MethodInvocation node, EvalConfiguration config) { |
// Currently supports only method invocation with <2 arguments and is used |
// to evaluate implemented operators for int, double and String values. |
- var cont = new MethodInvocationEK( |
- node.arguments, node.name, config.environment, config.continuation); |
+ var cont = new MethodInvocationEK(node.arguments, node.name, |
+ config.environment, config.exceptionComponents, config.continuation); |
- return new EvalConfiguration(node.receiver, config.environment, cont); |
+ return new EvalConfiguration( |
+ node.receiver, config.environment, config.exceptionComponents, cont); |
} |
Configuration visitConstructorInvocation( |
ConstructorInvocation node, EvalConfiguration config) { |
- ApplicationContinuation cont = |
- new ConstructorInvocationA(node.target, config.continuation); |
+ ApplicationContinuation cont = new ConstructorInvocationA( |
+ node.target, config.exceptionComponents, config.continuation); |
var args = _getArgumentExpressions(node.arguments, node.target.function); |
- return new EvalListConfiguration(args, config.environment, cont); |
+ return new EvalListConfiguration( |
+ args, config.environment, config.exceptionComponents, cont); |
} |
Configuration visitNot(Not node, EvalConfiguration config) { |
- return new EvalConfiguration( |
- node.operand, config.environment, new NotEK(config.continuation)); |
+ return new EvalConfiguration(node.operand, config.environment, |
+ config.exceptionComponents, new NotEK(config.continuation)); |
} |
Configuration visitLogicalExpression( |
LogicalExpression node, EvalConfiguration config) { |
if ('||' == node.operator) { |
- var cont = new OrEK(node.right, config.environment, config.continuation); |
- return new EvalConfiguration(node.left, config.environment, cont); |
+ var cont = new OrEK(node.right, config.environment, |
+ config.exceptionComponents, config.continuation); |
+ return new EvalConfiguration( |
+ node.left, config.environment, config.exceptionComponents, cont); |
} else { |
assert('&&' == node.operator); |
- var cont = new AndEK(node.right, config.environment, config.continuation); |
- return new EvalConfiguration(node.left, config.environment, cont); |
+ var cont = new AndEK(node.right, config.environment, |
+ config.exceptionComponents, config.continuation); |
+ return new EvalConfiguration( |
+ node.left, config.environment, config.exceptionComponents, cont); |
} |
} |
Configuration visitConditionalExpression( |
ConditionalExpression node, EvalConfiguration config) { |
- var cont = new ConditionalEK( |
- node.then, node.otherwise, config.environment, config.continuation); |
- return new EvalConfiguration(node.condition, config.environment, cont); |
+ var cont = new ConditionalEK(node.then, node.otherwise, config.environment, |
+ config.exceptionComponents, config.continuation); |
+ return new EvalConfiguration( |
+ node.condition, config.environment, config.exceptionComponents, cont); |
} |
Configuration visitStringConcatenation( |
@@ -231,7 +246,8 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> { |
var expressions = node.expressions |
.map((Expression e) => new PositionalExpression(e)) |
.toList(); |
- return new EvalListConfiguration(expressions, config.environment, cont); |
+ return new EvalListConfiguration( |
+ expressions, config.environment, config.exceptionComponents, cont); |
} |
Configuration visitThisExpression( |
@@ -269,10 +285,10 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> { |
} |
Configuration visitLet(Let node, EvalConfiguration config) { |
- var letCont = new LetEK( |
- node.variable, node.body, config.environment, config.continuation); |
- return new EvalConfiguration( |
- node.variable.initializer, config.environment, letCont); |
+ var letCont = new LetEK(node.variable, node.body, config.environment, |
+ config.exceptionComponents, config.continuation); |
+ return new EvalConfiguration(node.variable.initializer, config.environment, |
+ config.exceptionComponents, letCont); |
} |
} |
@@ -280,28 +296,35 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> { |
class State { |
final Label labels; |
// TODO: Add switch labels. |
- // TODO: Add component for exception support. |
+ final ExceptionComponents exceptionComponents; |
final ExpressionContinuation returnContinuation; |
final StatementContinuation continuation; |
- State(this.labels, this.returnContinuation, this.continuation); |
+ State(this.labels, this.exceptionComponents, this.returnContinuation, |
+ this.continuation); |
- const State.initial() |
+ State.initial() |
: labels = null, |
+ exceptionComponents = new ExceptionComponents.initial(), |
returnContinuation = null, |
continuation = null; |
State withBreak(Statement stmt, Environment env) { |
Label breakLabels = new Label(stmt, env, continuation, labels); |
- return new State(breakLabels, returnContinuation, continuation); |
+ return new State( |
+ breakLabels, exceptionComponents, returnContinuation, continuation); |
} |
State withReturnContinuation(ExpressionContinuation returnCont) { |
- return new State(labels, returnCont, continuation); |
+ return new State(labels, exceptionComponents, returnCont, continuation); |
} |
State withContinuation(StatementContinuation cont) { |
- return new State(labels, returnContinuation, cont); |
+ return new State(labels, exceptionComponents, returnContinuation, cont); |
+ } |
+ |
+ State withException(ExceptionComponents state) { |
+ return new State(labels, state, returnContinuation, continuation); |
} |
Label lookupLabel(LabeledStatement s) { |
@@ -344,10 +367,14 @@ class EvalConfiguration extends Configuration { |
/// Environment in which the expression is evaluated. |
final Environment environment; |
+ /// Exception components. |
+ final ExceptionComponents exceptionComponents; |
+ |
/// Next continuation to be applied. |
final Continuation continuation; |
- EvalConfiguration(this.expression, this.environment, this.continuation); |
+ EvalConfiguration(this.expression, this.environment, this.exceptionComponents, |
+ this.continuation); |
Configuration step(StatementExecuter executer) => |
executer.eval(expression, this); |
@@ -357,12 +384,14 @@ class EvalConfiguration extends Configuration { |
class EvalListConfiguration extends Configuration { |
final List<InterpreterExpression> expressions; |
final Environment environment; |
+ final ExceptionComponents exceptionComponents; |
final ApplicationContinuation continuation; |
- EvalListConfiguration(this.expressions, this.environment, this.continuation); |
+ EvalListConfiguration(this.expressions, this.environment, |
+ this.exceptionComponents, this.continuation); |
- Configuration step(StatementExecuter executer) => |
- executer.evalList(expressions, environment, continuation); |
+ Configuration step(StatementExecuter executer) => executer.evalList( |
+ expressions, environment, exceptionComponents, continuation); |
} |
/// Configuration for execution of a [Statement]. |
@@ -408,6 +437,16 @@ class ApplicationConfiguration extends Configuration { |
Configuration step(StatementExecuter _) => continuation(values); |
} |
+class ThrowConfiguration extends Configuration { |
+ final ExceptionHandler handler; |
+ final Value exception; |
+ final StackTrace stacktrace; |
+ |
+ ThrowConfiguration(this.handler, this.exception, this.stacktrace); |
+ |
+ Configuration step(StatementExecuter _) => handler(exception, stacktrace); |
+} |
+ |
// ------------------------------------------------------------------------ |
// Interpreter Expressions and Values |
// ------------------------------------------------------------------------ |
@@ -529,7 +568,8 @@ class WhileConditionSK extends StatementContinuation { |
Configuration call(Environment _) { |
// Evaluate the condition for the while loop execution. |
var cont = new WhileConditionEK(condition, body, enclosingEnv, state); |
- return new EvalConfiguration(condition, enclosingEnv, cont); |
+ return new EvalConfiguration( |
+ condition, enclosingEnv, state.exceptionComponents, cont); |
} |
} |
@@ -547,14 +587,15 @@ class NewSK extends StatementContinuation { |
class ConstructorBodySK extends StatementContinuation { |
final Statement body; |
final Environment environment; |
- // TODO(zhivkag): Add component for exception handler. |
+ final ExceptionComponents exceptionComponents; |
final StatementContinuation continuation; |
- ConstructorBodySK(this.body, this.environment, this.continuation); |
+ ConstructorBodySK( |
+ this.body, this.environment, this.exceptionComponents, this.continuation); |
Configuration call(Environment _) { |
- return new ExecConfiguration( |
- body, environment, new State(null, null, continuation)); |
+ return new ExecConfiguration(body, environment, |
+ new State(null, exceptionComponents, null, continuation)); |
} |
} |
@@ -634,15 +675,16 @@ class StringConcatenationA extends ApplicationContinuation { |
/// Represents the application continuation for static invocation. |
class StaticInvocationA extends ApplicationContinuation { |
final FunctionNode function; |
+ final ExceptionComponents exceptionComponents; |
final ExpressionContinuation continuation; |
- StaticInvocationA(this.function, this.continuation); |
+ StaticInvocationA(this.function, this.exceptionComponents, this.continuation); |
Configuration call(List<InterpreterValue> argValues) { |
Environment functionEnv = |
ApplicationContinuation.createEnvironment(function, argValues); |
- State bodyState = new State( |
- null, continuation, new ExitSK(continuation, Value.nullInstance)); |
+ State bodyState = new State(null, exceptionComponents, continuation, |
+ new ExitSK(continuation, Value.nullInstance)); |
return new ExecConfiguration(function.body, functionEnv, bodyState); |
} |
@@ -654,17 +696,19 @@ class StaticInvocationA extends ApplicationContinuation { |
/// It creates the newly allocated object instance. |
class ConstructorInvocationA extends ApplicationContinuation { |
final Constructor constructor; |
+ final ExceptionComponents exceptionComponents; |
final ExpressionContinuation continuation; |
- ConstructorInvocationA(this.constructor, this.continuation); |
+ ConstructorInvocationA( |
+ this.constructor, this.exceptionComponents, this.continuation); |
Configuration call(List<InterpreterValue> argValues) { |
Environment ctrEnv = ApplicationContinuation.createEnvironment( |
constructor.function, argValues); |
var class_ = new Class(constructor.enclosingClass.reference); |
var newObject = new ObjectValue(class_); |
- var cont = new InitializationEK( |
- constructor, ctrEnv, new NewSK(continuation, new Location(newObject))); |
+ var cont = new InitializationEK(constructor, ctrEnv, exceptionComponents, |
+ new NewSK(continuation, new Location(newObject))); |
return new ValuePassingConfiguration(cont, newObject); |
} |
@@ -677,14 +721,17 @@ class ConstructorInvocationA extends ApplicationContinuation { |
class ConstructorInitializerA extends ApplicationContinuation { |
final Constructor constructor; |
final Location location; |
+ final ExceptionComponents exceptionComponents; |
final ConstructorBodySK continuation; |
- ConstructorInitializerA(this.constructor, this.location, this.continuation); |
+ ConstructorInitializerA(this.constructor, this.location, |
+ this.exceptionComponents, this.continuation); |
Configuration call(List<InterpreterValue> vs) { |
Environment ctrEnv = |
ApplicationContinuation.createEnvironment(constructor.function, vs); |
- var cont = new InitializationEK(constructor, ctrEnv, continuation); |
+ var cont = new InitializationEK( |
+ constructor, ctrEnv, exceptionComponents, continuation); |
return new ValuePassingConfiguration(cont, location.value); |
} |
@@ -696,12 +743,13 @@ class InstanceFieldsA extends ApplicationContinuation { |
final Constructor constructor; |
final Location location; |
final Environment environment; |
+ final ExceptionComponents exceptionComponents; |
final ConstructorBodySK continuation; |
final Class _currentClass; |
- InstanceFieldsA( |
- this.constructor, this.location, this.environment, this.continuation) |
+ InstanceFieldsA(this.constructor, this.location, this.environment, |
+ this.exceptionComponents, this.continuation) |
: _currentClass = new Class(constructor.enclosingClass.reference); |
Configuration call(List<InterpreterValue> fieldValues) { |
@@ -736,10 +784,11 @@ class InstanceFieldsA extends ApplicationContinuation { |
Configuration _createEvalListConfig(SuperInitializer initializer) { |
List<InterpreterExpression> args = _getArgumentExpressions( |
initializer.arguments, initializer.target.function); |
- var cont = |
- new ConstructorInitializerA(initializer.target, location, continuation); |
+ var cont = new ConstructorInitializerA( |
+ initializer.target, location, exceptionComponents, continuation); |
- return new EvalListConfiguration(args, environment, cont); |
+ return new EvalListConfiguration( |
+ args, environment, exceptionComponents, cont); |
} |
EvalConfiguration _createEvalConfig(Initializer initializer) { |
@@ -749,9 +798,9 @@ class InstanceFieldsA extends ApplicationContinuation { |
// We start with index = 0 since we are evaluating the expression for the |
// first initializer in the initializer list. |
- var cont = new InitializerListEK( |
- constructor, 0, location, environment, continuation); |
- return new EvalConfiguration(expr, environment, cont); |
+ var cont = new InitializerListEK(constructor, 0, location, environment, |
+ exceptionComponents, continuation); |
+ return new EvalConfiguration(expr, environment, exceptionComponents, cont); |
} |
} |
// ------------------------------------------------------------------------ |
@@ -807,14 +856,15 @@ class PropertySetEK extends ExpressionContinuation { |
final Expression value; |
final Name setterName; |
final Environment environment; |
+ final ExceptionComponents exceptionComponents; |
final ExpressionContinuation continuation; |
- PropertySetEK( |
- this.value, this.setterName, this.environment, this.continuation); |
+ PropertySetEK(this.value, this.setterName, this.environment, |
+ this.exceptionComponents, this.continuation); |
Configuration call(Value receiver) { |
var cont = new SetterEK(receiver, setterName, continuation); |
- return new EvalConfiguration(value, environment, cont); |
+ return new EvalConfiguration(value, environment, exceptionComponents, cont); |
} |
} |
@@ -838,15 +888,17 @@ class ExpressionListEK extends ExpressionContinuation { |
final InterpreterExpression currentExpression; |
final List<InterpreterExpression> expressions; |
final Environment environment; |
+ final ExceptionComponents exceptionComponents; |
final ApplicationContinuation applicationContinuation; |
ExpressionListEK(this.currentExpression, this.expressions, this.environment, |
- this.applicationContinuation); |
+ this.exceptionComponents, this.applicationContinuation); |
Configuration call(Value v) { |
ValueA app = |
new ValueA(currentExpression.assignValue(v), applicationContinuation); |
- return new EvalListConfiguration(expressions, environment, app); |
+ return new EvalListConfiguration( |
+ expressions, environment, exceptionComponents, app); |
} |
} |
@@ -854,10 +906,11 @@ class MethodInvocationEK extends ExpressionContinuation { |
final Arguments arguments; |
final Name methodName; |
final Environment environment; |
+ final ExceptionComponents exceptionComponents; |
final ExpressionContinuation continuation; |
- MethodInvocationEK( |
- this.arguments, this.methodName, this.environment, this.continuation); |
+ MethodInvocationEK(this.arguments, this.methodName, this.environment, |
+ this.exceptionComponents, this.continuation); |
Configuration call(Value receiver) { |
if (arguments.positional.isEmpty) { |
@@ -867,7 +920,8 @@ class MethodInvocationEK extends ExpressionContinuation { |
var cont = new ArgumentsEK( |
receiver, methodName, arguments, environment, continuation); |
- return new EvalConfiguration(arguments.positional.first, environment, cont); |
+ return new EvalConfiguration( |
+ arguments.positional.first, environment, exceptionComponents, cont); |
} |
} |
@@ -918,28 +972,34 @@ class NotEK extends ExpressionContinuation { |
class OrEK extends ExpressionContinuation { |
final Expression right; |
final Environment environment; |
+ final ExceptionComponents exceptionComponents; |
final ExpressionContinuation continuation; |
- OrEK(this.right, this.environment, this.continuation); |
+ OrEK(this.right, this.environment, this.exceptionComponents, |
+ this.continuation); |
Configuration call(Value left) { |
return identical(Value.trueInstance, left) |
? new ValuePassingConfiguration(continuation, Value.trueInstance) |
- : new EvalConfiguration(right, environment, continuation); |
+ : new EvalConfiguration( |
+ right, environment, exceptionComponents, continuation); |
} |
} |
class AndEK extends ExpressionContinuation { |
final Expression right; |
final Environment environment; |
+ final ExceptionComponents exceptionComponents; |
final ExpressionContinuation continuation; |
- AndEK(this.right, this.environment, this.continuation); |
+ AndEK(this.right, this.environment, this.exceptionComponents, |
+ this.continuation); |
Configuration call(Value left) { |
return identical(Value.falseInstance, left) |
? new ValuePassingConfiguration(continuation, Value.falseInstance) |
- : new EvalConfiguration(right, environment, continuation); |
+ : new EvalConfiguration( |
+ right, environment, exceptionComponents, continuation); |
} |
} |
@@ -947,14 +1007,18 @@ class ConditionalEK extends ExpressionContinuation { |
final Expression then; |
final Expression otherwise; |
final Environment environment; |
+ final ExceptionComponents exceptionComponents; |
final ExpressionContinuation continuation; |
- ConditionalEK(this.then, this.otherwise, this.environment, this.continuation); |
+ ConditionalEK(this.then, this.otherwise, this.environment, |
+ this.exceptionComponents, this.continuation); |
Configuration call(Value value) { |
return identical(Value.trueInstance, value) |
- ? new EvalConfiguration(then, environment, continuation) |
- : new EvalConfiguration(otherwise, environment, continuation); |
+ ? new EvalConfiguration( |
+ then, environment, exceptionComponents, continuation) |
+ : new EvalConfiguration( |
+ otherwise, environment, exceptionComponents, continuation); |
} |
} |
@@ -962,14 +1026,17 @@ class LetEK extends ExpressionContinuation { |
final VariableDeclaration variable; |
final Expression letBody; |
final Environment environment; |
+ final ExceptionComponents exceptionComponents; |
final ExpressionContinuation continuation; |
- LetEK(this.variable, this.letBody, this.environment, this.continuation); |
+ LetEK(this.variable, this.letBody, this.environment, this.exceptionComponents, |
+ this.continuation); |
Configuration call(Value value) { |
var letEnv = new Environment(environment); |
letEnv.extend(variable, value); |
- return new EvalConfiguration(letBody, letEnv, continuation); |
+ return new EvalConfiguration( |
+ letBody, letEnv, exceptionComponents, continuation); |
} |
} |
@@ -1032,10 +1099,11 @@ class VariableInitializerEK extends ExpressionContinuation { |
class InitializationEK extends ExpressionContinuation { |
final Constructor constructor; |
final Environment environment; |
- // TODO(zhivkag): Add components for exception handling support |
+ final ExceptionComponents exceptionComponents; |
final StatementContinuation continuation; |
- InitializationEK(this.constructor, this.environment, this.continuation); |
+ InitializationEK(this.constructor, this.environment, this.exceptionComponents, |
+ this.continuation); |
Configuration call(Value value) { |
Location location = new Location(value); |
@@ -1048,13 +1116,13 @@ class InitializationEK extends ExpressionContinuation { |
// The statement body is captured by the next statement continuation and |
// expressions for field initialization are evaluated. |
var ctrEnv = environment.extendWithThis(value); |
- var bodyCont = |
- new ConstructorBodySK(constructor.function.body, ctrEnv, continuation); |
+ var bodyCont = new ConstructorBodySK( |
+ constructor.function.body, ctrEnv, exceptionComponents, continuation); |
var initializers = _getFieldInitializers(constructor.enclosingClass); |
- var fieldsCont = |
- new InstanceFieldsA(constructor, location, ctrEnv, bodyCont); |
+ var fieldsCont = new InstanceFieldsA( |
+ constructor, location, ctrEnv, exceptionComponents, bodyCont); |
return new EvalListConfiguration( |
- initializers, new Environment.empty(), fieldsCont); |
+ initializers, new Environment.empty(), exceptionComponents, fieldsCont); |
} |
/// Creates the next configuration to further initializer the value for |
@@ -1067,9 +1135,10 @@ class InitializationEK extends ExpressionContinuation { |
// the current environment. |
List<InterpreterExpression> exprs = |
_getArgumentExpressions(current.arguments, current.target.function); |
- var cont = |
- new ConstructorInitializerA(current.target, location, continuation); |
- return new EvalListConfiguration(exprs, environment, cont); |
+ var cont = new ConstructorInitializerA( |
+ current.target, location, exceptionComponents, continuation); |
+ return new EvalListConfiguration( |
+ exprs, environment, exceptionComponents, cont); |
} |
Expression expr = (current is FieldInitializer) |
? current.value |
@@ -1077,9 +1146,9 @@ class InitializationEK extends ExpressionContinuation { |
// The index is set to 0 since we are evaluating the expression for the |
// first initializer in the initializer list. |
- var cont = new InitializerListEK( |
- constructor, 0, location, environment, continuation); |
- return new EvalConfiguration(expr, environment, cont); |
+ var cont = new InitializerListEK(constructor, 0, location, environment, |
+ exceptionComponents, continuation); |
+ return new EvalConfiguration(expr, environment, exceptionComponents, cont); |
} |
} |
@@ -1088,19 +1157,20 @@ class InitializerListEK extends ExpressionContinuation { |
final int initializerIndex; |
final Location location; |
final Environment environment; |
- // TODO(zhivkag): Add componnents for exception handling. |
+ final ExceptionComponents exceptionComponents; |
final ConstructorBodySK continuation; |
+ |
final Class _currentClass; |
InitializerListEK(this.constructor, this.initializerIndex, this.location, |
- this.environment, this.continuation) |
+ this.environment, this.exceptionComponents, this.continuation) |
: _currentClass = new Class(constructor.enclosingClass.reference); |
/// Creates a continuation for the evaluation of the initializer at position |
/// [index]. |
InitializerListEK withInitializerIndex(int index) { |
- return new InitializerListEK( |
- constructor, index, location, environment, continuation); |
+ return new InitializerListEK(constructor, index, location, environment, |
+ exceptionComponents, continuation); |
} |
Configuration call(Value value) { |
@@ -1139,18 +1209,65 @@ class InitializerListEK extends ExpressionContinuation { |
: (next as LocalInitializer).variable.initializer; |
var cont = withInitializerIndex(initializerIndex + 1); |
- return new EvalConfiguration(nextExpr, env, cont); |
+ return new EvalConfiguration(nextExpr, env, exceptionComponents, cont); |
} |
Configuration _createEvalListConfig( |
Arguments args, Constructor ctr, Environment env) { |
List<InterpreterExpression> exprs = |
_getArgumentExpressions(args, ctr.function); |
- var cont = new ConstructorInitializerA(ctr, location, continuation); |
- return new EvalListConfiguration(exprs, env, cont); |
+ var cont = new ConstructorInitializerA( |
+ ctr, location, exceptionComponents, continuation); |
+ return new EvalListConfiguration(exprs, env, exceptionComponents, cont); |
} |
} |
+// ------------------------------------------------------------------------ |
+// Exceptions Handlers |
+// ------------------------------------------------------------------------ |
+ |
+abstract class ExceptionHandler extends Continuation { |
+ ExceptionHandler get nextHandler; |
+ |
+ Configuration call(Value exception, StackTrace stacktrace); |
+} |
+ |
+// ------------------------------------------------------------------------ |
+// Exceptions |
+// ------------------------------------------------------------------------ |
+/// Represents the components for Exception handling. |
+/// |
+/// It contains the list of exception handlers, a stack trace and optional |
+/// components, current stacktrace and exception. |
+class ExceptionComponents { |
+ final ExceptionHandler handler; |
+ final StackTrace stackTrace; |
+ |
+ /// Current exception and stack trace. |
+ /// |
+ /// Components enabling support for `rethrow` expressions and set only in |
+ /// catch clauses. |
+ final StackTrace currentStackTrace; |
+ final Value currentException; |
+ |
+ ExceptionComponents(this.handler, this.stackTrace, this.currentStackTrace, |
+ this.currentException); |
+ |
+ // TODO(zhivkag): Add a top level handler for initial exception state. |
+ ExceptionComponents.initial() |
+ : handler = null, |
+ stackTrace = null, |
+ currentStackTrace = null, |
+ currentException = null; |
+} |
+ |
+class StackTrace { |
+ final Expression expression; |
+ final StackTrace stackTrace; |
+ |
+ StackTrace(this.expression, this.stackTrace); |
+} |
+ |
/// Executes statements. |
/// |
/// Execution of a statement completes in one of the following ways: |
@@ -1175,9 +1292,9 @@ class StatementExecuter |
statement.accept1(this, conf); |
Configuration eval(Expression expression, EvalConfiguration config) => |
evaluator.eval(expression, config); |
- Configuration evalList( |
- List<InterpreterExpression> es, Environment env, Continuation cont) => |
- evaluator.evalList(es, env, cont); |
+ Configuration evalList(List<InterpreterExpression> es, Environment env, |
+ ExceptionComponents ecs, Continuation cont) => |
+ evaluator.evalList(es, env, ecs, cont); |
Configuration defaultStatement(Statement node, ExecConfiguration conf) { |
throw notImplemented( |
@@ -1192,7 +1309,8 @@ class StatementExecuter |
Configuration visitExpressionStatement( |
ExpressionStatement node, ExecConfiguration conf) { |
var cont = new ExpressionEK(conf.state.continuation, conf.environment); |
- return new EvalConfiguration(node.expression, conf.environment, cont); |
+ return new EvalConfiguration(node.expression, conf.environment, |
+ conf.state.exceptionComponents, cont); |
} |
Configuration visitBlock(Block node, ExecConfiguration conf) { |
@@ -1216,7 +1334,8 @@ class StatementExecuter |
var cont = new IfConditionEK( |
node.then, node.otherwise, conf.environment, conf.state); |
- return new EvalConfiguration(node.condition, conf.environment, cont); |
+ return new EvalConfiguration( |
+ node.condition, conf.environment, conf.state.exceptionComponents, cont); |
} |
Configuration visitLabeledStatement( |
@@ -1236,7 +1355,8 @@ class StatementExecuter |
var cont = new WhileConditionEK( |
node.condition, node.body, conf.environment, conf.state); |
- return new EvalConfiguration(node.condition, conf.environment, cont); |
+ return new EvalConfiguration( |
+ node.condition, conf.environment, conf.state.exceptionComponents, cont); |
} |
Configuration visitDoStatement(DoStatement node, ExecConfiguration conf) { |
@@ -1255,9 +1375,8 @@ class StatementExecuter |
return new ValuePassingConfiguration( |
conf.state.returnContinuation, Value.nullInstance); |
} |
- |
- return new EvalConfiguration( |
- node.expression, conf.environment, conf.state.returnContinuation); |
+ return new EvalConfiguration(node.expression, conf.environment, |
+ conf.state.exceptionComponents, conf.state.returnContinuation); |
} |
Configuration visitVariableDeclaration( |
@@ -1265,7 +1384,8 @@ class StatementExecuter |
if (node.initializer != null) { |
var cont = new VariableInitializerEK( |
node, conf.environment, conf.state.continuation); |
- return new EvalConfiguration(node.initializer, conf.environment, cont); |
+ return new EvalConfiguration(node.initializer, conf.environment, |
+ conf.state.exceptionComponents, cont); |
} |
return new ForwardConfiguration(conf.state.continuation, |
conf.environment.extend(node, Value.nullInstance)); |