| 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 <sstream> | 9 #include <sstream> |
| 10 | 10 |
| (...skipping 6397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6408 Handle<JSReceiver> props; | 6408 Handle<JSReceiver> props; |
| 6409 if (!Object::ToObject(isolate, properties).ToHandle(&props)) { | 6409 if (!Object::ToObject(isolate, properties).ToHandle(&props)) { |
| 6410 THROW_NEW_ERROR(isolate, | 6410 THROW_NEW_ERROR(isolate, |
| 6411 NewTypeError(MessageTemplate::kUndefinedOrNullToObject), | 6411 NewTypeError(MessageTemplate::kUndefinedOrNullToObject), |
| 6412 Object); | 6412 Object); |
| 6413 } | 6413 } |
| 6414 // 4. Let keys be props.[[OwnPropertyKeys]](). | 6414 // 4. Let keys be props.[[OwnPropertyKeys]](). |
| 6415 // 5. ReturnIfAbrupt(keys). | 6415 // 5. ReturnIfAbrupt(keys). |
| 6416 Handle<FixedArray> keys; | 6416 Handle<FixedArray> keys; |
| 6417 ASSIGN_RETURN_ON_EXCEPTION( | 6417 ASSIGN_RETURN_ON_EXCEPTION( |
| 6418 isolate, keys, | 6418 isolate, keys, JSReceiver::GetKeys(props, OWN_ONLY, ALL_PROPERTIES), |
| 6419 JSReceiver::GetKeys(props, JSReceiver::OWN_ONLY, ALL_PROPERTIES), Object); | 6419 Object); |
| 6420 // 6. Let descriptors be an empty List. | 6420 // 6. Let descriptors be an empty List. |
| 6421 int capacity = keys->length(); | 6421 int capacity = keys->length(); |
| 6422 std::vector<PropertyDescriptor> descriptors(capacity); | 6422 std::vector<PropertyDescriptor> descriptors(capacity); |
| 6423 size_t descriptors_index = 0; | 6423 size_t descriptors_index = 0; |
| 6424 // 7. Repeat for each element nextKey of keys in List order, | 6424 // 7. Repeat for each element nextKey of keys in List order, |
| 6425 for (int i = 0; i < keys->length(); ++i) { | 6425 for (int i = 0; i < keys->length(); ++i) { |
| 6426 Handle<Object> next_key(keys->get(i), isolate); | 6426 Handle<Object> next_key(keys->get(i), isolate); |
| 6427 // 7a. Let propDesc be props.[[GetOwnProperty]](nextKey). | 6427 // 7a. Let propDesc be props.[[GetOwnProperty]](nextKey). |
| 6428 // 7b. ReturnIfAbrupt(propDesc). | 6428 // 7b. ReturnIfAbrupt(propDesc). |
| 6429 bool success = false; | 6429 bool success = false; |
| (...skipping 1690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8120 } | 8120 } |
| 8121 } | 8121 } |
| 8122 } | 8122 } |
| 8123 } | 8123 } |
| 8124 } else { | 8124 } else { |
| 8125 // Only deep copy fields from the object literal expression. | 8125 // Only deep copy fields from the object literal expression. |
| 8126 // In particular, don't try to copy the length attribute of | 8126 // In particular, don't try to copy the length attribute of |
| 8127 // an array. | 8127 // an array. |
| 8128 PropertyFilter filter = static_cast<PropertyFilter>( | 8128 PropertyFilter filter = static_cast<PropertyFilter>( |
| 8129 ONLY_WRITABLE | ONLY_ENUMERABLE | ONLY_CONFIGURABLE); | 8129 ONLY_WRITABLE | ONLY_ENUMERABLE | ONLY_CONFIGURABLE); |
| 8130 KeyAccumulator accumulator(isolate, filter); | 8130 KeyAccumulator accumulator(isolate, OWN_ONLY, filter); |
| 8131 accumulator.NextPrototype(); | 8131 accumulator.NextPrototype(); |
| 8132 copy->CollectOwnPropertyNames(&accumulator, filter); | 8132 copy->CollectOwnPropertyNames(&accumulator, filter); |
| 8133 Handle<FixedArray> names = accumulator.GetKeys(); | 8133 Handle<FixedArray> names = accumulator.GetKeys(); |
| 8134 for (int i = 0; i < names->length(); i++) { | 8134 for (int i = 0; i < names->length(); i++) { |
| 8135 DCHECK(names->get(i)->IsName()); | 8135 DCHECK(names->get(i)->IsName()); |
| 8136 Handle<Name> name(Name::cast(names->get(i))); | 8136 Handle<Name> name(Name::cast(names->get(i))); |
| 8137 Handle<Object> value = | 8137 Handle<Object> value = |
| 8138 Object::GetProperty(copy, name).ToHandleChecked(); | 8138 Object::GetProperty(copy, name).ToHandleChecked(); |
| 8139 if (value->IsJSObject()) { | 8139 if (value->IsJSObject()) { |
| 8140 Handle<JSObject> result; | 8140 Handle<JSObject> result; |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8625 return Just(true); | 8625 return Just(true); |
| 8626 } | 8626 } |
| 8627 | 8627 |
| 8628 | 8628 |
| 8629 // Returns |true| on success, |false| if prototype walking should be stopped, | 8629 // Returns |true| on success, |false| if prototype walking should be stopped, |
| 8630 // |nothing| if an exception was thrown. | 8630 // |nothing| if an exception was thrown. |
| 8631 static Maybe<bool> GetKeysFromJSObject(Isolate* isolate, | 8631 static Maybe<bool> GetKeysFromJSObject(Isolate* isolate, |
| 8632 Handle<JSReceiver> receiver, | 8632 Handle<JSReceiver> receiver, |
| 8633 Handle<JSObject> object, | 8633 Handle<JSObject> object, |
| 8634 PropertyFilter* filter, | 8634 PropertyFilter* filter, |
| 8635 JSReceiver::KeyCollectionType type, | 8635 KeyCollectionType type, |
| 8636 KeyAccumulator* accumulator) { | 8636 KeyAccumulator* accumulator) { |
| 8637 accumulator->NextPrototype(); | 8637 accumulator->NextPrototype(); |
| 8638 // Check access rights if required. | 8638 // Check access rights if required. |
| 8639 if (object->IsAccessCheckNeeded() && | 8639 if (object->IsAccessCheckNeeded() && |
| 8640 !isolate->MayAccess(handle(isolate->context()), object)) { | 8640 !isolate->MayAccess(handle(isolate->context()), object)) { |
| 8641 // The cross-origin spec says that [[Enumerate]] shall return an empty | 8641 // The cross-origin spec says that [[Enumerate]] shall return an empty |
| 8642 // iterator when it doesn't have access... | 8642 // iterator when it doesn't have access... |
| 8643 if (type == JSReceiver::INCLUDE_PROTOS) { | 8643 if (type == INCLUDE_PROTOS) { |
| 8644 return Just(false); | 8644 return Just(false); |
| 8645 } | 8645 } |
| 8646 // ...whereas [[OwnPropertyKeys]] shall return whitelisted properties. | 8646 // ...whereas [[OwnPropertyKeys]] shall return whitelisted properties. |
| 8647 DCHECK(type == JSReceiver::OWN_ONLY); | 8647 DCHECK_EQ(OWN_ONLY, type); |
| 8648 *filter = static_cast<PropertyFilter>(*filter | ONLY_ALL_CAN_READ); | 8648 *filter = static_cast<PropertyFilter>(*filter | ONLY_ALL_CAN_READ); |
| 8649 } | 8649 } |
| 8650 | 8650 |
| 8651 JSObject::CollectOwnElementKeys(object, accumulator, *filter); | 8651 JSObject::CollectOwnElementKeys(object, accumulator, *filter); |
| 8652 | 8652 |
| 8653 // Add the element keys from the interceptor. | 8653 // Add the element keys from the interceptor. |
| 8654 Maybe<bool> success = | 8654 Maybe<bool> success = |
| 8655 GetKeysFromInterceptor<v8::IndexedPropertyEnumeratorCallback, kIndexed>( | 8655 GetKeysFromInterceptor<v8::IndexedPropertyEnumeratorCallback, kIndexed>( |
| 8656 isolate, receiver, object, *filter, accumulator); | 8656 isolate, receiver, object, *filter, accumulator); |
| 8657 MAYBE_RETURN(success, Nothing<bool>()); | 8657 MAYBE_RETURN(success, Nothing<bool>()); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 8688 MAYBE_RETURN(success, Nothing<bool>()); | 8688 MAYBE_RETURN(success, Nothing<bool>()); |
| 8689 return Just(true); | 8689 return Just(true); |
| 8690 } | 8690 } |
| 8691 | 8691 |
| 8692 | 8692 |
| 8693 // Helper function for JSReceiver::GetKeys() below. Can be called recursively. | 8693 // Helper function for JSReceiver::GetKeys() below. Can be called recursively. |
| 8694 // Returns |true| or |nothing|. | 8694 // Returns |true| or |nothing|. |
| 8695 static Maybe<bool> GetKeys_Internal(Isolate* isolate, | 8695 static Maybe<bool> GetKeys_Internal(Isolate* isolate, |
| 8696 Handle<JSReceiver> receiver, | 8696 Handle<JSReceiver> receiver, |
| 8697 Handle<JSReceiver> object, | 8697 Handle<JSReceiver> object, |
| 8698 JSReceiver::KeyCollectionType type, | 8698 KeyCollectionType type, |
| 8699 PropertyFilter filter, | 8699 PropertyFilter filter, |
| 8700 KeyAccumulator* accumulator) { | 8700 KeyAccumulator* accumulator) { |
| 8701 PrototypeIterator::WhereToEnd end = type == JSReceiver::OWN_ONLY | 8701 PrototypeIterator::WhereToEnd end = type == OWN_ONLY |
| 8702 ? PrototypeIterator::END_AT_NON_HIDDEN | 8702 ? PrototypeIterator::END_AT_NON_HIDDEN |
| 8703 : PrototypeIterator::END_AT_NULL; | 8703 : PrototypeIterator::END_AT_NULL; |
| 8704 for (PrototypeIterator iter(isolate, object, | 8704 for (PrototypeIterator iter(isolate, object, |
| 8705 PrototypeIterator::START_AT_RECEIVER); | 8705 PrototypeIterator::START_AT_RECEIVER); |
| 8706 !iter.IsAtEnd(end); iter.Advance()) { | 8706 !iter.IsAtEnd(end); iter.Advance()) { |
| 8707 Handle<JSReceiver> current = | 8707 Handle<JSReceiver> current = |
| 8708 PrototypeIterator::GetCurrent<JSReceiver>(iter); | 8708 PrototypeIterator::GetCurrent<JSReceiver>(iter); |
| 8709 Maybe<bool> result = Just(false); // Dummy initialization. | 8709 Maybe<bool> result = Just(false); // Dummy initialization. |
| 8710 if (current->IsJSProxy()) { | 8710 if (current->IsJSProxy()) { |
| 8711 if (type == JSReceiver::OWN_ONLY) { | 8711 if (type == OWN_ONLY) { |
| 8712 result = JSProxy::OwnPropertyKeys(isolate, receiver, | 8712 result = JSProxy::OwnPropertyKeys(isolate, receiver, |
| 8713 Handle<JSProxy>::cast(current), | 8713 Handle<JSProxy>::cast(current), |
| 8714 filter, accumulator); | 8714 filter, accumulator); |
| 8715 } else { | 8715 } else { |
| 8716 DCHECK(type == JSReceiver::INCLUDE_PROTOS); | 8716 DCHECK(type == INCLUDE_PROTOS); |
| 8717 result = JSProxy::Enumerate( | 8717 result = JSProxy::Enumerate( |
| 8718 isolate, receiver, Handle<JSProxy>::cast(current), accumulator); | 8718 isolate, receiver, Handle<JSProxy>::cast(current), accumulator); |
| 8719 } | 8719 } |
| 8720 } else { | 8720 } else { |
| 8721 DCHECK(current->IsJSObject()); | 8721 DCHECK(current->IsJSObject()); |
| 8722 result = GetKeysFromJSObject(isolate, receiver, | 8722 result = GetKeysFromJSObject(isolate, receiver, |
| 8723 Handle<JSObject>::cast(current), &filter, | 8723 Handle<JSObject>::cast(current), &filter, |
| 8724 type, accumulator); | 8724 type, accumulator); |
| 8725 } | 8725 } |
| 8726 MAYBE_RETURN(result, Nothing<bool>()); | 8726 MAYBE_RETURN(result, Nothing<bool>()); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8868 // then: | 8868 // then: |
| 8869 if (extensible_target && nonconfigurable_keys_length == 0) { | 8869 if (extensible_target && nonconfigurable_keys_length == 0) { |
| 8870 // 15a. Return trapResult. | 8870 // 15a. Return trapResult. |
| 8871 return accumulator->AddKeysFromProxy(proxy, trap_result); | 8871 return accumulator->AddKeysFromProxy(proxy, trap_result); |
| 8872 } | 8872 } |
| 8873 // 16. Let uncheckedResultKeys be a new List which is a copy of trapResult. | 8873 // 16. Let uncheckedResultKeys be a new List which is a copy of trapResult. |
| 8874 Zone set_zone; | 8874 Zone set_zone; |
| 8875 const int kPresent = 1; | 8875 const int kPresent = 1; |
| 8876 const int kGone = 0; | 8876 const int kGone = 0; |
| 8877 IdentityMap<int> unchecked_result_keys(isolate->heap(), &set_zone); | 8877 IdentityMap<int> unchecked_result_keys(isolate->heap(), &set_zone); |
| 8878 int unchecked_result_keys_size = trap_result->length(); | 8878 int unchecked_result_keys_size = 0; |
| 8879 for (int i = 0; i < trap_result->length(); ++i) { | 8879 for (int i = 0; i < trap_result->length(); ++i) { |
| 8880 DCHECK(trap_result->get(i)->IsUniqueName()); | 8880 DCHECK(trap_result->get(i)->IsUniqueName()); |
| 8881 unchecked_result_keys.Set(trap_result->get(i), kPresent); | 8881 Object* key = trap_result->get(i); |
| 8882 int* entry = unchecked_result_keys.Get(key); |
| 8883 if (*entry != kPresent) { |
| 8884 *entry = kPresent; |
| 8885 unchecked_result_keys_size++; |
| 8886 } |
| 8882 } | 8887 } |
| 8883 // 17. Repeat, for each key that is an element of targetNonconfigurableKeys: | 8888 // 17. Repeat, for each key that is an element of targetNonconfigurableKeys: |
| 8884 for (int i = 0; i < nonconfigurable_keys_length; ++i) { | 8889 for (int i = 0; i < nonconfigurable_keys_length; ++i) { |
| 8885 Object* key = target_nonconfigurable_keys->get(i); | 8890 Object* key = target_nonconfigurable_keys->get(i); |
| 8886 // 17a. If key is not an element of uncheckedResultKeys, throw a | 8891 // 17a. If key is not an element of uncheckedResultKeys, throw a |
| 8887 // TypeError exception. | 8892 // TypeError exception. |
| 8888 int* found = unchecked_result_keys.Find(key); | 8893 int* found = unchecked_result_keys.Find(key); |
| 8889 if (found == nullptr || *found == kGone) { | 8894 if (found == nullptr || *found == kGone) { |
| 8890 isolate->Throw(*isolate->factory()->NewTypeError( | 8895 isolate->Throw(*isolate->factory()->NewTypeError( |
| 8891 MessageTemplate::kProxyOwnKeysMissing, handle(key, isolate))); | 8896 MessageTemplate::kProxyOwnKeysMissing, handle(key, isolate))); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8926 return accumulator->AddKeysFromProxy(proxy, trap_result); | 8931 return accumulator->AddKeysFromProxy(proxy, trap_result); |
| 8927 } | 8932 } |
| 8928 | 8933 |
| 8929 | 8934 |
| 8930 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, | 8935 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, |
| 8931 KeyCollectionType type, | 8936 KeyCollectionType type, |
| 8932 PropertyFilter filter, | 8937 PropertyFilter filter, |
| 8933 GetKeysConversion keys_conversion) { | 8938 GetKeysConversion keys_conversion) { |
| 8934 USE(ContainsOnlyValidKeys); | 8939 USE(ContainsOnlyValidKeys); |
| 8935 Isolate* isolate = object->GetIsolate(); | 8940 Isolate* isolate = object->GetIsolate(); |
| 8936 KeyAccumulator accumulator(isolate, filter); | 8941 KeyAccumulator accumulator(isolate, type, filter); |
| 8937 MAYBE_RETURN( | 8942 MAYBE_RETURN( |
| 8938 GetKeys_Internal(isolate, object, object, type, filter, &accumulator), | 8943 GetKeys_Internal(isolate, object, object, type, filter, &accumulator), |
| 8939 MaybeHandle<FixedArray>()); | 8944 MaybeHandle<FixedArray>()); |
| 8940 Handle<FixedArray> keys = accumulator.GetKeys(keys_conversion); | 8945 Handle<FixedArray> keys = accumulator.GetKeys(keys_conversion); |
| 8941 DCHECK(ContainsOnlyValidKeys(keys)); | 8946 DCHECK(ContainsOnlyValidKeys(keys)); |
| 8942 return keys; | 8947 return keys; |
| 8943 } | 8948 } |
| 8944 | 8949 |
| 8945 | 8950 |
| 8946 bool Map::DictionaryElementsInPrototypeChainOnly() { | 8951 bool Map::DictionaryElementsInPrototypeChainOnly() { |
| (...skipping 10823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19770 if (cell->value() != *new_value) { | 19775 if (cell->value() != *new_value) { |
| 19771 cell->set_value(*new_value); | 19776 cell->set_value(*new_value); |
| 19772 Isolate* isolate = cell->GetIsolate(); | 19777 Isolate* isolate = cell->GetIsolate(); |
| 19773 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 19778 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 19774 isolate, DependentCode::kPropertyCellChangedGroup); | 19779 isolate, DependentCode::kPropertyCellChangedGroup); |
| 19775 } | 19780 } |
| 19776 } | 19781 } |
| 19777 | 19782 |
| 19778 } // namespace internal | 19783 } // namespace internal |
| 19779 } // namespace v8 | 19784 } // namespace v8 |
| OLD | NEW |