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/key-accumulator.h" | 5 #include "src/key-accumulator.h" |
| 6 | 6 |
| 7 #include "src/elements.h" | 7 #include "src/elements.h" |
| 8 #include "src/factory.h" | 8 #include "src/factory.h" |
| 9 #include "src/isolate-inl.h" | 9 #include "src/isolate-inl.h" |
| 10 #include "src/objects-inl.h" | 10 #include "src/objects-inl.h" |
| 11 #include "src/property-descriptor.h" | 11 #include "src/property-descriptor.h" |
| 12 | 12 |
| 13 | 13 |
| 14 namespace v8 { | 14 namespace v8 { |
| 15 namespace internal { | 15 namespace internal { |
| 16 | 16 |
| 17 | 17 |
| 18 KeyAccumulator::~KeyAccumulator() { | 18 KeyAccumulator::~KeyAccumulator() { |
| 19 for (size_t i = 0; i < elements_.size(); i++) { | 19 for (size_t i = 0; i < elements_.size(); i++) { |
| 20 delete elements_[i]; | 20 delete elements_[i]; |
| 21 } | 21 } |
| 22 } | 22 } |
| 23 | 23 |
| 24 | 24 template <typename F> |
| 25 Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) { | 25 MaybeHandle<FixedArray> KeyAccumulator::GetKeys_Internal( |
| 26 GetKeysConversion convert, bool trivial, F& accumulate) { | |
| 26 if (length_ == 0) { | 27 if (length_ == 0) { |
| 27 return isolate_->factory()->empty_fixed_array(); | 28 return isolate_->factory()->empty_fixed_array(); |
| 28 } | 29 } |
| 29 // Make sure we have all the lengths collected. | 30 // Make sure we have all the lengths collected. |
| 30 NextPrototype(); | 31 NextPrototype(); |
| 31 | 32 |
| 32 // Assemble the result array by first adding the element keys and then the | 33 // Assemble the result array by first adding the element keys and then the |
| 33 // property keys. We use the total number of String + Symbol keys per level in | 34 // property keys. We use the total number of String + Symbol keys per level in |
| 34 // |level_lengths_| and the available element keys in the corresponding bucket | 35 // |level_lengths_| and the available element keys in the corresponding bucket |
| 35 // in |elements_| to deduce the number of keys to take from the | 36 // in |elements_| to deduce the number of keys to take from the |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 52 // Add the element indices for this prototype level. | 53 // Add the element indices for this prototype level. |
| 53 std::vector<uint32_t>* elements = elements_[level]; | 54 std::vector<uint32_t>* elements = elements_[level]; |
| 54 int num_elements = static_cast<int>(elements->size()); | 55 int num_elements = static_cast<int>(elements->size()); |
| 55 for (int i = 0; i < num_elements; i++) { | 56 for (int i = 0; i < num_elements; i++) { |
| 56 Handle<Object> key; | 57 Handle<Object> key; |
| 57 if (convert == KEEP_NUMBERS) { | 58 if (convert == KEEP_NUMBERS) { |
| 58 key = isolate_->factory()->NewNumberFromUint(elements->at(i)); | 59 key = isolate_->factory()->NewNumberFromUint(elements->at(i)); |
| 59 } else { | 60 } else { |
| 60 key = isolate_->factory()->Uint32ToString(elements->at(i)); | 61 key = isolate_->factory()->Uint32ToString(elements->at(i)); |
| 61 } | 62 } |
| 62 result->set(insertion_index, *key); | 63 auto did_accumulate = accumulate(result, insertion_index, *key); |
|
Camillo Bruni
2016/02/03 12:03:48
auto => Maybe<bool>
| |
| 63 insertion_index++; | 64 MAYBE_RETURN(did_accumulate, Handle<FixedArray>()); |
| 65 if (did_accumulate.FromJust()) insertion_index++; | |
| 64 } | 66 } |
| 65 } | 67 } |
| 66 // Add the string property keys for this prototype level. | 68 // Add the string property keys for this prototype level. |
| 67 for (int i = 0; i < num_string_properties; i++) { | 69 for (int i = 0; i < num_string_properties; i++) { |
| 68 Object* key = string_properties_->KeyAt(string_properties_index); | 70 Object* key = string_properties_->KeyAt(string_properties_index); |
| 69 result->set(insertion_index, key); | 71 auto did_accumulate = accumulate(result, insertion_index, key); |
| 70 insertion_index++; | 72 MAYBE_RETURN(did_accumulate, Handle<FixedArray>()); |
| 73 if (did_accumulate.FromJust()) insertion_index++; | |
| 71 string_properties_index++; | 74 string_properties_index++; |
| 72 } | 75 } |
| 73 // Add the symbol property keys for this prototype level. | 76 // Add the symbol property keys for this prototype level. |
| 74 for (int i = 0; i < num_symbol_properties; i++) { | 77 for (int i = 0; i < num_symbol_properties; i++) { |
| 75 Object* key = symbol_properties_->KeyAt(symbol_properties_index); | 78 Object* key = symbol_properties_->KeyAt(symbol_properties_index); |
| 76 result->set(insertion_index, key); | 79 auto did_accumulate = accumulate(result, insertion_index, key); |
| 77 insertion_index++; | 80 MAYBE_RETURN(did_accumulate, Handle<FixedArray>()); |
| 81 if (did_accumulate.FromJust()) insertion_index++; | |
| 78 symbol_properties_index++; | 82 symbol_properties_index++; |
| 79 } | 83 } |
| 80 } | 84 } |
| 81 | 85 |
| 82 DCHECK_EQ(insertion_index, length_); | 86 if (trivial) { |
| 87 DCHECK_EQ(insertion_index, length_); | |
| 88 } else if (insertion_index < length_) { | |
| 89 result->Shrink(insertion_index); | |
| 90 } | |
| 83 return result; | 91 return result; |
| 84 } | 92 } |
| 85 | 93 |
| 94 Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) { | |
| 95 auto add_key = [](Handle<FixedArray> result, int i, Object* key) { | |
| 96 result->set(i, key); | |
| 97 return Just(true); | |
| 98 }; | |
| 99 return GetKeys_Internal(convert, true, add_key).ToHandleChecked(); | |
| 100 } | |
| 101 | |
| 102 MaybeHandle<FixedArray> KeyAccumulator::GetValues(Handle<JSReceiver> receiver, | |
| 103 GetKeysConversion convert) { | |
| 104 Isolate* isolate = isolate_; | |
| 105 auto add_value = [receiver, isolate](Handle<FixedArray> result, int i, | |
|
Camillo Bruni
2016/02/03 12:03:48
I'm fine with the "auto" type for the accumulate l
caitp (gmail)
2016/02/03 12:57:30
replaced all non-lambda's with proper types
| |
| 106 Object* key) { | |
| 107 Handle<Object> value; | |
| 108 Handle<Name> name = Handle<Name>::cast(handle(key, isolate)); | |
| 109 | |
| 110 PropertyDescriptor descriptor; | |
| 111 auto owned = JSReceiver::GetOwnPropertyDescriptor(isolate, receiver, name, | |
| 112 &descriptor); | |
| 113 MAYBE_RETURN(owned, Nothing<bool>()); | |
| 114 if (!owned.FromJust() || !descriptor.enumerable()) return Just(false); | |
| 115 | |
| 116 if (Object::GetPropertyOrElement(receiver, name, STRICT).ToHandle(&value)) { | |
| 117 result->set(i, *value); | |
| 118 return Just(true); | |
| 119 } | |
| 120 return Nothing<bool>(); | |
| 121 }; | |
| 122 | |
| 123 return GetKeys_Internal(convert, false, add_value); | |
| 124 } | |
| 125 | |
| 126 MaybeHandle<FixedArray> KeyAccumulator::GetEntries(Handle<JSReceiver> receiver, | |
| 127 GetKeysConversion convert) { | |
| 128 Isolate* isolate = isolate_; | |
| 129 auto add_entry = [receiver, isolate](Handle<FixedArray> result, int i, | |
| 130 Object* key) { | |
| 131 Handle<Object> value; | |
| 132 Handle<Name> name = Handle<Name>::cast(handle(key, isolate)); | |
| 133 | |
| 134 PropertyDescriptor descriptor; | |
| 135 auto owned = JSReceiver::GetOwnPropertyDescriptor(isolate, receiver, name, | |
| 136 &descriptor); | |
| 137 MAYBE_RETURN(owned, Nothing<bool>()); | |
| 138 if (!owned.FromJust() || !descriptor.enumerable()) return Just(false); | |
| 139 | |
| 140 if (Object::GetPropertyOrElement(receiver, name, STRICT).ToHandle(&value)) { | |
| 141 auto entry_storage = isolate->factory()->NewUninitializedFixedArray(2); | |
| 142 entry_storage->set(0, key); | |
| 143 entry_storage->set(1, *value); | |
| 144 auto entry = isolate->factory()->NewJSArrayWithElements(entry_storage); | |
| 145 result->set(i, *entry); | |
| 146 return Just(true); | |
| 147 } | |
| 148 return Nothing<bool>(); | |
| 149 }; | |
| 150 | |
| 151 return GetKeys_Internal(convert, false, add_entry); | |
| 152 } | |
| 86 | 153 |
| 87 namespace { | 154 namespace { |
| 88 | 155 |
| 89 bool AccumulatorHasKey(std::vector<uint32_t>* sub_elements, uint32_t key) { | 156 bool AccumulatorHasKey(std::vector<uint32_t>* sub_elements, uint32_t key) { |
| 90 return std::binary_search(sub_elements->begin(), sub_elements->end(), key); | 157 return std::binary_search(sub_elements->begin(), sub_elements->end(), key); |
| 91 } | 158 } |
| 92 | 159 |
| 93 } // namespace | 160 } // namespace |
| 94 | 161 |
| 95 bool KeyAccumulator::AddKey(Object* key, AddKeyConversion convert) { | 162 bool KeyAccumulator::AddKey(Object* key, AddKeyConversion convert) { |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 306 level_lengths_.push_back(level_symbol_length_); | 373 level_lengths_.push_back(level_symbol_length_); |
| 307 } | 374 } |
| 308 elements_.push_back(new std::vector<uint32_t>()); | 375 elements_.push_back(new std::vector<uint32_t>()); |
| 309 level_string_length_ = 0; | 376 level_string_length_ = 0; |
| 310 level_symbol_length_ = 0; | 377 level_symbol_length_ = 0; |
| 311 } | 378 } |
| 312 | 379 |
| 313 | 380 |
| 314 } // namespace internal | 381 } // namespace internal |
| 315 } // namespace v8 | 382 } // namespace v8 |
| OLD | NEW |