Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Side by Side Diff: src/objects.cc

Issue 1668853002: [proxies] allow duplicate keys for [[OwnPropertyKeys]] trap. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-array.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 6398 matching lines...) Expand 10 before | Expand all | Expand 10 after
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,
6419 JSReceiver::GetKeys(props, JSReceiver::OWN_ONLY, ALL_PROPERTIES), Object); 6419 JSReceiver::GetKeys(props, KeyCollectionType::OWN_ONLY, ALL_PROPERTIES),
6420 Object);
6420 // 6. Let descriptors be an empty List. 6421 // 6. Let descriptors be an empty List.
6421 int capacity = keys->length(); 6422 int capacity = keys->length();
6422 std::vector<PropertyDescriptor> descriptors(capacity); 6423 std::vector<PropertyDescriptor> descriptors(capacity);
6423 size_t descriptors_index = 0; 6424 size_t descriptors_index = 0;
6424 // 7. Repeat for each element nextKey of keys in List order, 6425 // 7. Repeat for each element nextKey of keys in List order,
6425 for (int i = 0; i < keys->length(); ++i) { 6426 for (int i = 0; i < keys->length(); ++i) {
6426 Handle<Object> next_key(keys->get(i), isolate); 6427 Handle<Object> next_key(keys->get(i), isolate);
6427 // 7a. Let propDesc be props.[[GetOwnProperty]](nextKey). 6428 // 7a. Let propDesc be props.[[GetOwnProperty]](nextKey).
6428 // 7b. ReturnIfAbrupt(propDesc). 6429 // 7b. ReturnIfAbrupt(propDesc).
6429 bool success = false; 6430 bool success = false;
(...skipping 1690 matching lines...) Expand 10 before | Expand all | Expand 10 after
8120 } 8121 }
8121 } 8122 }
8122 } 8123 }
8123 } 8124 }
8124 } else { 8125 } else {
8125 // Only deep copy fields from the object literal expression. 8126 // Only deep copy fields from the object literal expression.
8126 // In particular, don't try to copy the length attribute of 8127 // In particular, don't try to copy the length attribute of
8127 // an array. 8128 // an array.
8128 PropertyFilter filter = static_cast<PropertyFilter>( 8129 PropertyFilter filter = static_cast<PropertyFilter>(
8129 ONLY_WRITABLE | ONLY_ENUMERABLE | ONLY_CONFIGURABLE); 8130 ONLY_WRITABLE | ONLY_ENUMERABLE | ONLY_CONFIGURABLE);
8130 KeyAccumulator accumulator(isolate, filter); 8131 KeyAccumulator accumulator(isolate, KeyCollectionType::OWN_ONLY, filter);
8131 accumulator.NextPrototype(); 8132 accumulator.NextPrototype();
8132 copy->CollectOwnPropertyNames(&accumulator, filter); 8133 copy->CollectOwnPropertyNames(&accumulator, filter);
8133 Handle<FixedArray> names = accumulator.GetKeys(); 8134 Handle<FixedArray> names = accumulator.GetKeys();
8134 for (int i = 0; i < names->length(); i++) { 8135 for (int i = 0; i < names->length(); i++) {
8135 DCHECK(names->get(i)->IsName()); 8136 DCHECK(names->get(i)->IsName());
8136 Handle<Name> name(Name::cast(names->get(i))); 8137 Handle<Name> name(Name::cast(names->get(i)));
8137 Handle<Object> value = 8138 Handle<Object> value =
8138 Object::GetProperty(copy, name).ToHandleChecked(); 8139 Object::GetProperty(copy, name).ToHandleChecked();
8139 if (value->IsJSObject()) { 8140 if (value->IsJSObject()) {
8140 Handle<JSObject> result; 8141 Handle<JSObject> result;
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
8625 return Just(true); 8626 return Just(true);
8626 } 8627 }
8627 8628
8628 8629
8629 // Returns |true| on success, |false| if prototype walking should be stopped, 8630 // Returns |true| on success, |false| if prototype walking should be stopped,
8630 // |nothing| if an exception was thrown. 8631 // |nothing| if an exception was thrown.
8631 static Maybe<bool> GetKeysFromJSObject(Isolate* isolate, 8632 static Maybe<bool> GetKeysFromJSObject(Isolate* isolate,
8632 Handle<JSReceiver> receiver, 8633 Handle<JSReceiver> receiver,
8633 Handle<JSObject> object, 8634 Handle<JSObject> object,
8634 PropertyFilter* filter, 8635 PropertyFilter* filter,
8635 JSReceiver::KeyCollectionType type, 8636 KeyCollectionType type,
8636 KeyAccumulator* accumulator) { 8637 KeyAccumulator* accumulator) {
8637 accumulator->NextPrototype(); 8638 accumulator->NextPrototype();
8638 // Check access rights if required. 8639 // Check access rights if required.
8639 if (object->IsAccessCheckNeeded() && 8640 if (object->IsAccessCheckNeeded() &&
8640 !isolate->MayAccess(handle(isolate->context()), object)) { 8641 !isolate->MayAccess(handle(isolate->context()), object)) {
8641 // The cross-origin spec says that [[Enumerate]] shall return an empty 8642 // The cross-origin spec says that [[Enumerate]] shall return an empty
8642 // iterator when it doesn't have access... 8643 // iterator when it doesn't have access...
8643 if (type == JSReceiver::INCLUDE_PROTOS) { 8644 if (type == KeyCollectionType::INCLUDE_PROTOS) {
8644 return Just(false); 8645 return Just(false);
8645 } 8646 }
8646 // ...whereas [[OwnPropertyKeys]] shall return whitelisted properties. 8647 // ...whereas [[OwnPropertyKeys]] shall return whitelisted properties.
8647 DCHECK(type == JSReceiver::OWN_ONLY); 8648 DCHECK_EQ(KeyCollectionType::OWN_ONLY, type);
8648 *filter = static_cast<PropertyFilter>(*filter | ONLY_ALL_CAN_READ); 8649 *filter = static_cast<PropertyFilter>(*filter | ONLY_ALL_CAN_READ);
8649 } 8650 }
8650 8651
8651 JSObject::CollectOwnElementKeys(object, accumulator, *filter); 8652 JSObject::CollectOwnElementKeys(object, accumulator, *filter);
8652 8653
8653 // Add the element keys from the interceptor. 8654 // Add the element keys from the interceptor.
8654 Maybe<bool> success = 8655 Maybe<bool> success =
8655 GetKeysFromInterceptor<v8::IndexedPropertyEnumeratorCallback, kIndexed>( 8656 GetKeysFromInterceptor<v8::IndexedPropertyEnumeratorCallback, kIndexed>(
8656 isolate, receiver, object, *filter, accumulator); 8657 isolate, receiver, object, *filter, accumulator);
8657 MAYBE_RETURN(success, Nothing<bool>()); 8658 MAYBE_RETURN(success, Nothing<bool>());
(...skipping 30 matching lines...) Expand all
8688 MAYBE_RETURN(success, Nothing<bool>()); 8689 MAYBE_RETURN(success, Nothing<bool>());
8689 return Just(true); 8690 return Just(true);
8690 } 8691 }
8691 8692
8692 8693
8693 // Helper function for JSReceiver::GetKeys() below. Can be called recursively. 8694 // Helper function for JSReceiver::GetKeys() below. Can be called recursively.
8694 // Returns |true| or |nothing|. 8695 // Returns |true| or |nothing|.
8695 static Maybe<bool> GetKeys_Internal(Isolate* isolate, 8696 static Maybe<bool> GetKeys_Internal(Isolate* isolate,
8696 Handle<JSReceiver> receiver, 8697 Handle<JSReceiver> receiver,
8697 Handle<JSReceiver> object, 8698 Handle<JSReceiver> object,
8698 JSReceiver::KeyCollectionType type, 8699 KeyCollectionType type,
8699 PropertyFilter filter, 8700 PropertyFilter filter,
8700 KeyAccumulator* accumulator) { 8701 KeyAccumulator* accumulator) {
8701 PrototypeIterator::WhereToEnd end = type == JSReceiver::OWN_ONLY 8702 PrototypeIterator::WhereToEnd end = type == KeyCollectionType::OWN_ONLY
8702 ? PrototypeIterator::END_AT_NON_HIDDEN 8703 ? PrototypeIterator::END_AT_NON_HIDDEN
8703 : PrototypeIterator::END_AT_NULL; 8704 : PrototypeIterator::END_AT_NULL;
8704 for (PrototypeIterator iter(isolate, object, 8705 for (PrototypeIterator iter(isolate, object,
8705 PrototypeIterator::START_AT_RECEIVER); 8706 PrototypeIterator::START_AT_RECEIVER);
8706 !iter.IsAtEnd(end); iter.Advance()) { 8707 !iter.IsAtEnd(end); iter.Advance()) {
8707 Handle<JSReceiver> current = 8708 Handle<JSReceiver> current =
8708 PrototypeIterator::GetCurrent<JSReceiver>(iter); 8709 PrototypeIterator::GetCurrent<JSReceiver>(iter);
8709 Maybe<bool> result = Just(false); // Dummy initialization. 8710 Maybe<bool> result = Just(false); // Dummy initialization.
8710 if (current->IsJSProxy()) { 8711 if (current->IsJSProxy()) {
8711 if (type == JSReceiver::OWN_ONLY) { 8712 if (type == KeyCollectionType::OWN_ONLY) {
8712 result = JSProxy::OwnPropertyKeys(isolate, receiver, 8713 result = JSProxy::OwnPropertyKeys(isolate, receiver,
8713 Handle<JSProxy>::cast(current), 8714 Handle<JSProxy>::cast(current),
8714 filter, accumulator); 8715 filter, accumulator);
8715 } else { 8716 } else {
8716 DCHECK(type == JSReceiver::INCLUDE_PROTOS); 8717 DCHECK(type == KeyCollectionType::INCLUDE_PROTOS);
8717 result = JSProxy::Enumerate( 8718 result = JSProxy::Enumerate(
8718 isolate, receiver, Handle<JSProxy>::cast(current), accumulator); 8719 isolate, receiver, Handle<JSProxy>::cast(current), accumulator);
8719 } 8720 }
8720 } else { 8721 } else {
8721 DCHECK(current->IsJSObject()); 8722 DCHECK(current->IsJSObject());
8722 result = GetKeysFromJSObject(isolate, receiver, 8723 result = GetKeysFromJSObject(isolate, receiver,
8723 Handle<JSObject>::cast(current), &filter, 8724 Handle<JSObject>::cast(current), &filter,
8724 type, accumulator); 8725 type, accumulator);
8725 } 8726 }
8726 MAYBE_RETURN(result, Nothing<bool>()); 8727 MAYBE_RETURN(result, Nothing<bool>());
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
8868 // then: 8869 // then:
8869 if (extensible_target && nonconfigurable_keys_length == 0) { 8870 if (extensible_target && nonconfigurable_keys_length == 0) {
8870 // 15a. Return trapResult. 8871 // 15a. Return trapResult.
8871 return accumulator->AddKeysFromProxy(proxy, trap_result); 8872 return accumulator->AddKeysFromProxy(proxy, trap_result);
8872 } 8873 }
8873 // 16. Let uncheckedResultKeys be a new List which is a copy of trapResult. 8874 // 16. Let uncheckedResultKeys be a new List which is a copy of trapResult.
8874 Zone set_zone; 8875 Zone set_zone;
8875 const int kPresent = 1; 8876 const int kPresent = 1;
8876 const int kGone = 0; 8877 const int kGone = 0;
8877 IdentityMap<int> unchecked_result_keys(isolate->heap(), &set_zone); 8878 IdentityMap<int> unchecked_result_keys(isolate->heap(), &set_zone);
8878 int unchecked_result_keys_size = trap_result->length(); 8879 int unchecked_result_keys_size = 0;
8879 for (int i = 0; i < trap_result->length(); ++i) { 8880 for (int i = 0; i < trap_result->length(); ++i) {
8880 DCHECK(trap_result->get(i)->IsUniqueName()); 8881 DCHECK(trap_result->get(i)->IsUniqueName());
8881 unchecked_result_keys.Set(trap_result->get(i), kPresent); 8882 Object* key = trap_result->get(i);
8883 int* found = unchecked_result_keys.Find(key);
8884 if (found == nullptr || *found == kGone) {
Camillo Bruni 2016/02/04 11:59:07 I didn't fully check how IdentityMaps work, but th
8885 unchecked_result_keys.Set(key, kPresent);
8886 unchecked_result_keys_size++;
8887 }
8882 } 8888 }
8883 // 17. Repeat, for each key that is an element of targetNonconfigurableKeys: 8889 // 17. Repeat, for each key that is an element of targetNonconfigurableKeys:
8884 for (int i = 0; i < nonconfigurable_keys_length; ++i) { 8890 for (int i = 0; i < nonconfigurable_keys_length; ++i) {
8885 Object* key = target_nonconfigurable_keys->get(i); 8891 Object* key = target_nonconfigurable_keys->get(i);
8886 // 17a. If key is not an element of uncheckedResultKeys, throw a 8892 // 17a. If key is not an element of uncheckedResultKeys, throw a
8887 // TypeError exception. 8893 // TypeError exception.
8888 int* found = unchecked_result_keys.Find(key); 8894 int* found = unchecked_result_keys.Find(key);
8889 if (found == nullptr || *found == kGone) { 8895 if (found == nullptr || *found == kGone) {
8890 isolate->Throw(*isolate->factory()->NewTypeError( 8896 isolate->Throw(*isolate->factory()->NewTypeError(
8891 MessageTemplate::kProxyOwnKeysMissing, handle(key, isolate))); 8897 MessageTemplate::kProxyOwnKeysMissing, handle(key, isolate)));
8892 return Nothing<bool>(); 8898 return Nothing<bool>();
8893 } 8899 }
8894 // 17b. Remove key from uncheckedResultKeys. 8900 // 17b. Remove key from uncheckedResultKeys.
Camillo Bruni 2016/02/04 11:59:07 I read this now as remove all occurences of key fr
8895 *found = kGone; 8901 *found = kGone;
8896 unchecked_result_keys_size--; 8902 unchecked_result_keys_size--;
8897 } 8903 }
8898 // 18. If extensibleTarget is true, return trapResult. 8904 // 18. If extensibleTarget is true, return trapResult.
8899 if (extensible_target) { 8905 if (extensible_target) {
8900 return accumulator->AddKeysFromProxy(proxy, trap_result); 8906 return accumulator->AddKeysFromProxy(proxy, trap_result);
8901 } 8907 }
8902 // 19. Repeat, for each key that is an element of targetConfigurableKeys: 8908 // 19. Repeat, for each key that is an element of targetConfigurableKeys:
8903 for (int i = 0; i < target_configurable_keys->length(); ++i) { 8909 for (int i = 0; i < target_configurable_keys->length(); ++i) {
8904 Object* key = target_configurable_keys->get(i); 8910 Object* key = target_configurable_keys->get(i);
(...skipping 21 matching lines...) Expand all
8926 return accumulator->AddKeysFromProxy(proxy, trap_result); 8932 return accumulator->AddKeysFromProxy(proxy, trap_result);
8927 } 8933 }
8928 8934
8929 8935
8930 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, 8936 MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object,
8931 KeyCollectionType type, 8937 KeyCollectionType type,
8932 PropertyFilter filter, 8938 PropertyFilter filter,
8933 GetKeysConversion keys_conversion) { 8939 GetKeysConversion keys_conversion) {
8934 USE(ContainsOnlyValidKeys); 8940 USE(ContainsOnlyValidKeys);
8935 Isolate* isolate = object->GetIsolate(); 8941 Isolate* isolate = object->GetIsolate();
8936 KeyAccumulator accumulator(isolate, filter); 8942 KeyAccumulator accumulator(isolate, type, filter);
8937 MAYBE_RETURN( 8943 MAYBE_RETURN(
8938 GetKeys_Internal(isolate, object, object, type, filter, &accumulator), 8944 GetKeys_Internal(isolate, object, object, type, filter, &accumulator),
8939 MaybeHandle<FixedArray>()); 8945 MaybeHandle<FixedArray>());
8940 Handle<FixedArray> keys = accumulator.GetKeys(keys_conversion); 8946 Handle<FixedArray> keys = accumulator.GetKeys(keys_conversion);
8941 DCHECK(ContainsOnlyValidKeys(keys)); 8947 DCHECK(ContainsOnlyValidKeys(keys));
8942 return keys; 8948 return keys;
8943 } 8949 }
8944 8950
8945 8951
8946 bool Map::DictionaryElementsInPrototypeChainOnly() { 8952 bool Map::DictionaryElementsInPrototypeChainOnly() {
(...skipping 10823 matching lines...) Expand 10 before | Expand all | Expand 10 after
19770 if (cell->value() != *new_value) { 19776 if (cell->value() != *new_value) {
19771 cell->set_value(*new_value); 19777 cell->set_value(*new_value);
19772 Isolate* isolate = cell->GetIsolate(); 19778 Isolate* isolate = cell->GetIsolate();
19773 cell->dependent_code()->DeoptimizeDependentCodeGroup( 19779 cell->dependent_code()->DeoptimizeDependentCodeGroup(
19774 isolate, DependentCode::kPropertyCellChangedGroup); 19780 isolate, DependentCode::kPropertyCellChangedGroup);
19775 } 19781 }
19776 } 19782 }
19777 19783
19778 } // namespace internal 19784 } // namespace internal
19779 } // namespace v8 19785 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime/runtime-array.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698