| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 <memory> | 9 #include <memory> |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 7967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7978 } | 7978 } |
| 7979 if (object->IsJSGlobalProxy()) { | 7979 if (object->IsJSGlobalProxy()) { |
| 7980 PrototypeIterator iter(isolate, *object); | 7980 PrototypeIterator iter(isolate, *object); |
| 7981 if (iter.IsAtEnd()) return false; | 7981 if (iter.IsAtEnd()) return false; |
| 7982 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); | 7982 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); |
| 7983 return iter.GetCurrent<JSObject>()->map()->is_extensible(); | 7983 return iter.GetCurrent<JSObject>()->map()->is_extensible(); |
| 7984 } | 7984 } |
| 7985 return object->map()->is_extensible(); | 7985 return object->map()->is_extensible(); |
| 7986 } | 7986 } |
| 7987 | 7987 |
| 7988 namespace { |
| 7988 | 7989 |
| 7989 template <typename Dictionary> | 7990 template <typename Dictionary> |
| 7990 static void ApplyAttributesToDictionary(Dictionary* dictionary, | 7991 void DictionaryDetailsAtPut(Isolate* isolate, Handle<Dictionary> dictionary, |
| 7991 const PropertyAttributes attributes) { | 7992 int entry, PropertyDetails details) { |
| 7993 dictionary->DetailsAtPut(entry, details); |
| 7994 } |
| 7995 |
| 7996 template <> |
| 7997 void DictionaryDetailsAtPut<GlobalDictionary>( |
| 7998 Isolate* isolate, Handle<GlobalDictionary> dictionary, int entry, |
| 7999 PropertyDetails details) { |
| 8000 Object* value = dictionary->ValueAt(entry); |
| 8001 DCHECK(value->IsPropertyCell()); |
| 8002 value = PropertyCell::cast(value)->value(); |
| 8003 PropertyCell::PrepareForValue(dictionary, entry, handle(value, isolate), |
| 8004 details); |
| 8005 } |
| 8006 |
| 8007 template <typename Dictionary> |
| 8008 void ApplyAttributesToDictionary(Isolate* isolate, |
| 8009 Handle<Dictionary> dictionary, |
| 8010 const PropertyAttributes attributes) { |
| 7992 int capacity = dictionary->Capacity(); | 8011 int capacity = dictionary->Capacity(); |
| 7993 Isolate* isolate = dictionary->GetIsolate(); | |
| 7994 for (int i = 0; i < capacity; i++) { | 8012 for (int i = 0; i < capacity; i++) { |
| 7995 Object* k = dictionary->KeyAt(i); | 8013 Object* k = dictionary->KeyAt(i); |
| 7996 if (dictionary->IsKey(isolate, k) && | 8014 if (dictionary->IsKey(isolate, k) && |
| 7997 !(k->IsSymbol() && Symbol::cast(k)->is_private())) { | 8015 !(k->IsSymbol() && Symbol::cast(k)->is_private())) { |
| 7998 PropertyDetails details = dictionary->DetailsAt(i); | 8016 PropertyDetails details = dictionary->DetailsAt(i); |
| 7999 int attrs = attributes; | 8017 int attrs = attributes; |
| 8000 // READ_ONLY is an invalid attribute for JS setters/getters. | 8018 // READ_ONLY is an invalid attribute for JS setters/getters. |
| 8001 if ((attributes & READ_ONLY) && details.type() == ACCESSOR_CONSTANT) { | 8019 if ((attributes & READ_ONLY) && details.type() == ACCESSOR_CONSTANT) { |
| 8002 Object* v = dictionary->ValueAt(i); | 8020 Object* v = dictionary->ValueAt(i); |
| 8003 if (v->IsPropertyCell()) v = PropertyCell::cast(v)->value(); | 8021 if (v->IsPropertyCell()) v = PropertyCell::cast(v)->value(); |
| 8004 if (v->IsAccessorPair()) attrs &= ~READ_ONLY; | 8022 if (v->IsAccessorPair()) attrs &= ~READ_ONLY; |
| 8005 } | 8023 } |
| 8006 details = details.CopyAddAttributes( | 8024 details = details.CopyAddAttributes( |
| 8007 static_cast<PropertyAttributes>(attrs)); | 8025 static_cast<PropertyAttributes>(attrs)); |
| 8008 dictionary->DetailsAtPut(i, details); | 8026 DictionaryDetailsAtPut<Dictionary>(isolate, dictionary, i, details); |
| 8009 } | 8027 } |
| 8010 } | 8028 } |
| 8011 } | 8029 } |
| 8012 | 8030 |
| 8031 } // namespace |
| 8013 | 8032 |
| 8014 template <PropertyAttributes attrs> | 8033 template <PropertyAttributes attrs> |
| 8015 Maybe<bool> JSObject::PreventExtensionsWithTransition( | 8034 Maybe<bool> JSObject::PreventExtensionsWithTransition( |
| 8016 Handle<JSObject> object, ShouldThrow should_throw) { | 8035 Handle<JSObject> object, ShouldThrow should_throw) { |
| 8017 STATIC_ASSERT(attrs == NONE || attrs == SEALED || attrs == FROZEN); | 8036 STATIC_ASSERT(attrs == NONE || attrs == SEALED || attrs == FROZEN); |
| 8018 | 8037 |
| 8019 // Sealing/freezing sloppy arguments should be handled elsewhere. | 8038 // Sealing/freezing sloppy arguments should be handled elsewhere. |
| 8020 DCHECK(!object->HasSloppyArgumentsElements()); | 8039 DCHECK(!object->HasSloppyArgumentsElements()); |
| 8021 | 8040 |
| 8022 Isolate* isolate = object->GetIsolate(); | 8041 Isolate* isolate = object->GetIsolate(); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8091 ElementsKind new_kind = | 8110 ElementsKind new_kind = |
| 8092 IsStringWrapperElementsKind(old_map->elements_kind()) | 8111 IsStringWrapperElementsKind(old_map->elements_kind()) |
| 8093 ? SLOW_STRING_WRAPPER_ELEMENTS | 8112 ? SLOW_STRING_WRAPPER_ELEMENTS |
| 8094 : DICTIONARY_ELEMENTS; | 8113 : DICTIONARY_ELEMENTS; |
| 8095 new_map->set_elements_kind(new_kind); | 8114 new_map->set_elements_kind(new_kind); |
| 8096 } | 8115 } |
| 8097 JSObject::MigrateToMap(object, new_map); | 8116 JSObject::MigrateToMap(object, new_map); |
| 8098 | 8117 |
| 8099 if (attrs != NONE) { | 8118 if (attrs != NONE) { |
| 8100 if (object->IsJSGlobalObject()) { | 8119 if (object->IsJSGlobalObject()) { |
| 8101 ApplyAttributesToDictionary(object->global_dictionary(), attrs); | 8120 Handle<GlobalDictionary> dictionary(object->global_dictionary(), |
| 8121 isolate); |
| 8122 ApplyAttributesToDictionary(isolate, dictionary, attrs); |
| 8102 } else { | 8123 } else { |
| 8103 ApplyAttributesToDictionary(object->property_dictionary(), attrs); | 8124 Handle<NameDictionary> dictionary(object->property_dictionary(), |
| 8125 isolate); |
| 8126 ApplyAttributesToDictionary(isolate, dictionary, attrs); |
| 8104 } | 8127 } |
| 8105 } | 8128 } |
| 8106 } | 8129 } |
| 8107 | 8130 |
| 8108 // Both seal and preventExtensions always go through without modifications to | 8131 // Both seal and preventExtensions always go through without modifications to |
| 8109 // typed array elements. Freeze works only if there are no actual elements. | 8132 // typed array elements. Freeze works only if there are no actual elements. |
| 8110 if (object->HasFixedTypedArrayElements()) { | 8133 if (object->HasFixedTypedArrayElements()) { |
| 8111 if (attrs == FROZEN && | 8134 if (attrs == FROZEN && |
| 8112 JSArrayBufferView::cast(*object)->byte_length()->Number() > 0) { | 8135 JSArrayBufferView::cast(*object)->byte_length()->Number() > 0) { |
| 8113 isolate->Throw(*isolate->factory()->NewTypeError( | 8136 isolate->Throw(*isolate->factory()->NewTypeError( |
| 8114 MessageTemplate::kCannotFreezeArrayBufferView)); | 8137 MessageTemplate::kCannotFreezeArrayBufferView)); |
| 8115 return Nothing<bool>(); | 8138 return Nothing<bool>(); |
| 8116 } | 8139 } |
| 8117 return Just(true); | 8140 return Just(true); |
| 8118 } | 8141 } |
| 8119 | 8142 |
| 8120 DCHECK(object->map()->has_dictionary_elements() || | 8143 DCHECK(object->map()->has_dictionary_elements() || |
| 8121 object->map()->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS); | 8144 object->map()->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS); |
| 8122 if (!new_element_dictionary.is_null()) { | 8145 if (!new_element_dictionary.is_null()) { |
| 8123 object->set_elements(*new_element_dictionary); | 8146 object->set_elements(*new_element_dictionary); |
| 8124 } | 8147 } |
| 8125 | 8148 |
| 8126 if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) { | 8149 if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) { |
| 8127 SeededNumberDictionary* dictionary = object->element_dictionary(); | 8150 Handle<SeededNumberDictionary> dictionary(object->element_dictionary(), |
| 8151 isolate); |
| 8128 // Make sure we never go back to the fast case | 8152 // Make sure we never go back to the fast case |
| 8129 object->RequireSlowElements(dictionary); | 8153 object->RequireSlowElements(*dictionary); |
| 8130 if (attrs != NONE) { | 8154 if (attrs != NONE) { |
| 8131 ApplyAttributesToDictionary(dictionary, attrs); | 8155 ApplyAttributesToDictionary(isolate, dictionary, attrs); |
| 8132 } | 8156 } |
| 8133 } | 8157 } |
| 8134 | 8158 |
| 8135 return Just(true); | 8159 return Just(true); |
| 8136 } | 8160 } |
| 8137 | 8161 |
| 8138 | 8162 |
| 8139 Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object, | 8163 Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object, |
| 8140 Representation representation, | 8164 Representation representation, |
| 8141 FieldIndex index) { | 8165 FieldIndex index) { |
| (...skipping 12167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 20309 // Check if the accessor uses a cached property. | 20333 // Check if the accessor uses a cached property. |
| 20310 if (!fti->cached_property_name()->IsTheHole(isolate)) { | 20334 if (!fti->cached_property_name()->IsTheHole(isolate)) { |
| 20311 return handle(Name::cast(fti->cached_property_name())); | 20335 return handle(Name::cast(fti->cached_property_name())); |
| 20312 } | 20336 } |
| 20313 } | 20337 } |
| 20314 return MaybeHandle<Name>(); | 20338 return MaybeHandle<Name>(); |
| 20315 } | 20339 } |
| 20316 | 20340 |
| 20317 } // namespace internal | 20341 } // namespace internal |
| 20318 } // namespace v8 | 20342 } // namespace v8 |
| OLD | NEW |