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 |