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 76ddc324089f5a8d4af74f5d83d289e633b7ec13..9dafbeb0d4f6b35b05198bb7a18ba243476033f9 100644 |
| --- a/pkg/kernel/lib/interpreter/interpreter.dart |
| +++ b/pkg/kernel/lib/interpreter/interpreter.dart |
| @@ -86,13 +86,14 @@ class Evaluator |
| Configuration eval(Expression expr, ExpressionConfiguration config) => |
| expr.accept1(this, config); |
| - Configuration evalArgs(List<ArgumentExpression> args, Environment env, |
| + Configuration evalList(List<InterpreterExpression> args, Environment env, |
|
Dmitry Stefantsov
2017/05/11 07:44:42
Now that we renamed "evalArgs" to "evalList", shou
zhivkag
2017/05/11 07:55:33
Done.
|
| ApplicationContinuation cont) { |
| if (args.isNotEmpty) { |
| return new ExpressionConfiguration(args.first.expression, env, |
| - new ActualArgumentsContinuation(args.first, args.skip(1), env, cont)); |
| + new ExpressionListContinuation(args.first, args.skip(1), env, cont)); |
| } |
| - return new ArgumentContinuationConfiguration(cont, <ArgumentValue>[]); |
| + return new ExpressionListContinuationConfiguration( |
| + cont, <InterpreterValue>[]); |
| } |
| Configuration defaultExpression( |
| @@ -148,11 +149,11 @@ class Evaluator |
| } else { |
| log.info('static-invocation-${node.target.name.toString()}\n'); |
| - List<ArgumentExpression> args = |
| + List<InterpreterExpression> args = |
| _createArgumentExpressionList(node.arguments, node.target.function); |
| ApplicationContinuation cont = new StaticInvocationApplication( |
| node.target.function, config.continuation); |
| - return new ArgumentsConfiguration(args, config.environment, cont); |
| + return new ExpressionListConfiguration(args, config.environment, cont); |
| } |
| } |
| @@ -168,16 +169,23 @@ class Evaluator |
| Configuration visitConstructorInvocation( |
| ConstructorInvocation node, ExpressionConfiguration config) { |
| - Class class_ = new Class(node.target.enclosingClass.reference); |
| + // Currently, the bodies of the constructors are not executed. |
| + // Currently initializer list is executed only for redirecting |
| + // constructors. |
| + if (node.target.function.body is! EmptyStatement) { |
| + throw 'Execution for body of constructor is not implemented.'; |
| + } |
| - // Currently we don't support initializers. |
| - // TODO: Modify to respect dart semantics for initialization. |
| - // 1. Init fields and eval initializers, repeat the same with super. |
| - // 2. Eval the Function body of the constructor. |
| - List<Value> fields = <Value>[]; |
| + var class_ = new Class(node.target.enclosingClass.reference); |
| + var newObject = |
| + new ObjectValue(class_, new List<Value>(class_.instanceSize)); |
| + ApplicationContinuation cont = new ConstructorInvocationApplication( |
| + newObject, node.target, config.continuation); |
| - return new ContinuationConfiguration( |
| - config.continuation, new ObjectValue(class_, fields)); |
| + var args = |
| + _createArgumentExpressionList(node.arguments, node.target.function); |
| + |
| + return new ExpressionListConfiguration(args, config.environment, cont); |
| } |
| Configuration visitNot(Not node, ExpressionConfiguration config) { |
| @@ -344,11 +352,12 @@ class ContinuationConfiguration extends Configuration { |
| } |
| /// Represents the configuration for applying an [ApplicationContinuation]. |
| -class ArgumentContinuationConfiguration extends Configuration { |
| +class ExpressionListContinuationConfiguration extends Configuration { |
| final ApplicationContinuation continuation; |
| - final List<ArgumentValue> argumentValues; |
| + final List<InterpreterValue> argumentValues; |
|
Dmitry Stefantsov
2017/05/11 07:44:42
Same as above. Shouldn't it be "listItemValues" or
zhivkag
2017/05/11 07:55:33
Done.
|
| - ArgumentContinuationConfiguration(this.continuation, this.argumentValues); |
| + ExpressionListContinuationConfiguration( |
| + this.continuation, this.argumentValues); |
| Configuration step(StatementExecuter _) => continuation(argumentValues); |
| } |
| @@ -369,67 +378,107 @@ class ExpressionConfiguration extends Configuration { |
| executer.eval(expression, this); |
| } |
| -/// Represents the configuration for evaluating a list of argument expressions. |
| -class ArgumentsConfiguration extends Configuration { |
| - final List<ArgumentExpression> arguments; |
| +/// Represents the configuration for evaluating a list of expressions. |
| +class ExpressionListConfiguration extends Configuration { |
| + final List<InterpreterExpression> expressions; |
| final Environment environment; |
| final Continuation continuation; |
| - ArgumentsConfiguration(this.arguments, this.environment, this.continuation); |
| + ExpressionListConfiguration( |
| + this.expressions, this.environment, this.continuation); |
| Configuration step(StatementExecuter executer) => |
| - executer.evalArgs(arguments, environment, continuation); |
| + executer.evalList(expressions, environment, continuation); |
| } |
| -abstract class ArgumentExpression { |
| +abstract class InterpreterExpression { |
| Expression get expression; |
| + |
| + InterpreterValue withValue(Value v); |
|
Dmitry Stefantsov
2017/05/11 07:44:42
Previously, when we defined "x.withSomething" meth
zhivkag
2017/05/11 07:55:33
Done.
|
| } |
| -class PositionalArgumentExpression extends ArgumentExpression { |
| +class PositionalArgumentExpression extends InterpreterExpression { |
| final Expression expression; |
| PositionalArgumentExpression(this.expression); |
| + |
| + InterpreterValue withValue(Value v) => new PositionalArgumentValue(v); |
| } |
| -class NamedArgumentExpression extends ArgumentExpression { |
| +class NamedArgumentExpression extends InterpreterExpression { |
| final String name; |
| final Expression expression; |
| NamedArgumentExpression(this.name, this.expression); |
| + InterpreterValue withValue(Value v) => new NamedArgumentValue(name, v); |
| } |
| -abstract class ArgumentValue { |
| +class LocalInitializerExpression extends InterpreterExpression { |
| + final VariableDeclaration variable; |
| + |
| + Expression get expression => variable.initializer; |
| + |
| + LocalInitializerExpression(this.variable); |
| + |
| + InterpreterValue withValue(Value v) => new LocalInitializerValue(variable, v); |
| +} |
| + |
| +class FieldInitializerExpression extends InterpreterExpression { |
| + final Field field; |
| + final Expression expression; |
| + |
| + FieldInitializerExpression(this.field, this.expression); |
| + |
| + InterpreterValue withValue(Value v) => new FieldInitializerValue(field, v); |
| +} |
| + |
| +abstract class InterpreterValue { |
| Value get value; |
| } |
| -class PositionalArgumentValue extends ArgumentValue { |
| +class PositionalArgumentValue extends InterpreterValue { |
| final Value value; |
| PositionalArgumentValue(this.value); |
| } |
| -class NamedArgumentValue extends ArgumentValue { |
| +class NamedArgumentValue extends InterpreterValue { |
| final String name; |
| final Value value; |
| NamedArgumentValue(this.name, this.value); |
| } |
| +class LocalInitializerValue extends InterpreterValue { |
| + final VariableDeclaration variable; |
| + final Value value; |
| + |
| + LocalInitializerValue(this.variable, this.value); |
| +} |
| + |
| +class FieldInitializerValue extends InterpreterValue { |
| + final Field field; |
| + final Value value; |
| + |
| + FieldInitializerValue(this.field, this.value); |
| +} |
| + |
| abstract class Continuation {} |
| /// Represents the continuation called after the evaluation of argument |
| /// expressions. |
| abstract class ApplicationContinuation extends Continuation { |
| - Configuration call(List<ArgumentValue> args); |
| + Configuration call(List<InterpreterValue> args); |
| /// Creates an environment binding actual argument values to formal parameters |
| /// of the function in a new environment, which is used to execute the |
| /// body od the function. |
| + /// TODO: Add checks for validation of arguments according to spec. |
| static Environment createEnvironment( |
| - FunctionNode function, List<ArgumentValue> args) { |
| + FunctionNode function, List<InterpreterValue> args) { |
| Environment newEnv = new Environment.empty(); |
| List<PositionalArgumentValue> positional = args.reversed |
| - .where((ArgumentValue av) => av is PositionalArgumentValue) |
| + .where((InterpreterValue av) => av is PositionalArgumentValue) |
| .toList(); |
| // Add positional parameters. |
| @@ -438,7 +487,7 @@ abstract class ApplicationContinuation extends Continuation { |
| } |
| Map<String, Value> named = new Map.fromIterable( |
| - args.where((ArgumentValue av) => av is NamedArgumentValue), |
| + args.where((InterpreterValue av) => av is NamedArgumentValue), |
| key: (NamedArgumentValue av) => av.name, |
| value: (NamedArgumentValue av) => av.value); |
| @@ -458,7 +507,7 @@ class StaticInvocationApplication extends ApplicationContinuation { |
| StaticInvocationApplication(this.function, this.continuation); |
| - Configuration call(List<ArgumentValue> args) { |
| + Configuration call(List<InterpreterValue> args) { |
| Environment functionEnv = |
| ApplicationContinuation.createEnvironment(function, args); |
| @@ -470,17 +519,127 @@ class StaticInvocationApplication extends ApplicationContinuation { |
| } |
| } |
| +/// Represents the application continuation for constructor invocation applied |
| +/// on the list of evaluated arguments. |
| +class ConstructorInvocationApplication extends ApplicationContinuation { |
| + final ObjectValue newObject; |
| + final Constructor constructor; |
| + final ExpressionContinuation expressionContinuation; |
| + |
| + ConstructorInvocationApplication( |
| + this.newObject, this.constructor, this.expressionContinuation); |
| + |
| + Configuration call(List<InterpreterValue> args) { |
| + Environment ctrEnv = |
| + ApplicationContinuation.createEnvironment(constructor.function, args); |
| + |
| + if (constructor.initializers.isNotEmpty && |
| + constructor.initializers.last is RedirectingInitializer) { |
| + var cont = new RedirectingConstructorInvocationApplication(newObject, |
| + constructor.initializers.last, ctrEnv, expressionContinuation); |
| + var es = _createLocalInitializerExpressionList( |
| + constructor.initializers.take(constructor.initializers.length - 1)); |
| + return new ExpressionListConfiguration(es, ctrEnv, cont); |
| + } |
| + |
| + var cont = new InstanceFieldsApplication( |
| + newObject, constructor, expressionContinuation); |
| + var fieldExpressions = _createInstanceInitializers(constructor); |
| + |
| + return new ExpressionListConfiguration(fieldExpressions, ctrEnv, cont); |
| + } |
| + |
| + /// Creates a list of expressions for local initializers. |
| + static List<InterpreterExpression> _createLocalInitializerExpressionList( |
| + List<LocalInitializer> initializers) { |
| + List<InterpreterExpression> es = <InterpreterExpression>[]; |
| + |
| + for (int i = 0; i < initializers.length; i++) { |
| + var current = initializers[i]; |
| + es.add(new LocalInitializerExpression(current.variable)); |
| + } |
| + return es; |
| + } |
| + |
| + /// Creates a list of expressions for instance field initializers in |
| + /// immediately enclosing class. |
| + static List<InterpreterExpression> _createInstanceInitializers( |
| + Constructor ctr) { |
| + Class currentClass = new Class(ctr.enclosingClass.reference); |
| + List<InterpreterExpression> es = <InterpreterExpression>[]; |
| + |
| + for (int i = currentClass.superclass?.instanceSize ?? 0; |
| + i < currentClass.instanceSize; |
| + i++) { |
| + Field current = currentClass.instanceFields[i]; |
| + if (current.initializer != null) { |
| + es.add(new FieldInitializerExpression(current, current.initializer)); |
| + } |
| + } |
| + |
| + return es; |
| + } |
| +} |
| + |
| +/// Represents the application continuation applied on the list of evaluated |
| +/// local initializer expressions. |
| +class RedirectingConstructorInvocationApplication |
| + extends ApplicationContinuation { |
| + final ObjectValue newObject; |
| + final RedirectingInitializer initializer; |
| + final Environment environment; |
| + final ExpressionContinuation expressionContinuation; |
| + |
| + RedirectingConstructorInvocationApplication(this.newObject, this.initializer, |
| + this.environment, this.expressionContinuation); |
| + |
| + Configuration call(List<InterpreterValue> localValues) { |
| + for (LocalInitializerValue current in localValues.reversed) { |
| + environment.expand(current.variable, current.value); |
| + } |
| + var cont = new ConstructorInvocationApplication( |
| + newObject, initializer.target, expressionContinuation); |
| + var args = _createArgumentExpressionList( |
| + initializer.arguments, initializer.target.function); |
| + |
| + return new ExpressionListConfiguration(args, environment, cont); |
| + } |
| +} |
| + |
| +/// Represents the application continuation applied on the list of evaluated |
| +/// field initializer expressions. |
| +class InstanceFieldsApplication extends ApplicationContinuation { |
| + final ObjectValue newObject; |
| + final Constructor constructor; |
| + final ExpressionContinuation expressionContinuation; |
| + |
| + final Class _currentClass; |
| + |
| + InstanceFieldsApplication( |
| + this.newObject, this.constructor, this.expressionContinuation) |
| + : _currentClass = new Class(constructor.enclosingClass.reference); |
| + |
| + Configuration call(List<InterpreterValue> fields) { |
| + for (FieldInitializerValue current in fields.reversed) { |
| + _currentClass.setProperty(newObject, current.field, current.value); |
| + } |
| + |
| + return new ContinuationConfiguration(expressionContinuation, newObject); |
| + } |
| +} |
| + |
| /// Represents the application continuation called after the evaluation of all |
| /// argument expressions for an invocation. |
| -class ArgumentValueApplication extends ApplicationContinuation { |
| - final ArgumentValue value; |
| +class ValueApplication extends ApplicationContinuation { |
| + final InterpreterValue value; |
| final ApplicationContinuation applicationContinuation; |
| - ArgumentValueApplication(this.value, this.applicationContinuation); |
| + ValueApplication(this.value, this.applicationContinuation); |
| - Configuration call(List<ArgumentValue> args) { |
| + Configuration call(List<InterpreterValue> args) { |
| args.add(value); |
| - return new ArgumentContinuationConfiguration(applicationContinuation, args); |
| + return new ExpressionListContinuationConfiguration( |
| + applicationContinuation, args); |
| } |
| } |
| @@ -557,28 +716,19 @@ class SetterContinuation extends ExpressionContinuation { |
| /// Represents a continuation to be called after the evaluation of an actual |
| /// argument for function invocation. |
| -/// TODO: Add checks for validation of arguments according to spec. |
| -class ActualArgumentsContinuation extends ExpressionContinuation { |
| - final ArgumentExpression currentArgument; |
| - final List<ArgumentExpression> arguments; |
| +class ExpressionListContinuation extends ExpressionContinuation { |
| + final InterpreterExpression currentExpression; |
| + final List<InterpreterExpression> expressions; |
| final Environment environment; |
| final ApplicationContinuation applicationContinuation; |
| - ActualArgumentsContinuation(this.currentArgument, this.arguments, |
| + ExpressionListContinuation(this.currentExpression, this.expressions, |
| this.environment, this.applicationContinuation); |
| Configuration call(Value v) { |
| - ArgumentValue argumentValue; |
| - if (currentArgument is NamedArgumentExpression) { |
| - argumentValue = new NamedArgumentValue( |
| - (currentArgument as NamedArgumentExpression).name, v); |
| - } else { |
| - assert(currentArgument is PositionalArgumentExpression); |
| - argumentValue = new PositionalArgumentValue(v); |
| - } |
| - |
| - return new ArgumentsConfiguration(arguments, environment, |
| - new ArgumentValueApplication(argumentValue, applicationContinuation)); |
| + ValueApplication app = new ValueApplication( |
| + currentExpression.withValue(v), applicationContinuation); |
| + return new ExpressionListConfiguration(expressions, environment, app); |
| } |
| } |
| @@ -814,9 +964,9 @@ class StatementExecuter extends StatementVisitor1<Configuration, State> { |
| statement.accept1(this, state); |
| Configuration eval(Expression expression, ExpressionConfiguration config) => |
| evaluator.eval(expression, config); |
| - Configuration evalArgs( |
| - List<ArgumentExpression> args, Environment env, Continuation cont) => |
| - evaluator.evalArgs(args, env, cont); |
| + Configuration evalList( |
| + List<InterpreterExpression> es, Environment env, Continuation cont) => |
| + evaluator.evalList(es, env, cont); |
| Configuration defaultStatement(Statement node, State state) { |
| throw notImplemented( |
| @@ -1146,9 +1296,9 @@ notImplemented({String m, Object obj}) { |
| /// Creates a list of all argument expressions to be evaluated for the |
| /// invocation of the provided [FunctionNode] containing the actual arguments |
| /// and the optional argument initializers. |
| -List<ArgumentExpression> _createArgumentExpressionList( |
| +List<InterpreterExpression> _createArgumentExpressionList( |
| Arguments providedArgs, FunctionNode fun) { |
| - List<ArgumentExpression> args = <ArgumentExpression>[]; |
| + List<InterpreterExpression> args = <InterpreterExpression>[]; |
| // Add positional arguments expressions. |
| args.addAll(providedArgs.positional |
| .map((Expression e) => new PositionalArgumentExpression(e))); |