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. | 183 var class_ = new Class(node.target.enclosingClass.reference); |
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 | 184 |
179 var class_ = new Class(node.target.enclosingClass.reference); | 185 var env = new InstanceEnvironment( |
180 var newObject = | 186 new ObjectValue(class_, new List<Value>(class_.instanceSize)), |
181 new ObjectValue(class_, new List<Value>(class_.instanceSize)); | 187 new Environment.empty()); |
182 | 188 var nextConfig = new NewInstanceConfiguration(config.continuation, env); |
183 ApplicationContinuation cont = new ConstructorInvocationApplication( | 189 ApplicationContinuation cont = |
184 newObject, node.target, config.continuation); | 190 new ConstructorInvocationApplication(env, node.target, nextConfig); |
185 | |
186 var args = | 191 var args = |
187 _createArgumentExpressionList(node.arguments, node.target.function); | 192 _createArgumentExpressionList(node.arguments, node.target.function); |
188 | 193 |
189 return new ExpressionListConfiguration(args, config.environment, cont); | 194 return new ExpressionListConfiguration(args, config.environment, cont); |
190 } | 195 } |
191 | 196 |
192 Configuration visitNot(Not node, ExpressionConfiguration config) { | 197 Configuration visitNot(Not node, ExpressionConfiguration config) { |
193 return new ExpressionConfiguration(node.operand, config.environment, | 198 return new ExpressionConfiguration(node.operand, config.environment, |
194 new NotContinuation(config.continuation)); | 199 new NotContinuation(config.continuation)); |
195 } | 200 } |
(...skipping 21 matching lines...) Expand all Loading... | |
217 } | 222 } |
218 | 223 |
219 Configuration visitStringConcatenation( | 224 Configuration visitStringConcatenation( |
220 StringConcatenation node, ExpressionConfiguration config) { | 225 StringConcatenation node, ExpressionConfiguration config) { |
221 var cont = new StringConcatenationContinuation( | 226 var cont = new StringConcatenationContinuation( |
222 node.expressions, config.environment, config.continuation); | 227 node.expressions, config.environment, config.continuation); |
223 return new ExpressionConfiguration( | 228 return new ExpressionConfiguration( |
224 node.expressions.first, config.environment, cont); | 229 node.expressions.first, config.environment, cont); |
225 } | 230 } |
226 | 231 |
232 Configuration visitThisExpression( | |
233 ThisExpression node, ExpressionConfiguration config) { | |
234 return new ContinuationConfiguration( | |
235 config.continuation, config.environment.thisInstance); | |
236 } | |
237 | |
227 // Evaluation of BasicLiterals. | 238 // Evaluation of BasicLiterals. |
228 Configuration visitStringLiteral( | 239 Configuration visitStringLiteral( |
229 StringLiteral node, ExpressionConfiguration config) { | 240 StringLiteral node, ExpressionConfiguration config) { |
230 return new ContinuationConfiguration( | 241 return new ContinuationConfiguration( |
231 config.continuation, new StringValue(node.value)); | 242 config.continuation, new StringValue(node.value)); |
232 } | 243 } |
233 | 244 |
234 Configuration visitIntLiteral( | 245 Configuration visitIntLiteral( |
235 IntLiteral node, ExpressionConfiguration config) { | 246 IntLiteral node, ExpressionConfiguration config) { |
236 return new ContinuationConfiguration( | 247 return new ContinuationConfiguration( |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
330 | 341 |
331 Configuration step(StatementExecuter executer) => | 342 Configuration step(StatementExecuter executer) => |
332 executer.exec(statement, state); | 343 executer.exec(statement, state); |
333 } | 344 } |
334 | 345 |
335 class ExitConfiguration extends StatementConfiguration { | 346 class ExitConfiguration extends StatementConfiguration { |
336 final ExpressionContinuation returnContinuation; | 347 final ExpressionContinuation returnContinuation; |
337 | 348 |
338 ExitConfiguration(this.returnContinuation) : super(null, null); | 349 ExitConfiguration(this.returnContinuation) : super(null, null); |
339 | 350 |
340 Configuration step(StatementExecuter executer) { | 351 Configuration step(StatementExecuter _) { |
341 return returnContinuation(Value.nullInstance); | 352 return returnContinuation(Value.nullInstance); |
342 } | 353 } |
343 } | 354 } |
344 | 355 |
356 class NewInstanceConfiguration extends StatementConfiguration { | |
357 final ExpressionContinuation continuation; | |
358 final Environment environment; | |
359 | |
360 NewInstanceConfiguration(this.continuation, this.environment) | |
361 : super(null, new State.initial()); | |
362 | |
363 Configuration step(StatementExecuter _) { | |
364 return continuation(environment.thisInstance); | |
365 } | |
366 } | |
367 | |
345 /// Represents the configuration for applying an [ExpressionContinuation]. | 368 /// Represents the configuration for applying an [ExpressionContinuation]. |
346 class ContinuationConfiguration extends Configuration { | 369 class ContinuationConfiguration extends Configuration { |
347 final ExpressionContinuation continuation; | 370 final ExpressionContinuation continuation; |
348 final Value value; | 371 final Value value; |
349 | 372 |
350 ContinuationConfiguration(this.continuation, this.value); | 373 ContinuationConfiguration(this.continuation, this.value); |
351 | 374 |
352 Configuration step(StatementExecuter _) => continuation(value); | 375 Configuration step(StatementExecuter _) => continuation(value); |
353 } | 376 } |
354 | 377 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
464 FieldInitializerValue(this.field, this.value); | 487 FieldInitializerValue(this.field, this.value); |
465 } | 488 } |
466 | 489 |
467 abstract class Continuation {} | 490 abstract class Continuation {} |
468 | 491 |
469 /// Represents the continuation called after the evaluation of argument | 492 /// Represents the continuation called after the evaluation of argument |
470 /// expressions. | 493 /// expressions. |
471 abstract class ApplicationContinuation extends Continuation { | 494 abstract class ApplicationContinuation extends Continuation { |
472 Configuration call(List<InterpreterValue> values); | 495 Configuration call(List<InterpreterValue> values); |
473 | 496 |
474 /// Creates an environment binding actual argument values to formal parameters | 497 /// 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 | 498 /// new environment or in the provided initial environment. |
476 /// body od the function. | |
477 /// TODO: Add checks for validation of arguments according to spec. | 499 /// TODO: Add checks for validation of arguments according to spec. |
478 static Environment createEnvironment( | 500 static Environment createEnvironment( |
479 FunctionNode function, List<InterpreterValue> args) { | 501 FunctionNode function, List<InterpreterValue> args, |
480 Environment newEnv = new Environment.empty(); | 502 [parentEnv]) { |
503 Environment newEnv = new Environment(parentEnv); | |
481 List<PositionalArgumentValue> positional = args.reversed | 504 List<PositionalArgumentValue> positional = args.reversed |
482 .where((InterpreterValue av) => av is PositionalArgumentValue) | 505 .where((InterpreterValue av) => av is PositionalArgumentValue) |
483 .toList(); | 506 .toList(); |
484 | 507 |
485 // Add positional parameters. | 508 // Add positional parameters. |
486 for (int i = 0; i < positional.length; ++i) { | 509 for (int i = 0; i < positional.length; ++i) { |
487 newEnv.expand(function.positionalParameters[i], positional[i].value); | 510 newEnv.expand(function.positionalParameters[i], positional[i].value); |
488 } | 511 } |
489 | 512 |
490 Map<String, Value> named = new Map.fromIterable( | 513 Map<String, Value> named = new Map.fromIterable( |
(...skipping 25 matching lines...) Expand all Loading... | |
516 .withExpressionContinuation(continuation) | 539 .withExpressionContinuation(continuation) |
517 .withConfiguration(new ExitConfiguration(continuation)) | 540 .withConfiguration(new ExitConfiguration(continuation)) |
518 .withEnvironment(functionEnv); | 541 .withEnvironment(functionEnv); |
519 return new StatementConfiguration(function.body, bodyState); | 542 return new StatementConfiguration(function.body, bodyState); |
520 } | 543 } |
521 } | 544 } |
522 | 545 |
523 /// Represents the application continuation for constructor invocation applied | 546 /// Represents the application continuation for constructor invocation applied |
524 /// on the list of evaluated arguments. | 547 /// on the list of evaluated arguments. |
525 class ConstructorInvocationApplication extends ApplicationContinuation { | 548 class ConstructorInvocationApplication extends ApplicationContinuation { |
526 final ObjectValue newObject; | 549 final InstanceEnvironment instanceEnvironment; |
527 final Constructor constructor; | 550 final Constructor constructor; |
528 final ExpressionContinuation expressionContinuation; | 551 final StatementConfiguration configuration; |
529 | 552 |
530 ConstructorInvocationApplication( | 553 ConstructorInvocationApplication( |
531 this.newObject, this.constructor, this.expressionContinuation); | 554 this.instanceEnvironment, this.constructor, this.configuration); |
532 | 555 |
533 Configuration call(List<InterpreterValue> argValues) { | 556 Configuration call(List<InterpreterValue> argValues) { |
534 Environment ctrEnv = ApplicationContinuation.createEnvironment( | 557 Environment ctrEnv = ApplicationContinuation.createEnvironment( |
535 constructor.function, argValues); | 558 constructor.function, argValues, instanceEnvironment); |
536 | 559 |
537 if (constructor.initializers.isNotEmpty && | 560 if (constructor.initializers.isNotEmpty && |
538 constructor.initializers.last is RedirectingInitializer) { | 561 constructor.initializers.last is RedirectingInitializer) { |
539 // Constructor is redirecting. | 562 // Constructor is redirecting. |
540 Initializer initializer = constructor.initializers.first; | 563 Initializer initializer = constructor.initializers.first; |
541 if (initializer is RedirectingInitializer) { | 564 if (initializer is RedirectingInitializer) { |
542 var app = new ConstructorInvocationApplication( | 565 var app = new ConstructorInvocationApplication( |
543 newObject, initializer.target, expressionContinuation); | 566 instanceEnvironment, initializer.target, configuration); |
544 var args = _createArgumentExpressionList( | 567 var args = _createArgumentExpressionList( |
545 initializer.arguments, initializer.target.function); | 568 initializer.arguments, initializer.target.function); |
546 | 569 |
547 return new ExpressionListConfiguration(args, ctrEnv, app); | 570 return new ExpressionListConfiguration(args, ctrEnv, app); |
548 } | 571 } |
549 // Redirecting initializer is not the only initializer. | 572 // Redirecting initializer is not the only initializer. |
550 for (Initializer i in constructor.initializers.reversed.skip(1)) { | 573 for (Initializer i in constructor.initializers.reversed.skip(1)) { |
551 assert(i is LocalInitializer); | 574 assert(i is LocalInitializer); |
552 } | 575 } |
553 var class_ = new Class(constructor.enclosingClass.reference); | 576 var class_ = new Class(constructor.enclosingClass.reference); |
554 var cont = new InitializerContinuation(newObject, class_, ctrEnv, | 577 var cont = new InitializerContinuation(instanceEnvironment, class_, |
555 constructor.initializers, expressionContinuation); | 578 ctrEnv, constructor.initializers, configuration); |
556 return new ExpressionConfiguration( | 579 return new ExpressionConfiguration( |
557 (initializer as LocalInitializer).variable.initializer, ctrEnv, cont); | 580 (initializer as LocalInitializer).variable.initializer, ctrEnv, cont); |
558 } | 581 } |
559 | 582 |
583 var newState = configuration.state | |
584 .withEnvironment(ctrEnv) | |
585 .withConfiguration(configuration); | |
586 | |
587 // Set head of configurations to be executed to configuration for current | |
588 // constructor body. | |
589 var nextConfiguration = | |
590 new StatementConfiguration(constructor.function.body, newState); | |
591 | |
560 // Initialize fields in immediately enclosing class. | 592 // Initialize fields in immediately enclosing class. |
561 var cont = new InstanceFieldsApplication( | 593 var cont = new InstanceFieldsApplication( |
562 newObject, constructor, ctrEnv, expressionContinuation); | 594 instanceEnvironment, constructor, ctrEnv, nextConfiguration); |
563 var fieldExpressions = _createInstanceInitializers(constructor); | 595 var fieldExpressions = _createInstanceInitializers(constructor); |
564 | 596 |
565 return new ExpressionListConfiguration(fieldExpressions, ctrEnv, cont); | 597 return new ExpressionListConfiguration(fieldExpressions, ctrEnv, cont); |
566 } | 598 } |
567 | 599 |
568 /// Creates a list of expressions for instance field initializers in | 600 /// Creates a list of expressions for instance field initializers in |
569 /// immediately enclosing class. | 601 /// immediately enclosing class. |
570 static List<InterpreterExpression> _createInstanceInitializers( | 602 static List<InterpreterExpression> _createInstanceInitializers( |
571 Constructor ctr) { | 603 Constructor ctr) { |
572 Class currentClass = new Class(ctr.enclosingClass.reference); | 604 Class currentClass = new Class(ctr.enclosingClass.reference); |
573 List<InterpreterExpression> es = <InterpreterExpression>[]; | 605 List<InterpreterExpression> es = <InterpreterExpression>[]; |
574 | 606 |
575 for (int i = currentClass.superclass?.instanceSize ?? 0; | 607 for (int i = currentClass.superclass?.instanceSize ?? 0; |
576 i < currentClass.instanceSize; | 608 i < currentClass.instanceSize; |
577 i++) { | 609 i++) { |
578 Field current = currentClass.instanceFields[i]; | 610 Field current = currentClass.instanceFields[i]; |
579 if (current.initializer != null) { | 611 if (current.initializer != null) { |
580 es.add(new FieldInitializerExpression(current, current.initializer)); | 612 es.add(new FieldInitializerExpression(current, current.initializer)); |
581 } | 613 } |
582 } | 614 } |
583 | 615 |
584 return es; | 616 return es; |
585 } | 617 } |
586 } | 618 } |
587 | 619 |
588 /// Represents the application continuation applied on the list of evaluated | 620 /// Represents the application continuation applied on the list of evaluated |
589 /// field initializer expressions. | 621 /// field initializer expressions. |
590 class InstanceFieldsApplication extends ApplicationContinuation { | 622 class InstanceFieldsApplication extends ApplicationContinuation { |
591 final ObjectValue newObject; | 623 final InstanceEnvironment instanceEnvironment; |
592 final Constructor constructor; | 624 final Constructor constructor; |
593 final Environment environment; | 625 final Environment environment; |
594 final ExpressionContinuation expressionContinuation; | 626 final StatementConfiguration configuration; |
595 | 627 |
596 final Class _currentClass; | 628 final Class _currentClass; |
597 | 629 |
598 InstanceFieldsApplication(this.newObject, this.constructor, this.environment, | 630 InstanceFieldsApplication(this.instanceEnvironment, this.constructor, |
599 this.expressionContinuation) | 631 this.environment, this.configuration) |
600 : _currentClass = new Class(constructor.enclosingClass.reference); | 632 : _currentClass = new Class(constructor.enclosingClass.reference); |
601 | 633 |
602 Configuration call(List<InterpreterValue> fieldValues) { | 634 Configuration call(List<InterpreterValue> fieldValues) { |
635 Value newObject = instanceEnvironment.thisInstance; | |
603 for (FieldInitializerValue current in fieldValues.reversed) { | 636 for (FieldInitializerValue current in fieldValues.reversed) { |
604 _currentClass.setProperty(newObject, current.field, current.value); | 637 _currentClass.setProperty(newObject, current.field, current.value); |
605 } | 638 } |
606 | 639 |
607 if (constructor.initializers.isEmpty) { | 640 if (constructor.initializers.isEmpty) { |
608 _initializeNullFields(_currentClass, newObject); | 641 _initializeNullFields(_currentClass, newObject); |
609 return new ContinuationConfiguration(expressionContinuation, newObject); | 642 return configuration; |
610 } | 643 } |
611 | 644 |
612 if (constructor.initializers.first is SuperInitializer) { | 645 if (constructor.initializers.first is SuperInitializer) { |
613 // SuperInitializer appears last in the initializer list. | 646 // SuperInitializer appears last in the initializer list. |
614 assert(constructor.initializers.length == 1); | 647 assert(constructor.initializers.length == 1); |
615 SuperInitializer current = constructor.initializers.first; | 648 SuperInitializer current = constructor.initializers.first; |
616 var args = _createArgumentExpressionList( | 649 var args = _createArgumentExpressionList( |
617 current.arguments, current.target.function); | 650 current.arguments, current.target.function); |
618 var superApp = new ConstructorInvocationApplication( | 651 var superApp = new ConstructorInvocationApplication( |
619 newObject, current.target, expressionContinuation); | 652 instanceEnvironment, current.target, configuration); |
620 _initializeNullFields(_currentClass, newObject); | 653 _initializeNullFields(_currentClass, newObject); |
621 return new ExpressionListConfiguration(args, environment, superApp); | 654 return new ExpressionListConfiguration(args, environment, superApp); |
622 } | 655 } |
623 | 656 |
624 Class class_ = new Class(constructor.enclosingClass.reference); | 657 Class class_ = new Class(constructor.enclosingClass.reference); |
625 Environment initEnv = new Environment(environment); | 658 Environment initEnv = new Environment(environment); |
626 | 659 |
627 var cont = new InitializerContinuation(newObject, class_, initEnv, | 660 var cont = new InitializerContinuation(instanceEnvironment, class_, initEnv, |
628 constructor.initializers, expressionContinuation); | 661 constructor.initializers, configuration); |
629 return new ExpressionConfiguration( | 662 return new ExpressionConfiguration( |
630 _getExpression(constructor.initializers.first), initEnv, cont); | 663 _getExpression(constructor.initializers.first), initEnv, cont); |
631 } | 664 } |
632 } | 665 } |
633 | 666 |
634 /// Represents the expression continuation applied on the list of evaluated | 667 /// Represents the expression continuation applied on the list of evaluated |
635 /// initializer expressions preceding a super call in the list. | 668 /// initializer expressions preceding a super call in the list. |
636 class InitializerContinuation extends ExpressionContinuation { | 669 class InitializerContinuation extends ExpressionContinuation { |
637 final ObjectValue newObject; | 670 final InstanceEnvironment instanceEnvironment; |
638 final Class currentClass; | 671 final Class currentClass; |
639 final Environment initializerEnvironment; | 672 final Environment initializerEnvironment; |
Dmitry Stefantsov
2017/05/16 11:06:52
Having two environments in the same continuation r
| |
640 final List<Initializer> initializers; | 673 final List<Initializer> initializers; |
641 final ExpressionContinuation continuation; | 674 final StatementConfiguration configuration; |
642 | 675 |
643 InitializerContinuation(this.newObject, this.currentClass, | 676 InitializerContinuation(this.instanceEnvironment, this.currentClass, |
644 this.initializerEnvironment, this.initializers, this.continuation); | 677 this.initializerEnvironment, this.initializers, this.configuration); |
645 | 678 |
646 Configuration call(Value v) { | 679 Configuration call(Value v) { |
680 Value newObject = instanceEnvironment.thisInstance; | |
647 Initializer current = initializers.first; | 681 Initializer current = initializers.first; |
648 if (current is FieldInitializer) { | 682 if (current is FieldInitializer) { |
649 currentClass.setProperty(newObject, current.field, v); | 683 currentClass.setProperty(newObject, current.field, v); |
650 } else if (current is LocalInitializer) { | 684 } else if (current is LocalInitializer) { |
651 initializerEnvironment.expand(current.variable, v); | 685 initializerEnvironment.expand(current.variable, v); |
652 } else { | 686 } else { |
653 throw 'Assigning value $v to ${current.runtimeType}'; | 687 throw 'Assigning value $v to ${current.runtimeType}'; |
654 } | 688 } |
655 | 689 |
656 if (initializers.length <= 1) { | 690 if (initializers.length <= 1) { |
657 // todo: return configuration for body of ctr. | |
658 _initializeNullFields(currentClass, newObject); | 691 _initializeNullFields(currentClass, newObject); |
659 return new ContinuationConfiguration(continuation, newObject); | 692 return configuration; |
660 } | 693 } |
661 | 694 |
662 Initializer next = initializers[1]; | 695 Initializer next = initializers[1]; |
663 | 696 |
664 if (next is RedirectingInitializer) { | 697 if (next is RedirectingInitializer) { |
665 // RedirectingInitializer appears last in the initializer list. | 698 // RedirectingInitializer appears last in the initializer list. |
666 assert(initializers.length == 2); | 699 assert(initializers.length == 2); |
667 var cont = new ConstructorInvocationApplication( | 700 var cont = new ConstructorInvocationApplication( |
668 newObject, next.target, continuation); | 701 instanceEnvironment, next.target, configuration); |
669 var args = | 702 var args = |
670 _createArgumentExpressionList(next.arguments, next.target.function); | 703 _createArgumentExpressionList(next.arguments, next.target.function); |
671 return new ExpressionListConfiguration( | 704 return new ExpressionListConfiguration( |
672 args, initializerEnvironment, cont); | 705 args, initializerEnvironment, cont); |
673 } | 706 } |
674 | 707 |
675 if (next is SuperInitializer) { | 708 if (next is SuperInitializer) { |
676 // SuperInitializer appears last in the initializer list. | 709 // SuperInitializer appears last in the initializer list. |
677 assert(initializers.length == 2); | 710 assert(initializers.length == 2); |
678 var args = | 711 var args = |
679 _createArgumentExpressionList(next.arguments, next.target.function); | 712 _createArgumentExpressionList(next.arguments, next.target.function); |
680 var superApp = new ConstructorInvocationApplication( | 713 var superApp = new ConstructorInvocationApplication( |
681 newObject, next.target, continuation); | 714 instanceEnvironment, next.target, configuration); |
682 _initializeNullFields(currentClass, newObject); | 715 _initializeNullFields(currentClass, newObject); |
683 return new ExpressionListConfiguration( | 716 return new ExpressionListConfiguration( |
684 args, initializerEnvironment, superApp); | 717 args, initializerEnvironment, superApp); |
685 } | 718 } |
686 | 719 |
687 var cont = new InitializerContinuation(newObject, currentClass, | 720 var cont = new InitializerContinuation(instanceEnvironment, currentClass, |
688 initializerEnvironment, initializers.skip(1).toList(), continuation); | 721 initializerEnvironment, initializers.skip(1).toList(), configuration); |
689 return new ExpressionConfiguration( | 722 return new ExpressionConfiguration( |
690 _getExpression(next), initializerEnvironment, cont); | 723 _getExpression(next), initializerEnvironment, cont); |
691 } | 724 } |
692 } | 725 } |
693 | 726 |
694 /// Represents the application continuation called after the evaluation of all | 727 /// Represents the application continuation called after the evaluation of all |
695 /// argument expressions for an invocation. | 728 /// argument expressions for an invocation. |
696 class ValueApplication extends ApplicationContinuation { | 729 class ValueApplication extends ApplicationContinuation { |
697 final InterpreterValue value; | 730 final InterpreterValue value; |
698 final ApplicationContinuation applicationContinuation; | 731 final ApplicationContinuation applicationContinuation; |
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1409 void _initializeNullFields(Class class_, ObjectValue newObject) { | 1442 void _initializeNullFields(Class class_, ObjectValue newObject) { |
1410 int superClassSize = class_.superclass?.instanceSize ?? 0; | 1443 int superClassSize = class_.superclass?.instanceSize ?? 0; |
1411 for (int i = superClassSize; i < class_.instanceSize; i++) { | 1444 for (int i = superClassSize; i < class_.instanceSize; i++) { |
1412 Field field = class_.instanceFields[i]; | 1445 Field field = class_.instanceFields[i]; |
1413 if (class_.getProperty(newObject, field) == null) { | 1446 if (class_.getProperty(newObject, field) == null) { |
1414 assert(field.initializer == null); | 1447 assert(field.initializer == null); |
1415 class_.setProperty(newObject, field, Value.nullInstance); | 1448 class_.setProperty(newObject, field, Value.nullInstance); |
1416 } | 1449 } |
1417 } | 1450 } |
1418 } | 1451 } |
OLD | NEW |