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

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

Issue 2874253002: Fix local initializer execution (Closed)
Patch Set: Revert some changes 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 | no next file » | 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 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698