Chromium Code Reviews| 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 25 matching lines...) Expand all Loading... | |
| 36 } | 36 } |
| 37 } | 37 } |
| 38 | 38 |
| 39 class Location { | 39 class Location { |
| 40 Value value; | 40 Value value; |
| 41 | 41 |
| 42 Location.empty(); | 42 Location.empty(); |
| 43 Location(this.value); | 43 Location(this.value); |
| 44 } | 44 } |
| 45 | 45 |
| 46 class EnvironmentLocation { | |
| 47 Environment environment; | |
| 48 | |
| 49 EnvironmentLocation.empty(); | |
| 50 EnvironmentLocation(this.environment); | |
| 51 } | |
| 52 | |
| 46 class Binding { | 53 class Binding { |
| 47 final VariableDeclaration variable; | 54 final VariableDeclaration variable; |
| 48 final Location location; | 55 final Location location; |
| 49 | 56 |
| 50 Binding(this.variable, this.location); | 57 Binding(this.variable, this.location); |
| 51 } | 58 } |
| 52 | 59 |
| 53 class Environment { | 60 class Environment { |
| 54 final List<Binding> bindings = <Binding>[]; | 61 final List<Binding> bindings = <Binding>[]; |
| 55 final Environment parent; | 62 final Environment parent; |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 256 config.continuation, config.environment.thisInstance); | 263 config.continuation, config.environment.thisInstance); |
| 257 } | 264 } |
| 258 | 265 |
| 259 Configuration visitThrow(Throw node, EvalConfiguration config) { | 266 Configuration visitThrow(Throw node, EvalConfiguration config) { |
| 260 var cont = new ThrowEK(config.exceptionComponents); | 267 var cont = new ThrowEK(config.exceptionComponents); |
| 261 | 268 |
| 262 return new EvalConfiguration( | 269 return new EvalConfiguration( |
| 263 node.expression, config.environment, config.exceptionComponents, cont); | 270 node.expression, config.environment, config.exceptionComponents, cont); |
| 264 } | 271 } |
| 265 | 272 |
| 273 Configuration visitFunctionExpression( | |
| 274 FunctionExpression node, EvalConfiguration config) { | |
| 275 var val = new FunctionValue( | |
| 276 node.function, new EnvironmentLocation(config.environment)); | |
| 277 return new ValuePassingConfiguration(config.continuation, val); | |
| 278 } | |
| 279 | |
| 266 // Evaluation of BasicLiterals. | 280 // Evaluation of BasicLiterals. |
| 267 Configuration visitStringLiteral( | 281 Configuration visitStringLiteral( |
| 268 StringLiteral node, EvalConfiguration config) { | 282 StringLiteral node, EvalConfiguration config) { |
| 269 return new ValuePassingConfiguration( | 283 return new ValuePassingConfiguration( |
| 270 config.continuation, new StringValue(node.value)); | 284 config.continuation, new StringValue(node.value)); |
| 271 } | 285 } |
| 272 | 286 |
| 273 Configuration visitIntLiteral(IntLiteral node, EvalConfiguration config) { | 287 Configuration visitIntLiteral(IntLiteral node, EvalConfiguration config) { |
| 274 return new ValuePassingConfiguration( | 288 return new ValuePassingConfiguration( |
| 275 config.continuation, new IntValue(node.value)); | 289 config.continuation, new IntValue(node.value)); |
| (...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 835 ? initializer.value | 849 ? initializer.value |
| 836 : (initializer as LocalInitializer).variable.initializer; | 850 : (initializer as LocalInitializer).variable.initializer; |
| 837 | 851 |
| 838 // We start with index = 0 since we are evaluating the expression for the | 852 // We start with index = 0 since we are evaluating the expression for the |
| 839 // first initializer in the initializer list. | 853 // first initializer in the initializer list. |
| 840 var cont = new InitializerListEK(constructor, 0, location, environment, | 854 var cont = new InitializerListEK(constructor, 0, location, environment, |
| 841 exceptionComponents, continuation); | 855 exceptionComponents, continuation); |
| 842 return new EvalConfiguration(expr, environment, exceptionComponents, cont); | 856 return new EvalConfiguration(expr, environment, exceptionComponents, cont); |
| 843 } | 857 } |
| 844 } | 858 } |
| 859 | |
| 860 class FunctionValueA extends ApplicationContinuation { | |
| 861 final FunctionValue receiver; | |
| 862 final ExceptionComponents exceptionComponents; | |
| 863 final ExpressionContinuation returnContinuation; | |
| 864 | |
| 865 FunctionValueA( | |
| 866 this.receiver, this.exceptionComponents, this.returnContinuation); | |
| 867 | |
| 868 Configuration call(List<InterpreterValue> vs) { | |
| 869 Environment env = ApplicationContinuation.createEnvironment( | |
| 870 receiver.function, vs, receiver.location.environment); | |
| 871 var scont = new ExitSK(returnContinuation, Value.nullInstance); | |
| 872 var state = new State(null, exceptionComponents, returnContinuation, scont); | |
| 873 return new ExecConfiguration(receiver.function.body, env, state); | |
| 874 } | |
| 875 } | |
| 876 | |
| 845 // ------------------------------------------------------------------------ | 877 // ------------------------------------------------------------------------ |
| 846 // Expression Continuations | 878 // Expression Continuations |
| 847 // ------------------------------------------------------------------------ | 879 // ------------------------------------------------------------------------ |
| 848 | 880 |
| 849 /// Represents an expression continuation. | 881 /// Represents an expression continuation. |
| 850 /// | 882 /// |
| 851 /// There are various kinds of [ExpressionContinuation]s and their names are | 883 /// There are various kinds of [ExpressionContinuation]s and their names are |
| 852 /// suffixed with "EK". | 884 /// suffixed with "EK". |
| 853 abstract class ExpressionContinuation extends Continuation { | 885 abstract class ExpressionContinuation extends Continuation { |
| 854 Configuration call(Value v); | 886 Configuration call(Value v); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 945 final Arguments arguments; | 977 final Arguments arguments; |
| 946 final Name methodName; | 978 final Name methodName; |
| 947 final Environment environment; | 979 final Environment environment; |
| 948 final ExceptionComponents exceptionComponents; | 980 final ExceptionComponents exceptionComponents; |
| 949 final ExpressionContinuation continuation; | 981 final ExpressionContinuation continuation; |
| 950 | 982 |
| 951 MethodInvocationEK(this.arguments, this.methodName, this.environment, | 983 MethodInvocationEK(this.arguments, this.methodName, this.environment, |
| 952 this.exceptionComponents, this.continuation); | 984 this.exceptionComponents, this.continuation); |
| 953 | 985 |
| 954 Configuration call(Value receiver) { | 986 Configuration call(Value receiver) { |
| 987 if (receiver is FunctionValue) { | |
| 988 // TODO(zhivkag): use method lookup instead. | |
| 989 assert(methodName.toString() == 'call'); | |
| 990 var args = _getArgumentExpressions(arguments, receiver.function); | |
| 991 var acont = | |
| 992 new FunctionValueA(receiver, exceptionComponents, continuation); | |
| 993 return new EvalListConfiguration( | |
| 994 args, environment, exceptionComponents, acont); | |
| 995 } | |
| 996 | |
| 955 if (arguments.positional.isEmpty) { | 997 if (arguments.positional.isEmpty) { |
| 956 Value returnValue = receiver.invokeMethod(methodName); | 998 Value returnValue = receiver.invokeMethod(methodName); |
| 957 return new ValuePassingConfiguration(continuation, returnValue); | 999 return new ValuePassingConfiguration(continuation, returnValue); |
| 958 } | 1000 } |
| 959 var cont = new ArgumentsEK( | 1001 var cont = new ArgumentsEK( |
| 960 receiver, methodName, arguments, environment, continuation); | 1002 receiver, methodName, arguments, environment, continuation); |
| 961 | 1003 |
| 962 return new EvalConfiguration( | 1004 return new EvalConfiguration( |
| 963 arguments.positional.first, environment, exceptionComponents, cont); | 1005 arguments.positional.first, environment, exceptionComponents, cont); |
| 964 } | 1006 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1065 final VariableDeclaration variable; | 1107 final VariableDeclaration variable; |
| 1066 final Expression letBody; | 1108 final Expression letBody; |
| 1067 final Environment environment; | 1109 final Environment environment; |
| 1068 final ExceptionComponents exceptionComponents; | 1110 final ExceptionComponents exceptionComponents; |
| 1069 final ExpressionContinuation continuation; | 1111 final ExpressionContinuation continuation; |
| 1070 | 1112 |
| 1071 LetEK(this.variable, this.letBody, this.environment, this.exceptionComponents, | 1113 LetEK(this.variable, this.letBody, this.environment, this.exceptionComponents, |
| 1072 this.continuation); | 1114 this.continuation); |
| 1073 | 1115 |
| 1074 Configuration call(Value value) { | 1116 Configuration call(Value value) { |
| 1075 var letEnv = new Environment(environment); | 1117 var letEnv = environment.extend(variable, value); |
| 1076 letEnv.extend(variable, value); | |
| 1077 return new EvalConfiguration( | 1118 return new EvalConfiguration( |
| 1078 letBody, letEnv, exceptionComponents, continuation); | 1119 letBody, letEnv, exceptionComponents, continuation); |
| 1079 } | 1120 } |
| 1080 } | 1121 } |
| 1081 | 1122 |
| 1082 /// Represents the continuation for the condition expression in [WhileStatement] . | 1123 /// Represents the continuation for the condition expression in [WhileStatement] . |
| 1083 class WhileConditionEK extends ExpressionContinuation { | 1124 class WhileConditionEK extends ExpressionContinuation { |
| 1084 final Expression condition; | 1125 final Expression condition; |
| 1085 final Statement body; | 1126 final Statement body; |
| 1086 final Environment enclosingEnv; | 1127 final Environment enclosingEnv; |
| (...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1539 VariableDeclaration node, ExecConfiguration conf) { | 1580 VariableDeclaration node, ExecConfiguration conf) { |
| 1540 if (node.initializer != null) { | 1581 if (node.initializer != null) { |
| 1541 var cont = new VariableInitializerEK( | 1582 var cont = new VariableInitializerEK( |
| 1542 node, conf.environment, conf.state.continuation); | 1583 node, conf.environment, conf.state.continuation); |
| 1543 return new EvalConfiguration(node.initializer, conf.environment, | 1584 return new EvalConfiguration(node.initializer, conf.environment, |
| 1544 conf.state.exceptionComponents, cont); | 1585 conf.state.exceptionComponents, cont); |
| 1545 } | 1586 } |
| 1546 return new ForwardConfiguration(conf.state.continuation, | 1587 return new ForwardConfiguration(conf.state.continuation, |
| 1547 conf.environment.extend(node, Value.nullInstance)); | 1588 conf.environment.extend(node, Value.nullInstance)); |
| 1548 } | 1589 } |
| 1590 | |
| 1591 Configuration visitFunctionDeclaration( | |
| 1592 FunctionDeclaration node, ExecConfiguration conf) { | |
| 1593 var fun = new FunctionValue(node.function, new EnvironmentLocation.empty()); | |
| 1594 var newEnv = conf.environment.extend(node.variable, fun); | |
| 1595 fun.location.environment = newEnv; | |
| 1596 return new ForwardConfiguration(conf.state.continuation, newEnv); | |
| 1597 } | |
| 1549 } | 1598 } |
| 1550 | 1599 |
| 1551 // ------------------------------------------------------------------------ | 1600 // ------------------------------------------------------------------------ |
| 1552 // VALUES | 1601 // VALUES |
| 1553 // ------------------------------------------------------------------------ | 1602 // ------------------------------------------------------------------------ |
| 1554 | 1603 |
| 1555 typedef Value Getter(Value receiver); | 1604 typedef Value Getter(Value receiver); |
| 1556 typedef void Setter(Value receiver, Value value); | 1605 typedef void Setter(Value receiver, Value value); |
| 1557 | 1606 |
| 1558 class Class { | 1607 class Class { |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1674 Object get value => this; | 1723 Object get value => this; |
| 1675 | 1724 |
| 1676 ObjectValue(this.class_) : fields = new List<Location>(class_.instanceSize) { | 1725 ObjectValue(this.class_) : fields = new List<Location>(class_.instanceSize) { |
| 1677 for (int i = 0; i < fields.length; i++) { | 1726 for (int i = 0; i < fields.length; i++) { |
| 1678 // Create fresh locations for each field. | 1727 // Create fresh locations for each field. |
| 1679 fields[i] = new Location.empty(); | 1728 fields[i] = new Location.empty(); |
| 1680 } | 1729 } |
| 1681 } | 1730 } |
| 1682 } | 1731 } |
| 1683 | 1732 |
| 1733 class FunctionValue extends Value { | |
| 1734 Class get class_ => throw 'Class for FunctionValue is not defined'; | |
| 1735 List<Location> get fields => throw 'FunctionValue has no fields.'; | |
| 1736 | |
| 1737 FunctionValue get value => this; | |
| 1738 | |
| 1739 final FunctionNode function; | |
| 1740 final EnvironmentLocation location; | |
|
Dmitry Stefantsov
2017/08/16 07:57:54
Why do we need an [EnvironmentLocation] here? As
zhivkag
2017/08/16 08:16:29
The specification is updated w.r.t. the discussion
Dmitry Stefantsov
2017/08/16 08:32:33
Yes, I remember the discussion. However, I may ha
zhivkag
2017/08/16 09:33:13
Thanks for the suggestion, I like this approach be
| |
| 1741 | |
| 1742 FunctionValue(this.function, this.location); | |
| 1743 } | |
| 1744 | |
| 1684 abstract class LiteralValue extends Value { | 1745 abstract class LiteralValue extends Value { |
| 1685 Class get class_ => | 1746 Class get class_ => |
| 1686 notImplemented(m: "Loading class for literal is not implemented."); | 1747 notImplemented(m: "Loading class for literal is not implemented."); |
| 1687 List<Location> get fields => | 1748 List<Location> get fields => |
| 1688 notImplemented(m: "Literal value does not have fields"); | 1749 notImplemented(m: "Literal value does not have fields"); |
| 1689 | 1750 |
| 1690 const LiteralValue(); | 1751 const LiteralValue(); |
| 1691 } | 1752 } |
| 1692 | 1753 |
| 1693 class StringValue extends LiteralValue { | 1754 class StringValue extends LiteralValue { |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1840 /// Initializes all non initialized fields from the provided class to | 1901 /// Initializes all non initialized fields from the provided class to |
| 1841 /// `Value.nullInstance` in the provided value. | 1902 /// `Value.nullInstance` in the provided value. |
| 1842 void _initializeNullFields(Class class_, Value value) { | 1903 void _initializeNullFields(Class class_, Value value) { |
| 1843 int startIndex = class_.superclass?.instanceSize ?? 0; | 1904 int startIndex = class_.superclass?.instanceSize ?? 0; |
| 1844 for (int i = startIndex; i < class_.instanceSize; i++) { | 1905 for (int i = startIndex; i < class_.instanceSize; i++) { |
| 1845 if (value.fields[i].value == null) { | 1906 if (value.fields[i].value == null) { |
| 1846 value.fields[i].value = Value.nullInstance; | 1907 value.fields[i].value = Value.nullInstance; |
| 1847 } | 1908 } |
| 1848 } | 1909 } |
| 1849 } | 1910 } |
| OLD | NEW |