| 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/keys.h" | 5 #include "src/keys.h" |
| 6 | 6 |
| 7 #include "src/api-arguments.h" | 7 #include "src/api-arguments.h" |
| 8 #include "src/elements.h" | 8 #include "src/elements.h" |
| 9 #include "src/factory.h" | 9 #include "src/factory.h" |
| 10 #include "src/identity-map.h" | 10 #include "src/identity-map.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 if (!(e->IsName() || e->IsNumber())) return false; | 28 if (!(e->IsName() || e->IsNumber())) return false; |
| 29 } | 29 } |
| 30 return true; | 30 return true; |
| 31 } | 31 } |
| 32 | 32 |
| 33 } // namespace | 33 } // namespace |
| 34 | 34 |
| 35 // static | 35 // static |
| 36 MaybeHandle<FixedArray> KeyAccumulator::GetKeys( | 36 MaybeHandle<FixedArray> KeyAccumulator::GetKeys( |
| 37 Handle<JSReceiver> object, KeyCollectionMode mode, PropertyFilter filter, | 37 Handle<JSReceiver> object, KeyCollectionMode mode, PropertyFilter filter, |
| 38 GetKeysConversion keys_conversion, bool filter_proxy_keys, bool is_for_in) { | 38 GetKeysConversion keys_conversion, bool is_for_in) { |
| 39 Isolate* isolate = object->GetIsolate(); | 39 Isolate* isolate = object->GetIsolate(); |
| 40 FastKeyAccumulator accumulator(isolate, object, mode, filter); | 40 FastKeyAccumulator accumulator(isolate, object, mode, filter); |
| 41 accumulator.set_filter_proxy_keys(filter_proxy_keys); | |
| 42 accumulator.set_is_for_in(is_for_in); | 41 accumulator.set_is_for_in(is_for_in); |
| 43 return accumulator.GetKeys(keys_conversion); | 42 return accumulator.GetKeys(keys_conversion); |
| 44 } | 43 } |
| 45 | 44 |
| 46 Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) { | 45 Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) { |
| 47 if (keys_.is_null()) { | 46 if (keys_.is_null()) { |
| 48 return isolate_->factory()->empty_fixed_array(); | 47 return isolate_->factory()->empty_fixed_array(); |
| 49 } | 48 } |
| 50 if (mode_ == KeyCollectionMode::kOwnOnly && | 49 if (mode_ == KeyCollectionMode::kOwnOnly && |
| 51 keys_->map() == isolate_->heap()->fixed_array_map()) { | 50 keys_->map() == isolate_->heap()->fixed_array_map()) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 store_position++; | 127 store_position++; |
| 129 } | 128 } |
| 130 if (store_position == 0) return isolate->factory()->empty_fixed_array(); | 129 if (store_position == 0) return isolate->factory()->empty_fixed_array(); |
| 131 keys->Shrink(store_position); | 130 keys->Shrink(store_position); |
| 132 return keys; | 131 return keys; |
| 133 } | 132 } |
| 134 | 133 |
| 135 // Returns "nothing" in case of exception, "true" on success. | 134 // Returns "nothing" in case of exception, "true" on success. |
| 136 Maybe<bool> KeyAccumulator::AddKeysFromJSProxy(Handle<JSProxy> proxy, | 135 Maybe<bool> KeyAccumulator::AddKeysFromJSProxy(Handle<JSProxy> proxy, |
| 137 Handle<FixedArray> keys) { | 136 Handle<FixedArray> keys) { |
| 138 if (filter_proxy_keys_) { | 137 // Postpone the enumerable check for for-in to the ForInFilter step. |
| 139 DCHECK(!is_for_in_); | 138 if (!is_for_in_) { |
| 140 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 139 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 141 isolate_, keys, FilterProxyKeys(this, proxy, keys, filter_), | 140 isolate_, keys, FilterProxyKeys(this, proxy, keys, filter_), |
| 142 Nothing<bool>()); | 141 Nothing<bool>()); |
| 143 } | 142 if (mode_ == KeyCollectionMode::kOwnOnly) { |
| 144 if (mode_ == KeyCollectionMode::kOwnOnly && !is_for_in_) { | 143 // If we collect only the keys from a JSProxy do not sort or deduplicate. |
| 145 // If we collect only the keys from a JSProxy do not sort or deduplicate it. | 144 keys_ = keys; |
| 146 keys_ = keys; | 145 return Just(true); |
| 147 return Just(true); | 146 } |
| 148 } | 147 } |
| 149 AddKeys(keys, is_for_in_ ? CONVERT_TO_ARRAY_INDEX : DO_NOT_CONVERT); | 148 AddKeys(keys, is_for_in_ ? CONVERT_TO_ARRAY_INDEX : DO_NOT_CONVERT); |
| 150 return Just(true); | 149 return Just(true); |
| 151 } | 150 } |
| 152 | 151 |
| 153 Maybe<bool> KeyAccumulator::CollectKeys(Handle<JSReceiver> receiver, | 152 Maybe<bool> KeyAccumulator::CollectKeys(Handle<JSReceiver> receiver, |
| 154 Handle<JSReceiver> object) { | 153 Handle<JSReceiver> object) { |
| 155 // Proxies have no hidden prototype and we should not trigger the | 154 // Proxies have no hidden prototype and we should not trigger the |
| 156 // [[GetPrototypeOf]] trap on the last iteration when using | 155 // [[GetPrototypeOf]] trap on the last iteration when using |
| 157 // AdvanceFollowingProxies. | 156 // AdvanceFollowingProxies. |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 437 } | 436 } |
| 438 } | 437 } |
| 439 // The properties-only case failed because there were probably elements on the | 438 // The properties-only case failed because there were probably elements on the |
| 440 // receiver. | 439 // receiver. |
| 441 return GetOwnKeysWithElements<true>(isolate_, object, keys_conversion); | 440 return GetOwnKeysWithElements<true>(isolate_, object, keys_conversion); |
| 442 } | 441 } |
| 443 | 442 |
| 444 MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow( | 443 MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow( |
| 445 GetKeysConversion keys_conversion) { | 444 GetKeysConversion keys_conversion) { |
| 446 KeyAccumulator accumulator(isolate_, mode_, filter_); | 445 KeyAccumulator accumulator(isolate_, mode_, filter_); |
| 447 accumulator.set_filter_proxy_keys(filter_proxy_keys_); | |
| 448 accumulator.set_is_for_in(is_for_in_); | 446 accumulator.set_is_for_in(is_for_in_); |
| 449 accumulator.set_last_non_empty_prototype(last_non_empty_prototype_); | 447 accumulator.set_last_non_empty_prototype(last_non_empty_prototype_); |
| 450 | 448 |
| 451 MAYBE_RETURN(accumulator.CollectKeys(receiver_, receiver_), | 449 MAYBE_RETURN(accumulator.CollectKeys(receiver_, receiver_), |
| 452 MaybeHandle<FixedArray>()); | 450 MaybeHandle<FixedArray>()); |
| 453 return accumulator.GetKeys(keys_conversion); | 451 return accumulator.GetKeys(keys_conversion); |
| 454 } | 452 } |
| 455 | 453 |
| 456 namespace { | 454 namespace { |
| 457 | 455 |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 return AddKeysFromJSProxy(proxy, trap_result); | 851 return AddKeysFromJSProxy(proxy, trap_result); |
| 854 } | 852 } |
| 855 | 853 |
| 856 Maybe<bool> KeyAccumulator::CollectOwnJSProxyTargetKeys( | 854 Maybe<bool> KeyAccumulator::CollectOwnJSProxyTargetKeys( |
| 857 Handle<JSProxy> proxy, Handle<JSReceiver> target) { | 855 Handle<JSProxy> proxy, Handle<JSReceiver> target) { |
| 858 // TODO(cbruni): avoid creating another KeyAccumulator | 856 // TODO(cbruni): avoid creating another KeyAccumulator |
| 859 Handle<FixedArray> keys; | 857 Handle<FixedArray> keys; |
| 860 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 858 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 861 isolate_, keys, | 859 isolate_, keys, |
| 862 KeyAccumulator::GetKeys(target, KeyCollectionMode::kOwnOnly, filter_, | 860 KeyAccumulator::GetKeys(target, KeyCollectionMode::kOwnOnly, filter_, |
| 863 GetKeysConversion::kConvertToString, | 861 GetKeysConversion::kConvertToString, is_for_in_), |
| 864 filter_proxy_keys_, is_for_in_), | |
| 865 Nothing<bool>()); | 862 Nothing<bool>()); |
| 866 bool prev_filter_proxy_keys_ = filter_proxy_keys_; | |
| 867 filter_proxy_keys_ = false; | |
| 868 Maybe<bool> result = AddKeysFromJSProxy(proxy, keys); | 863 Maybe<bool> result = AddKeysFromJSProxy(proxy, keys); |
| 869 filter_proxy_keys_ = prev_filter_proxy_keys_; | |
| 870 return result; | 864 return result; |
| 871 } | 865 } |
| 872 | 866 |
| 873 } // namespace internal | 867 } // namespace internal |
| 874 } // namespace v8 | 868 } // namespace v8 |
| OLD | NEW |