| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 | 4 |
| 5 #include "vm/ast.h" | 5 #include "vm/ast.h" |
| 6 #include "vm/compiler.h" | 6 #include "vm/compiler.h" |
| 7 #include "vm/dart_entry.h" | 7 #include "vm/dart_entry.h" |
| 8 #include "vm/isolate.h" | 8 #include "vm/isolate.h" |
| 9 #include "vm/object_store.h" | 9 #include "vm/object_store.h" |
| 10 #include "vm/resolver.h" | 10 #include "vm/resolver.h" |
| (...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 return NULL; | 510 return NULL; |
| 511 } | 511 } |
| 512 return new StoreLocalNode(token_pos(), &local(), rhs); | 512 return new StoreLocalNode(token_pos(), &local(), rhs); |
| 513 } | 513 } |
| 514 | 514 |
| 515 | 515 |
| 516 AstNode* LoadStaticFieldNode::MakeAssignmentNode(AstNode* rhs) { | 516 AstNode* LoadStaticFieldNode::MakeAssignmentNode(AstNode* rhs) { |
| 517 if (field().is_final()) { | 517 if (field().is_final()) { |
| 518 return NULL; | 518 return NULL; |
| 519 } | 519 } |
| 520 if (Isolate::Current()->TypeChecksEnabled()) { | 520 if (Isolate::Current()->flags().type_checks()) { |
| 521 rhs = new AssignableNode( | 521 rhs = new AssignableNode( |
| 522 field().token_pos(), | 522 field().token_pos(), |
| 523 rhs, | 523 rhs, |
| 524 AbstractType::ZoneHandle(field().type()), | 524 AbstractType::ZoneHandle(field().type()), |
| 525 String::ZoneHandle(field().name())); | 525 String::ZoneHandle(field().name())); |
| 526 } | 526 } |
| 527 return new StoreStaticFieldNode(token_pos(), field(), rhs); | 527 return new StoreStaticFieldNode(token_pos(), field(), rhs); |
| 528 } | 528 } |
| 529 | 529 |
| 530 | 530 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 550 } | 550 } |
| 551 | 551 |
| 552 | 552 |
| 553 AstNode* LoadIndexedNode::MakeAssignmentNode(AstNode* rhs) { | 553 AstNode* LoadIndexedNode::MakeAssignmentNode(AstNode* rhs) { |
| 554 return new StoreIndexedNode(token_pos(), array(), index_expr(), | 554 return new StoreIndexedNode(token_pos(), array(), index_expr(), |
| 555 rhs, super_class()); | 555 rhs, super_class()); |
| 556 } | 556 } |
| 557 | 557 |
| 558 | 558 |
| 559 AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) { | 559 AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) { |
| 560 Thread* thread = Thread::Current(); |
| 561 Zone* zone = thread->zone(); |
| 562 Isolate* isolate = thread->isolate(); |
| 560 if (is_super_getter()) { | 563 if (is_super_getter()) { |
| 561 ASSERT(receiver() != NULL); | 564 ASSERT(receiver() != NULL); |
| 562 const String& setter_name = | 565 const String& setter_name = |
| 563 String::ZoneHandle(Field::SetterSymbol(field_name_)); | 566 String::ZoneHandle(zone, Field::SetterSymbol(field_name_)); |
| 564 Function& setter = Function::ZoneHandle( | 567 Function& setter = Function::ZoneHandle(zone, |
| 565 Resolver::ResolveDynamicAnyArgs(cls(), setter_name)); | 568 Resolver::ResolveDynamicAnyArgs(cls(), setter_name)); |
| 566 if (setter.IsNull() || setter.is_abstract()) { | 569 if (setter.IsNull() || setter.is_abstract()) { |
| 567 // No instance setter found in super class chain, | 570 // No instance setter found in super class chain, |
| 568 // noSuchMethod will be called at runtime. | 571 // noSuchMethod will be called at runtime. |
| 569 return new StaticSetterNode(token_pos(), | 572 return new StaticSetterNode(token_pos(), |
| 570 receiver(), | 573 receiver(), |
| 571 cls(), | 574 cls(), |
| 572 field_name_, | 575 field_name_, |
| 573 rhs); | 576 rhs); |
| 574 } | 577 } |
| 575 return new StaticSetterNode(token_pos(), | 578 return new StaticSetterNode(token_pos(), |
| 576 receiver(), | 579 receiver(), |
| 577 field_name_, | 580 field_name_, |
| 578 setter, | 581 setter, |
| 579 rhs); | 582 rhs); |
| 580 } | 583 } |
| 581 | 584 |
| 582 if (owner().IsLibraryPrefix()) { | 585 if (owner().IsLibraryPrefix()) { |
| 583 const LibraryPrefix& prefix = LibraryPrefix::Cast(owner_); | 586 const LibraryPrefix& prefix = LibraryPrefix::Cast(owner_); |
| 584 // The parser has already dealt with the pathological case where a | 587 // The parser has already dealt with the pathological case where a |
| 585 // library imports itself. See Parser::ResolveIdentInPrefixScope() | 588 // library imports itself. See Parser::ResolveIdentInPrefixScope() |
| 586 ASSERT(field_name_.CharAt(0) != Library::kPrivateIdentifierStart); | 589 ASSERT(field_name_.CharAt(0) != Library::kPrivateIdentifierStart); |
| 587 | 590 |
| 588 // If the prefix is not yet loaded, the getter doesn't exist. Return a | 591 // If the prefix is not yet loaded, the getter doesn't exist. Return a |
| 589 // setter that will throw a NSME at runtime. | 592 // setter that will throw a NSME at runtime. |
| 590 if (!prefix.is_loaded()) { | 593 if (!prefix.is_loaded()) { |
| 591 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); | 594 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); |
| 592 } | 595 } |
| 593 | 596 |
| 594 Object& obj = Object::Handle(prefix.LookupObject(field_name_)); | 597 Object& obj = Object::Handle(zone, prefix.LookupObject(field_name_)); |
| 595 if (obj.IsField()) { | 598 if (obj.IsField()) { |
| 596 const Field& field = Field::ZoneHandle(Field::Cast(obj).raw()); | 599 const Field& field = Field::ZoneHandle(zone, Field::Cast(obj).raw()); |
| 597 if (!field.is_final()) { | 600 if (!field.is_final()) { |
| 598 if (Isolate::Current()->TypeChecksEnabled()) { | 601 if (isolate->flags().type_checks()) { |
| 599 rhs = new AssignableNode(field.token_pos(), | 602 rhs = new AssignableNode(field.token_pos(), |
| 600 rhs, | 603 rhs, |
| 601 AbstractType::ZoneHandle(field.type()), | 604 AbstractType::ZoneHandle(zone, field.type()), |
| 602 field_name_); | 605 field_name_); |
| 603 } | 606 } |
| 604 return new StoreStaticFieldNode(token_pos(), field, rhs); | 607 return new StoreStaticFieldNode(token_pos(), field, rhs); |
| 605 } | 608 } |
| 606 } | 609 } |
| 607 | 610 |
| 608 // No field found in prefix. Look for a setter function. | 611 // No field found in prefix. Look for a setter function. |
| 609 const String& setter_name = String::Handle(Field::SetterName(field_name_)); | 612 const String& setter_name = String::Handle(zone, |
| 613 Field::SetterName(field_name_)); |
| 610 obj = prefix.LookupObject(setter_name); | 614 obj = prefix.LookupObject(setter_name); |
| 611 if (obj.IsFunction()) { | 615 if (obj.IsFunction()) { |
| 612 const Function& setter = Function::ZoneHandle(Function::Cast(obj).raw()); | 616 const Function& setter = Function::ZoneHandle(zone, |
| 617 Function::Cast(obj).raw()); |
| 613 ASSERT(setter.is_static() && setter.IsSetterFunction()); | 618 ASSERT(setter.is_static() && setter.IsSetterFunction()); |
| 614 return new StaticSetterNode( | 619 return new StaticSetterNode( |
| 615 token_pos(), NULL, field_name_, setter, rhs); | 620 token_pos(), NULL, field_name_, setter, rhs); |
| 616 } | 621 } |
| 617 | 622 |
| 618 // No writeable field and no setter found in the prefix. Return a | 623 // No writeable field and no setter found in the prefix. Return a |
| 619 // non-existing setter that will throw an NSM error. | 624 // non-existing setter that will throw an NSM error. |
| 620 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); | 625 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); |
| 621 } | 626 } |
| 622 | 627 |
| 623 if (owner().IsLibrary()) { | 628 if (owner().IsLibrary()) { |
| 624 const Library& library = Library::Cast(owner()); | 629 const Library& library = Library::Cast(owner()); |
| 625 Object& obj = Object::Handle(library.ResolveName(field_name_)); | 630 Object& obj = Object::Handle(zone, library.ResolveName(field_name_)); |
| 626 if (obj.IsField()) { | 631 if (obj.IsField()) { |
| 627 const Field& field = Field::ZoneHandle(Field::Cast(obj).raw()); | 632 const Field& field = Field::ZoneHandle(zone, Field::Cast(obj).raw()); |
| 628 if (!field.is_final()) { | 633 if (!field.is_final()) { |
| 629 if (Isolate::Current()->TypeChecksEnabled()) { | 634 if (isolate->flags().type_checks()) { |
| 630 rhs = new AssignableNode(field.token_pos(), | 635 rhs = new AssignableNode(field.token_pos(), |
| 631 rhs, | 636 rhs, |
| 632 AbstractType::ZoneHandle(field.type()), | 637 AbstractType::ZoneHandle(zone, field.type()), |
| 633 field_name_); | 638 field_name_); |
| 634 } | 639 } |
| 635 return new StoreStaticFieldNode(token_pos(), field, rhs); | 640 return new StoreStaticFieldNode(token_pos(), field, rhs); |
| 636 } | 641 } |
| 637 } | 642 } |
| 638 | 643 |
| 639 // No field found in library. Look for a setter function. | 644 // No field found in library. Look for a setter function. |
| 640 const String& setter_name = String::Handle(Field::SetterName(field_name_)); | 645 const String& setter_name = String::Handle(zone, |
| 646 Field::SetterName(field_name_)); |
| 641 obj = library.ResolveName(setter_name); | 647 obj = library.ResolveName(setter_name); |
| 642 if (obj.IsFunction()) { | 648 if (obj.IsFunction()) { |
| 643 const Function& setter = Function::ZoneHandle(Function::Cast(obj).raw()); | 649 const Function& setter = Function::ZoneHandle(zone, |
| 650 Function::Cast(obj).raw()); |
| 644 ASSERT(setter.is_static() && setter.IsSetterFunction()); | 651 ASSERT(setter.is_static() && setter.IsSetterFunction()); |
| 645 return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs); | 652 return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs); |
| 646 } | 653 } |
| 647 | 654 |
| 648 // No writeable field and no setter found in the library. Return a | 655 // No writeable field and no setter found in the library. Return a |
| 649 // non-existing setter that will throw an NSM error. | 656 // non-existing setter that will throw an NSM error. |
| 650 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); | 657 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); |
| 651 } | 658 } |
| 652 | 659 |
| 653 const Function& setter = | 660 const Function& setter = |
| 654 Function::ZoneHandle(cls().LookupSetterFunction(field_name_)); | 661 Function::ZoneHandle(zone, cls().LookupSetterFunction(field_name_)); |
| 655 if (!setter.IsNull() && setter.IsStaticFunction()) { | 662 if (!setter.IsNull() && setter.IsStaticFunction()) { |
| 656 return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs); | 663 return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs); |
| 657 } | 664 } |
| 658 // Could not find a static setter. Look for a field. | 665 // Could not find a static setter. Look for a field. |
| 659 // Access to a lazily initialized static field that has not yet been | 666 // Access to a lazily initialized static field that has not yet been |
| 660 // initialized is compiled to a static implicit getter. | 667 // initialized is compiled to a static implicit getter. |
| 661 // A setter may not exist for such a field. | 668 // A setter may not exist for such a field. |
| 662 const Field& field = Field::ZoneHandle(cls().LookupStaticField(field_name_)); | 669 const Field& field = Field::ZoneHandle(zone, |
| 670 cls().LookupStaticField(field_name_)); |
| 663 if (!field.IsNull()) { | 671 if (!field.IsNull()) { |
| 664 if (field.is_final()) { | 672 if (field.is_final()) { |
| 665 // Attempting to assign to a final variable will cause a NoSuchMethodError | 673 // Attempting to assign to a final variable will cause a NoSuchMethodError |
| 666 // to be thrown. Change static getter to non-existent static setter in | 674 // to be thrown. Change static getter to non-existent static setter in |
| 667 // order to trigger the throw at runtime. | 675 // order to trigger the throw at runtime. |
| 668 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); | 676 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); |
| 669 } | 677 } |
| 670 #if defined(DEBUG) | 678 #if defined(DEBUG) |
| 671 const String& getter_name = String::Handle(Field::GetterName(field_name_)); | 679 const String& getter_name = String::Handle(zone, |
| 680 Field::GetterName(field_name_)); |
| 672 const Function& getter = | 681 const Function& getter = |
| 673 Function::Handle(cls().LookupStaticFunction(getter_name)); | 682 Function::Handle(zone, cls().LookupStaticFunction(getter_name)); |
| 674 ASSERT(!getter.IsNull() && | 683 ASSERT(!getter.IsNull() && |
| 675 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)); | 684 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)); |
| 676 #endif | 685 #endif |
| 677 if (Isolate::Current()->TypeChecksEnabled()) { | 686 if (isolate->flags().type_checks()) { |
| 678 rhs = new AssignableNode( | 687 rhs = new AssignableNode( |
| 679 field.token_pos(), | 688 field.token_pos(), |
| 680 rhs, | 689 rhs, |
| 681 AbstractType::ZoneHandle(field.type()), | 690 AbstractType::ZoneHandle(zone, field.type()), |
| 682 String::ZoneHandle(field.name())); | 691 String::ZoneHandle(zone, field.name())); |
| 683 } | 692 } |
| 684 return new StoreStaticFieldNode(token_pos(), field, rhs); | 693 return new StoreStaticFieldNode(token_pos(), field, rhs); |
| 685 } | 694 } |
| 686 // Didn't find a static setter or a static field. Make a call to | 695 // Didn't find a static setter or a static field. Make a call to |
| 687 // the non-existent setter to trigger a NoSuchMethodError at runtime. | 696 // the non-existent setter to trigger a NoSuchMethodError at runtime. |
| 688 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); | 697 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); |
| 689 } | 698 } |
| 690 | 699 |
| 691 | 700 |
| 692 AstNode* StaticCallNode::MakeAssignmentNode(AstNode* rhs) { | 701 AstNode* StaticCallNode::MakeAssignmentNode(AstNode* rhs) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 if (result.IsError() || result.IsNull()) { | 743 if (result.IsError() || result.IsNull()) { |
| 735 // TODO(turnidge): We could get better error messages by returning | 744 // TODO(turnidge): We could get better error messages by returning |
| 736 // the Error object directly to the parser. This will involve | 745 // the Error object directly to the parser. This will involve |
| 737 // replumbing all of the EvalConstExpr methods. | 746 // replumbing all of the EvalConstExpr methods. |
| 738 return NULL; | 747 return NULL; |
| 739 } | 748 } |
| 740 return &Instance::ZoneHandle(Instance::Cast(result).raw()); | 749 return &Instance::ZoneHandle(Instance::Cast(result).raw()); |
| 741 } | 750 } |
| 742 | 751 |
| 743 } // namespace dart | 752 } // namespace dart |
| OLD | NEW |