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

Side by Side Diff: src/key-accumulator.cc

Issue 1637753004: [es7] refactor and fix Object.values() / Object.entries() (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: keepin it fresh 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
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698