| 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 6704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6715 | 6715 |
| 6716 return context->extension_object()->ReferencesObject(obj); | 6716 return context->extension_object()->ReferencesObject(obj); |
| 6717 } | 6717 } |
| 6718 } | 6718 } |
| 6719 | 6719 |
| 6720 // No references to object. | 6720 // No references to object. |
| 6721 return false; | 6721 return false; |
| 6722 } | 6722 } |
| 6723 | 6723 |
| 6724 | 6724 |
| 6725 Maybe<bool> JSObject::PreventExtensionsInternal(Handle<JSObject> object) { | 6725 #define RETURN_FAILURE(isolate, should_throw, call) \ |
| 6726 do { \ |
| 6727 if ((should_throw) == DONT_THROW) { \ |
| 6728 return Just(false); \ |
| 6729 } else { \ |
| 6730 isolate->Throw(*isolate->factory()->call); \ |
| 6731 return Nothing<bool>(); \ |
| 6732 } \ |
| 6733 } while (false) |
| 6734 |
| 6735 |
| 6736 Maybe<bool> JSReceiver::PreventExtensions(Handle<JSReceiver> object, |
| 6737 ShouldThrow should_throw) { |
| 6738 if (!object->IsJSObject()) return Just(false); |
| 6739 // TODO(neis): Deal with proxies. |
| 6740 return JSObject::PreventExtensions(Handle<JSObject>::cast(object), |
| 6741 should_throw); |
| 6742 } |
| 6743 |
| 6744 |
| 6745 Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object, |
| 6746 ShouldThrow should_throw) { |
| 6726 Isolate* isolate = object->GetIsolate(); | 6747 Isolate* isolate = object->GetIsolate(); |
| 6727 | 6748 |
| 6728 if (!object->map()->is_extensible()) return Just(true); | 6749 if (!object->map()->is_extensible()) return Just(true); |
| 6729 | 6750 |
| 6730 if (!object->HasSloppyArgumentsElements() && !object->map()->is_observed()) { | 6751 if (!object->HasSloppyArgumentsElements() && !object->map()->is_observed()) { |
| 6731 return PreventExtensionsWithTransition<NONE>(object); | 6752 return PreventExtensionsWithTransition<NONE>(object, should_throw); |
| 6732 } | 6753 } |
| 6733 | 6754 |
| 6734 if (object->IsAccessCheckNeeded() && | 6755 if (object->IsAccessCheckNeeded() && |
| 6735 !isolate->MayAccess(handle(isolate->context()), object)) { | 6756 !isolate->MayAccess(handle(isolate->context()), object)) { |
| 6736 isolate->ReportFailedAccessCheck(object); | 6757 isolate->ReportFailedAccessCheck(object); |
| 6737 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); | 6758 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); |
| 6738 UNREACHABLE(); | 6759 UNREACHABLE(); |
| 6739 return Just(false); | 6760 RETURN_FAILURE(isolate, should_throw, |
| 6761 NewTypeError(MessageTemplate::kNoAccess)); |
| 6740 } | 6762 } |
| 6741 | 6763 |
| 6742 if (object->IsJSGlobalProxy()) { | 6764 if (object->IsJSGlobalProxy()) { |
| 6743 PrototypeIterator iter(isolate, object); | 6765 PrototypeIterator iter(isolate, object); |
| 6744 if (iter.IsAtEnd()) return Just(true); | 6766 if (iter.IsAtEnd()) return Just(true); |
| 6745 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 6767 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 6746 return PreventExtensionsInternal( | 6768 return PreventExtensions(PrototypeIterator::GetCurrent<JSObject>(iter), |
| 6747 PrototypeIterator::GetCurrent<JSObject>(iter)); | 6769 should_throw); |
| 6748 } | 6770 } |
| 6749 | 6771 |
| 6750 // It's not possible to seal objects with external array elements | 6772 // It's not possible to seal objects with external array elements |
| 6751 if (object->HasFixedTypedArrayElements()) { | 6773 if (object->HasFixedTypedArrayElements()) { |
| 6752 isolate->Throw(*isolate->factory()->NewTypeError( | 6774 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6753 MessageTemplate::kCannotPreventExtExternalArray)); | 6775 MessageTemplate::kCannotPreventExtExternalArray)); |
| 6754 return Nothing<bool>(); | 6776 return Nothing<bool>(); |
| 6755 } | 6777 } |
| 6756 | 6778 |
| 6757 // If there are fast elements we normalize. | 6779 // If there are fast elements we normalize. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 6774 RETURN_ON_EXCEPTION_VALUE( | 6796 RETURN_ON_EXCEPTION_VALUE( |
| 6775 isolate, | 6797 isolate, |
| 6776 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), | 6798 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), |
| 6777 isolate->factory()->the_hole_value()), | 6799 isolate->factory()->the_hole_value()), |
| 6778 Nothing<bool>()); | 6800 Nothing<bool>()); |
| 6779 } | 6801 } |
| 6780 return Just(true); | 6802 return Just(true); |
| 6781 } | 6803 } |
| 6782 | 6804 |
| 6783 | 6805 |
| 6784 static MaybeHandle<Object> ReturnObjectOrThrowTypeError( | |
| 6785 Handle<JSObject> object, Maybe<bool> maybe, MessageTemplate::Template msg) { | |
| 6786 if (!maybe.IsJust()) return MaybeHandle<Object>(); | |
| 6787 if (maybe.FromJust()) return object; | |
| 6788 Isolate* isolate = object->GetIsolate(); | |
| 6789 THROW_NEW_ERROR(isolate, NewTypeError(msg), Object); | |
| 6790 } | |
| 6791 | |
| 6792 | |
| 6793 MaybeHandle<Object> JSObject::PreventExtensions(Handle<JSObject> object) { | |
| 6794 return ReturnObjectOrThrowTypeError(object, PreventExtensionsInternal(object), | |
| 6795 MessageTemplate::kCannotPreventExt); | |
| 6796 } | |
| 6797 | |
| 6798 | |
| 6799 bool JSObject::IsExtensible(Handle<JSObject> object) { | 6806 bool JSObject::IsExtensible(Handle<JSObject> object) { |
| 6800 Isolate* isolate = object->GetIsolate(); | 6807 Isolate* isolate = object->GetIsolate(); |
| 6801 if (object->IsAccessCheckNeeded() && | 6808 if (object->IsAccessCheckNeeded() && |
| 6802 !isolate->MayAccess(handle(isolate->context()), object)) { | 6809 !isolate->MayAccess(handle(isolate->context()), object)) { |
| 6803 return true; | 6810 return true; |
| 6804 } | 6811 } |
| 6805 if (object->IsJSGlobalProxy()) { | 6812 if (object->IsJSGlobalProxy()) { |
| 6806 PrototypeIterator iter(isolate, *object); | 6813 PrototypeIterator iter(isolate, *object); |
| 6807 if (iter.IsAtEnd()) return false; | 6814 if (iter.IsAtEnd()) return false; |
| 6808 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); | 6815 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 6830 } | 6837 } |
| 6831 details = details.CopyAddAttributes( | 6838 details = details.CopyAddAttributes( |
| 6832 static_cast<PropertyAttributes>(attrs)); | 6839 static_cast<PropertyAttributes>(attrs)); |
| 6833 dictionary->DetailsAtPut(i, details); | 6840 dictionary->DetailsAtPut(i, details); |
| 6834 } | 6841 } |
| 6835 } | 6842 } |
| 6836 } | 6843 } |
| 6837 | 6844 |
| 6838 | 6845 |
| 6839 template <PropertyAttributes attrs> | 6846 template <PropertyAttributes attrs> |
| 6840 Maybe<bool> JSObject::PreventExtensionsWithTransition(Handle<JSObject> object) { | 6847 Maybe<bool> JSObject::PreventExtensionsWithTransition( |
| 6848 Handle<JSObject> object, ShouldThrow should_throw) { |
| 6841 STATIC_ASSERT(attrs == NONE || attrs == SEALED || attrs == FROZEN); | 6849 STATIC_ASSERT(attrs == NONE || attrs == SEALED || attrs == FROZEN); |
| 6842 | 6850 |
| 6843 // Sealing/freezing sloppy arguments should be handled elsewhere. | 6851 // Sealing/freezing sloppy arguments should be handled elsewhere. |
| 6844 DCHECK(!object->HasSloppyArgumentsElements()); | 6852 DCHECK(!object->HasSloppyArgumentsElements()); |
| 6845 DCHECK(!object->map()->is_observed()); | 6853 DCHECK(!object->map()->is_observed()); |
| 6846 | 6854 |
| 6847 Isolate* isolate = object->GetIsolate(); | 6855 Isolate* isolate = object->GetIsolate(); |
| 6848 if (object->IsAccessCheckNeeded() && | 6856 if (object->IsAccessCheckNeeded() && |
| 6849 !isolate->MayAccess(handle(isolate->context()), object)) { | 6857 !isolate->MayAccess(handle(isolate->context()), object)) { |
| 6850 isolate->ReportFailedAccessCheck(object); | 6858 isolate->ReportFailedAccessCheck(object); |
| 6851 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); | 6859 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); |
| 6852 UNREACHABLE(); | 6860 UNREACHABLE(); |
| 6861 RETURN_FAILURE(isolate, should_throw, |
| 6862 NewTypeError(MessageTemplate::kNoAccess)); |
| 6853 } | 6863 } |
| 6854 | 6864 |
| 6855 if (object->IsJSGlobalProxy()) { | 6865 if (object->IsJSGlobalProxy()) { |
| 6856 PrototypeIterator iter(isolate, object); | 6866 PrototypeIterator iter(isolate, object); |
| 6857 if (iter.IsAtEnd()) return Just(true); | 6867 if (iter.IsAtEnd()) return Just(true); |
| 6858 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 6868 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
| 6859 return PreventExtensionsWithTransition<attrs>( | 6869 return PreventExtensionsWithTransition<attrs>( |
| 6860 PrototypeIterator::GetCurrent<JSObject>(iter)); | 6870 PrototypeIterator::GetCurrent<JSObject>(iter), should_throw); |
| 6861 } | 6871 } |
| 6862 | 6872 |
| 6863 // It's not possible to seal or freeze objects with external array elements | 6873 // It's not possible to seal or freeze objects with external array elements |
| 6864 if (object->HasFixedTypedArrayElements()) { | 6874 if (object->HasFixedTypedArrayElements()) { |
| 6865 isolate->Throw(*isolate->factory()->NewTypeError( | 6875 isolate->Throw(*isolate->factory()->NewTypeError( |
| 6866 MessageTemplate::kCannotPreventExtExternalArray)); | 6876 MessageTemplate::kCannotPreventExtExternalArray)); |
| 6867 return Nothing<bool>(); | 6877 return Nothing<bool>(); |
| 6868 } | 6878 } |
| 6869 | 6879 |
| 6870 Handle<SeededNumberDictionary> new_element_dictionary; | 6880 Handle<SeededNumberDictionary> new_element_dictionary; |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6937 if (attrs != NONE) { | 6947 if (attrs != NONE) { |
| 6938 ApplyAttributesToDictionary(dictionary, attrs); | 6948 ApplyAttributesToDictionary(dictionary, attrs); |
| 6939 } | 6949 } |
| 6940 } | 6950 } |
| 6941 | 6951 |
| 6942 return Just(true); | 6952 return Just(true); |
| 6943 } | 6953 } |
| 6944 | 6954 |
| 6945 | 6955 |
| 6946 MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) { | 6956 MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) { |
| 6947 return ReturnObjectOrThrowTypeError( | 6957 return PreventExtensionsWithTransition<FROZEN>(object, THROW_ON_ERROR) |
| 6948 object, PreventExtensionsWithTransition<FROZEN>(object), | 6958 .IsJust() |
| 6949 MessageTemplate::kCannotPreventExt); | 6959 ? object |
| 6960 : MaybeHandle<Object>(); |
| 6950 } | 6961 } |
| 6951 | 6962 |
| 6952 | 6963 |
| 6953 MaybeHandle<Object> JSObject::Seal(Handle<JSObject> object) { | 6964 MaybeHandle<Object> JSObject::Seal(Handle<JSObject> object) { |
| 6954 return ReturnObjectOrThrowTypeError( | 6965 return PreventExtensionsWithTransition<SEALED>(object, THROW_ON_ERROR) |
| 6955 object, PreventExtensionsWithTransition<SEALED>(object), | 6966 .IsJust() |
| 6956 MessageTemplate::kCannotPreventExt); | 6967 ? object |
| 6968 : MaybeHandle<Object>(); |
| 6957 } | 6969 } |
| 6958 | 6970 |
| 6959 | 6971 |
| 6960 void JSObject::SetObserved(Handle<JSObject> object) { | 6972 void JSObject::SetObserved(Handle<JSObject> object) { |
| 6961 DCHECK(!object->IsJSGlobalProxy()); | 6973 DCHECK(!object->IsJSGlobalProxy()); |
| 6962 DCHECK(!object->IsJSGlobalObject()); | 6974 DCHECK(!object->IsJSGlobalObject()); |
| 6963 Isolate* isolate = object->GetIsolate(); | 6975 Isolate* isolate = object->GetIsolate(); |
| 6964 Handle<Map> new_map; | 6976 Handle<Map> new_map; |
| 6965 Handle<Map> old_map(object->map(), isolate); | 6977 Handle<Map> old_map(object->map(), isolate); |
| 6966 DCHECK(!old_map->is_observed()); | 6978 DCHECK(!old_map->is_observed()); |
| (...skipping 10790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17757 if (cell->value() != *new_value) { | 17769 if (cell->value() != *new_value) { |
| 17758 cell->set_value(*new_value); | 17770 cell->set_value(*new_value); |
| 17759 Isolate* isolate = cell->GetIsolate(); | 17771 Isolate* isolate = cell->GetIsolate(); |
| 17760 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17772 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 17761 isolate, DependentCode::kPropertyCellChangedGroup); | 17773 isolate, DependentCode::kPropertyCellChangedGroup); |
| 17762 } | 17774 } |
| 17763 } | 17775 } |
| 17764 | 17776 |
| 17765 } // namespace internal | 17777 } // namespace internal |
| 17766 } // namespace v8 | 17778 } // namespace v8 |
| OLD | NEW |