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

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

Issue 2999673002: Implement support for property accessors (Closed)
Patch Set: Merge Created 3 years, 4 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/object_property_access.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 6007a946ac7f17010d482626fede668df43528a8..7f26686d624cb96d621f22b23513e5fcf5e7cee4 100644
--- a/pkg/kernel/lib/interpreter/interpreter.dart
+++ b/pkg/kernel/lib/interpreter/interpreter.dart
@@ -185,7 +185,8 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> {
}
Configuration visitPropertyGet(PropertyGet node, EvalConfiguration config) {
- var cont = new PropertyGetEK(node.name, config.continuation);
+ var cont = new PropertyGetEK(
+ node.name, config.exceptionComponents, config.continuation);
return new EvalConfiguration(
node.receiver, config.environment, config.exceptionComponents, cont);
}
@@ -1040,11 +1041,30 @@ class PrintEK extends ExpressionContinuation {
class PropertyGetEK extends ExpressionContinuation {
final Name name;
+ final ExceptionComponents exceptionComponents;
final ExpressionContinuation continuation;
- PropertyGetEK(this.name, this.continuation);
+ PropertyGetEK(this.name, this.exceptionComponents, this.continuation);
Configuration call(Value receiver) {
+ if (receiver.class_.isMethod(name)) {
+ var method = receiver.class_.lookup(name);
+ // Return the function value with this bound to receiver.
+ var env = new Environment.empty().extendWithThis(receiver);
+ return new ValuePassingConfiguration(
+ continuation, new FunctionValue(method, env));
+ }
+
+ if (receiver.class_.isGetter(name)) {
+ var getter = receiver.class_.lookup(name);
+ var state = new State.initial()
+ .withReturnContinuation(continuation)
+ .withContinuation(new ExitSK(continuation, Value.nullInstance))
+ .withException(exceptionComponents);
+ return new ExecConfiguration(
+ getter.body, new Environment.empty().extendWithThis(receiver), state);
+ }
+
Value propertyValue = receiver.class_.lookupImplicitGetter(name)(receiver);
return new ValuePassingConfiguration(continuation, propertyValue);
}
@@ -1061,7 +1081,8 @@ class PropertySetEK extends ExpressionContinuation {
this.exceptionComponents, this.continuation);
Configuration call(Value receiver) {
- var cont = new SetterEK(receiver, setterName, continuation);
+ var cont =
+ new SetterEK(receiver, setterName, exceptionComponents, continuation);
return new EvalConfiguration(value, environment, exceptionComponents, cont);
}
}
@@ -1069,11 +1090,25 @@ class PropertySetEK extends ExpressionContinuation {
class SetterEK extends ExpressionContinuation {
final Value receiver;
final Name name;
+ final ExceptionComponents exceptionComponents;
final ExpressionContinuation continuation;
- SetterEK(this.receiver, this.name, this.continuation);
+ SetterEK(
+ this.receiver, this.name, this.exceptionComponents, this.continuation);
Configuration call(Value v) {
+ if (receiver.class_.isSetter(name)) {
+ var setter = receiver.class_.lookup(name);
+ var env = new Environment.empty()
+ .extendWithThis(receiver)
+ .extend(setter.positionalParameters.first, v);
+ var state = new State.initial()
+ .withReturnContinuation(continuation)
+ .withContinuation(new ExitSK(continuation, Value.nullInstance))
+ .withException(exceptionComponents);
+ return new ExecConfiguration(setter.body, env, state);
+ }
+
Setter setter = receiver.class_.lookupImplicitSetter(name);
setter(receiver, v);
return new ValuePassingConfiguration(continuation, v);
@@ -1144,25 +1179,34 @@ class MethodInvocationEK extends ExpressionContinuation {
this.exceptionComponents, this.continuation);
Configuration call(Value receiver) {
- if (receiver is FunctionValue) {
- // TODO(zhivkag): use method lookup instead.
- assert(methodName.toString() == 'call');
- var args = _getArgumentExpressions(arguments, receiver.function);
- var acont =
- new FunctionValueA(receiver, exceptionComponents, continuation);
- return new EvalListConfiguration(
- args, environment, exceptionComponents, acont);
+ if (receiver is LiteralValue) {
+ // TODO(zhivkag): CPS method invocation for literals
+ if (arguments.positional.isEmpty) {
+ Value returnValue = receiver.invokeMethod(methodName);
+ return new ValuePassingConfiguration(continuation, returnValue);
+ }
+ var cont = new ArgumentsEK(
+ receiver, methodName, arguments, environment, continuation);
+
+ return new EvalConfiguration(
+ arguments.positional.first, environment, exceptionComponents, cont);
}
- if (arguments.positional.isEmpty) {
- Value returnValue = receiver.invokeMethod(methodName);
- return new ValuePassingConfiguration(continuation, returnValue);
+ FunctionValue fun;
+ if (receiver is FunctionValue) {
+ // TODO(zhivkag): Throw an exception when method is not call.
+ assert(methodName.toString() == "call");
+ fun = receiver;
+ } else {
+ assert(receiver.class_.isMethod(methodName));
+ fun = new FunctionValue(receiver.class_.lookup(methodName),
+ new Environment.empty().extendWithThis(receiver));
}
- var cont = new ArgumentsEK(
- receiver, methodName, arguments, environment, continuation);
- return new EvalConfiguration(
- arguments.positional.first, environment, exceptionComponents, cont);
+ var args = _getArgumentExpressions(arguments, fun.function);
+ var acont = new FunctionValueA(receiver, exceptionComponents, continuation);
+ return new EvalListConfiguration(
+ args, environment, exceptionComponents, acont);
}
}
@@ -1811,9 +1855,16 @@ class Class {
Setter setter = implicitSetters[name];
if (setter != null) return setter;
if (superclass != null) return superclass.lookupImplicitSetter(name);
+ // TODO(zhivkag): Throw NoSuchInstance error instead.
return (Value receiver, Value value) => notImplemented(obj: name);
}
+ FunctionNode lookup(Name name) => methods[name]?.function;
+
+ bool isGetter(Name name) => methods[name]?.isGetter ?? false;
+ bool isSetter(Name name) => methods[name]?.isSetter ?? false;
+ bool isMethod(Name name) => !(methods[name]?.isAccessor ?? true);
+
/// Populates implicit getters and setters for the current class and its
/// superclass recursively.
_populateImplicitGettersAndSetters(ast.Class class_) {
« no previous file with comments | « no previous file | pkg/kernel/testcases/interpreter/object_property_access.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698