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 29 matching lines...) Expand all Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |