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 |