Chromium Code Reviews| Index: src/key-accumulator.cc |
| diff --git a/src/key-accumulator.cc b/src/key-accumulator.cc |
| index e7a9c3ccebccd3ba56b7a87b6cc7c1f9148deae7..0f46a69ad2c6a47931925ba80453d422e695bfe8 100644 |
| --- a/src/key-accumulator.cc |
| +++ b/src/key-accumulator.cc |
| @@ -21,8 +21,9 @@ KeyAccumulator::~KeyAccumulator() { |
| } |
| } |
| - |
| -Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) { |
| +template <typename F> |
| +MaybeHandle<FixedArray> KeyAccumulator::GetKeys_Internal( |
| + GetKeysConversion convert, bool trivial, F& accumulate) { |
| if (length_ == 0) { |
| return isolate_->factory()->empty_fixed_array(); |
| } |
| @@ -59,30 +60,96 @@ Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) { |
| } else { |
| key = isolate_->factory()->Uint32ToString(elements->at(i)); |
| } |
| - result->set(insertion_index, *key); |
| - insertion_index++; |
| + auto did_accumulate = accumulate(result, insertion_index, *key); |
|
Camillo Bruni
2016/02/03 12:03:48
auto => Maybe<bool>
|
| + MAYBE_RETURN(did_accumulate, Handle<FixedArray>()); |
| + if (did_accumulate.FromJust()) insertion_index++; |
| } |
| } |
| // Add the string property keys for this prototype level. |
| for (int i = 0; i < num_string_properties; i++) { |
| Object* key = string_properties_->KeyAt(string_properties_index); |
| - result->set(insertion_index, key); |
| - insertion_index++; |
| + auto did_accumulate = accumulate(result, insertion_index, key); |
| + MAYBE_RETURN(did_accumulate, Handle<FixedArray>()); |
| + if (did_accumulate.FromJust()) insertion_index++; |
| string_properties_index++; |
| } |
| // Add the symbol property keys for this prototype level. |
| for (int i = 0; i < num_symbol_properties; i++) { |
| Object* key = symbol_properties_->KeyAt(symbol_properties_index); |
| - result->set(insertion_index, key); |
| - insertion_index++; |
| + auto did_accumulate = accumulate(result, insertion_index, key); |
| + MAYBE_RETURN(did_accumulate, Handle<FixedArray>()); |
| + if (did_accumulate.FromJust()) insertion_index++; |
| symbol_properties_index++; |
| } |
| } |
| - DCHECK_EQ(insertion_index, length_); |
| + if (trivial) { |
| + DCHECK_EQ(insertion_index, length_); |
| + } else if (insertion_index < length_) { |
| + result->Shrink(insertion_index); |
| + } |
| return result; |
| } |
| +Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) { |
| + auto add_key = [](Handle<FixedArray> result, int i, Object* key) { |
| + result->set(i, key); |
| + return Just(true); |
| + }; |
| + return GetKeys_Internal(convert, true, add_key).ToHandleChecked(); |
| +} |
| + |
| +MaybeHandle<FixedArray> KeyAccumulator::GetValues(Handle<JSReceiver> receiver, |
| + GetKeysConversion convert) { |
| + Isolate* isolate = isolate_; |
| + 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
|
| + Object* key) { |
| + Handle<Object> value; |
| + Handle<Name> name = Handle<Name>::cast(handle(key, isolate)); |
| + |
| + PropertyDescriptor descriptor; |
| + auto owned = JSReceiver::GetOwnPropertyDescriptor(isolate, receiver, name, |
| + &descriptor); |
| + MAYBE_RETURN(owned, Nothing<bool>()); |
| + if (!owned.FromJust() || !descriptor.enumerable()) return Just(false); |
| + |
| + if (Object::GetPropertyOrElement(receiver, name, STRICT).ToHandle(&value)) { |
| + result->set(i, *value); |
| + return Just(true); |
| + } |
| + return Nothing<bool>(); |
| + }; |
| + |
| + return GetKeys_Internal(convert, false, add_value); |
| +} |
| + |
| +MaybeHandle<FixedArray> KeyAccumulator::GetEntries(Handle<JSReceiver> receiver, |
| + GetKeysConversion convert) { |
| + Isolate* isolate = isolate_; |
| + auto add_entry = [receiver, isolate](Handle<FixedArray> result, int i, |
| + Object* key) { |
| + Handle<Object> value; |
| + Handle<Name> name = Handle<Name>::cast(handle(key, isolate)); |
| + |
| + PropertyDescriptor descriptor; |
| + auto owned = JSReceiver::GetOwnPropertyDescriptor(isolate, receiver, name, |
| + &descriptor); |
| + MAYBE_RETURN(owned, Nothing<bool>()); |
| + if (!owned.FromJust() || !descriptor.enumerable()) return Just(false); |
| + |
| + if (Object::GetPropertyOrElement(receiver, name, STRICT).ToHandle(&value)) { |
| + auto entry_storage = isolate->factory()->NewUninitializedFixedArray(2); |
| + entry_storage->set(0, key); |
| + entry_storage->set(1, *value); |
| + auto entry = isolate->factory()->NewJSArrayWithElements(entry_storage); |
| + result->set(i, *entry); |
| + return Just(true); |
| + } |
| + return Nothing<bool>(); |
| + }; |
| + |
| + return GetKeys_Internal(convert, false, add_entry); |
| +} |
| namespace { |