Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 library kernel.interpreter; | 4 library kernel.interpreter; |
| 5 | 5 |
| 6 import '../ast.dart'; | 6 import '../ast.dart'; |
| 7 import '../ast.dart' as ast show Class; | 7 import '../ast.dart' as ast show Class; |
| 8 | 8 |
| 9 import '../log.dart'; | 9 import '../log.dart'; |
| 10 export '../log.dart'; | 10 export '../log.dart'; |
| (...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 528 | 528 |
| 529 ConstructorInvocationApplication( | 529 ConstructorInvocationApplication( |
| 530 this.newObject, this.constructor, this.expressionContinuation); | 530 this.newObject, this.constructor, this.expressionContinuation); |
| 531 | 531 |
| 532 Configuration call(List<InterpreterValue> argValues) { | 532 Configuration call(List<InterpreterValue> argValues) { |
| 533 Environment ctrEnv = ApplicationContinuation.createEnvironment( | 533 Environment ctrEnv = ApplicationContinuation.createEnvironment( |
| 534 constructor.function, argValues); | 534 constructor.function, argValues); |
| 535 | 535 |
| 536 if (constructor.initializers.isNotEmpty && | 536 if (constructor.initializers.isNotEmpty && |
| 537 constructor.initializers.last is RedirectingInitializer) { | 537 constructor.initializers.last is RedirectingInitializer) { |
| 538 var cont = new RedirectingConstructorInvocationApplication(newObject, | 538 // Constructor is redirecting. |
| 539 constructor.initializers.last, ctrEnv, expressionContinuation); | 539 Initializer initializer = constructor.initializers.first; |
| 540 var es = _createLocalInitializerExpressionList( | 540 if (initializer is RedirectingInitializer) { |
| 541 constructor.initializers.take(constructor.initializers.length - 1)); | 541 var app = new ConstructorInvocationApplication( |
| 542 return new ExpressionListConfiguration(es, ctrEnv, cont); | 542 newObject, initializer.target, expressionContinuation); |
| 543 var args = _createArgumentExpressionList( | |
| 544 initializer.arguments, initializer.target.function); | |
| 545 | |
| 546 return new ExpressionListConfiguration(args, ctrEnv, app); | |
| 547 } | |
| 548 // Redirecting initializer is not the only initializer. | |
|
Dmitry Stefantsov
2017/05/15 07:31:37
Maybe we should assert here that all the initializ
zhivkag
2017/05/15 07:50:05
Done.
| |
| 549 var class_ = new Class(constructor.enclosingClass.reference); | |
| 550 var cont = new InitializerContinuation(newObject, class_, ctrEnv, | |
| 551 constructor.initializers, expressionContinuation); | |
| 552 return new ExpressionConfiguration( | |
| 553 _getExpression(constructor.initializers.first), ctrEnv, cont); | |
|
Dmitry Stefantsov
2017/05/15 07:31:37
The first initializer can only be a LocalInitializ
zhivkag
2017/05/15 07:50:05
Done.
| |
| 543 } | 554 } |
| 544 | 555 |
| 556 // Initialize fields in immediately enclosing class. | |
| 545 var cont = new InstanceFieldsApplication( | 557 var cont = new InstanceFieldsApplication( |
| 546 newObject, constructor, ctrEnv, expressionContinuation); | 558 newObject, constructor, ctrEnv, expressionContinuation); |
| 547 var fieldExpressions = _createInstanceInitializers(constructor); | 559 var fieldExpressions = _createInstanceInitializers(constructor); |
| 548 | 560 |
| 549 return new ExpressionListConfiguration(fieldExpressions, ctrEnv, cont); | 561 return new ExpressionListConfiguration(fieldExpressions, ctrEnv, cont); |
| 550 } | 562 } |
| 551 | 563 |
| 552 /// Creates a list of expressions for local initializers. | |
| 553 static List<InterpreterExpression> _createLocalInitializerExpressionList( | |
| 554 List<LocalInitializer> initializers) { | |
| 555 List<InterpreterExpression> es = <InterpreterExpression>[]; | |
| 556 | |
| 557 for (int i = 0; i < initializers.length; i++) { | |
| 558 var current = initializers[i]; | |
| 559 es.add(new LocalInitializerExpression(current.variable)); | |
| 560 } | |
| 561 return es; | |
| 562 } | |
| 563 | |
| 564 /// Creates a list of expressions for instance field initializers in | 564 /// Creates a list of expressions for instance field initializers in |
| 565 /// immediately enclosing class. | 565 /// immediately enclosing class. |
| 566 static List<InterpreterExpression> _createInstanceInitializers( | 566 static List<InterpreterExpression> _createInstanceInitializers( |
| 567 Constructor ctr) { | 567 Constructor ctr) { |
| 568 Class currentClass = new Class(ctr.enclosingClass.reference); | 568 Class currentClass = new Class(ctr.enclosingClass.reference); |
| 569 List<InterpreterExpression> es = <InterpreterExpression>[]; | 569 List<InterpreterExpression> es = <InterpreterExpression>[]; |
| 570 | 570 |
| 571 for (int i = currentClass.superclass?.instanceSize ?? 0; | 571 for (int i = currentClass.superclass?.instanceSize ?? 0; |
| 572 i < currentClass.instanceSize; | 572 i < currentClass.instanceSize; |
| 573 i++) { | 573 i++) { |
| 574 Field current = currentClass.instanceFields[i]; | 574 Field current = currentClass.instanceFields[i]; |
| 575 if (current.initializer != null) { | 575 if (current.initializer != null) { |
| 576 es.add(new FieldInitializerExpression(current, current.initializer)); | 576 es.add(new FieldInitializerExpression(current, current.initializer)); |
| 577 } | 577 } |
| 578 } | 578 } |
| 579 | 579 |
| 580 return es; | 580 return es; |
| 581 } | 581 } |
| 582 } | 582 } |
| 583 | 583 |
| 584 /// Represents the application continuation applied on the list of evaluated | 584 /// Represents the application continuation applied on the list of evaluated |
| 585 /// local initializer expressions. | |
| 586 class RedirectingConstructorInvocationApplication | |
| 587 extends ApplicationContinuation { | |
| 588 final ObjectValue newObject; | |
| 589 final RedirectingInitializer initializer; | |
| 590 final Environment environment; | |
| 591 final ExpressionContinuation expressionContinuation; | |
| 592 | |
| 593 RedirectingConstructorInvocationApplication(this.newObject, this.initializer, | |
| 594 this.environment, this.expressionContinuation); | |
| 595 | |
| 596 Configuration call(List<InterpreterValue> localValues) { | |
| 597 for (LocalInitializerValue current in localValues.reversed) { | |
| 598 environment.expand(current.variable, current.value); | |
| 599 } | |
| 600 var cont = new ConstructorInvocationApplication( | |
| 601 newObject, initializer.target, expressionContinuation); | |
| 602 var args = _createArgumentExpressionList( | |
| 603 initializer.arguments, initializer.target.function); | |
| 604 | |
| 605 return new ExpressionListConfiguration(args, environment, cont); | |
| 606 } | |
| 607 } | |
| 608 | |
| 609 /// Represents the application continuation applied on the list of evaluated | |
| 610 /// field initializer expressions. | 585 /// field initializer expressions. |
| 611 class InstanceFieldsApplication extends ApplicationContinuation { | 586 class InstanceFieldsApplication extends ApplicationContinuation { |
| 612 final ObjectValue newObject; | 587 final ObjectValue newObject; |
| 613 final Constructor constructor; | 588 final Constructor constructor; |
| 614 final Environment environment; | 589 final Environment environment; |
| 615 final ExpressionContinuation expressionContinuation; | 590 final ExpressionContinuation expressionContinuation; |
| 616 | 591 |
| 617 final Class _currentClass; | 592 final Class _currentClass; |
| 618 | 593 |
| 619 InstanceFieldsApplication(this.newObject, this.constructor, this.environment, | 594 InstanceFieldsApplication(this.newObject, this.constructor, this.environment, |
| 620 this.expressionContinuation) | 595 this.expressionContinuation) |
| 621 : _currentClass = new Class(constructor.enclosingClass.reference); | 596 : _currentClass = new Class(constructor.enclosingClass.reference); |
| 622 | 597 |
| 623 Configuration call(List<InterpreterValue> fieldValues) { | 598 Configuration call(List<InterpreterValue> fieldValues) { |
| 624 for (FieldInitializerValue current in fieldValues.reversed) { | 599 for (FieldInitializerValue current in fieldValues.reversed) { |
| 625 _currentClass.setProperty(newObject, current.field, current.value); | 600 _currentClass.setProperty(newObject, current.field, current.value); |
| 626 } | 601 } |
| 627 | 602 |
| 628 var es = _createInitializerListExpressions(constructor.initializers); | 603 if (constructor.initializers.isEmpty || |
| 629 List<Initializer> initializers = constructor.initializers.skip(es.length); | 604 constructor.initializers.first is SuperInitializer) { |
| 605 // todo: eval super args or constructor body configuration. | |
| 606 return new ContinuationConfiguration(expressionContinuation, newObject); | |
| 607 } | |
| 630 | 608 |
| 631 ApplicationContinuation cont = new InitializerListApplication(newObject, | 609 Class class_ = new Class(constructor.enclosingClass.reference); |
| 632 constructor, environment, initializers, expressionContinuation); | 610 Environment initEnv = new Environment(environment); |
| 633 | 611 |
| 634 return new ExpressionListConfiguration(es, environment, cont); | 612 var cont = new InitializerContinuation(newObject, class_, initEnv, |
| 613 constructor.initializers, expressionContinuation); | |
| 614 return new ExpressionConfiguration( | |
| 615 _getExpression(constructor.initializers.first), initEnv, cont); | |
| 635 } | 616 } |
| 636 } | 617 } |
| 637 | 618 |
| 638 /// Represents the application continuation applied on the list of evaluated | 619 /// Represents the expression continuation applied on the list of evaluated |
| 639 /// initializer expressions preceding a super call in the list. | 620 /// initializer expressions preceding a super call in the list. |
| 640 class InitializerListApplication extends ApplicationContinuation { | 621 class InitializerContinuation extends ExpressionContinuation { |
| 641 final ObjectValue newObject; | 622 final ObjectValue newObject; |
| 642 final Constructor constructor; | 623 final Class currentClass; |
| 643 final Environment environment; | 624 final Environment initializerEnvironment; |
| 644 final List<Initializer> remainingInitializers; | 625 final List<Initializer> initializers; |
| 645 final ExpressionContinuation expressionContinuation; | 626 final ExpressionContinuation continuation; |
| 646 | 627 |
| 647 final Class _currentClass; | 628 InitializerContinuation(this.newObject, this.currentClass, |
| 629 this.initializerEnvironment, this.initializers, this.continuation); | |
| 648 | 630 |
| 649 InitializerListApplication(this.newObject, this.constructor, this.environment, | 631 Configuration call(Value v) { |
| 650 this.remainingInitializers, this.expressionContinuation) | 632 Initializer current = initializers.first; |
| 651 : _currentClass = new Class(constructor.enclosingClass.reference); | 633 if (current is FieldInitializer) { |
| 652 | 634 currentClass.setProperty(newObject, current.field, v); |
| 653 Configuration call(List<InterpreterValue> values) { | 635 } else if (current is LocalInitializer) { |
| 654 var initEnv = new Environment(environment); | 636 initializerEnvironment.expand(current.variable, v); |
| 655 | 637 } else { |
| 656 // Apply values from evaluation to object or/and initializer environment. | 638 throw 'Assigning value $v to ${current.runtimeType}'; |
| 657 for (InterpreterValue current in values.reversed) { | |
| 658 if (current is LocalInitializerValue) { | |
| 659 initEnv.expand(current.variable, current.value); | |
| 660 } else if (current is FieldInitializerValue) { | |
| 661 _currentClass.setProperty(newObject, current.field, current.value); | |
| 662 } else { | |
| 663 throw '${current.runtimeType} in InitializerListApplication'; | |
| 664 } | |
| 665 } | 639 } |
| 666 | 640 |
| 667 if (remainingInitializers.isNotEmpty) { | 641 if (initializers.length <= 1) { |
| 668 assert(remainingInitializers.first is SuperInitializer); | 642 // todo: return configuration for body of ctr. |
| 669 // todo: Evaluate arguments for super invocation. | 643 return new ContinuationConfiguration(continuation, newObject); |
| 670 } | 644 } |
| 671 | 645 |
| 672 return new ContinuationConfiguration(expressionContinuation, newObject); | 646 Initializer next = initializers[1]; |
| 647 | |
| 648 if (next is RedirectingInitializer) { | |
| 649 var cont = new ConstructorInvocationApplication( | |
| 650 newObject, next.target, continuation); | |
| 651 var args = | |
| 652 _createArgumentExpressionList(next.arguments, next.target.function); | |
| 653 return new ExpressionListConfiguration( | |
| 654 args, initializerEnvironment, cont); | |
| 655 } | |
| 656 | |
| 657 if (next is SuperInitializer) { | |
| 658 // todo: eval args for super. | |
| 659 return new ContinuationConfiguration(continuation, newObject); | |
|
Dmitry Stefantsov
2017/05/15 07:31:37
Do I get it right that we assume that the super co
zhivkag
2017/05/15 07:50:05
As we don't support super invocation in this CL, w
| |
| 660 } | |
| 661 | |
| 662 var cont = new InitializerContinuation(newObject, currentClass, | |
| 663 initializerEnvironment, initializers.skip(1), continuation); | |
| 664 return new ExpressionConfiguration( | |
| 665 _getExpression(next), initializerEnvironment, cont); | |
| 673 } | 666 } |
| 674 } | 667 } |
| 675 | 668 |
| 676 /// Represents the application continuation called after the evaluation of all | 669 /// Represents the application continuation called after the evaluation of all |
| 677 /// argument expressions for an invocation. | 670 /// argument expressions for an invocation. |
| 678 class ValueApplication extends ApplicationContinuation { | 671 class ValueApplication extends ApplicationContinuation { |
| 679 final InterpreterValue value; | 672 final InterpreterValue value; |
| 680 final ApplicationContinuation applicationContinuation; | 673 final ApplicationContinuation applicationContinuation; |
| 681 | 674 |
| 682 ValueApplication(this.value, this.applicationContinuation); | 675 ValueApplication(this.value, this.applicationContinuation); |
| (...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1368 args.add(new NamedArgumentExpression(current.name, current.value)); | 1361 args.add(new NamedArgumentExpression(current.name, current.value)); |
| 1369 namedFormals.remove(current.name); | 1362 namedFormals.remove(current.name); |
| 1370 } | 1363 } |
| 1371 | 1364 |
| 1372 // Add missing optional named initializers. | 1365 // Add missing optional named initializers. |
| 1373 args.addAll(namedFormals.values); | 1366 args.addAll(namedFormals.values); |
| 1374 | 1367 |
| 1375 return args; | 1368 return args; |
| 1376 } | 1369 } |
| 1377 | 1370 |
| 1378 List<InterpreterExpression> _createInitializerListExpressions( | 1371 Expression _getExpression(Initializer initializer) { |
| 1379 List<Initializer> initializers) { | 1372 if (initializer is FieldInitializer) { |
| 1380 List<InterpreterExpression> es = <InterpreterExpression>[]; | 1373 return initializer.value; |
| 1381 | 1374 } |
| 1382 for (Initializer current in initializers) { | 1375 if (initializer is LocalInitializer) { |
| 1383 if (current is FieldInitializer) { | 1376 return initializer.variable.initializer; |
| 1384 es.add(new FieldInitializerExpression(current.field, current.value)); | |
| 1385 } else if (current is LocalInitializer) { | |
| 1386 es.add(new LocalInitializerExpression(current.variable)); | |
| 1387 } else { | |
| 1388 assert(current is SuperInitializer); | |
| 1389 return es; | |
| 1390 } | |
| 1391 } | 1377 } |
| 1392 | 1378 |
| 1393 return es; | 1379 throw '${initializer.runtimeType} has no epxression.'; |
| 1394 } | 1380 } |
| OLD | NEW |