OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/objects.h" | 5 #include "src/objects.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <iomanip> | 8 #include <iomanip> |
9 #include <sstream> | 9 #include <sstream> |
10 | 10 |
(...skipping 6700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6711 | 6711 |
6712 return context->extension_object()->ReferencesObject(obj); | 6712 return context->extension_object()->ReferencesObject(obj); |
6713 } | 6713 } |
6714 } | 6714 } |
6715 | 6715 |
6716 // No references to object. | 6716 // No references to object. |
6717 return false; | 6717 return false; |
6718 } | 6718 } |
6719 | 6719 |
6720 | 6720 |
6721 Maybe<bool> JSObject::PreventExtensionsInternal(Handle<JSObject> object) { | 6721 #define RETURN_FAILURE(isolate, should_throw, call) \ |
6722 do { \ | |
6723 if ((should_throw) == DONT_THROW) { \ | |
6724 return Just(false); \ | |
6725 } else { \ | |
6726 isolate->Throw(*isolate->factory()->call); \ | |
6727 return Nothing<bool>(); \ | |
6728 } \ | |
6729 } while (false) | |
6730 | |
6731 | |
6732 Maybe<bool> JSReceiver::PreventExtensions(Handle<JSReceiver> object, | |
6733 ShouldThrow should_throw) { | |
6734 if (!object->IsJSObject()) return Just(false); // TODO(proxies) | |
rossberg
2015/10/19 14:33:08
Style nit: TODO(neis): what
neis
2015/10/20 07:58:35
Done.
| |
6735 return JSObject::PreventExtensions(Handle<JSObject>::cast(object), | |
6736 should_throw); | |
6737 } | |
6738 | |
6739 | |
6740 Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object, | |
6741 ShouldThrow should_throw) { | |
6722 Isolate* isolate = object->GetIsolate(); | 6742 Isolate* isolate = object->GetIsolate(); |
6723 | 6743 |
6724 if (!object->map()->is_extensible()) return Just(true); | 6744 if (!object->map()->is_extensible()) return Just(true); |
6725 | 6745 |
6726 if (!object->HasSloppyArgumentsElements() && !object->map()->is_observed()) { | 6746 if (!object->HasSloppyArgumentsElements() && !object->map()->is_observed()) { |
6727 return PreventExtensionsWithTransition<NONE>(object); | 6747 return PreventExtensionsWithTransition<NONE>(object, should_throw); |
6728 } | 6748 } |
6729 | 6749 |
6730 if (object->IsAccessCheckNeeded() && | 6750 if (object->IsAccessCheckNeeded() && |
6731 !isolate->MayAccess(handle(isolate->context()), object)) { | 6751 !isolate->MayAccess(handle(isolate->context()), object)) { |
6732 isolate->ReportFailedAccessCheck(object); | 6752 isolate->ReportFailedAccessCheck(object); |
6733 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); | 6753 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); |
6734 UNREACHABLE(); | 6754 UNREACHABLE(); |
6735 return Just(false); | 6755 RETURN_FAILURE(isolate, should_throw, |
6756 NewTypeError(MessageTemplate::kNoAccess)); | |
6736 } | 6757 } |
6737 | 6758 |
6738 if (object->IsJSGlobalProxy()) { | 6759 if (object->IsJSGlobalProxy()) { |
6739 PrototypeIterator iter(isolate, object); | 6760 PrototypeIterator iter(isolate, object); |
6740 if (iter.IsAtEnd()) return Just(true); | 6761 if (iter.IsAtEnd()) return Just(true); |
6741 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 6762 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
6742 return PreventExtensionsInternal( | 6763 return PreventExtensions(PrototypeIterator::GetCurrent<JSObject>(iter), |
6743 PrototypeIterator::GetCurrent<JSObject>(iter)); | 6764 should_throw); |
6744 } | 6765 } |
6745 | 6766 |
6746 // It's not possible to seal objects with external array elements | 6767 // It's not possible to seal objects with external array elements |
6747 if (object->HasFixedTypedArrayElements()) { | 6768 if (object->HasFixedTypedArrayElements()) { |
6748 isolate->Throw(*isolate->factory()->NewTypeError( | 6769 isolate->Throw(*isolate->factory()->NewTypeError( |
6749 MessageTemplate::kCannotPreventExtExternalArray)); | 6770 MessageTemplate::kCannotPreventExtExternalArray)); |
6750 return Nothing<bool>(); | 6771 return Nothing<bool>(); |
6751 } | 6772 } |
6752 | 6773 |
6753 // If there are fast elements we normalize. | 6774 // If there are fast elements we normalize. |
(...skipping 16 matching lines...) Expand all Loading... | |
6770 RETURN_ON_EXCEPTION_VALUE( | 6791 RETURN_ON_EXCEPTION_VALUE( |
6771 isolate, | 6792 isolate, |
6772 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), | 6793 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), |
6773 isolate->factory()->the_hole_value()), | 6794 isolate->factory()->the_hole_value()), |
6774 Nothing<bool>()); | 6795 Nothing<bool>()); |
6775 } | 6796 } |
6776 return Just(true); | 6797 return Just(true); |
6777 } | 6798 } |
6778 | 6799 |
6779 | 6800 |
6780 static MaybeHandle<Object> ReturnObjectOrThrowTypeError( | |
6781 Handle<JSObject> object, Maybe<bool> maybe, MessageTemplate::Template msg) { | |
6782 if (!maybe.IsJust()) return MaybeHandle<Object>(); | |
6783 if (maybe.FromJust()) return object; | |
6784 Isolate* isolate = object->GetIsolate(); | |
6785 THROW_NEW_ERROR(isolate, NewTypeError(msg), Object); | |
6786 } | |
6787 | |
6788 | |
6789 MaybeHandle<Object> JSObject::PreventExtensions(Handle<JSObject> object) { | |
6790 return ReturnObjectOrThrowTypeError(object, PreventExtensionsInternal(object), | |
6791 MessageTemplate::kCannotPreventExt); | |
6792 } | |
6793 | |
6794 | |
6795 bool JSObject::IsExtensible(Handle<JSObject> object) { | 6801 bool JSObject::IsExtensible(Handle<JSObject> object) { |
6796 Isolate* isolate = object->GetIsolate(); | 6802 Isolate* isolate = object->GetIsolate(); |
6797 if (object->IsAccessCheckNeeded() && | 6803 if (object->IsAccessCheckNeeded() && |
6798 !isolate->MayAccess(handle(isolate->context()), object)) { | 6804 !isolate->MayAccess(handle(isolate->context()), object)) { |
6799 return true; | 6805 return true; |
6800 } | 6806 } |
6801 if (object->IsJSGlobalProxy()) { | 6807 if (object->IsJSGlobalProxy()) { |
6802 PrototypeIterator iter(isolate, *object); | 6808 PrototypeIterator iter(isolate, *object); |
6803 if (iter.IsAtEnd()) return false; | 6809 if (iter.IsAtEnd()) return false; |
6804 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); | 6810 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); |
(...skipping 21 matching lines...) Expand all Loading... | |
6826 } | 6832 } |
6827 details = details.CopyAddAttributes( | 6833 details = details.CopyAddAttributes( |
6828 static_cast<PropertyAttributes>(attrs)); | 6834 static_cast<PropertyAttributes>(attrs)); |
6829 dictionary->DetailsAtPut(i, details); | 6835 dictionary->DetailsAtPut(i, details); |
6830 } | 6836 } |
6831 } | 6837 } |
6832 } | 6838 } |
6833 | 6839 |
6834 | 6840 |
6835 template <PropertyAttributes attrs> | 6841 template <PropertyAttributes attrs> |
6836 Maybe<bool> JSObject::PreventExtensionsWithTransition(Handle<JSObject> object) { | 6842 Maybe<bool> JSObject::PreventExtensionsWithTransition( |
6843 Handle<JSObject> object, ShouldThrow should_throw) { | |
6837 STATIC_ASSERT(attrs == NONE || attrs == SEALED || attrs == FROZEN); | 6844 STATIC_ASSERT(attrs == NONE || attrs == SEALED || attrs == FROZEN); |
6838 | 6845 |
6839 // Sealing/freezing sloppy arguments should be handled elsewhere. | 6846 // Sealing/freezing sloppy arguments should be handled elsewhere. |
6840 DCHECK(!object->HasSloppyArgumentsElements()); | 6847 DCHECK(!object->HasSloppyArgumentsElements()); |
6841 DCHECK(!object->map()->is_observed()); | 6848 DCHECK(!object->map()->is_observed()); |
6842 | 6849 |
6843 Isolate* isolate = object->GetIsolate(); | 6850 Isolate* isolate = object->GetIsolate(); |
6844 if (object->IsAccessCheckNeeded() && | 6851 if (object->IsAccessCheckNeeded() && |
6845 !isolate->MayAccess(handle(isolate->context()), object)) { | 6852 !isolate->MayAccess(handle(isolate->context()), object)) { |
6846 isolate->ReportFailedAccessCheck(object); | 6853 isolate->ReportFailedAccessCheck(object); |
6847 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); | 6854 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); |
6848 UNREACHABLE(); | 6855 UNREACHABLE(); |
6856 RETURN_FAILURE(isolate, should_throw, | |
6857 NewTypeError(MessageTemplate::kNoAccess)); | |
6849 } | 6858 } |
6850 | 6859 |
6851 if (object->IsJSGlobalProxy()) { | 6860 if (object->IsJSGlobalProxy()) { |
6852 PrototypeIterator iter(isolate, object); | 6861 PrototypeIterator iter(isolate, object); |
6853 if (iter.IsAtEnd()) return Just(true); | 6862 if (iter.IsAtEnd()) return Just(true); |
6854 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 6863 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
6855 return PreventExtensionsWithTransition<attrs>( | 6864 return PreventExtensionsWithTransition<attrs>( |
6856 PrototypeIterator::GetCurrent<JSObject>(iter)); | 6865 PrototypeIterator::GetCurrent<JSObject>(iter), should_throw); |
6857 } | 6866 } |
6858 | 6867 |
6859 // It's not possible to seal or freeze objects with external array elements | 6868 // It's not possible to seal or freeze objects with external array elements |
6860 if (object->HasFixedTypedArrayElements()) { | 6869 if (object->HasFixedTypedArrayElements()) { |
6861 isolate->Throw(*isolate->factory()->NewTypeError( | 6870 isolate->Throw(*isolate->factory()->NewTypeError( |
6862 MessageTemplate::kCannotPreventExtExternalArray)); | 6871 MessageTemplate::kCannotPreventExtExternalArray)); |
6863 return Nothing<bool>(); | 6872 return Nothing<bool>(); |
6864 } | 6873 } |
6865 | 6874 |
6866 Handle<SeededNumberDictionary> new_element_dictionary; | 6875 Handle<SeededNumberDictionary> new_element_dictionary; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6933 if (attrs != NONE) { | 6942 if (attrs != NONE) { |
6934 ApplyAttributesToDictionary(dictionary, attrs); | 6943 ApplyAttributesToDictionary(dictionary, attrs); |
6935 } | 6944 } |
6936 } | 6945 } |
6937 | 6946 |
6938 return Just(true); | 6947 return Just(true); |
6939 } | 6948 } |
6940 | 6949 |
6941 | 6950 |
6942 MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) { | 6951 MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) { |
6943 return ReturnObjectOrThrowTypeError( | 6952 ASSIGN_OR_RETURN(bool, result, PreventExtensionsWithTransition<FROZEN>( |
6944 object, PreventExtensionsWithTransition<FROZEN>(object), | 6953 object, THROW_ON_ERROR), |
6945 MessageTemplate::kCannotPreventExt); | 6954 MaybeHandle<Object>()); |
6955 return object; | |
6946 } | 6956 } |
6947 | 6957 |
6948 | 6958 |
6949 MaybeHandle<Object> JSObject::Seal(Handle<JSObject> object) { | 6959 MaybeHandle<Object> JSObject::Seal(Handle<JSObject> object) { |
6950 return ReturnObjectOrThrowTypeError( | 6960 ASSIGN_OR_RETURN(bool, result, PreventExtensionsWithTransition<SEALED>( |
6951 object, PreventExtensionsWithTransition<SEALED>(object), | 6961 object, THROW_ON_ERROR), |
6952 MessageTemplate::kCannotPreventExt); | 6962 MaybeHandle<Object>()); |
6963 return object; | |
6953 } | 6964 } |
6954 | 6965 |
6955 | 6966 |
6956 void JSObject::SetObserved(Handle<JSObject> object) { | 6967 void JSObject::SetObserved(Handle<JSObject> object) { |
6957 DCHECK(!object->IsJSGlobalProxy()); | 6968 DCHECK(!object->IsJSGlobalProxy()); |
6958 DCHECK(!object->IsJSGlobalObject()); | 6969 DCHECK(!object->IsJSGlobalObject()); |
6959 Isolate* isolate = object->GetIsolate(); | 6970 Isolate* isolate = object->GetIsolate(); |
6960 Handle<Map> new_map; | 6971 Handle<Map> new_map; |
6961 Handle<Map> old_map(object->map(), isolate); | 6972 Handle<Map> old_map(object->map(), isolate); |
6962 DCHECK(!old_map->is_observed()); | 6973 DCHECK(!old_map->is_observed()); |
(...skipping 10699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
17662 if (cell->value() != *new_value) { | 17673 if (cell->value() != *new_value) { |
17663 cell->set_value(*new_value); | 17674 cell->set_value(*new_value); |
17664 Isolate* isolate = cell->GetIsolate(); | 17675 Isolate* isolate = cell->GetIsolate(); |
17665 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17676 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
17666 isolate, DependentCode::kPropertyCellChangedGroup); | 17677 isolate, DependentCode::kPropertyCellChangedGroup); |
17667 } | 17678 } |
17668 } | 17679 } |
17669 | 17680 |
17670 } // namespace internal | 17681 } // namespace internal |
17671 } // namespace v8 | 17682 } // namespace v8 |
OLD | NEW |