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 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 |