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

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

Issue 2881053002: Add support for super constructor invocation (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/kernel/testcases/interpreter/object_super_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 library kernel.interpreter; 4 library kernel.interpreter;
5 5
6 import '../ast.dart'; 6 import '../ast.dart';
7 import '../ast.dart' as ast show Class; 7 import '../ast.dart' as ast show Class;
8 8
9 import '../log.dart'; 9 import '../log.dart';
10 export '../log.dart'; 10 export '../log.dart';
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 // Currently, the bodies of the constructors are not executed. 172 // Currently, the bodies of the constructors are not executed.
173 // Currently initializer list is executed only for redirecting 173 // Currently initializer list is executed only for redirecting
174 // constructors. 174 // constructors.
175 if (node.target.function.body is! EmptyStatement) { 175 if (node.target.function.body is! EmptyStatement) {
176 throw 'Execution for body of constructor is not implemented.'; 176 throw 'Execution for body of constructor is not implemented.';
177 } 177 }
178 178
179 var class_ = new Class(node.target.enclosingClass.reference); 179 var class_ = new Class(node.target.enclosingClass.reference);
180 var newObject = 180 var newObject =
181 new ObjectValue(class_, new List<Value>(class_.instanceSize)); 181 new ObjectValue(class_, new List<Value>(class_.instanceSize));
182
182 ApplicationContinuation cont = new ConstructorInvocationApplication( 183 ApplicationContinuation cont = new ConstructorInvocationApplication(
183 newObject, node.target, config.continuation); 184 newObject, node.target, config.continuation);
184 185
185 var args = 186 var args =
186 _createArgumentExpressionList(node.arguments, node.target.function); 187 _createArgumentExpressionList(node.arguments, node.target.function);
187 188
188 return new ExpressionListConfiguration(args, config.environment, cont); 189 return new ExpressionListConfiguration(args, config.environment, cont);
189 } 190 }
190 191
191 Configuration visitNot(Not node, ExpressionConfiguration config) { 192 Configuration visitNot(Not node, ExpressionConfiguration config) {
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 597
597 InstanceFieldsApplication(this.newObject, this.constructor, this.environment, 598 InstanceFieldsApplication(this.newObject, this.constructor, this.environment,
598 this.expressionContinuation) 599 this.expressionContinuation)
599 : _currentClass = new Class(constructor.enclosingClass.reference); 600 : _currentClass = new Class(constructor.enclosingClass.reference);
600 601
601 Configuration call(List<InterpreterValue> fieldValues) { 602 Configuration call(List<InterpreterValue> fieldValues) {
602 for (FieldInitializerValue current in fieldValues.reversed) { 603 for (FieldInitializerValue current in fieldValues.reversed) {
603 _currentClass.setProperty(newObject, current.field, current.value); 604 _currentClass.setProperty(newObject, current.field, current.value);
604 } 605 }
605 606
606 if (constructor.initializers.isEmpty || 607 if (constructor.initializers.isEmpty) {
607 constructor.initializers.first is SuperInitializer) {
608 // todo: eval super args or constructor body configuration.
609 return new ContinuationConfiguration(expressionContinuation, newObject); 608 return new ContinuationConfiguration(expressionContinuation, newObject);
610 } 609 }
611 610
611 if (constructor.initializers.first is SuperInitializer) {
612 // SuperInitializer appears last in the initializer list.
613 assert(constructor.initializers.length == 1);
614 SuperInitializer current = constructor.initializers.first;
615 var args = _createArgumentExpressionList(
616 current.arguments, current.target.function);
617 var superApp = new ConstructorInvocationApplication(
618 newObject, current.target, expressionContinuation);
619 _initializeNullFields(_currentClass, newObject);
620 return new ExpressionListConfiguration(args, environment, superApp);
621 }
622
612 Class class_ = new Class(constructor.enclosingClass.reference); 623 Class class_ = new Class(constructor.enclosingClass.reference);
613 Environment initEnv = new Environment(environment); 624 Environment initEnv = new Environment(environment);
614 625
615 var cont = new InitializerContinuation(newObject, class_, initEnv, 626 var cont = new InitializerContinuation(newObject, class_, initEnv,
616 constructor.initializers, expressionContinuation); 627 constructor.initializers, expressionContinuation);
617 return new ExpressionConfiguration( 628 return new ExpressionConfiguration(
618 _getExpression(constructor.initializers.first), initEnv, cont); 629 _getExpression(constructor.initializers.first), initEnv, cont);
619 } 630 }
620 } 631 }
621 632
(...skipping 14 matching lines...) Expand all
636 if (current is FieldInitializer) { 647 if (current is FieldInitializer) {
637 currentClass.setProperty(newObject, current.field, v); 648 currentClass.setProperty(newObject, current.field, v);
638 } else if (current is LocalInitializer) { 649 } else if (current is LocalInitializer) {
639 initializerEnvironment.expand(current.variable, v); 650 initializerEnvironment.expand(current.variable, v);
640 } else { 651 } else {
641 throw 'Assigning value $v to ${current.runtimeType}'; 652 throw 'Assigning value $v to ${current.runtimeType}';
642 } 653 }
643 654
644 if (initializers.length <= 1) { 655 if (initializers.length <= 1) {
645 // todo: return configuration for body of ctr. 656 // todo: return configuration for body of ctr.
646 return new ContinuationConfiguration(continuation, newObject); 657 return new ContinuationConfiguration(continuation, newObject);
Dmitry Stefantsov 2017/05/15 11:48:23 Should we call "_initializeNullFields" here before
zhivkag 2017/05/15 11:58:14 Yes, thanks! Done.
647 } 658 }
648 659
649 Initializer next = initializers[1]; 660 Initializer next = initializers[1];
650 661
651 if (next is RedirectingInitializer) { 662 if (next is RedirectingInitializer) {
663 // RedirectingInitializer appears last in the initializer list.
664 assert(initializers.length == 2);
652 var cont = new ConstructorInvocationApplication( 665 var cont = new ConstructorInvocationApplication(
653 newObject, next.target, continuation); 666 newObject, next.target, continuation);
654 var args = 667 var args =
655 _createArgumentExpressionList(next.arguments, next.target.function); 668 _createArgumentExpressionList(next.arguments, next.target.function);
656 return new ExpressionListConfiguration( 669 return new ExpressionListConfiguration(
657 args, initializerEnvironment, cont); 670 args, initializerEnvironment, cont);
658 } 671 }
659 672
660 if (next is SuperInitializer) { 673 if (next is SuperInitializer) {
661 // todo: eval args for super. 674 // SuperInitializer appears last in the initializer list.
662 if (currentClass.superclass.superclass != null) { 675 assert(initializers.length == 2);
663 throw 'Super initializer invocation is not supported.'; 676 var args =
664 } 677 _createArgumentExpressionList(next.arguments, next.target.function);
665 return new ContinuationConfiguration(continuation, newObject); 678 var superApp = new ConstructorInvocationApplication(
679 newObject, next.target, continuation);
680 _initializeNullFields(currentClass, newObject);
681 return new ExpressionListConfiguration(
682 args, initializerEnvironment, superApp);
666 } 683 }
667 684
668 var cont = new InitializerContinuation(newObject, currentClass, 685 var cont = new InitializerContinuation(newObject, currentClass,
669 initializerEnvironment, initializers.skip(1).toList(), continuation); 686 initializerEnvironment, initializers.skip(1).toList(), continuation);
670 return new ExpressionConfiguration( 687 return new ExpressionConfiguration(
671 _getExpression(next), initializerEnvironment, cont); 688 _getExpression(next), initializerEnvironment, cont);
672 } 689 }
673 } 690 }
674 691
675 /// Represents the application continuation called after the evaluation of all 692 /// Represents the application continuation called after the evaluation of all
(...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after
1377 Expression _getExpression(Initializer initializer) { 1394 Expression _getExpression(Initializer initializer) {
1378 if (initializer is FieldInitializer) { 1395 if (initializer is FieldInitializer) {
1379 return initializer.value; 1396 return initializer.value;
1380 } 1397 }
1381 if (initializer is LocalInitializer) { 1398 if (initializer is LocalInitializer) {
1382 return initializer.variable.initializer; 1399 return initializer.variable.initializer;
1383 } 1400 }
1384 1401
1385 throw '${initializer.runtimeType} has no epxression.'; 1402 throw '${initializer.runtimeType} has no epxression.';
1386 } 1403 }
1404
1405 /// Initializes all non initialized fields in given class with
1406 /// [Value.nullInstance].
1407 void _initializeNullFields(Class class_, ObjectValue newObject) {
1408 int superClassSize = class_.superclass?.instanceSize ?? 0;
1409 for (int i = superClassSize; i < class_.instanceSize; i++) {
1410 Field field = class_.instanceFields[i];
1411 if (class_.getProperty(newObject, field) == null) {
1412 assert(field.initializer == null);
1413 class_.setProperty(newObject, field, Value.nullInstance);
1414 }
1415 }
1416 }
OLDNEW
« no previous file with comments | « no previous file | pkg/kernel/testcases/interpreter/object_super_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698