Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Unified Diff: pkg/kernel/lib/interpreter/interpreter.dart

Issue 2880343002: Add support for execution of constructor body (Closed)
Patch Set: Refactor Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/kernel/testcases/interpreter/constructor_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/kernel/lib/interpreter/interpreter.dart
diff --git a/pkg/kernel/lib/interpreter/interpreter.dart b/pkg/kernel/lib/interpreter/interpreter.dart
index 28ec77ac289dbea03df028274ce35cea1b7c5bb7..73330c1b15e9da5f9b846f9085bad20bb465094f 100644
--- a/pkg/kernel/lib/interpreter/interpreter.dart
+++ b/pkg/kernel/lib/interpreter/interpreter.dart
@@ -47,6 +47,10 @@ class Environment {
final List<Binding> bindings = <Binding>[];
final Environment parent;
+ Value get thisInstance => (parent != null)
+ ? parent.thisInstance
+ : throw "Invalid reference to 'this' expression";
+
Environment.empty() : parent = null;
Environment(this.parent);
@@ -80,6 +84,13 @@ class Environment {
}
}
+class InstanceEnvironment extends Environment {
+ final ObjectValue _thisInstance;
+ Value get thisInstance => _thisInstance;
+
+ InstanceEnvironment(this._thisInstance, Environment env) : super(env);
+}
+
/// Evaluate expressions.
class Evaluator
extends ExpressionVisitor1<Configuration, ExpressionConfiguration> {
@@ -169,16 +180,8 @@ class Evaluator
Configuration visitConstructorInvocation(
ConstructorInvocation node, ExpressionConfiguration config) {
- // 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.';
- }
-
ApplicationContinuation cont =
new ConstructorInvocationApplication(node.target, config.continuation);
-
var args =
_createArgumentExpressionList(node.arguments, node.target.function);
@@ -222,6 +225,12 @@ class Evaluator
expressions, config.environment, cont);
}
+ Configuration visitThisExpression(
+ ThisExpression node, ExpressionConfiguration config) {
+ return new ContinuationConfiguration(
+ config.continuation, config.environment.thisInstance);
+ }
+
// Evaluation of BasicLiterals.
Configuration visitStringLiteral(
StringLiteral node, ExpressionConfiguration config) {
@@ -335,11 +344,23 @@ class ExitConfiguration extends StatementConfiguration {
ExitConfiguration(this.returnContinuation) : super(null, null);
- Configuration step(StatementExecuter executer) {
+ Configuration step(StatementExecuter _) {
return returnContinuation(Value.nullInstance);
}
}
+class NewInstanceConfiguration extends StatementConfiguration {
+ final ExpressionContinuation continuation;
+ final ObjectValue newObject;
+
+ NewInstanceConfiguration(this.continuation, this.newObject)
+ : super(null, new State.initial());
+
+ Configuration step(StatementExecuter _) {
+ return continuation(newObject);
+ }
+}
+
/// Represents the configuration for applying an [ExpressionContinuation].
class ContinuationConfiguration extends Configuration {
final ExpressionContinuation continuation;
@@ -469,13 +490,13 @@ abstract class Continuation {}
abstract class ApplicationContinuation extends Continuation {
Configuration call(List<InterpreterValue> values);
- /// 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.
+ /// Binds actual argument values to formal parameters of the function in a
+ /// new environment or in the provided initial environment.
/// TODO: Add checks for validation of arguments according to spec.
static Environment createEnvironment(
- FunctionNode function, List<InterpreterValue> args) {
- Environment newEnv = new Environment.empty();
+ FunctionNode function, List<InterpreterValue> args,
+ [Environment parentEnv]) {
+ Environment newEnv = new Environment(parentEnv);
List<PositionalValue> positional = args.reversed
.where((InterpreterValue av) => av is PositionalValue)
.toList();
@@ -534,68 +555,76 @@ class ConstructorInvocationApplication extends ApplicationContinuation {
var newObject =
new ObjectValue(class_, new List<Value>(class_.instanceSize));
- var cont =
- new ObjectInitializationContinuation(constructor, ctrEnv, continuation);
-
- return new ContinuationConfiguration(cont, newObject);
+ return new ObjectInitializationConfiguration(
+ constructor,
+ new InstanceEnvironment(newObject, ctrEnv),
+ new NewInstanceConfiguration(continuation, newObject));
Dmitry Stefantsov 2017/05/18 12:56:51 I think this statement would be hard to translate
}
}
/// Represents the application continuation for redirecting constructor
/// invocation applied on the list of evaluated arguments.
class RedirectingConstructorApplication extends ApplicationContinuation {
- final ObjectValue newObject;
final Constructor constructor;
- final ExpressionContinuation continuation;
+ final Environment environment;
+ final StatementConfiguration configuration;
RedirectingConstructorApplication(
- this.newObject, this.constructor, this.continuation);
+ this.constructor, this.environment, this.configuration);
Configuration call(List<InterpreterValue> argValues) {
+ Value object = environment.thisInstance;
Environment ctrEnv = ApplicationContinuation.createEnvironment(
- constructor.function, argValues);
- var cont =
- new ObjectInitializationContinuation(constructor, ctrEnv, continuation);
- return new ContinuationConfiguration(cont, newObject);
+ constructor.function,
+ argValues,
+ new InstanceEnvironment(object, new Environment.empty()));
+
+ return new ObjectInitializationConfiguration(
+ constructor, ctrEnv, configuration);
}
}
/// Represents the application continuation for super constructor
/// invocation applied on the list of evaluated arguments.
class SuperConstructorApplication extends ApplicationContinuation {
- final ObjectValue newObject;
final Constructor constructor;
- // TODO: remember to execute body of previous ctr.
- final ExpressionContinuation continuation;
+ final Environment environment;
+ final StatementConfiguration configuration;
SuperConstructorApplication(
- this.newObject, this.constructor, this.continuation);
+ this.constructor, this.environment, this.configuration);
Configuration call(List<InterpreterValue> argValues) {
- Environment ctrEnv = ApplicationContinuation.createEnvironment(
- constructor.function, argValues);
- var cont =
- new ObjectInitializationContinuation(constructor, ctrEnv, continuation);
- return new ContinuationConfiguration(cont, newObject);
+ Value object = environment.thisInstance;
+
+ Environment superEnv = ApplicationContinuation.createEnvironment(
+ constructor.function,
+ argValues,
+ new InstanceEnvironment(object, new Environment.empty()));
+
+ return new ObjectInitializationConfiguration(
+ constructor, superEnv, configuration);
}
}
-class ObjectInitializationContinuation extends ExpressionContinuation {
+/// Represents the configuration for execution of initializer and
+/// constructor body statements for initialization of a newly allocated object.
+class ObjectInitializationConfiguration extends Configuration {
final Constructor constructor;
final Environment environment;
- final ExpressionContinuation continuation;
+ final StatementConfiguration configuration;
- ObjectInitializationContinuation(
- this.constructor, this.environment, this.continuation);
+ ObjectInitializationConfiguration(
+ this.constructor, this.environment, this.configuration);
- Configuration call(Value v) {
+ Configuration step(StatementExecuter _) {
if (constructor.initializers.isNotEmpty &&
constructor.initializers.last is RedirectingInitializer) {
// Constructor is redirecting.
Initializer initializer = constructor.initializers.first;
if (initializer is RedirectingInitializer) {
var app = new RedirectingConstructorApplication(
- v, initializer.target, continuation);
+ initializer.target, environment, configuration);
var args = _createArgumentExpressionList(
initializer.arguments, initializer.target.function);
@@ -606,17 +635,26 @@ class ObjectInitializationContinuation extends ExpressionContinuation {
assert(i is LocalInitializer);
}
var class_ = new Class(constructor.enclosingClass.reference);
+ var initEnv = new Environment(environment);
var cont = new InitializerContinuation(
- v, class_, environment, constructor.initializers, continuation);
+ class_, initEnv, constructor.initializers, configuration);
return new ExpressionConfiguration(
(initializer as LocalInitializer).variable.initializer,
- environment,
+ initEnv,
cont);
}
+ // Set head of configurations to be executed to configuration for current
+ // constructor body.
+ var state = new State.initial()
+ .withEnvironment(environment)
+ .withConfiguration(configuration);
+ var bodyConfig =
+ new StatementConfiguration(constructor.function.body, state);
+
// Initialize fields in immediately enclosing class.
- var cont = new InstanceFieldsApplication(
- v, constructor, environment, continuation);
+ var cont =
+ new InstanceFieldsApplication(constructor, environment, bodyConfig);
var fieldExpressions = _createInstanceInitializers(constructor);
return new ExpressionListConfiguration(
@@ -646,44 +684,47 @@ class ObjectInitializationContinuation extends ExpressionContinuation {
/// Represents the application continuation applied on the list of evaluated
/// field initializer expressions.
class InstanceFieldsApplication extends ApplicationContinuation {
- final ObjectValue newObject;
final Constructor constructor;
final Environment environment;
- final ExpressionContinuation expressionContinuation;
+ final StatementConfiguration configuration;
final Class _currentClass;
+ final ObjectValue _newObject;
- InstanceFieldsApplication(this.newObject, this.constructor, this.environment,
- this.expressionContinuation)
- : _currentClass = new Class(constructor.enclosingClass.reference);
+ InstanceFieldsApplication(
+ this.constructor, this.environment, this.configuration)
+ : _currentClass = new Class(constructor.enclosingClass.reference),
+ _newObject = environment.thisInstance;
Configuration call(List<InterpreterValue> fieldValues) {
for (FieldInitializerValue current in fieldValues.reversed) {
- _currentClass.setProperty(newObject, current.field, current.value);
+ _currentClass.setProperty(_newObject, current.field, current.value);
}
if (constructor.initializers.isEmpty) {
- _initializeNullFields(_currentClass, newObject);
- return new ContinuationConfiguration(expressionContinuation, newObject);
+ _initializeNullFields(_currentClass, _newObject);
+ return configuration;
}
+ // Produce next configuration.
if (constructor.initializers.first is SuperInitializer) {
// SuperInitializer appears last in the initializer list.
assert(constructor.initializers.length == 1);
SuperInitializer current = constructor.initializers.first;
var args = _createArgumentExpressionList(
current.arguments, current.target.function);
+
var superApp = new SuperConstructorApplication(
- newObject, current.target, expressionContinuation);
- _initializeNullFields(_currentClass, newObject);
+ current.target, environment, configuration);
+ _initializeNullFields(_currentClass, _newObject);
return new ExpressionListConfiguration(args, environment, superApp);
}
Class class_ = new Class(constructor.enclosingClass.reference);
Environment initEnv = new Environment(environment);
- var cont = new InitializerContinuation(newObject, class_, initEnv,
- constructor.initializers, expressionContinuation);
+ var cont = new InitializerContinuation(
+ class_, initEnv, constructor.initializers, configuration);
return new ExpressionConfiguration(
_getExpression(constructor.initializers.first), initEnv, cont);
}
@@ -692,16 +733,16 @@ class InstanceFieldsApplication extends ApplicationContinuation {
/// Represents the expression continuation applied on the list of evaluated
/// initializer expressions preceding a super call in the list.
class InitializerContinuation extends ExpressionContinuation {
- final ObjectValue newObject;
final Class currentClass;
final Environment initializerEnvironment;
final List<Initializer> initializers;
- final ExpressionContinuation continuation;
+ final StatementConfiguration configuration;
- InitializerContinuation(this.newObject, this.currentClass,
- this.initializerEnvironment, this.initializers, this.continuation);
+ InitializerContinuation(this.currentClass, this.initializerEnvironment,
+ this.initializers, this.configuration);
Configuration call(Value v) {
+ ObjectValue newObject = initializerEnvironment.thisInstance;
Initializer current = initializers.first;
if (current is FieldInitializer) {
currentClass.setProperty(newObject, current.field, v);
@@ -712,9 +753,8 @@ class InitializerContinuation extends ExpressionContinuation {
}
if (initializers.length <= 1) {
- // todo: return configuration for body of ctr.
_initializeNullFields(currentClass, newObject);
- return new ContinuationConfiguration(continuation, newObject);
+ return configuration;
}
Initializer next = initializers[1];
@@ -722,12 +762,11 @@ class InitializerContinuation extends ExpressionContinuation {
if (next is RedirectingInitializer) {
// RedirectingInitializer appears last in the initializer list.
assert(initializers.length == 2);
- var cont = new RedirectingConstructorApplication(
- newObject, next.target, continuation);
+ var app = new RedirectingConstructorApplication(
+ next.target, initializerEnvironment, configuration);
var args =
_createArgumentExpressionList(next.arguments, next.target.function);
- return new ExpressionListConfiguration(
- args, initializerEnvironment, cont);
+ return new ExpressionListConfiguration(args, initializerEnvironment, app);
}
if (next is SuperInitializer) {
@@ -735,15 +774,15 @@ class InitializerContinuation extends ExpressionContinuation {
assert(initializers.length == 2);
var args =
_createArgumentExpressionList(next.arguments, next.target.function);
- var superApp =
- new SuperConstructorApplication(newObject, next.target, continuation);
+ var superApp = new SuperConstructorApplication(
+ next.target, initializerEnvironment, configuration);
_initializeNullFields(currentClass, newObject);
return new ExpressionListConfiguration(
args, initializerEnvironment, superApp);
}
- var cont = new InitializerContinuation(newObject, currentClass,
- initializerEnvironment, initializers.skip(1).toList(), continuation);
+ var cont = new InitializerContinuation(currentClass, initializerEnvironment,
+ initializers.skip(1).toList(), configuration);
return new ExpressionConfiguration(
_getExpression(next), initializerEnvironment, cont);
}
« no previous file with comments | « no previous file | pkg/kernel/testcases/interpreter/constructor_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698