OLD | NEW |
---|---|
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 library kernel.interpreter; | 4 library kernel.interpreter; |
5 | 5 |
6 import '../ast.dart'; | 6 import '../ast.dart'; |
7 import '../ast.dart' as ast show Class; | 7 import '../ast.dart' as ast show Class; |
8 | 8 |
9 import '../log.dart'; | 9 import '../log.dart'; |
10 export '../log.dart'; | 10 export '../log.dart'; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
155 } | 155 } |
156 | 156 |
157 Configuration visitVariableSet(VariableSet node, EvalConfiguration config) { | 157 Configuration visitVariableSet(VariableSet node, EvalConfiguration config) { |
158 var cont = new VariableSetEK( | 158 var cont = new VariableSetEK( |
159 node.variable, config.environment, config.continuation); | 159 node.variable, config.environment, config.continuation); |
160 return new EvalConfiguration( | 160 return new EvalConfiguration( |
161 node.value, config.environment, config.exceptionComponents, cont); | 161 node.value, config.environment, config.exceptionComponents, cont); |
162 } | 162 } |
163 | 163 |
164 Configuration visitPropertyGet(PropertyGet node, EvalConfiguration config) { | 164 Configuration visitPropertyGet(PropertyGet node, EvalConfiguration config) { |
165 var cont = new PropertyGetEK(node.name, config.continuation); | 165 var cont = new PropertyGetEK( |
166 node.name, config.exceptionComponents, config.continuation); | |
166 return new EvalConfiguration( | 167 return new EvalConfiguration( |
167 node.receiver, config.environment, config.exceptionComponents, cont); | 168 node.receiver, config.environment, config.exceptionComponents, cont); |
168 } | 169 } |
169 | 170 |
170 Configuration visitPropertySet(PropertySet node, EvalConfiguration config) { | 171 Configuration visitPropertySet(PropertySet node, EvalConfiguration config) { |
171 var cont = new PropertySetEK(node.value, node.name, config.environment, | 172 var cont = new PropertySetEK(node.value, node.name, config.environment, |
172 config.exceptionComponents, config.continuation); | 173 config.exceptionComponents, config.continuation); |
173 return new EvalConfiguration( | 174 return new EvalConfiguration( |
174 node.receiver, config.environment, config.exceptionComponents, cont); | 175 node.receiver, config.environment, config.exceptionComponents, cont); |
175 } | 176 } |
(...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
956 | 957 |
957 Configuration call(Value v) { | 958 Configuration call(Value v) { |
958 log.info('print(${v.value.runtimeType}: ${v.value})\n'); | 959 log.info('print(${v.value.runtimeType}: ${v.value})\n'); |
959 print(v.value); | 960 print(v.value); |
960 return new ValuePassingConfiguration(continuation, Value.nullInstance); | 961 return new ValuePassingConfiguration(continuation, Value.nullInstance); |
961 } | 962 } |
962 } | 963 } |
963 | 964 |
964 class PropertyGetEK extends ExpressionContinuation { | 965 class PropertyGetEK extends ExpressionContinuation { |
965 final Name name; | 966 final Name name; |
967 final ExceptionComponents exceptionComponents; | |
966 final ExpressionContinuation continuation; | 968 final ExpressionContinuation continuation; |
967 | 969 |
968 PropertyGetEK(this.name, this.continuation); | 970 PropertyGetEK(this.name, this.exceptionComponents, this.continuation); |
969 | 971 |
970 Configuration call(Value receiver) { | 972 Configuration call(Value receiver) { |
973 if (receiver.class_.isMethod(name)) { | |
974 var method = receiver.class_.lookup(name); | |
975 // Return the function value with this bound to receiver. | |
976 method.location.environment = | |
977 new Environment.empty().extendWithThis(receiver); | |
978 return new ValuePassingConfiguration(continuation, method); | |
979 } | |
980 | |
981 if (receiver.class_.isGetter(name)) { | |
982 var getter = receiver.class_.lookup(name); | |
983 var state = new State.initial() | |
984 .withReturnContinuation(continuation) | |
985 .withContinuation(new ExitSK(continuation, Value.nullInstance)) | |
986 .withException(exceptionComponents); | |
987 return new ExecConfiguration(getter.function.body, | |
988 new Environment.empty().extendWithThis(receiver), state); | |
989 } | |
990 | |
971 Value propertyValue = receiver.class_.lookupImplicitGetter(name)(receiver); | 991 Value propertyValue = receiver.class_.lookupImplicitGetter(name)(receiver); |
972 return new ValuePassingConfiguration(continuation, propertyValue); | 992 return new ValuePassingConfiguration(continuation, propertyValue); |
973 } | 993 } |
974 } | 994 } |
975 | 995 |
976 class PropertySetEK extends ExpressionContinuation { | 996 class PropertySetEK extends ExpressionContinuation { |
977 final Expression value; | 997 final Expression value; |
978 final Name setterName; | 998 final Name setterName; |
979 final Environment environment; | 999 final Environment environment; |
980 final ExceptionComponents exceptionComponents; | 1000 final ExceptionComponents exceptionComponents; |
981 final ExpressionContinuation continuation; | 1001 final ExpressionContinuation continuation; |
982 | 1002 |
983 PropertySetEK(this.value, this.setterName, this.environment, | 1003 PropertySetEK(this.value, this.setterName, this.environment, |
984 this.exceptionComponents, this.continuation); | 1004 this.exceptionComponents, this.continuation); |
985 | 1005 |
986 Configuration call(Value receiver) { | 1006 Configuration call(Value receiver) { |
987 var cont = new SetterEK(receiver, setterName, continuation); | 1007 var cont = |
1008 new SetterEK(receiver, setterName, exceptionComponents, continuation); | |
988 return new EvalConfiguration(value, environment, exceptionComponents, cont); | 1009 return new EvalConfiguration(value, environment, exceptionComponents, cont); |
989 } | 1010 } |
990 } | 1011 } |
991 | 1012 |
992 class SetterEK extends ExpressionContinuation { | 1013 class SetterEK extends ExpressionContinuation { |
993 final Value receiver; | 1014 final Value receiver; |
994 final Name name; | 1015 final Name name; |
1016 final ExceptionComponents exceptionComponents; | |
995 final ExpressionContinuation continuation; | 1017 final ExpressionContinuation continuation; |
996 | 1018 |
997 SetterEK(this.receiver, this.name, this.continuation); | 1019 SetterEK( |
1020 this.receiver, this.name, this.exceptionComponents, this.continuation); | |
998 | 1021 |
999 Configuration call(Value v) { | 1022 Configuration call(Value v) { |
1023 if (receiver.class_.isSetter(name)) { | |
1024 var setter = receiver.class_.lookup(name); | |
1025 var env = new Environment.empty() | |
1026 .extendWithThis(receiver) | |
1027 .extend(setter.function.positionalParameters.first, v); | |
1028 var state = new State.initial() | |
1029 .withReturnContinuation(continuation) | |
1030 .withContinuation(new ExitSK(continuation, Value.nullInstance)) | |
1031 .withException(exceptionComponents); | |
1032 return new ExecConfiguration(setter.function.body, env, state); | |
1033 } | |
1034 | |
1000 Setter setter = receiver.class_.lookupImplicitSetter(name); | 1035 Setter setter = receiver.class_.lookupImplicitSetter(name); |
1001 setter(receiver, v); | 1036 setter(receiver, v); |
1002 return new ValuePassingConfiguration(continuation, v); | 1037 return new ValuePassingConfiguration(continuation, v); |
1003 } | 1038 } |
1004 } | 1039 } |
1005 | 1040 |
1006 /// Represents a continuation to be called after the evaluation of an actual | 1041 /// Represents a continuation to be called after the evaluation of an actual |
1007 /// argument for function invocation. | 1042 /// argument for function invocation. |
1008 class ExpressionListEK extends ExpressionContinuation { | 1043 class ExpressionListEK extends ExpressionContinuation { |
1009 final InterpreterExpression currentExpression; | 1044 final InterpreterExpression currentExpression; |
(...skipping 17 matching lines...) Expand all Loading... | |
1027 final Arguments arguments; | 1062 final Arguments arguments; |
1028 final Name methodName; | 1063 final Name methodName; |
1029 final Environment environment; | 1064 final Environment environment; |
1030 final ExceptionComponents exceptionComponents; | 1065 final ExceptionComponents exceptionComponents; |
1031 final ExpressionContinuation continuation; | 1066 final ExpressionContinuation continuation; |
1032 | 1067 |
1033 MethodInvocationEK(this.arguments, this.methodName, this.environment, | 1068 MethodInvocationEK(this.arguments, this.methodName, this.environment, |
1034 this.exceptionComponents, this.continuation); | 1069 this.exceptionComponents, this.continuation); |
1035 | 1070 |
1036 Configuration call(Value receiver) { | 1071 Configuration call(Value receiver) { |
1037 if (receiver is FunctionValue) { | 1072 if (receiver is LiteralValue) { |
1038 // TODO(zhivkag): use method lookup instead. | 1073 // TODO(zhivkag): CPS method invocation for literals |
1039 assert(methodName.toString() == 'call'); | 1074 if (arguments.positional.isEmpty) { |
1040 var args = _getArgumentExpressions(arguments, receiver.function); | 1075 Value returnValue = receiver.invokeMethod(methodName); |
1041 var acont = | 1076 return new ValuePassingConfiguration(continuation, returnValue); |
1042 new FunctionValueA(receiver, exceptionComponents, continuation); | 1077 } |
1043 return new EvalListConfiguration( | 1078 var cont = new ArgumentsEK( |
1044 args, environment, exceptionComponents, acont); | 1079 receiver, methodName, arguments, environment, continuation); |
1080 | |
1081 return new EvalConfiguration( | |
1082 arguments.positional.first, environment, exceptionComponents, cont); | |
1045 } | 1083 } |
1046 | 1084 |
1047 if (arguments.positional.isEmpty) { | 1085 FunctionValue fun; |
1048 Value returnValue = receiver.invokeMethod(methodName); | 1086 if (receiver is FunctionValue) { |
1049 return new ValuePassingConfiguration(continuation, returnValue); | 1087 assert(methodName.toString() == "call"); |
Dmitry Stefantsov
2017/08/16 08:48:55
Maybe it's better to throw an exception here using
zhivkag
2017/08/16 09:39:49
Added a TODO.
| |
1088 fun = receiver; | |
1089 } else { | |
1090 assert(receiver.class_.isMethod(methodName)); | |
1091 fun = receiver.class_.lookup(methodName); | |
1092 fun.location.environment = | |
1093 new Environment.empty().extendWithThis(receiver); | |
1050 } | 1094 } |
1051 var cont = new ArgumentsEK( | |
1052 receiver, methodName, arguments, environment, continuation); | |
1053 | 1095 |
1054 return new EvalConfiguration( | 1096 var args = _getArgumentExpressions(arguments, fun.function); |
1055 arguments.positional.first, environment, exceptionComponents, cont); | 1097 var acont = new FunctionValueA(receiver, exceptionComponents, continuation); |
1098 return new EvalListConfiguration( | |
1099 args, environment, exceptionComponents, acont); | |
1056 } | 1100 } |
1057 } | 1101 } |
1058 | 1102 |
1059 class ArgumentsEK extends ExpressionContinuation { | 1103 class ArgumentsEK extends ExpressionContinuation { |
1060 final Value receiver; | 1104 final Value receiver; |
1061 final Name methodName; | 1105 final Name methodName; |
1062 final Arguments arguments; | 1106 final Arguments arguments; |
1063 final Environment environment; | 1107 final Environment environment; |
1064 final ExpressionContinuation continuation; | 1108 final ExpressionContinuation continuation; |
1065 | 1109 |
(...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1695 Getter getter = implicitGetters[name]; | 1739 Getter getter = implicitGetters[name]; |
1696 if (getter != null) return getter; | 1740 if (getter != null) return getter; |
1697 if (superclass != null) return superclass.lookupImplicitGetter(name); | 1741 if (superclass != null) return superclass.lookupImplicitGetter(name); |
1698 return (Value receiver) => notImplemented(obj: name); | 1742 return (Value receiver) => notImplemented(obj: name); |
1699 } | 1743 } |
1700 | 1744 |
1701 Setter lookupImplicitSetter(Name name) { | 1745 Setter lookupImplicitSetter(Name name) { |
1702 Setter setter = implicitSetters[name]; | 1746 Setter setter = implicitSetters[name]; |
1703 if (setter != null) return setter; | 1747 if (setter != null) return setter; |
1704 if (superclass != null) return superclass.lookupImplicitSetter(name); | 1748 if (superclass != null) return superclass.lookupImplicitSetter(name); |
1749 // todo: throw NoSuchInstance error instead. | |
Dmitry Stefantsov
2017/08/16 08:48:55
todo ==> TODO
zhivkag
2017/08/16 09:39:49
Done.
| |
1705 return (Value receiver, Value value) => notImplemented(obj: name); | 1750 return (Value receiver, Value value) => notImplemented(obj: name); |
1706 } | 1751 } |
1707 | 1752 |
1753 FunctionValue lookup(Name name) { | |
1754 var fun = methods[name]?.function; | |
1755 assert(fun != null); | |
1756 return new FunctionValue(fun, new EnvironmentLocation.empty()); | |
1757 } | |
1758 | |
1759 bool isGetter(Name name) => methods[name]?.isGetter ?? false; | |
1760 bool isSetter(Name name) => methods[name]?.isSetter ?? false; | |
1761 bool isMethod(Name name) => !(methods[name]?.isAccessor ?? true); | |
1762 | |
1708 /// Populates implicit getters and setters for the current class and its | 1763 /// Populates implicit getters and setters for the current class and its |
1709 /// superclass recursively. | 1764 /// superclass recursively. |
1710 _populateImplicitGettersAndSetters(ast.Class class_) { | 1765 _populateImplicitGettersAndSetters(ast.Class class_) { |
1711 if (class_.superclass != null) { | 1766 if (class_.superclass != null) { |
1712 _populateImplicitGettersAndSetters(class_.superclass); | 1767 _populateImplicitGettersAndSetters(class_.superclass); |
1713 } | 1768 } |
1714 | 1769 |
1715 for (Field f in class_.fields) { | 1770 for (Field f in class_.fields) { |
1716 if (f.isStatic) continue; | 1771 if (f.isStatic) continue; |
1717 assert(f.hasImplicitGetter); | 1772 assert(f.hasImplicitGetter); |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1954 /// Initializes all non initialized fields from the provided class to | 2009 /// Initializes all non initialized fields from the provided class to |
1955 /// `Value.nullInstance` in the provided value. | 2010 /// `Value.nullInstance` in the provided value. |
1956 void _initializeNullFields(Class class_, Value value) { | 2011 void _initializeNullFields(Class class_, Value value) { |
1957 int startIndex = class_.superclass?.instanceSize ?? 0; | 2012 int startIndex = class_.superclass?.instanceSize ?? 0; |
1958 for (int i = startIndex; i < class_.instanceSize; i++) { | 2013 for (int i = startIndex; i < class_.instanceSize; i++) { |
1959 if (value.fields[i].value == null) { | 2014 if (value.fields[i].value == null) { |
1960 value.fields[i].value = Value.nullInstance; | 2015 value.fields[i].value = Value.nullInstance; |
1961 } | 2016 } |
1962 } | 2017 } |
1963 } | 2018 } |
OLD | NEW |