OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 } | 708 } |
709 default: | 709 default: |
710 break; | 710 break; |
711 } | 711 } |
712 | 712 |
713 Top::ReportFailedAccessCheck(current, access_type); | 713 Top::ReportFailedAccessCheck(current, access_type); |
714 return false; | 714 return false; |
715 } | 715 } |
716 | 716 |
717 | 717 |
| 718 // TODO(1095): we should traverse hidden prototype hierachy as well. |
| 719 static bool CheckElementAccess(JSObject* obj, |
| 720 uint32_t index, |
| 721 v8::AccessType access_type) { |
| 722 if (obj->IsAccessCheckNeeded() && |
| 723 !Top::MayIndexedAccess(obj, index, access_type)) { |
| 724 return false; |
| 725 } |
| 726 |
| 727 return true; |
| 728 } |
| 729 |
| 730 |
718 // Enumerator used as indices into the array returned from GetOwnProperty | 731 // Enumerator used as indices into the array returned from GetOwnProperty |
719 enum PropertyDescriptorIndices { | 732 enum PropertyDescriptorIndices { |
720 IS_ACCESSOR_INDEX, | 733 IS_ACCESSOR_INDEX, |
721 VALUE_INDEX, | 734 VALUE_INDEX, |
722 GETTER_INDEX, | 735 GETTER_INDEX, |
723 SETTER_INDEX, | 736 SETTER_INDEX, |
724 WRITABLE_INDEX, | 737 WRITABLE_INDEX, |
725 ENUMERABLE_INDEX, | 738 ENUMERABLE_INDEX, |
726 CONFIGURABLE_INDEX, | 739 CONFIGURABLE_INDEX, |
727 DESCRIPTOR_SIZE | 740 DESCRIPTOR_SIZE |
(...skipping 22 matching lines...) Expand all Loading... |
750 case JSObject::UNDEFINED_ELEMENT: | 763 case JSObject::UNDEFINED_ELEMENT: |
751 return Heap::undefined_value(); | 764 return Heap::undefined_value(); |
752 | 765 |
753 case JSObject::STRING_CHARACTER_ELEMENT: { | 766 case JSObject::STRING_CHARACTER_ELEMENT: { |
754 // Special handling of string objects according to ECMAScript 5 | 767 // Special handling of string objects according to ECMAScript 5 |
755 // 15.5.5.2. Note that this might be a string object with elements | 768 // 15.5.5.2. Note that this might be a string object with elements |
756 // other than the actual string value. This is covered by the | 769 // other than the actual string value. This is covered by the |
757 // subsequent cases. | 770 // subsequent cases. |
758 Handle<JSValue> js_value = Handle<JSValue>::cast(obj); | 771 Handle<JSValue> js_value = Handle<JSValue>::cast(obj); |
759 Handle<String> str(String::cast(js_value->value())); | 772 Handle<String> str(String::cast(js_value->value())); |
760 Handle<String> substr = SubString(str, index, index+1, NOT_TENURED); | 773 Handle<String> substr = SubString(str, index, index + 1, NOT_TENURED); |
761 | 774 |
762 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); | 775 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); |
763 elms->set(VALUE_INDEX, *substr); | 776 elms->set(VALUE_INDEX, *substr); |
764 elms->set(WRITABLE_INDEX, Heap::false_value()); | 777 elms->set(WRITABLE_INDEX, Heap::false_value()); |
765 elms->set(ENUMERABLE_INDEX, Heap::false_value()); | 778 elms->set(ENUMERABLE_INDEX, Heap::false_value()); |
766 elms->set(CONFIGURABLE_INDEX, Heap::false_value()); | 779 elms->set(CONFIGURABLE_INDEX, Heap::false_value()); |
767 return *desc; | 780 return *desc; |
768 } | 781 } |
769 | 782 |
770 case JSObject::INTERCEPTED_ELEMENT: | 783 case JSObject::INTERCEPTED_ELEMENT: |
771 case JSObject::FAST_ELEMENT: { | 784 case JSObject::FAST_ELEMENT: { |
772 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); | 785 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); |
773 Handle<Object> element = GetElement(Handle<Object>(obj), index); | 786 elms->set(VALUE_INDEX, *GetElement(obj, index)); |
774 elms->set(VALUE_INDEX, *element); | |
775 elms->set(WRITABLE_INDEX, Heap::true_value()); | 787 elms->set(WRITABLE_INDEX, Heap::true_value()); |
776 elms->set(ENUMERABLE_INDEX, Heap::true_value()); | 788 elms->set(ENUMERABLE_INDEX, Heap::true_value()); |
777 elms->set(CONFIGURABLE_INDEX, Heap::true_value()); | 789 elms->set(CONFIGURABLE_INDEX, Heap::true_value()); |
778 return *desc; | 790 return *desc; |
779 } | 791 } |
780 | 792 |
781 case JSObject::DICTIONARY_ELEMENT: { | 793 case JSObject::DICTIONARY_ELEMENT: { |
| 794 Handle<JSObject> holder = obj; |
782 if (obj->IsJSGlobalProxy()) { | 795 if (obj->IsJSGlobalProxy()) { |
783 Object* proto = obj->GetPrototype(); | 796 Object* proto = obj->GetPrototype(); |
784 if (proto->IsNull()) return Heap::undefined_value(); | 797 if (proto->IsNull()) return Heap::undefined_value(); |
785 ASSERT(proto->IsJSGlobalObject()); | 798 ASSERT(proto->IsJSGlobalObject()); |
786 obj = Handle<JSObject>(JSObject::cast(proto)); | 799 holder = Handle<JSObject>(JSObject::cast(proto)); |
787 } | 800 } |
788 NumberDictionary* dictionary = obj->element_dictionary(); | 801 NumberDictionary* dictionary = holder->element_dictionary(); |
789 int entry = dictionary->FindEntry(index); | 802 int entry = dictionary->FindEntry(index); |
790 ASSERT(entry != NumberDictionary::kNotFound); | 803 ASSERT(entry != NumberDictionary::kNotFound); |
791 PropertyDetails details = dictionary->DetailsAt(entry); | 804 PropertyDetails details = dictionary->DetailsAt(entry); |
792 switch (details.type()) { | 805 switch (details.type()) { |
793 case CALLBACKS: { | 806 case CALLBACKS: { |
794 // This is an accessor property with getter and/or setter. | 807 // This is an accessor property with getter and/or setter. |
795 FixedArray* callbacks = | 808 FixedArray* callbacks = |
796 FixedArray::cast(dictionary->ValueAt(entry)); | 809 FixedArray::cast(dictionary->ValueAt(entry)); |
797 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); | 810 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); |
798 elms->set(GETTER_INDEX, callbacks->get(0)); | 811 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) { |
799 elms->set(SETTER_INDEX, callbacks->get(1)); | 812 elms->set(GETTER_INDEX, callbacks->get(0)); |
| 813 } |
| 814 if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) { |
| 815 elms->set(SETTER_INDEX, callbacks->get(1)); |
| 816 } |
800 break; | 817 break; |
801 } | 818 } |
802 case NORMAL: | 819 case NORMAL: |
803 // This is a data property. | 820 // This is a data property. |
804 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); | 821 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); |
805 elms->set(VALUE_INDEX, dictionary->ValueAt(entry)); | 822 elms->set(VALUE_INDEX, *GetElement(obj, index)); |
806 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!details.IsReadOnly())); | 823 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!details.IsReadOnly())); |
807 break; | 824 break; |
808 default: | 825 default: |
809 UNREACHABLE(); | 826 UNREACHABLE(); |
810 break; | 827 break; |
811 } | 828 } |
812 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!details.IsDontEnum())); | 829 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!details.IsDontEnum())); |
813 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!details.IsDontDelete())); | 830 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!details.IsDontDelete())); |
814 return *desc; | 831 return *desc; |
815 } | 832 } |
(...skipping 10182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10998 } else { | 11015 } else { |
10999 // Handle last resort GC and make sure to allow future allocations | 11016 // Handle last resort GC and make sure to allow future allocations |
11000 // to grow the heap without causing GCs (if possible). | 11017 // to grow the heap without causing GCs (if possible). |
11001 Counters::gc_last_resort_from_js.Increment(); | 11018 Counters::gc_last_resort_from_js.Increment(); |
11002 Heap::CollectAllGarbage(false); | 11019 Heap::CollectAllGarbage(false); |
11003 } | 11020 } |
11004 } | 11021 } |
11005 | 11022 |
11006 | 11023 |
11007 } } // namespace v8::internal | 11024 } } // namespace v8::internal |
OLD | NEW |