Chromium Code Reviews| 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. |
| 138 if (!is_for_in_) { | |
| 139 DCHECK(!is_for_in_); | 139 DCHECK(!is_for_in_); |
|
adamk
2016/07/28 18:03:13
I think this DCHECK can safely die now :)
Camillo Bruni
2016/07/29 08:31:07
better be sure :D
| |
| 140 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 140 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 141 isolate_, keys, FilterProxyKeys(this, proxy, keys, filter_), | 141 isolate_, keys, FilterProxyKeys(this, proxy, keys, filter_), |
| 142 Nothing<bool>()); | 142 Nothing<bool>()); |
| 143 } | 143 if (mode_ == KeyCollectionMode::kOwnOnly) { |
| 144 if (mode_ == KeyCollectionMode::kOwnOnly && !is_for_in_) { | 144 // 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. | 145 keys_ = keys; |
| 146 keys_ = keys; | 146 return Just(true); |
| 147 return Just(true); | 147 } |
| 148 } | 148 } |
| 149 AddKeys(keys, is_for_in_ ? CONVERT_TO_ARRAY_INDEX : DO_NOT_CONVERT); | 149 AddKeys(keys, is_for_in_ ? CONVERT_TO_ARRAY_INDEX : DO_NOT_CONVERT); |
| 150 return Just(true); | 150 return Just(true); |
| 151 } | 151 } |
| 152 | 152 |
| 153 Maybe<bool> KeyAccumulator::CollectKeys(Handle<JSReceiver> receiver, | 153 Maybe<bool> KeyAccumulator::CollectKeys(Handle<JSReceiver> receiver, |
| 154 Handle<JSReceiver> object) { | 154 Handle<JSReceiver> object) { |
| 155 // Proxies have no hidden prototype and we should not trigger the | 155 // Proxies have no hidden prototype and we should not trigger the |
| 156 // [[GetPrototypeOf]] trap on the last iteration when using | 156 // [[GetPrototypeOf]] trap on the last iteration when using |
| 157 // AdvanceFollowingProxies. | 157 // AdvanceFollowingProxies. |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 437 } | 437 } |
| 438 } | 438 } |
| 439 // The properties-only case failed because there were probably elements on the | 439 // The properties-only case failed because there were probably elements on the |
| 440 // receiver. | 440 // receiver. |
| 441 return GetOwnKeysWithElements<true>(isolate_, object, keys_conversion); | 441 return GetOwnKeysWithElements<true>(isolate_, object, keys_conversion); |
| 442 } | 442 } |
| 443 | 443 |
| 444 MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow( | 444 MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow( |
| 445 GetKeysConversion keys_conversion) { | 445 GetKeysConversion keys_conversion) { |
| 446 KeyAccumulator accumulator(isolate_, mode_, filter_); | 446 KeyAccumulator accumulator(isolate_, mode_, filter_); |
| 447 accumulator.set_filter_proxy_keys(filter_proxy_keys_); | |
| 448 accumulator.set_is_for_in(is_for_in_); | 447 accumulator.set_is_for_in(is_for_in_); |
| 449 accumulator.set_last_non_empty_prototype(last_non_empty_prototype_); | 448 accumulator.set_last_non_empty_prototype(last_non_empty_prototype_); |
| 450 | 449 |
| 451 MAYBE_RETURN(accumulator.CollectKeys(receiver_, receiver_), | 450 MAYBE_RETURN(accumulator.CollectKeys(receiver_, receiver_), |
| 452 MaybeHandle<FixedArray>()); | 451 MaybeHandle<FixedArray>()); |
| 453 return accumulator.GetKeys(keys_conversion); | 452 return accumulator.GetKeys(keys_conversion); |
| 454 } | 453 } |
| 455 | 454 |
| 456 namespace { | 455 namespace { |
| 457 | 456 |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 853 return AddKeysFromJSProxy(proxy, trap_result); | 852 return AddKeysFromJSProxy(proxy, trap_result); |
| 854 } | 853 } |
| 855 | 854 |
| 856 Maybe<bool> KeyAccumulator::CollectOwnJSProxyTargetKeys( | 855 Maybe<bool> KeyAccumulator::CollectOwnJSProxyTargetKeys( |
| 857 Handle<JSProxy> proxy, Handle<JSReceiver> target) { | 856 Handle<JSProxy> proxy, Handle<JSReceiver> target) { |
| 858 // TODO(cbruni): avoid creating another KeyAccumulator | 857 // TODO(cbruni): avoid creating another KeyAccumulator |
| 859 Handle<FixedArray> keys; | 858 Handle<FixedArray> keys; |
| 860 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 859 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 861 isolate_, keys, | 860 isolate_, keys, |
| 862 KeyAccumulator::GetKeys(target, KeyCollectionMode::kOwnOnly, filter_, | 861 KeyAccumulator::GetKeys(target, KeyCollectionMode::kOwnOnly, filter_, |
| 863 GetKeysConversion::kConvertToString, | 862 GetKeysConversion::kConvertToString, is_for_in_), |
| 864 filter_proxy_keys_, is_for_in_), | |
| 865 Nothing<bool>()); | 863 Nothing<bool>()); |
| 866 bool prev_filter_proxy_keys_ = filter_proxy_keys_; | |
| 867 filter_proxy_keys_ = false; | |
| 868 Maybe<bool> result = AddKeysFromJSProxy(proxy, keys); | 864 Maybe<bool> result = AddKeysFromJSProxy(proxy, keys); |
| 869 filter_proxy_keys_ = prev_filter_proxy_keys_; | |
| 870 return result; | 865 return result; |
| 871 } | 866 } |
| 872 | 867 |
| 873 } // namespace internal | 868 } // namespace internal |
| 874 } // namespace v8 | 869 } // namespace v8 |
| OLD | NEW |