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 |