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

Side by Side 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 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 29 matching lines...) Expand all
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 class Environment {
47 final List<Binding> bindings = <Binding>[]; 47 final List<Binding> bindings = <Binding>[];
48 final Environment parent; 48 final Environment parent;
49 49
50 Value get thisInstance => (parent != null)
51 ? parent.thisInstance
52 : throw "Invalid reference to 'this' expression";
53
50 Environment.empty() : parent = null; 54 Environment.empty() : parent = null;
51 Environment(this.parent); 55 Environment(this.parent);
52 56
53 bool contains(VariableDeclaration variable) { 57 bool contains(VariableDeclaration variable) {
54 for (Binding b in bindings.reversed) { 58 for (Binding b in bindings.reversed) {
55 if (identical(b.variable, variable)) return true; 59 if (identical(b.variable, variable)) return true;
56 } 60 }
57 return parent?.contains(variable) ?? false; 61 return parent?.contains(variable) ?? false;
58 } 62 }
59 63
(...skipping 13 matching lines...) Expand all
73 assert(contains(variable)); 77 assert(contains(variable));
74 lookupBinding(variable).value = value; 78 lookupBinding(variable).value = value;
75 } 79 }
76 80
77 void expand(VariableDeclaration variable, Value value) { 81 void expand(VariableDeclaration variable, Value value) {
78 assert(!contains(variable)); 82 assert(!contains(variable));
79 bindings.add(new Binding(variable, value)); 83 bindings.add(new Binding(variable, value));
80 } 84 }
81 } 85 }
82 86
87 class InstanceEnvironment extends Environment {
88 final ObjectValue _thisInstance;
89 Value get thisInstance => _thisInstance;
90
91 InstanceEnvironment(this._thisInstance, Environment env) : super(env);
92 }
93
83 /// Evaluate expressions. 94 /// Evaluate expressions.
84 class Evaluator 95 class Evaluator
85 extends ExpressionVisitor1<Configuration, ExpressionConfiguration> { 96 extends ExpressionVisitor1<Configuration, ExpressionConfiguration> {
86 Configuration eval(Expression expr, ExpressionConfiguration config) => 97 Configuration eval(Expression expr, ExpressionConfiguration config) =>
87 expr.accept1(this, config); 98 expr.accept1(this, config);
88 99
89 Configuration evalList(List<InterpreterExpression> list, Environment env, 100 Configuration evalList(List<InterpreterExpression> list, Environment env,
90 ApplicationContinuation cont) { 101 ApplicationContinuation cont) {
91 if (list.isNotEmpty) { 102 if (list.isNotEmpty) {
92 return new ExpressionConfiguration(list.first.expression, env, 103 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 173 // Currently supports only method invocation with <2 arguments and is used
163 // to evaluate implemented operators for int, double and String values. 174 // to evaluate implemented operators for int, double and String values.
164 var cont = new MethodInvocationContinuation( 175 var cont = new MethodInvocationContinuation(
165 node.arguments, node.name, config.environment, config.continuation); 176 node.arguments, node.name, config.environment, config.continuation);
166 177
167 return new ExpressionConfiguration(node.receiver, config.environment, cont); 178 return new ExpressionConfiguration(node.receiver, config.environment, cont);
168 } 179 }
169 180
170 Configuration visitConstructorInvocation( 181 Configuration visitConstructorInvocation(
171 ConstructorInvocation node, ExpressionConfiguration config) { 182 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 ApplicationContinuation cont = 183 ApplicationContinuation cont =
180 new ConstructorInvocationApplication(node.target, config.continuation); 184 new ConstructorInvocationApplication(node.target, config.continuation);
181
182 var args = 185 var args =
183 _createArgumentExpressionList(node.arguments, node.target.function); 186 _createArgumentExpressionList(node.arguments, node.target.function);
184 187
185 return new ExpressionListConfiguration(args, config.environment, cont); 188 return new ExpressionListConfiguration(args, config.environment, cont);
186 } 189 }
187 190
188 Configuration visitNot(Not node, ExpressionConfiguration config) { 191 Configuration visitNot(Not node, ExpressionConfiguration config) {
189 return new ExpressionConfiguration(node.operand, config.environment, 192 return new ExpressionConfiguration(node.operand, config.environment,
190 new NotContinuation(config.continuation)); 193 new NotContinuation(config.continuation));
191 } 194 }
(...skipping 23 matching lines...) Expand all
215 Configuration visitStringConcatenation( 218 Configuration visitStringConcatenation(
216 StringConcatenation node, ExpressionConfiguration config) { 219 StringConcatenation node, ExpressionConfiguration config) {
217 var cont = new StringConcatenationContinuation(config.continuation); 220 var cont = new StringConcatenationContinuation(config.continuation);
218 var expressions = node.expressions 221 var expressions = node.expressions
219 .map((Expression e) => new PositionalExpression(e)) 222 .map((Expression e) => new PositionalExpression(e))
220 .toList(); 223 .toList();
221 return new ExpressionListConfiguration( 224 return new ExpressionListConfiguration(
222 expressions, config.environment, cont); 225 expressions, config.environment, cont);
223 } 226 }
224 227
228 Configuration visitThisExpression(
229 ThisExpression node, ExpressionConfiguration config) {
230 return new ContinuationConfiguration(
231 config.continuation, config.environment.thisInstance);
232 }
233
225 // Evaluation of BasicLiterals. 234 // Evaluation of BasicLiterals.
226 Configuration visitStringLiteral( 235 Configuration visitStringLiteral(
227 StringLiteral node, ExpressionConfiguration config) { 236 StringLiteral node, ExpressionConfiguration config) {
228 return new ContinuationConfiguration( 237 return new ContinuationConfiguration(
229 config.continuation, new StringValue(node.value)); 238 config.continuation, new StringValue(node.value));
230 } 239 }
231 240
232 Configuration visitIntLiteral( 241 Configuration visitIntLiteral(
233 IntLiteral node, ExpressionConfiguration config) { 242 IntLiteral node, ExpressionConfiguration config) {
234 return new ContinuationConfiguration( 243 return new ContinuationConfiguration(
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 337
329 Configuration step(StatementExecuter executer) => 338 Configuration step(StatementExecuter executer) =>
330 executer.exec(statement, state); 339 executer.exec(statement, state);
331 } 340 }
332 341
333 class ExitConfiguration extends StatementConfiguration { 342 class ExitConfiguration extends StatementConfiguration {
334 final ExpressionContinuation returnContinuation; 343 final ExpressionContinuation returnContinuation;
335 344
336 ExitConfiguration(this.returnContinuation) : super(null, null); 345 ExitConfiguration(this.returnContinuation) : super(null, null);
337 346
338 Configuration step(StatementExecuter executer) { 347 Configuration step(StatementExecuter _) {
339 return returnContinuation(Value.nullInstance); 348 return returnContinuation(Value.nullInstance);
340 } 349 }
341 } 350 }
342 351
352 class NewInstanceConfiguration extends StatementConfiguration {
353 final ExpressionContinuation continuation;
354 final ObjectValue newObject;
355
356 NewInstanceConfiguration(this.continuation, this.newObject)
357 : super(null, new State.initial());
358
359 Configuration step(StatementExecuter _) {
360 return continuation(newObject);
361 }
362 }
363
343 /// Represents the configuration for applying an [ExpressionContinuation]. 364 /// Represents the configuration for applying an [ExpressionContinuation].
344 class ContinuationConfiguration extends Configuration { 365 class ContinuationConfiguration extends Configuration {
345 final ExpressionContinuation continuation; 366 final ExpressionContinuation continuation;
346 final Value value; 367 final Value value;
347 368
348 ContinuationConfiguration(this.continuation, this.value); 369 ContinuationConfiguration(this.continuation, this.value);
349 370
350 Configuration step(StatementExecuter _) => continuation(value); 371 Configuration step(StatementExecuter _) => continuation(value);
351 } 372 }
352 373
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 FieldInitializerValue(this.field, this.value); 483 FieldInitializerValue(this.field, this.value);
463 } 484 }
464 485
465 abstract class Continuation {} 486 abstract class Continuation {}
466 487
467 /// Represents the continuation called after the evaluation of argument 488 /// Represents the continuation called after the evaluation of argument
468 /// expressions. 489 /// expressions.
469 abstract class ApplicationContinuation extends Continuation { 490 abstract class ApplicationContinuation extends Continuation {
470 Configuration call(List<InterpreterValue> values); 491 Configuration call(List<InterpreterValue> values);
471 492
472 /// Creates an environment binding actual argument values to formal parameters 493 /// Binds actual argument values to formal parameters of the function in a
473 /// of the function in a new environment, which is used to execute the 494 /// new environment or in the provided initial environment.
474 /// body od the function.
475 /// TODO: Add checks for validation of arguments according to spec. 495 /// TODO: Add checks for validation of arguments according to spec.
476 static Environment createEnvironment( 496 static Environment createEnvironment(
477 FunctionNode function, List<InterpreterValue> args) { 497 FunctionNode function, List<InterpreterValue> args,
478 Environment newEnv = new Environment.empty(); 498 [Environment parentEnv]) {
499 Environment newEnv = new Environment(parentEnv);
479 List<PositionalValue> positional = args.reversed 500 List<PositionalValue> positional = args.reversed
480 .where((InterpreterValue av) => av is PositionalValue) 501 .where((InterpreterValue av) => av is PositionalValue)
481 .toList(); 502 .toList();
482 503
483 // Add positional parameters. 504 // Add positional parameters.
484 for (int i = 0; i < positional.length; ++i) { 505 for (int i = 0; i < positional.length; ++i) {
485 newEnv.expand(function.positionalParameters[i], positional[i].value); 506 newEnv.expand(function.positionalParameters[i], positional[i].value);
486 } 507 }
487 508
488 Map<String, Value> named = new Map.fromIterable( 509 Map<String, Value> named = new Map.fromIterable(
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 ConstructorInvocationApplication(this.constructor, this.continuation); 548 ConstructorInvocationApplication(this.constructor, this.continuation);
528 549
529 Configuration call(List<InterpreterValue> argValues) { 550 Configuration call(List<InterpreterValue> argValues) {
530 Environment ctrEnv = ApplicationContinuation.createEnvironment( 551 Environment ctrEnv = ApplicationContinuation.createEnvironment(
531 constructor.function, argValues); 552 constructor.function, argValues);
532 553
533 var class_ = new Class(constructor.enclosingClass.reference); 554 var class_ = new Class(constructor.enclosingClass.reference);
534 var newObject = 555 var newObject =
535 new ObjectValue(class_, new List<Value>(class_.instanceSize)); 556 new ObjectValue(class_, new List<Value>(class_.instanceSize));
536 557
537 var cont = 558 return new ObjectInitializationConfiguration(
538 new ObjectInitializationContinuation(constructor, ctrEnv, continuation); 559 constructor,
539 560 new InstanceEnvironment(newObject, ctrEnv),
540 return new ContinuationConfiguration(cont, newObject); 561 new NewInstanceConfiguration(continuation, newObject));
Dmitry Stefantsov 2017/05/18 12:56:51 I think this statement would be hard to translate
541 } 562 }
542 } 563 }
543 564
544 /// Represents the application continuation for redirecting constructor 565 /// Represents the application continuation for redirecting constructor
545 /// invocation applied on the list of evaluated arguments. 566 /// invocation applied on the list of evaluated arguments.
546 class RedirectingConstructorApplication extends ApplicationContinuation { 567 class RedirectingConstructorApplication extends ApplicationContinuation {
547 final ObjectValue newObject;
548 final Constructor constructor; 568 final Constructor constructor;
549 final ExpressionContinuation continuation; 569 final Environment environment;
570 final StatementConfiguration configuration;
550 571
551 RedirectingConstructorApplication( 572 RedirectingConstructorApplication(
552 this.newObject, this.constructor, this.continuation); 573 this.constructor, this.environment, this.configuration);
553 574
554 Configuration call(List<InterpreterValue> argValues) { 575 Configuration call(List<InterpreterValue> argValues) {
576 Value object = environment.thisInstance;
555 Environment ctrEnv = ApplicationContinuation.createEnvironment( 577 Environment ctrEnv = ApplicationContinuation.createEnvironment(
556 constructor.function, argValues); 578 constructor.function,
557 var cont = 579 argValues,
558 new ObjectInitializationContinuation(constructor, ctrEnv, continuation); 580 new InstanceEnvironment(object, new Environment.empty()));
559 return new ContinuationConfiguration(cont, newObject); 581
582 return new ObjectInitializationConfiguration(
583 constructor, ctrEnv, configuration);
560 } 584 }
561 } 585 }
562 586
563 /// Represents the application continuation for super constructor 587 /// Represents the application continuation for super constructor
564 /// invocation applied on the list of evaluated arguments. 588 /// invocation applied on the list of evaluated arguments.
565 class SuperConstructorApplication extends ApplicationContinuation { 589 class SuperConstructorApplication extends ApplicationContinuation {
566 final ObjectValue newObject;
567 final Constructor constructor; 590 final Constructor constructor;
568 // TODO: remember to execute body of previous ctr. 591 final Environment environment;
569 final ExpressionContinuation continuation; 592 final StatementConfiguration configuration;
570 593
571 SuperConstructorApplication( 594 SuperConstructorApplication(
572 this.newObject, this.constructor, this.continuation); 595 this.constructor, this.environment, this.configuration);
573 596
574 Configuration call(List<InterpreterValue> argValues) { 597 Configuration call(List<InterpreterValue> argValues) {
575 Environment ctrEnv = ApplicationContinuation.createEnvironment( 598 Value object = environment.thisInstance;
576 constructor.function, argValues); 599
577 var cont = 600 Environment superEnv = ApplicationContinuation.createEnvironment(
578 new ObjectInitializationContinuation(constructor, ctrEnv, continuation); 601 constructor.function,
579 return new ContinuationConfiguration(cont, newObject); 602 argValues,
603 new InstanceEnvironment(object, new Environment.empty()));
604
605 return new ObjectInitializationConfiguration(
606 constructor, superEnv, configuration);
580 } 607 }
581 } 608 }
582 609
583 class ObjectInitializationContinuation extends ExpressionContinuation { 610 /// Represents the configuration for execution of initializer and
611 /// constructor body statements for initialization of a newly allocated object.
612 class ObjectInitializationConfiguration extends Configuration {
584 final Constructor constructor; 613 final Constructor constructor;
585 final Environment environment; 614 final Environment environment;
586 final ExpressionContinuation continuation; 615 final StatementConfiguration configuration;
587 616
588 ObjectInitializationContinuation( 617 ObjectInitializationConfiguration(
589 this.constructor, this.environment, this.continuation); 618 this.constructor, this.environment, this.configuration);
590 619
591 Configuration call(Value v) { 620 Configuration step(StatementExecuter _) {
592 if (constructor.initializers.isNotEmpty && 621 if (constructor.initializers.isNotEmpty &&
593 constructor.initializers.last is RedirectingInitializer) { 622 constructor.initializers.last is RedirectingInitializer) {
594 // Constructor is redirecting. 623 // Constructor is redirecting.
595 Initializer initializer = constructor.initializers.first; 624 Initializer initializer = constructor.initializers.first;
596 if (initializer is RedirectingInitializer) { 625 if (initializer is RedirectingInitializer) {
597 var app = new RedirectingConstructorApplication( 626 var app = new RedirectingConstructorApplication(
598 v, initializer.target, continuation); 627 initializer.target, environment, configuration);
599 var args = _createArgumentExpressionList( 628 var args = _createArgumentExpressionList(
600 initializer.arguments, initializer.target.function); 629 initializer.arguments, initializer.target.function);
601 630
602 return new ExpressionListConfiguration(args, environment, app); 631 return new ExpressionListConfiguration(args, environment, app);
603 } 632 }
604 // Redirecting initializer is not the only initializer. 633 // Redirecting initializer is not the only initializer.
605 for (Initializer i in constructor.initializers.reversed.skip(1)) { 634 for (Initializer i in constructor.initializers.reversed.skip(1)) {
606 assert(i is LocalInitializer); 635 assert(i is LocalInitializer);
607 } 636 }
608 var class_ = new Class(constructor.enclosingClass.reference); 637 var class_ = new Class(constructor.enclosingClass.reference);
638 var initEnv = new Environment(environment);
609 var cont = new InitializerContinuation( 639 var cont = new InitializerContinuation(
610 v, class_, environment, constructor.initializers, continuation); 640 class_, initEnv, constructor.initializers, configuration);
611 return new ExpressionConfiguration( 641 return new ExpressionConfiguration(
612 (initializer as LocalInitializer).variable.initializer, 642 (initializer as LocalInitializer).variable.initializer,
613 environment, 643 initEnv,
614 cont); 644 cont);
615 } 645 }
616 646
647 // Set head of configurations to be executed to configuration for current
648 // constructor body.
649 var state = new State.initial()
650 .withEnvironment(environment)
651 .withConfiguration(configuration);
652 var bodyConfig =
653 new StatementConfiguration(constructor.function.body, state);
654
617 // Initialize fields in immediately enclosing class. 655 // Initialize fields in immediately enclosing class.
618 var cont = new InstanceFieldsApplication( 656 var cont =
619 v, constructor, environment, continuation); 657 new InstanceFieldsApplication(constructor, environment, bodyConfig);
620 var fieldExpressions = _createInstanceInitializers(constructor); 658 var fieldExpressions = _createInstanceInitializers(constructor);
621 659
622 return new ExpressionListConfiguration( 660 return new ExpressionListConfiguration(
623 fieldExpressions, new Environment.empty(), cont); 661 fieldExpressions, new Environment.empty(), cont);
624 } 662 }
625 663
626 /// Creates a list of expressions for instance field initializers in 664 /// Creates a list of expressions for instance field initializers in
627 /// immediately enclosing class. 665 /// immediately enclosing class.
628 static List<InterpreterExpression> _createInstanceInitializers( 666 static List<InterpreterExpression> _createInstanceInitializers(
629 Constructor ctr) { 667 Constructor ctr) {
630 Class currentClass = new Class(ctr.enclosingClass.reference); 668 Class currentClass = new Class(ctr.enclosingClass.reference);
631 List<InterpreterExpression> es = <InterpreterExpression>[]; 669 List<InterpreterExpression> es = <InterpreterExpression>[];
632 670
633 for (int i = currentClass.superclass?.instanceSize ?? 0; 671 for (int i = currentClass.superclass?.instanceSize ?? 0;
634 i < currentClass.instanceSize; 672 i < currentClass.instanceSize;
635 i++) { 673 i++) {
636 Field current = currentClass.instanceFields[i]; 674 Field current = currentClass.instanceFields[i];
637 if (current.initializer != null) { 675 if (current.initializer != null) {
638 es.add(new FieldInitializerExpression(current, current.initializer)); 676 es.add(new FieldInitializerExpression(current, current.initializer));
639 } 677 }
640 } 678 }
641 679
642 return es; 680 return es;
643 } 681 }
644 } 682 }
645 683
646 /// Represents the application continuation applied on the list of evaluated 684 /// Represents the application continuation applied on the list of evaluated
647 /// field initializer expressions. 685 /// field initializer expressions.
648 class InstanceFieldsApplication extends ApplicationContinuation { 686 class InstanceFieldsApplication extends ApplicationContinuation {
649 final ObjectValue newObject;
650 final Constructor constructor; 687 final Constructor constructor;
651 final Environment environment; 688 final Environment environment;
652 final ExpressionContinuation expressionContinuation; 689 final StatementConfiguration configuration;
653 690
654 final Class _currentClass; 691 final Class _currentClass;
692 final ObjectValue _newObject;
655 693
656 InstanceFieldsApplication(this.newObject, this.constructor, this.environment, 694 InstanceFieldsApplication(
657 this.expressionContinuation) 695 this.constructor, this.environment, this.configuration)
658 : _currentClass = new Class(constructor.enclosingClass.reference); 696 : _currentClass = new Class(constructor.enclosingClass.reference),
697 _newObject = environment.thisInstance;
659 698
660 Configuration call(List<InterpreterValue> fieldValues) { 699 Configuration call(List<InterpreterValue> fieldValues) {
661 for (FieldInitializerValue current in fieldValues.reversed) { 700 for (FieldInitializerValue current in fieldValues.reversed) {
662 _currentClass.setProperty(newObject, current.field, current.value); 701 _currentClass.setProperty(_newObject, current.field, current.value);
663 } 702 }
664 703
665 if (constructor.initializers.isEmpty) { 704 if (constructor.initializers.isEmpty) {
666 _initializeNullFields(_currentClass, newObject); 705 _initializeNullFields(_currentClass, _newObject);
667 return new ContinuationConfiguration(expressionContinuation, newObject); 706 return configuration;
668 } 707 }
669 708
709 // Produce next configuration.
670 if (constructor.initializers.first is SuperInitializer) { 710 if (constructor.initializers.first is SuperInitializer) {
671 // SuperInitializer appears last in the initializer list. 711 // SuperInitializer appears last in the initializer list.
672 assert(constructor.initializers.length == 1); 712 assert(constructor.initializers.length == 1);
673 SuperInitializer current = constructor.initializers.first; 713 SuperInitializer current = constructor.initializers.first;
674 var args = _createArgumentExpressionList( 714 var args = _createArgumentExpressionList(
675 current.arguments, current.target.function); 715 current.arguments, current.target.function);
716
676 var superApp = new SuperConstructorApplication( 717 var superApp = new SuperConstructorApplication(
677 newObject, current.target, expressionContinuation); 718 current.target, environment, configuration);
678 _initializeNullFields(_currentClass, newObject); 719 _initializeNullFields(_currentClass, _newObject);
679 return new ExpressionListConfiguration(args, environment, superApp); 720 return new ExpressionListConfiguration(args, environment, superApp);
680 } 721 }
681 722
682 Class class_ = new Class(constructor.enclosingClass.reference); 723 Class class_ = new Class(constructor.enclosingClass.reference);
683 Environment initEnv = new Environment(environment); 724 Environment initEnv = new Environment(environment);
684 725
685 var cont = new InitializerContinuation(newObject, class_, initEnv, 726 var cont = new InitializerContinuation(
686 constructor.initializers, expressionContinuation); 727 class_, initEnv, constructor.initializers, configuration);
687 return new ExpressionConfiguration( 728 return new ExpressionConfiguration(
688 _getExpression(constructor.initializers.first), initEnv, cont); 729 _getExpression(constructor.initializers.first), initEnv, cont);
689 } 730 }
690 } 731 }
691 732
692 /// Represents the expression continuation applied on the list of evaluated 733 /// Represents the expression continuation applied on the list of evaluated
693 /// initializer expressions preceding a super call in the list. 734 /// initializer expressions preceding a super call in the list.
694 class InitializerContinuation extends ExpressionContinuation { 735 class InitializerContinuation extends ExpressionContinuation {
695 final ObjectValue newObject;
696 final Class currentClass; 736 final Class currentClass;
697 final Environment initializerEnvironment; 737 final Environment initializerEnvironment;
698 final List<Initializer> initializers; 738 final List<Initializer> initializers;
699 final ExpressionContinuation continuation; 739 final StatementConfiguration configuration;
700 740
701 InitializerContinuation(this.newObject, this.currentClass, 741 InitializerContinuation(this.currentClass, this.initializerEnvironment,
702 this.initializerEnvironment, this.initializers, this.continuation); 742 this.initializers, this.configuration);
703 743
704 Configuration call(Value v) { 744 Configuration call(Value v) {
745 ObjectValue newObject = initializerEnvironment.thisInstance;
705 Initializer current = initializers.first; 746 Initializer current = initializers.first;
706 if (current is FieldInitializer) { 747 if (current is FieldInitializer) {
707 currentClass.setProperty(newObject, current.field, v); 748 currentClass.setProperty(newObject, current.field, v);
708 } else if (current is LocalInitializer) { 749 } else if (current is LocalInitializer) {
709 initializerEnvironment.expand(current.variable, v); 750 initializerEnvironment.expand(current.variable, v);
710 } else { 751 } else {
711 throw 'Assigning value $v to ${current.runtimeType}'; 752 throw 'Assigning value $v to ${current.runtimeType}';
712 } 753 }
713 754
714 if (initializers.length <= 1) { 755 if (initializers.length <= 1) {
715 // todo: return configuration for body of ctr.
716 _initializeNullFields(currentClass, newObject); 756 _initializeNullFields(currentClass, newObject);
717 return new ContinuationConfiguration(continuation, newObject); 757 return configuration;
718 } 758 }
719 759
720 Initializer next = initializers[1]; 760 Initializer next = initializers[1];
721 761
722 if (next is RedirectingInitializer) { 762 if (next is RedirectingInitializer) {
723 // RedirectingInitializer appears last in the initializer list. 763 // RedirectingInitializer appears last in the initializer list.
724 assert(initializers.length == 2); 764 assert(initializers.length == 2);
725 var cont = new RedirectingConstructorApplication( 765 var app = new RedirectingConstructorApplication(
726 newObject, next.target, continuation); 766 next.target, initializerEnvironment, configuration);
727 var args = 767 var args =
728 _createArgumentExpressionList(next.arguments, next.target.function); 768 _createArgumentExpressionList(next.arguments, next.target.function);
729 return new ExpressionListConfiguration( 769 return new ExpressionListConfiguration(args, initializerEnvironment, app);
730 args, initializerEnvironment, cont);
731 } 770 }
732 771
733 if (next is SuperInitializer) { 772 if (next is SuperInitializer) {
734 // SuperInitializer appears last in the initializer list. 773 // SuperInitializer appears last in the initializer list.
735 assert(initializers.length == 2); 774 assert(initializers.length == 2);
736 var args = 775 var args =
737 _createArgumentExpressionList(next.arguments, next.target.function); 776 _createArgumentExpressionList(next.arguments, next.target.function);
738 var superApp = 777 var superApp = new SuperConstructorApplication(
739 new SuperConstructorApplication(newObject, next.target, continuation); 778 next.target, initializerEnvironment, configuration);
740 _initializeNullFields(currentClass, newObject); 779 _initializeNullFields(currentClass, newObject);
741 return new ExpressionListConfiguration( 780 return new ExpressionListConfiguration(
742 args, initializerEnvironment, superApp); 781 args, initializerEnvironment, superApp);
743 } 782 }
744 783
745 var cont = new InitializerContinuation(newObject, currentClass, 784 var cont = new InitializerContinuation(currentClass, initializerEnvironment,
746 initializerEnvironment, initializers.skip(1).toList(), continuation); 785 initializers.skip(1).toList(), configuration);
747 return new ExpressionConfiguration( 786 return new ExpressionConfiguration(
748 _getExpression(next), initializerEnvironment, cont); 787 _getExpression(next), initializerEnvironment, cont);
749 } 788 }
750 } 789 }
751 790
752 /// Represents the application continuation called after the evaluation of all 791 /// Represents the application continuation called after the evaluation of all
753 /// argument expressions for an invocation. 792 /// argument expressions for an invocation.
754 class ValueApplication extends ApplicationContinuation { 793 class ValueApplication extends ApplicationContinuation {
755 final InterpreterValue value; 794 final InterpreterValue value;
756 final ApplicationContinuation applicationContinuation; 795 final ApplicationContinuation applicationContinuation;
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
1453 void _initializeNullFields(Class class_, ObjectValue newObject) { 1492 void _initializeNullFields(Class class_, ObjectValue newObject) {
1454 int superClassSize = class_.superclass?.instanceSize ?? 0; 1493 int superClassSize = class_.superclass?.instanceSize ?? 0;
1455 for (int i = superClassSize; i < class_.instanceSize; i++) { 1494 for (int i = superClassSize; i < class_.instanceSize; i++) {
1456 Field field = class_.instanceFields[i]; 1495 Field field = class_.instanceFields[i];
1457 if (class_.getProperty(newObject, field) == null) { 1496 if (class_.getProperty(newObject, field) == null) {
1458 assert(field.initializer == null); 1497 assert(field.initializer == null);
1459 class_.setProperty(newObject, field, Value.nullInstance); 1498 class_.setProperty(newObject, field, Value.nullInstance);
1460 } 1499 }
1461 } 1500 }
1462 } 1501 }
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