Chromium Code Reviews| 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 |