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

Side by Side Diff: src/runtime.cc

Issue 6250133: Merge r6592, r6612, r6618 and r6626 into 2.4 branch (Closed) Base URL: http://v8.googlecode.com/svn/branches/2.4/
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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 595 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 if (!result->IsProperty()) { 606 if (!result->IsProperty()) {
607 Object* proto = obj->GetPrototype(); 607 Object* proto = obj->GetPrototype();
608 if (proto->IsJSObject() && 608 if (proto->IsJSObject() &&
609 JSObject::cast(proto)->map()->is_hidden_prototype()) 609 JSObject::cast(proto)->map()->is_hidden_prototype())
610 GetOwnPropertyImplementation(JSObject::cast(proto), 610 GetOwnPropertyImplementation(JSObject::cast(proto),
611 name, result); 611 name, result);
612 } 612 }
613 } 613 }
614 614
615 615
616 static bool CheckAccessException(LookupResult* result,
617 v8::AccessType access_type) {
618 if (result->type() == CALLBACKS) {
619 Object* callback = result->GetCallbackObject();
620 if (callback->IsAccessorInfo()) {
621 AccessorInfo* info = AccessorInfo::cast(callback);
622 bool can_access =
623 (access_type == v8::ACCESS_HAS &&
624 (info->all_can_read() || info->all_can_write())) ||
625 (access_type == v8::ACCESS_GET && info->all_can_read()) ||
626 (access_type == v8::ACCESS_SET && info->all_can_write());
627 return can_access;
628 }
629 }
630
631 return false;
632 }
633
634
635 static bool CheckAccess(JSObject* obj,
636 String* name,
637 LookupResult* result,
638 v8::AccessType access_type) {
639 ASSERT(result->IsProperty());
640
641 JSObject* holder = result->holder();
642 JSObject* current = obj;
643 while (true) {
644 if (current->IsAccessCheckNeeded() &&
645 !Top::MayNamedAccess(current, name, access_type)) {
646 // Access check callback denied the access, but some properties
647 // can have a special permissions which override callbacks descision
648 // (currently see v8::AccessControl).
649 break;
650 }
651
652 if (current == holder) {
653 return true;
654 }
655
656 current = JSObject::cast(current->GetPrototype());
657 }
658
659 // API callbacks can have per callback access exceptions.
660 switch (result->type()) {
661 case CALLBACKS: {
662 if (CheckAccessException(result, access_type)) {
663 return true;
664 }
665 break;
666 }
667 case INTERCEPTOR: {
668 // If the object has an interceptor, try real named properties.
669 // Overwrite the result to fetch the correct property later.
670 holder->LookupRealNamedProperty(name, result);
671 if (result->IsProperty()) {
672 if (CheckAccessException(result, access_type)) {
673 return true;
674 }
675 }
676 break;
677 }
678 default:
679 break;
680 }
681
682 Top::ReportFailedAccessCheck(current, access_type);
683 return false;
684 }
685
686
687 // TODO(1095): we should traverse hidden prototype hierachy as well.
688 static bool CheckElementAccess(JSObject* obj,
689 uint32_t index,
690 v8::AccessType access_type) {
691 if (obj->IsAccessCheckNeeded() &&
692 !Top::MayIndexedAccess(obj, index, access_type)) {
693 return false;
694 }
695
696 return true;
697 }
698
699
616 // Enumerator used as indices into the array returned from GetOwnProperty 700 // Enumerator used as indices into the array returned from GetOwnProperty
617 enum PropertyDescriptorIndices { 701 enum PropertyDescriptorIndices {
618 IS_ACCESSOR_INDEX, 702 IS_ACCESSOR_INDEX,
619 VALUE_INDEX, 703 VALUE_INDEX,
620 GETTER_INDEX, 704 GETTER_INDEX,
621 SETTER_INDEX, 705 SETTER_INDEX,
622 WRITABLE_INDEX, 706 WRITABLE_INDEX,
623 ENUMERABLE_INDEX, 707 ENUMERABLE_INDEX,
624 CONFIGURABLE_INDEX, 708 CONFIGURABLE_INDEX,
625 DESCRIPTOR_SIZE 709 DESCRIPTOR_SIZE
(...skipping 22 matching lines...) Expand all
648 case JSObject::UNDEFINED_ELEMENT: 732 case JSObject::UNDEFINED_ELEMENT:
649 return Heap::undefined_value(); 733 return Heap::undefined_value();
650 734
651 case JSObject::STRING_CHARACTER_ELEMENT: { 735 case JSObject::STRING_CHARACTER_ELEMENT: {
652 // Special handling of string objects according to ECMAScript 5 736 // Special handling of string objects according to ECMAScript 5
653 // 15.5.5.2. Note that this might be a string object with elements 737 // 15.5.5.2. Note that this might be a string object with elements
654 // other than the actual string value. This is covered by the 738 // other than the actual string value. This is covered by the
655 // subsequent cases. 739 // subsequent cases.
656 Handle<JSValue> js_value = Handle<JSValue>::cast(obj); 740 Handle<JSValue> js_value = Handle<JSValue>::cast(obj);
657 Handle<String> str(String::cast(js_value->value())); 741 Handle<String> str(String::cast(js_value->value()));
658 Handle<String> substr = SubString(str, index, index+1, NOT_TENURED); 742 Handle<String> substr = SubString(str, index, index + 1, NOT_TENURED);
659 743
660 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); 744 elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
661 elms->set(VALUE_INDEX, *substr); 745 elms->set(VALUE_INDEX, *substr);
662 elms->set(WRITABLE_INDEX, Heap::false_value()); 746 elms->set(WRITABLE_INDEX, Heap::false_value());
663 elms->set(ENUMERABLE_INDEX, Heap::false_value()); 747 elms->set(ENUMERABLE_INDEX, Heap::false_value());
664 elms->set(CONFIGURABLE_INDEX, Heap::false_value()); 748 elms->set(CONFIGURABLE_INDEX, Heap::false_value());
665 return *desc; 749 return *desc;
666 } 750 }
667 751
668 case JSObject::INTERCEPTED_ELEMENT: 752 case JSObject::INTERCEPTED_ELEMENT:
669 case JSObject::FAST_ELEMENT: { 753 case JSObject::FAST_ELEMENT: {
670 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); 754 elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
671 Handle<Object> element = GetElement(Handle<Object>(obj), index); 755 elms->set(VALUE_INDEX, *GetElement(obj, index));
672 elms->set(VALUE_INDEX, *element);
673 elms->set(WRITABLE_INDEX, Heap::true_value()); 756 elms->set(WRITABLE_INDEX, Heap::true_value());
674 elms->set(ENUMERABLE_INDEX, Heap::true_value()); 757 elms->set(ENUMERABLE_INDEX, Heap::true_value());
675 elms->set(CONFIGURABLE_INDEX, Heap::true_value()); 758 elms->set(CONFIGURABLE_INDEX, Heap::true_value());
676 return *desc; 759 return *desc;
677 } 760 }
678 761
679 case JSObject::DICTIONARY_ELEMENT: { 762 case JSObject::DICTIONARY_ELEMENT: {
680 NumberDictionary* dictionary = obj->element_dictionary(); 763 Handle<JSObject> holder = obj;
764 if (obj->IsJSGlobalProxy()) {
765 Object* proto = obj->GetPrototype();
766 if (proto->IsNull()) return Heap::undefined_value();
767 ASSERT(proto->IsJSGlobalObject());
768 holder = Handle<JSObject>(JSObject::cast(proto));
769 }
770 NumberDictionary* dictionary = holder->element_dictionary();
681 int entry = dictionary->FindEntry(index); 771 int entry = dictionary->FindEntry(index);
682 ASSERT(entry != NumberDictionary::kNotFound); 772 ASSERT(entry != NumberDictionary::kNotFound);
683 PropertyDetails details = dictionary->DetailsAt(entry); 773 PropertyDetails details = dictionary->DetailsAt(entry);
684 switch (details.type()) { 774 switch (details.type()) {
685 case CALLBACKS: { 775 case CALLBACKS: {
686 // This is an accessor property with getter and/or setter. 776 // This is an accessor property with getter and/or setter.
687 FixedArray* callbacks = 777 FixedArray* callbacks =
688 FixedArray::cast(dictionary->ValueAt(entry)); 778 FixedArray::cast(dictionary->ValueAt(entry));
689 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); 779 elms->set(IS_ACCESSOR_INDEX, Heap::true_value());
690 elms->set(GETTER_INDEX, callbacks->get(0)); 780 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) {
691 elms->set(SETTER_INDEX, callbacks->get(1)); 781 elms->set(GETTER_INDEX, callbacks->get(0));
782 }
783 if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) {
784 elms->set(SETTER_INDEX, callbacks->get(1));
785 }
692 break; 786 break;
693 } 787 }
694 case NORMAL: 788 case NORMAL:
695 // This is a data property. 789 // This is a data property.
696 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); 790 elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
697 elms->set(VALUE_INDEX, dictionary->ValueAt(entry)); 791 elms->set(VALUE_INDEX, *GetElement(obj, index));
698 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!details.IsReadOnly())); 792 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!details.IsReadOnly()));
699 break; 793 break;
700 default: 794 default:
701 UNREACHABLE(); 795 UNREACHABLE();
702 break; 796 break;
703 } 797 }
704 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!details.IsDontEnum())); 798 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!details.IsDontEnum()));
705 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!details.IsDontDelete())); 799 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!details.IsDontDelete()));
706 return *desc; 800 return *desc;
707 } 801 }
708 } 802 }
709 } 803 }
710 804
711 // Use recursive implementation to also traverse hidden prototypes 805 // Use recursive implementation to also traverse hidden prototypes
712 GetOwnPropertyImplementation(*obj, *name, &result); 806 GetOwnPropertyImplementation(*obj, *name, &result);
713 807
714 if (!result.IsProperty()) { 808 if (!result.IsProperty()) {
715 return Heap::undefined_value(); 809 return Heap::undefined_value();
716 } 810 }
717 811
812 if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) {
813 return Heap::false_value();
814 }
815
718 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!result.IsDontEnum())); 816 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!result.IsDontEnum()));
719 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!result.IsDontDelete())); 817 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!result.IsDontDelete()));
720 818
721 bool is_js_accessor = (result.type() == CALLBACKS) && 819 bool is_js_accessor = (result.type() == CALLBACKS) &&
722 (result.GetCallbackObject()->IsFixedArray()); 820 (result.GetCallbackObject()->IsFixedArray());
723 821
724 if (is_js_accessor) { 822 if (is_js_accessor) {
725 // __defineGetter__/__defineSetter__ callback. 823 // __defineGetter__/__defineSetter__ callback.
824 elms->set(IS_ACCESSOR_INDEX, Heap::true_value());
825
726 FixedArray* structure = FixedArray::cast(result.GetCallbackObject()); 826 FixedArray* structure = FixedArray::cast(result.GetCallbackObject());
727 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); 827 if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) {
728 elms->set(GETTER_INDEX, structure->get(0)); 828 elms->set(GETTER_INDEX, structure->get(0));
729 elms->set(SETTER_INDEX, structure->get(1)); 829 }
830 if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) {
831 elms->set(SETTER_INDEX, structure->get(1));
832 }
730 } else { 833 } else {
731 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); 834 elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
732 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly())); 835 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly()));
733 836
734 PropertyAttributes attrs; 837 PropertyAttributes attrs;
838 // GetProperty will check access and report any violations.
735 Object* value = obj->GetProperty(*obj, &result, *name, &attrs); 839 Object* value = obj->GetProperty(*obj, &result, *name, &attrs);
736 if (value->IsFailure()) return value; 840 if (value->IsFailure()) return value;
737 elms->set(VALUE_INDEX, value); 841 elms->set(VALUE_INDEX, value);
738 } 842 }
739 843
740 return *desc; 844 return *desc;
741 } 845 }
742 846
743 847
744 static Object* Runtime_PreventExtensions(Arguments args) { 848 static Object* Runtime_PreventExtensions(Arguments args) {
(...skipping 9407 matching lines...) Expand 10 before | Expand all | Expand 10 after
10152 } else { 10256 } else {
10153 // Handle last resort GC and make sure to allow future allocations 10257 // Handle last resort GC and make sure to allow future allocations
10154 // to grow the heap without causing GCs (if possible). 10258 // to grow the heap without causing GCs (if possible).
10155 Counters::gc_last_resort_from_js.Increment(); 10259 Counters::gc_last_resort_from_js.Increment();
10156 Heap::CollectAllGarbage(false); 10260 Heap::CollectAllGarbage(false);
10157 } 10261 }
10158 } 10262 }
10159 10263
10160 10264
10161 } } // namespace v8::internal 10265 } } // 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