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" |
11 #include "src/isolate-inl.h" | 11 #include "src/isolate-inl.h" |
12 #include "src/objects-inl.h" | 12 #include "src/objects-inl.h" |
13 #include "src/property-descriptor.h" | 13 #include "src/property-descriptor.h" |
14 #include "src/prototype.h" | 14 #include "src/prototype.h" |
15 | 15 |
16 namespace v8 { | 16 namespace v8 { |
17 namespace internal { | 17 namespace internal { |
18 | 18 |
19 KeyAccumulator::~KeyAccumulator() { | 19 KeyAccumulator::~KeyAccumulator() { |
20 for (size_t i = 0; i < elements_.size(); i++) { | 20 for (size_t i = 0; i < elements_.size(); i++) { |
21 delete elements_[i]; | 21 delete elements_[i]; |
22 } | 22 } |
23 } | 23 } |
24 | 24 |
| 25 namespace { |
| 26 |
| 27 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { |
| 28 int len = array->length(); |
| 29 for (int i = 0; i < len; i++) { |
| 30 Object* e = array->get(i); |
| 31 if (!(e->IsName() || e->IsNumber())) return false; |
| 32 } |
| 33 return true; |
| 34 } |
| 35 |
| 36 } // namespace |
| 37 |
| 38 MaybeHandle<FixedArray> KeyAccumulator::GetKeys( |
| 39 Handle<JSReceiver> object, KeyCollectionType type, PropertyFilter filter, |
| 40 GetKeysConversion keys_conversion, bool filter_proxy_keys) { |
| 41 USE(ContainsOnlyValidKeys); |
| 42 Isolate* isolate = object->GetIsolate(); |
| 43 KeyAccumulator accumulator(isolate, type, filter); |
| 44 accumulator.set_filter_proxy_keys(filter_proxy_keys); |
| 45 MAYBE_RETURN(accumulator.CollectKeys(object, object), |
| 46 MaybeHandle<FixedArray>()); |
| 47 Handle<FixedArray> keys = accumulator.GetKeys(keys_conversion); |
| 48 DCHECK(ContainsOnlyValidKeys(keys)); |
| 49 return keys; |
| 50 } |
| 51 |
25 Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) { | 52 Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) { |
26 if (length_ == 0) { | 53 if (length_ == 0) { |
27 return isolate_->factory()->empty_fixed_array(); | 54 return isolate_->factory()->empty_fixed_array(); |
28 } | 55 } |
29 // Make sure we have all the lengths collected. | 56 // Make sure we have all the lengths collected. |
30 NextPrototype(); | 57 NextPrototype(); |
31 | 58 |
32 if (type_ == OWN_ONLY && !ownProxyKeys_.is_null()) { | 59 if (type_ == OWN_ONLY && !ownProxyKeys_.is_null()) { |
33 return ownProxyKeys_; | 60 return ownProxyKeys_; |
34 } | 61 } |
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 return keys; | 588 return keys; |
562 } | 589 } |
563 } | 590 } |
564 // The properties-only case failed because there were probably elements on the | 591 // The properties-only case failed because there were probably elements on the |
565 // receiver. | 592 // receiver. |
566 return GetOwnKeysWithElements<true>(isolate_, object, convert); | 593 return GetOwnKeysWithElements<true>(isolate_, object, convert); |
567 } | 594 } |
568 | 595 |
569 MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow( | 596 MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow( |
570 GetKeysConversion convert) { | 597 GetKeysConversion convert) { |
571 return JSReceiver::GetKeys(receiver_, type_, ENUMERABLE_STRINGS, KEEP_NUMBERS, | 598 return JSReceiver::GetKeys(receiver_, type_, filter_, KEEP_NUMBERS, |
572 filter_proxy_keys_); | 599 filter_proxy_keys_); |
573 } | 600 } |
574 | 601 |
575 enum IndexedOrNamed { kIndexed, kNamed }; | 602 enum IndexedOrNamed { kIndexed, kNamed }; |
576 | 603 |
577 // Returns |true| on success, |nothing| on exception. | 604 // Returns |true| on success, |nothing| on exception. |
578 template <class Callback, IndexedOrNamed type> | 605 template <class Callback, IndexedOrNamed type> |
579 static Maybe<bool> GetKeysFromInterceptor(Handle<JSReceiver> receiver, | 606 static Maybe<bool> GetKeysFromInterceptor(Handle<JSReceiver> receiver, |
580 Handle<JSObject> object, | 607 Handle<JSObject> object, |
581 KeyAccumulator* accumulator) { | 608 KeyAccumulator* accumulator) { |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 NextPrototype(); // Prepare for accumulating keys. | 899 NextPrototype(); // Prepare for accumulating keys. |
873 bool prev_filter_proxy_keys_ = filter_proxy_keys_; | 900 bool prev_filter_proxy_keys_ = filter_proxy_keys_; |
874 filter_proxy_keys_ = false; | 901 filter_proxy_keys_ = false; |
875 Maybe<bool> result = AddKeysFromJSProxy(proxy, keys); | 902 Maybe<bool> result = AddKeysFromJSProxy(proxy, keys); |
876 filter_proxy_keys_ = prev_filter_proxy_keys_; | 903 filter_proxy_keys_ = prev_filter_proxy_keys_; |
877 return result; | 904 return result; |
878 } | 905 } |
879 | 906 |
880 } // namespace internal | 907 } // namespace internal |
881 } // namespace v8 | 908 } // namespace v8 |
OLD | NEW |