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

Side by Side Diff: src/runtime.cc

Issue 6334107: Merge r6592, r6612, r6618, r6626 and r6636 into 3.0 branch (Closed) Base URL: http://v8.googlecode.com/svn/branches/3.0/
Patch Set: '' Created 9 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « src/objects.cc ('k') | src/v8natives.js » ('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 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 626 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 if (!result->IsProperty()) { 637 if (!result->IsProperty()) {
638 Object* proto = obj->GetPrototype(); 638 Object* proto = obj->GetPrototype();
639 if (proto->IsJSObject() && 639 if (proto->IsJSObject() &&
640 JSObject::cast(proto)->map()->is_hidden_prototype()) 640 JSObject::cast(proto)->map()->is_hidden_prototype())
641 GetOwnPropertyImplementation(JSObject::cast(proto), 641 GetOwnPropertyImplementation(JSObject::cast(proto),
642 name, result); 642 name, result);
643 } 643 }
644 } 644 }
645 645
646 646
647 static bool CheckAccessException(LookupResult* result,
648 v8::AccessType access_type) {
649 if (result->type() == CALLBACKS) {
650 Object* callback = result->GetCallbackObject();
651 if (callback->IsAccessorInfo()) {
652 AccessorInfo* info = AccessorInfo::cast(callback);
653 bool can_access =
654 (access_type == v8::ACCESS_HAS &&
655 (info->all_can_read() || info->all_can_write())) ||
656 (access_type == v8::ACCESS_GET && info->all_can_read()) ||
657 (access_type == v8::ACCESS_SET && info->all_can_write());
658 return can_access;
659 }
660 }
661
662 return false;
663 }
664
665
666 static bool CheckAccess(JSObject* obj,
667 String* name,
668 LookupResult* result,
669 v8::AccessType access_type) {
670 ASSERT(result->IsProperty());
671
672 JSObject* holder = result->holder();
673 JSObject* current = obj;
674 while (true) {
675 if (current->IsAccessCheckNeeded() &&
676 !Top::MayNamedAccess(current, name, access_type)) {
677 // Access check callback denied the access, but some properties
678 // can have a special permissions which override callbacks descision
679 // (currently see v8::AccessControl).
680 break;
681 }
682
683 if (current == holder) {
684 return true;
685 }
686
687 current = JSObject::cast(current->GetPrototype());
688 }
689
690 // API callbacks can have per callback access exceptions.
691 switch (result->type()) {
692 case CALLBACKS: {
693 if (CheckAccessException(result, access_type)) {
694 return true;
695 }
696 break;
697 }
698 case INTERCEPTOR: {
699 // If the object has an interceptor, try real named properties.
700 // Overwrite the result to fetch the correct property later.
701 holder->LookupRealNamedProperty(name, result);
702 if (result->IsProperty()) {
703 if (CheckAccessException(result, access_type)) {
704 return true;
705 }
706 }
707 break;
708 }
709 default:
710 break;
711 }
712
713 Top::ReportFailedAccessCheck(current, access_type);
714 return false;
715 }
716
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
647 // Enumerator used as indices into the array returned from GetOwnProperty 731 // Enumerator used as indices into the array returned from GetOwnProperty
648 enum PropertyDescriptorIndices { 732 enum PropertyDescriptorIndices {
649 IS_ACCESSOR_INDEX, 733 IS_ACCESSOR_INDEX,
650 VALUE_INDEX, 734 VALUE_INDEX,
651 GETTER_INDEX, 735 GETTER_INDEX,
652 SETTER_INDEX, 736 SETTER_INDEX,
653 WRITABLE_INDEX, 737 WRITABLE_INDEX,
654 ENUMERABLE_INDEX, 738 ENUMERABLE_INDEX,
655 CONFIGURABLE_INDEX, 739 CONFIGURABLE_INDEX,
656 DESCRIPTOR_SIZE 740 DESCRIPTOR_SIZE
(...skipping 22 matching lines...) Expand all
679 case JSObject::UNDEFINED_ELEMENT: 763 case JSObject::UNDEFINED_ELEMENT:
680 return Heap::undefined_value(); 764 return Heap::undefined_value();
681 765
682 case JSObject::STRING_CHARACTER_ELEMENT: { 766 case JSObject::STRING_CHARACTER_ELEMENT: {
683 // Special handling of string objects according to ECMAScript 5 767 // Special handling of string objects according to ECMAScript 5
684 // 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
685 // other than the actual string value. This is covered by the 769 // other than the actual string value. This is covered by the
686 // subsequent cases. 770 // subsequent cases.
687 Handle<JSValue> js_value = Handle<JSValue>::cast(obj); 771 Handle<JSValue> js_value = Handle<JSValue>::cast(obj);
688 Handle<String> str(String::cast(js_value->value())); 772 Handle<String> str(String::cast(js_value->value()));
689 Handle<String> substr = SubString(str, index, index+1, NOT_TENURED); 773 Handle<String> substr = SubString(str, index, index + 1, NOT_TENURED);
690 774
691 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); 775 elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
692 elms->set(VALUE_INDEX, *substr); 776 elms->set(VALUE_INDEX, *substr);
693 elms->set(WRITABLE_INDEX, Heap::false_value()); 777 elms->set(WRITABLE_INDEX, Heap::false_value());
694 elms->set(ENUMERABLE_INDEX, Heap::false_value()); 778 elms->set(ENUMERABLE_INDEX, Heap::false_value());
695 elms->set(CONFIGURABLE_INDEX, Heap::false_value()); 779 elms->set(CONFIGURABLE_INDEX, Heap::false_value());
696 return *desc; 780 return *desc;
697 } 781 }
698 782
699 case JSObject::INTERCEPTED_ELEMENT: 783 case JSObject::INTERCEPTED_ELEMENT:
700 case JSObject::FAST_ELEMENT: { 784 case JSObject::FAST_ELEMENT: {
701 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); 785 elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
702 Handle<Object> element = GetElement(Handle<Object>(obj), index); 786 elms->set(VALUE_INDEX, *GetElement(obj, index));
703 elms->set(VALUE_INDEX, *element);
704 elms->set(WRITABLE_INDEX, Heap::true_value()); 787 elms->set(WRITABLE_INDEX, Heap::true_value());
705 elms->set(ENUMERABLE_INDEX, Heap::true_value()); 788 elms->set(ENUMERABLE_INDEX, Heap::true_value());
706 elms->set(CONFIGURABLE_INDEX, Heap::true_value()); 789 elms->set(CONFIGURABLE_INDEX, Heap::true_value());
707 return *desc; 790 return *desc;
708 } 791 }
709 792
710 case JSObject::DICTIONARY_ELEMENT: { 793 case JSObject::DICTIONARY_ELEMENT: {
711 NumberDictionary* dictionary = obj->element_dictionary(); 794 Handle<JSObject> holder = obj;
795 if (obj->IsJSGlobalProxy()) {
796 Object* proto = obj->GetPrototype();
797 if (proto->IsNull()) return Heap::undefined_value();
798 ASSERT(proto->IsJSGlobalObject());
799 holder = Handle<JSObject>(JSObject::cast(proto));
800 }
801 NumberDictionary* dictionary = holder->element_dictionary();
712 int entry = dictionary->FindEntry(index); 802 int entry = dictionary->FindEntry(index);
713 ASSERT(entry != NumberDictionary::kNotFound); 803 ASSERT(entry != NumberDictionary::kNotFound);
714 PropertyDetails details = dictionary->DetailsAt(entry); 804 PropertyDetails details = dictionary->DetailsAt(entry);
715 switch (details.type()) { 805 switch (details.type()) {
716 case CALLBACKS: { 806 case CALLBACKS: {
717 // This is an accessor property with getter and/or setter. 807 // This is an accessor property with getter and/or setter.
718 FixedArray* callbacks = 808 FixedArray* callbacks =
719 FixedArray::cast(dictionary->ValueAt(entry)); 809 FixedArray::cast(dictionary->ValueAt(entry));
720 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); 810 elms->set(IS_ACCESSOR_INDEX, Heap::true_value());
721 elms->set(GETTER_INDEX, callbacks->get(0)); 811 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) {
722 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 }
723 break; 817 break;
724 } 818 }
725 case NORMAL: 819 case NORMAL:
726 // This is a data property. 820 // This is a data property.
727 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); 821 elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
728 elms->set(VALUE_INDEX, dictionary->ValueAt(entry)); 822 elms->set(VALUE_INDEX, *GetElement(obj, index));
729 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!details.IsReadOnly())); 823 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!details.IsReadOnly()));
730 break; 824 break;
731 default: 825 default:
732 UNREACHABLE(); 826 UNREACHABLE();
733 break; 827 break;
734 } 828 }
735 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!details.IsDontEnum())); 829 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!details.IsDontEnum()));
736 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!details.IsDontDelete())); 830 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!details.IsDontDelete()));
737 return *desc; 831 return *desc;
738 } 832 }
739 } 833 }
740 } 834 }
741 835
742 // Use recursive implementation to also traverse hidden prototypes 836 // Use recursive implementation to also traverse hidden prototypes
743 GetOwnPropertyImplementation(*obj, *name, &result); 837 GetOwnPropertyImplementation(*obj, *name, &result);
744 838
745 if (!result.IsProperty()) { 839 if (!result.IsProperty()) {
746 return Heap::undefined_value(); 840 return Heap::undefined_value();
747 } 841 }
748 842
843 if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) {
844 return Heap::false_value();
845 }
846
749 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!result.IsDontEnum())); 847 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!result.IsDontEnum()));
750 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!result.IsDontDelete())); 848 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!result.IsDontDelete()));
751 849
752 bool is_js_accessor = (result.type() == CALLBACKS) && 850 bool is_js_accessor = (result.type() == CALLBACKS) &&
753 (result.GetCallbackObject()->IsFixedArray()); 851 (result.GetCallbackObject()->IsFixedArray());
754 852
755 if (is_js_accessor) { 853 if (is_js_accessor) {
756 // __defineGetter__/__defineSetter__ callback. 854 // __defineGetter__/__defineSetter__ callback.
855 elms->set(IS_ACCESSOR_INDEX, Heap::true_value());
856
757 FixedArray* structure = FixedArray::cast(result.GetCallbackObject()); 857 FixedArray* structure = FixedArray::cast(result.GetCallbackObject());
758 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); 858 if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) {
759 elms->set(GETTER_INDEX, structure->get(0)); 859 elms->set(GETTER_INDEX, structure->get(0));
760 elms->set(SETTER_INDEX, structure->get(1)); 860 }
861 if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) {
862 elms->set(SETTER_INDEX, structure->get(1));
863 }
761 } else { 864 } else {
762 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); 865 elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
763 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly())); 866 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly()));
764 867
765 PropertyAttributes attrs; 868 PropertyAttributes attrs;
766 Object* value; 869 Object* value;
870 // GetProperty will check access and report any violations.
767 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs); 871 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs);
768 if (!maybe_value->ToObject(&value)) return maybe_value; 872 if (!maybe_value->ToObject(&value)) return maybe_value;
769 } 873 }
770 elms->set(VALUE_INDEX, value); 874 elms->set(VALUE_INDEX, value);
771 } 875 }
772 876
773 return *desc; 877 return *desc;
774 } 878 }
775 879
776 880
(...skipping 10132 matching lines...) Expand 10 before | Expand all | Expand 10 after
10909 } else { 11013 } else {
10910 // Handle last resort GC and make sure to allow future allocations 11014 // Handle last resort GC and make sure to allow future allocations
10911 // to grow the heap without causing GCs (if possible). 11015 // to grow the heap without causing GCs (if possible).
10912 Counters::gc_last_resort_from_js.Increment(); 11016 Counters::gc_last_resort_from_js.Increment();
10913 Heap::CollectAllGarbage(false); 11017 Heap::CollectAllGarbage(false);
10914 } 11018 }
10915 } 11019 }
10916 11020
10917 11021
10918 } } // namespace v8::internal 11022 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | src/v8natives.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698