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

Side by Side Diff: pkg/kernel/lib/interpreter/interpreter.dart

Issue 2880343002: Add support for execution of constructor body (Closed)
Patch Set: 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 unified diff | Download patch
« no previous file with comments | « no previous file | pkg/kernel/testcases/interpreter/constructor_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
36 } 36 }
37 } 37 }
38 38
39 class Binding { 39 class Binding {
40 final VariableDeclaration variable; 40 final VariableDeclaration variable;
41 Value value; 41 Value value;
42 42
43 Binding(this.variable, this.value); 43 Binding(this.variable, this.value);
44 } 44 }
45 45
46 class Environment { 46 abstract class Environment {
Dmitry Stefantsov 2017/05/16 08:07:50 I'd rather handle the case of 'this' with a couple
zhivkag 2017/05/16 10:51:13 I see the limitations the previous hierarchy intro
Dmitry Stefantsov 2017/05/16 11:06:52 To me, additional methods look simpler and easier
47 final List<Binding> bindings = <Binding>[]; 47 final List<Binding> bindings = <Binding>[];
48 final Environment parent; 48 Environment get parent;
49 49
50 Environment.empty() : parent = null; 50 Environment();
51 Environment(this.parent); 51 factory Environment.withParent(Environment parent) {
52 if (parent is StaticEnvironment) {
53 return new StaticEnvironment(parent);
54 }
55 assert(parent is InstanceEnvironment);
56 return new InstanceEnvironment(parent);
57 }
52 58
53 bool contains(VariableDeclaration variable) { 59 bool contains(VariableDeclaration variable) {
54 for (Binding b in bindings.reversed) { 60 for (Binding b in bindings.reversed) {
55 if (identical(b.variable, variable)) return true; 61 if (identical(b.variable, variable)) return true;
56 } 62 }
57 return parent?.contains(variable) ?? false; 63 return parent?.contains(variable) ?? false;
58 } 64 }
59 65
60 Binding lookupBinding(VariableDeclaration variable) { 66 Binding lookupBinding(VariableDeclaration variable) {
61 assert(contains(variable)); 67 assert(contains(variable));
(...skipping 11 matching lines...) Expand all
73 assert(contains(variable)); 79 assert(contains(variable));
74 lookupBinding(variable).value = value; 80 lookupBinding(variable).value = value;
75 } 81 }
76 82
77 void expand(VariableDeclaration variable, Value value) { 83 void expand(VariableDeclaration variable, Value value) {
78 assert(!contains(variable)); 84 assert(!contains(variable));
79 bindings.add(new Binding(variable, value)); 85 bindings.add(new Binding(variable, value));
80 } 86 }
81 } 87 }
82 88
89 class StaticEnvironment extends Environment {
90 final StaticEnvironment parent;
91 StaticEnvironment.empty() : parent = null;
92 StaticEnvironment(this.parent);
93 }
94
95 class InstanceEnvironment extends Environment {
96 final Value _thisInstance;
97 final InstanceEnvironment parent;
98
99 get thisInstance => _thisInstance ?? parent.thisInstance;
Dmitry Stefantsov 2017/05/16 08:07:50 Just in case we decide to go with environment clas
zhivkag 2017/05/16 10:51:13 Done.
100
101 InstanceEnvironment.initial(this._thisInstance) : parent = null;
102 InstanceEnvironment(this.parent) : _thisInstance = null;
103 }
104
83 /// Evaluate expressions. 105 /// Evaluate expressions.
84 class Evaluator 106 class Evaluator
85 extends ExpressionVisitor1<Configuration, ExpressionConfiguration> { 107 extends ExpressionVisitor1<Configuration, ExpressionConfiguration> {
86 Configuration eval(Expression expr, ExpressionConfiguration config) => 108 Configuration eval(Expression expr, ExpressionConfiguration config) =>
87 expr.accept1(this, config); 109 expr.accept1(this, config);
88 110
89 Configuration evalList(List<InterpreterExpression> list, Environment env, 111 Configuration evalList(List<InterpreterExpression> list, Environment env,
90 ApplicationContinuation cont) { 112 ApplicationContinuation cont) {
91 if (list.isNotEmpty) { 113 if (list.isNotEmpty) {
92 return new ExpressionConfiguration(list.first.expression, env, 114 return new ExpressionConfiguration(list.first.expression, env,
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 // Currently supports only method invocation with <2 arguments and is used 184 // Currently supports only method invocation with <2 arguments and is used
163 // to evaluate implemented operators for int, double and String values. 185 // to evaluate implemented operators for int, double and String values.
164 var cont = new MethodInvocationContinuation( 186 var cont = new MethodInvocationContinuation(
165 node.arguments, node.name, config.environment, config.continuation); 187 node.arguments, node.name, config.environment, config.continuation);
166 188
167 return new ExpressionConfiguration(node.receiver, config.environment, cont); 189 return new ExpressionConfiguration(node.receiver, config.environment, cont);
168 } 190 }
169 191
170 Configuration visitConstructorInvocation( 192 Configuration visitConstructorInvocation(
171 ConstructorInvocation node, ExpressionConfiguration config) { 193 ConstructorInvocation node, ExpressionConfiguration config) {
172 // Currently, the bodies of the constructors are not executed.
173 // Currently initializer list is executed only for redirecting
174 // constructors.
175 if (node.target.function.body is! EmptyStatement) {
176 throw 'Execution for body of constructor is not implemented.';
177 }
178
179 var class_ = new Class(node.target.enclosingClass.reference); 194 var class_ = new Class(node.target.enclosingClass.reference);
180 var newObject = 195 var newObject =
181 new ObjectValue(class_, new List<Value>(class_.instanceSize)); 196 new ObjectValue(class_, new List<Value>(class_.instanceSize));
182 197 var nextConfig =
198 new NewInstanceConfiguration(config.continuation, newObject);
183 ApplicationContinuation cont = new ConstructorInvocationApplication( 199 ApplicationContinuation cont = new ConstructorInvocationApplication(
184 newObject, node.target, config.continuation); 200 newObject, node.target, nextConfig);
Dmitry Stefantsov 2017/05/16 08:07:50 I think it's better to keep 'config.continuation'
zhivkag 2017/05/16 10:51:13 Acknowledged.
185
186 var args = 201 var args =
187 _createArgumentExpressionList(node.arguments, node.target.function); 202 _createArgumentExpressionList(node.arguments, node.target.function);
188 203
189 return new ExpressionListConfiguration(args, config.environment, cont); 204 return new ExpressionListConfiguration(args, config.environment, cont);
190 } 205 }
191 206
192 Configuration visitNot(Not node, ExpressionConfiguration config) { 207 Configuration visitNot(Not node, ExpressionConfiguration config) {
193 return new ExpressionConfiguration(node.operand, config.environment, 208 return new ExpressionConfiguration(node.operand, config.environment,
194 new NotContinuation(config.continuation)); 209 new NotContinuation(config.continuation));
195 } 210 }
(...skipping 21 matching lines...) Expand all
217 } 232 }
218 233
219 Configuration visitStringConcatenation( 234 Configuration visitStringConcatenation(
220 StringConcatenation node, ExpressionConfiguration config) { 235 StringConcatenation node, ExpressionConfiguration config) {
221 var cont = new StringConcatenationContinuation( 236 var cont = new StringConcatenationContinuation(
222 node.expressions, config.environment, config.continuation); 237 node.expressions, config.environment, config.continuation);
223 return new ExpressionConfiguration( 238 return new ExpressionConfiguration(
224 node.expressions.first, config.environment, cont); 239 node.expressions.first, config.environment, cont);
225 } 240 }
226 241
242 Configuration visitThisExpression(
243 ThisExpression node, ExpressionConfiguration config) {
244 InstanceEnvironment env = config.environment;
245 return new ContinuationConfiguration(config.continuation, env.thisInstance);
246 }
247
227 // Evaluation of BasicLiterals. 248 // Evaluation of BasicLiterals.
228 Configuration visitStringLiteral( 249 Configuration visitStringLiteral(
229 StringLiteral node, ExpressionConfiguration config) { 250 StringLiteral node, ExpressionConfiguration config) {
230 return new ContinuationConfiguration( 251 return new ContinuationConfiguration(
231 config.continuation, new StringValue(node.value)); 252 config.continuation, new StringValue(node.value));
232 } 253 }
233 254
234 Configuration visitIntLiteral( 255 Configuration visitIntLiteral(
235 IntLiteral node, ExpressionConfiguration config) { 256 IntLiteral node, ExpressionConfiguration config) {
236 return new ContinuationConfiguration( 257 return new ContinuationConfiguration(
(...skipping 30 matching lines...) Expand all
267 class State { 288 class State {
268 final Environment environment; 289 final Environment environment;
269 final Label labels; 290 final Label labels;
270 final StatementConfiguration statementConfiguration; 291 final StatementConfiguration statementConfiguration;
271 292
272 final ExpressionContinuation returnContinuation; 293 final ExpressionContinuation returnContinuation;
273 294
274 State(this.environment, this.labels, this.statementConfiguration, 295 State(this.environment, this.labels, this.statementConfiguration,
275 this.returnContinuation); 296 this.returnContinuation);
276 297
277 State.initial() : this(new Environment.empty(), null, null, null); 298 State.initial() : this(new StaticEnvironment.empty(), null, null, null);
278 299
279 State withEnvironment(Environment env) { 300 State withEnvironment(Environment env) {
280 return new State(env, labels, statementConfiguration, returnContinuation); 301 return new State(env, labels, statementConfiguration, returnContinuation);
281 } 302 }
282 303
283 State withBreak(Statement stmt) { 304 State withBreak(Statement stmt) {
284 Label breakLabels = new Label(stmt, statementConfiguration, labels); 305 Label breakLabels = new Label(stmt, statementConfiguration, labels);
285 return new State( 306 return new State(
286 environment, breakLabels, statementConfiguration, returnContinuation); 307 environment, breakLabels, statementConfiguration, returnContinuation);
287 } 308 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 351
331 Configuration step(StatementExecuter executer) => 352 Configuration step(StatementExecuter executer) =>
332 executer.exec(statement, state); 353 executer.exec(statement, state);
333 } 354 }
334 355
335 class ExitConfiguration extends StatementConfiguration { 356 class ExitConfiguration extends StatementConfiguration {
336 final ExpressionContinuation returnContinuation; 357 final ExpressionContinuation returnContinuation;
337 358
338 ExitConfiguration(this.returnContinuation) : super(null, null); 359 ExitConfiguration(this.returnContinuation) : super(null, null);
339 360
340 Configuration step(StatementExecuter executer) { 361 Configuration step(StatementExecuter _) {
341 return returnContinuation(Value.nullInstance); 362 return returnContinuation(Value.nullInstance);
342 } 363 }
343 } 364 }
344 365
366 class NewInstanceConfiguration extends StatementConfiguration {
Dmitry Stefantsov 2017/05/16 08:07:50 In case we decide to keep the intermediate configu
Dmitry Stefantsov 2017/05/16 09:59:24 Thank you for the explanation offline about the 'N
zhivkag 2017/05/16 10:51:13 I assume some of the other comments were clarified
367 final ExpressionContinuation continuation;
368 final ObjectValue newObject;
369
370 NewInstanceConfiguration(this.continuation, this.newObject)
371 : super(null, new State.initial());
372
373 Configuration step(StatementExecuter _) {
374 return continuation(newObject);
375 }
376 }
377
345 /// Represents the configuration for applying an [ExpressionContinuation]. 378 /// Represents the configuration for applying an [ExpressionContinuation].
346 class ContinuationConfiguration extends Configuration { 379 class ContinuationConfiguration extends Configuration {
347 final ExpressionContinuation continuation; 380 final ExpressionContinuation continuation;
348 final Value value; 381 final Value value;
349 382
350 ContinuationConfiguration(this.continuation, this.value); 383 ContinuationConfiguration(this.continuation, this.value);
351 384
352 Configuration step(StatementExecuter _) => continuation(value); 385 Configuration step(StatementExecuter _) => continuation(value);
353 } 386 }
354 387
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 FieldInitializerValue(this.field, this.value); 497 FieldInitializerValue(this.field, this.value);
465 } 498 }
466 499
467 abstract class Continuation {} 500 abstract class Continuation {}
468 501
469 /// Represents the continuation called after the evaluation of argument 502 /// Represents the continuation called after the evaluation of argument
470 /// expressions. 503 /// expressions.
471 abstract class ApplicationContinuation extends Continuation { 504 abstract class ApplicationContinuation extends Continuation {
472 Configuration call(List<InterpreterValue> values); 505 Configuration call(List<InterpreterValue> values);
473 506
474 /// Creates an environment binding actual argument values to formal parameters 507 /// Binds actual argument values to formal parameters of the function in a
475 /// of the function in a new environment, which is used to execute the 508 /// new environment or in the provided initial environment.
476 /// body od the function.
477 /// TODO: Add checks for validation of arguments according to spec. 509 /// TODO: Add checks for validation of arguments according to spec.
478 static Environment createEnvironment( 510 static Environment createEnvironment(
479 FunctionNode function, List<InterpreterValue> args) { 511 FunctionNode function, List<InterpreterValue> args,
480 Environment newEnv = new Environment.empty(); 512 [initialEnv]) {
513 Environment newEnv = initialEnv ?? new StaticEnvironment.empty();
481 List<PositionalArgumentValue> positional = args.reversed 514 List<PositionalArgumentValue> positional = args.reversed
482 .where((InterpreterValue av) => av is PositionalArgumentValue) 515 .where((InterpreterValue av) => av is PositionalArgumentValue)
483 .toList(); 516 .toList();
484 517
485 // Add positional parameters. 518 // Add positional parameters.
486 for (int i = 0; i < positional.length; ++i) { 519 for (int i = 0; i < positional.length; ++i) {
487 newEnv.expand(function.positionalParameters[i], positional[i].value); 520 newEnv.expand(function.positionalParameters[i], positional[i].value);
488 } 521 }
489 522
490 Map<String, Value> named = new Map.fromIterable( 523 Map<String, Value> named = new Map.fromIterable(
(...skipping 27 matching lines...) Expand all
518 .withEnvironment(functionEnv); 551 .withEnvironment(functionEnv);
519 return new StatementConfiguration(function.body, bodyState); 552 return new StatementConfiguration(function.body, bodyState);
520 } 553 }
521 } 554 }
522 555
523 /// Represents the application continuation for constructor invocation applied 556 /// Represents the application continuation for constructor invocation applied
524 /// on the list of evaluated arguments. 557 /// on the list of evaluated arguments.
525 class ConstructorInvocationApplication extends ApplicationContinuation { 558 class ConstructorInvocationApplication extends ApplicationContinuation {
526 final ObjectValue newObject; 559 final ObjectValue newObject;
527 final Constructor constructor; 560 final Constructor constructor;
528 final ExpressionContinuation expressionContinuation; 561 final StatementConfiguration configuration;
Dmitry Stefantsov 2017/05/16 08:07:50 I think it's better to keep 'ExpressionContinuatio
zhivkag 2017/05/16 10:51:13 Acknowledged.
529 562
530 ConstructorInvocationApplication( 563 ConstructorInvocationApplication(
531 this.newObject, this.constructor, this.expressionContinuation); 564 this.newObject, this.constructor, this.configuration);
532 565
533 Configuration call(List<InterpreterValue> argValues) { 566 Configuration call(List<InterpreterValue> argValues) {
534 Environment ctrEnv = ApplicationContinuation.createEnvironment( 567 var bodyEnv = new InstanceEnvironment.initial(newObject);
535 constructor.function, argValues); 568 InstanceEnvironment ctrEnv = ApplicationContinuation.createEnvironment(
569 constructor.function, argValues, bodyEnv);
536 570
537 if (constructor.initializers.isNotEmpty && 571 if (constructor.initializers.isNotEmpty &&
538 constructor.initializers.last is RedirectingInitializer) { 572 constructor.initializers.last is RedirectingInitializer) {
539 // Constructor is redirecting. 573 // Constructor is redirecting.
540 Initializer initializer = constructor.initializers.first; 574 Initializer initializer = constructor.initializers.first;
541 if (initializer is RedirectingInitializer) { 575 if (initializer is RedirectingInitializer) {
542 var app = new ConstructorInvocationApplication( 576 var app = new ConstructorInvocationApplication(
543 newObject, initializer.target, expressionContinuation); 577 newObject, initializer.target, configuration);
544 var args = _createArgumentExpressionList( 578 var args = _createArgumentExpressionList(
545 initializer.arguments, initializer.target.function); 579 initializer.arguments, initializer.target.function);
546 580
547 return new ExpressionListConfiguration(args, ctrEnv, app); 581 return new ExpressionListConfiguration(args, ctrEnv, app);
548 } 582 }
549 // Redirecting initializer is not the only initializer. 583 // Redirecting initializer is not the only initializer.
550 for (Initializer i in constructor.initializers.reversed.skip(1)) { 584 for (Initializer i in constructor.initializers.reversed.skip(1)) {
551 assert(i is LocalInitializer); 585 assert(i is LocalInitializer);
552 } 586 }
553 var class_ = new Class(constructor.enclosingClass.reference); 587 var class_ = new Class(constructor.enclosingClass.reference);
554 var cont = new InitializerContinuation(newObject, class_, ctrEnv, 588 var cont = new InitializerContinuation(
555 constructor.initializers, expressionContinuation); 589 newObject, class_, ctrEnv, constructor.initializers, configuration);
556 return new ExpressionConfiguration( 590 return new ExpressionConfiguration(
557 (initializer as LocalInitializer).variable.initializer, ctrEnv, cont); 591 (initializer as LocalInitializer).variable.initializer, ctrEnv, cont);
558 } 592 }
559 593
594 var newState = configuration.state
595 .withEnvironment(bodyEnv)
596 .withConfiguration(configuration);
Dmitry Stefantsov 2017/05/16 08:07:50 Here we might have used 'withExpressionContinuatio
zhivkag 2017/05/16 10:51:13 Acknowledged.
597
598 // Set head of configurations to be executed to configuration for current
599 // constructor body.
600 var nextConfiguration =
601 new StatementConfiguration(constructor.function.body, newState);
Dmitry Stefantsov 2017/05/16 08:07:50 Here we may assume that the body of constructor ha
zhivkag 2017/05/16 10:51:13 Acknowledged.
602
560 // Initialize fields in immediately enclosing class. 603 // Initialize fields in immediately enclosing class.
561 var cont = new InstanceFieldsApplication( 604 var cont = new InstanceFieldsApplication(
562 newObject, constructor, ctrEnv, expressionContinuation); 605 newObject, constructor, ctrEnv, nextConfiguration);
563 var fieldExpressions = _createInstanceInitializers(constructor); 606 var fieldExpressions = _createInstanceInitializers(constructor);
564 607
565 return new ExpressionListConfiguration(fieldExpressions, ctrEnv, cont); 608 return new ExpressionListConfiguration(fieldExpressions, ctrEnv, cont);
566 } 609 }
567 610
568 /// Creates a list of expressions for instance field initializers in 611 /// Creates a list of expressions for instance field initializers in
569 /// immediately enclosing class. 612 /// immediately enclosing class.
570 static List<InterpreterExpression> _createInstanceInitializers( 613 static List<InterpreterExpression> _createInstanceInitializers(
571 Constructor ctr) { 614 Constructor ctr) {
572 Class currentClass = new Class(ctr.enclosingClass.reference); 615 Class currentClass = new Class(ctr.enclosingClass.reference);
(...skipping 10 matching lines...) Expand all
583 626
584 return es; 627 return es;
585 } 628 }
586 } 629 }
587 630
588 /// Represents the application continuation applied on the list of evaluated 631 /// Represents the application continuation applied on the list of evaluated
589 /// field initializer expressions. 632 /// field initializer expressions.
590 class InstanceFieldsApplication extends ApplicationContinuation { 633 class InstanceFieldsApplication extends ApplicationContinuation {
591 final ObjectValue newObject; 634 final ObjectValue newObject;
592 final Constructor constructor; 635 final Constructor constructor;
593 final Environment environment; 636 final InstanceEnvironment environment;
594 final ExpressionContinuation expressionContinuation; 637 final StatementConfiguration configuration;
595 638
596 final Class _currentClass; 639 final Class _currentClass;
597 640
598 InstanceFieldsApplication(this.newObject, this.constructor, this.environment, 641 InstanceFieldsApplication(
599 this.expressionContinuation) 642 this.newObject, this.constructor, this.environment, this.configuration)
600 : _currentClass = new Class(constructor.enclosingClass.reference); 643 : _currentClass = new Class(constructor.enclosingClass.reference);
601 644
602 Configuration call(List<InterpreterValue> fieldValues) { 645 Configuration call(List<InterpreterValue> fieldValues) {
603 for (FieldInitializerValue current in fieldValues.reversed) { 646 for (FieldInitializerValue current in fieldValues.reversed) {
604 _currentClass.setProperty(newObject, current.field, current.value); 647 _currentClass.setProperty(newObject, current.field, current.value);
605 } 648 }
606 649
607 if (constructor.initializers.isEmpty) { 650 if (constructor.initializers.isEmpty) {
608 _initializeNullFields(_currentClass, newObject); 651 _initializeNullFields(_currentClass, newObject);
609 return new ContinuationConfiguration(expressionContinuation, newObject); 652 return configuration;
610 } 653 }
611 654
612 if (constructor.initializers.first is SuperInitializer) { 655 if (constructor.initializers.first is SuperInitializer) {
613 // SuperInitializer appears last in the initializer list. 656 // SuperInitializer appears last in the initializer list.
614 assert(constructor.initializers.length == 1); 657 assert(constructor.initializers.length == 1);
615 SuperInitializer current = constructor.initializers.first; 658 SuperInitializer current = constructor.initializers.first;
616 var args = _createArgumentExpressionList( 659 var args = _createArgumentExpressionList(
617 current.arguments, current.target.function); 660 current.arguments, current.target.function);
618 var superApp = new ConstructorInvocationApplication( 661 var superApp = new ConstructorInvocationApplication(
619 newObject, current.target, expressionContinuation); 662 newObject, current.target, configuration);
620 _initializeNullFields(_currentClass, newObject); 663 _initializeNullFields(_currentClass, newObject);
621 return new ExpressionListConfiguration(args, environment, superApp); 664 return new ExpressionListConfiguration(args, environment, superApp);
622 } 665 }
623 666
624 Class class_ = new Class(constructor.enclosingClass.reference); 667 Class class_ = new Class(constructor.enclosingClass.reference);
625 Environment initEnv = new Environment(environment); 668 InstanceEnvironment initEnv = new Environment.withParent(environment);
626 669
627 var cont = new InitializerContinuation(newObject, class_, initEnv, 670 var cont = new InitializerContinuation(
628 constructor.initializers, expressionContinuation); 671 newObject, class_, initEnv, constructor.initializers, configuration);
629 return new ExpressionConfiguration( 672 return new ExpressionConfiguration(
630 _getExpression(constructor.initializers.first), initEnv, cont); 673 _getExpression(constructor.initializers.first), initEnv, cont);
631 } 674 }
632 } 675 }
633 676
634 /// Represents the expression continuation applied on the list of evaluated 677 /// Represents the expression continuation applied on the list of evaluated
635 /// initializer expressions preceding a super call in the list. 678 /// initializer expressions preceding a super call in the list.
636 class InitializerContinuation extends ExpressionContinuation { 679 class InitializerContinuation extends ExpressionContinuation {
637 final ObjectValue newObject; 680 final ObjectValue newObject;
638 final Class currentClass; 681 final Class currentClass;
639 final Environment initializerEnvironment; 682 final InstanceEnvironment initializerEnvironment;
640 final List<Initializer> initializers; 683 final List<Initializer> initializers;
641 final ExpressionContinuation continuation; 684 final StatementConfiguration configuration;
642 685
643 InitializerContinuation(this.newObject, this.currentClass, 686 InitializerContinuation(this.newObject, this.currentClass,
644 this.initializerEnvironment, this.initializers, this.continuation); 687 this.initializerEnvironment, this.initializers, this.configuration);
645 688
646 Configuration call(Value v) { 689 Configuration call(Value v) {
647 Initializer current = initializers.first; 690 Initializer current = initializers.first;
648 if (current is FieldInitializer) { 691 if (current is FieldInitializer) {
649 currentClass.setProperty(newObject, current.field, v); 692 currentClass.setProperty(newObject, current.field, v);
650 } else if (current is LocalInitializer) { 693 } else if (current is LocalInitializer) {
651 initializerEnvironment.expand(current.variable, v); 694 initializerEnvironment.expand(current.variable, v);
652 } else { 695 } else {
653 throw 'Assigning value $v to ${current.runtimeType}'; 696 throw 'Assigning value $v to ${current.runtimeType}';
654 } 697 }
655 698
656 if (initializers.length <= 1) { 699 if (initializers.length <= 1) {
657 // todo: return configuration for body of ctr.
658 _initializeNullFields(currentClass, newObject); 700 _initializeNullFields(currentClass, newObject);
659 return new ContinuationConfiguration(continuation, newObject); 701 return configuration;
660 } 702 }
661 703
662 Initializer next = initializers[1]; 704 Initializer next = initializers[1];
663 705
664 if (next is RedirectingInitializer) { 706 if (next is RedirectingInitializer) {
665 // RedirectingInitializer appears last in the initializer list. 707 // RedirectingInitializer appears last in the initializer list.
666 assert(initializers.length == 2); 708 assert(initializers.length == 2);
667 var cont = new ConstructorInvocationApplication( 709 var cont = new ConstructorInvocationApplication(
668 newObject, next.target, continuation); 710 newObject, next.target, configuration);
669 var args = 711 var args =
670 _createArgumentExpressionList(next.arguments, next.target.function); 712 _createArgumentExpressionList(next.arguments, next.target.function);
671 return new ExpressionListConfiguration( 713 return new ExpressionListConfiguration(
672 args, initializerEnvironment, cont); 714 args, initializerEnvironment, cont);
673 } 715 }
674 716
675 if (next is SuperInitializer) { 717 if (next is SuperInitializer) {
676 // SuperInitializer appears last in the initializer list. 718 // SuperInitializer appears last in the initializer list.
677 assert(initializers.length == 2); 719 assert(initializers.length == 2);
678 var args = 720 var args =
679 _createArgumentExpressionList(next.arguments, next.target.function); 721 _createArgumentExpressionList(next.arguments, next.target.function);
680 var superApp = new ConstructorInvocationApplication( 722 var superApp = new ConstructorInvocationApplication(
681 newObject, next.target, continuation); 723 newObject, next.target, configuration);
682 _initializeNullFields(currentClass, newObject); 724 _initializeNullFields(currentClass, newObject);
683 return new ExpressionListConfiguration( 725 return new ExpressionListConfiguration(
684 args, initializerEnvironment, superApp); 726 args, initializerEnvironment, superApp);
685 } 727 }
686 728
687 var cont = new InitializerContinuation(newObject, currentClass, 729 var cont = new InitializerContinuation(newObject, currentClass,
688 initializerEnvironment, initializers.skip(1).toList(), continuation); 730 initializerEnvironment, initializers.skip(1).toList(), configuration);
689 return new ExpressionConfiguration( 731 return new ExpressionConfiguration(
690 _getExpression(next), initializerEnvironment, cont); 732 _getExpression(next), initializerEnvironment, cont);
691 } 733 }
692 } 734 }
693 735
694 /// Represents the application continuation called after the evaluation of all 736 /// Represents the application continuation called after the evaluation of all
695 /// argument expressions for an invocation. 737 /// argument expressions for an invocation.
696 class ValueApplication extends ApplicationContinuation { 738 class ValueApplication extends ApplicationContinuation {
697 final InterpreterValue value; 739 final InterpreterValue value;
698 final ApplicationContinuation applicationContinuation; 740 final ApplicationContinuation applicationContinuation;
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
936 class LetContinuation extends ExpressionContinuation { 978 class LetContinuation extends ExpressionContinuation {
937 final VariableDeclaration variable; 979 final VariableDeclaration variable;
938 final Expression letBody; 980 final Expression letBody;
939 final Environment environment; 981 final Environment environment;
940 final ExpressionContinuation continuation; 982 final ExpressionContinuation continuation;
941 983
942 LetContinuation( 984 LetContinuation(
943 this.variable, this.letBody, this.environment, this.continuation); 985 this.variable, this.letBody, this.environment, this.continuation);
944 986
945 Configuration call(Value value) { 987 Configuration call(Value value) {
946 var letEnv = new Environment(environment); 988 var letEnv = new Environment.withParent(environment);
947 letEnv.expand(variable, value); 989 letEnv.expand(variable, value);
948 return new ExpressionConfiguration(letBody, letEnv, continuation); 990 return new ExpressionConfiguration(letBody, letEnv, continuation);
949 } 991 }
950 } 992 }
951 993
952 /// Represents the continuation for the condition expression in [WhileStatement] . 994 /// Represents the continuation for the condition expression in [WhileStatement] .
953 class WhileConditionContinuation extends ExpressionContinuation { 995 class WhileConditionContinuation extends ExpressionContinuation {
954 final WhileStatement node; 996 final WhileStatement node;
955 final State state; 997 final State state;
956 998
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 new ExpressionStatementContinuation(state.statementConfiguration); 1088 new ExpressionStatementContinuation(state.statementConfiguration);
1047 return new ExpressionConfiguration( 1089 return new ExpressionConfiguration(
1048 node.expression, state.environment, cont); 1090 node.expression, state.environment, cont);
1049 } 1091 }
1050 1092
1051 Configuration visitBlock(Block node, State state) { 1093 Configuration visitBlock(Block node, State state) {
1052 if (node.statements.isEmpty) { 1094 if (node.statements.isEmpty) {
1053 return state.statementConfiguration; 1095 return state.statementConfiguration;
1054 } 1096 }
1055 State blockState = 1097 State blockState =
1056 state.withEnvironment(new Environment(state.environment)); 1098 state.withEnvironment(new Environment.withParent(state.environment));
1057 StatementConfiguration configuration = state.statementConfiguration; 1099 StatementConfiguration configuration = state.statementConfiguration;
1058 for (Statement s in node.statements.reversed) { 1100 for (Statement s in node.statements.reversed) {
1059 configuration = new StatementConfiguration( 1101 configuration = new StatementConfiguration(
1060 s, blockState.withConfiguration(configuration)); 1102 s, blockState.withConfiguration(configuration));
1061 } 1103 }
1062 return configuration; 1104 return configuration;
1063 } 1105 }
1064 1106
1065 Configuration visitEmptyStatement(EmptyStatement node, State state) { 1107 Configuration visitEmptyStatement(EmptyStatement node, State state) {
1066 return state.statementConfiguration; 1108 return state.statementConfiguration;
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
1409 void _initializeNullFields(Class class_, ObjectValue newObject) { 1451 void _initializeNullFields(Class class_, ObjectValue newObject) {
1410 int superClassSize = class_.superclass?.instanceSize ?? 0; 1452 int superClassSize = class_.superclass?.instanceSize ?? 0;
1411 for (int i = superClassSize; i < class_.instanceSize; i++) { 1453 for (int i = superClassSize; i < class_.instanceSize; i++) {
1412 Field field = class_.instanceFields[i]; 1454 Field field = class_.instanceFields[i];
1413 if (class_.getProperty(newObject, field) == null) { 1455 if (class_.getProperty(newObject, field) == null) {
1414 assert(field.initializer == null); 1456 assert(field.initializer == null);
1415 class_.setProperty(newObject, field, Value.nullInstance); 1457 class_.setProperty(newObject, field, Value.nullInstance);
1416 } 1458 }
1417 } 1459 }
1418 } 1460 }
OLDNEW
« 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