Chromium Code Reviews| Index: src/objects.cc |
| diff --git a/src/objects.cc b/src/objects.cc |
| index 98b3056eedf7e528247cf4624c63925aff438566..4fa4cbbaca55026cf0f1266a65f54b4d963620b3 100644 |
| --- a/src/objects.cc |
| +++ b/src/objects.cc |
| @@ -763,17 +763,6 @@ MaybeHandle<Object> Object::GetProperty(LookupIterator* it) { |
| } |
| -#define STACK_CHECK(result_value) \ |
| - do { \ |
| - StackLimitCheck stack_check(isolate); \ |
| - if (stack_check.HasOverflowed()) { \ |
| - isolate->Throw(*isolate->factory()->NewRangeError( \ |
| - MessageTemplate::kStackOverflow)); \ |
| - return result_value; \ |
| - } \ |
| - } while (false) |
| - |
| - |
| // static |
| MaybeHandle<Object> JSProxy::GetProperty(Isolate* isolate, |
| Handle<JSProxy> proxy, |
| @@ -789,7 +778,7 @@ MaybeHandle<Object> JSProxy::GetProperty(Isolate* isolate, |
| } |
| DCHECK(!name->IsPrivate()); |
| - STACK_CHECK(MaybeHandle<Object>()); |
| + STACK_CHECK(isolate, MaybeHandle<Object>()); |
| Handle<Name> trap_name = isolate->factory()->get_string(); |
| // 1. Assert: IsPropertyKey(P) is true. |
| // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. |
| @@ -1002,7 +991,7 @@ MaybeHandle<Object> JSProxy::GetPrototype(Handle<JSProxy> proxy) { |
| Isolate* isolate = proxy->GetIsolate(); |
| Handle<String> trap_name = isolate->factory()->getPrototypeOf_string(); |
| - STACK_CHECK(MaybeHandle<Object>()); |
| + STACK_CHECK(isolate, MaybeHandle<Object>()); |
| // 1. Let handler be the value of the [[ProxyHandler]] internal slot. |
| // 2. If handler is null, throw a TypeError exception. |
| @@ -4849,7 +4838,7 @@ void JSProxy::Revoke(Handle<JSProxy> proxy) { |
| Maybe<bool> JSProxy::HasProperty(Isolate* isolate, Handle<JSProxy> proxy, |
| Handle<Name> name) { |
| DCHECK(!name->IsPrivate()); |
| - STACK_CHECK(Nothing<bool>()); |
| + STACK_CHECK(isolate, Nothing<bool>()); |
| // 1. (Assert) |
| // 2. Let handler be the value of the [[ProxyHandler]] internal slot of O. |
| Handle<Object> handler(proxy->handler(), isolate); |
| @@ -4918,7 +4907,7 @@ Maybe<bool> JSProxy::SetProperty(Handle<JSProxy> proxy, Handle<Name> name, |
| LanguageMode language_mode) { |
| DCHECK(!name->IsPrivate()); |
| Isolate* isolate = proxy->GetIsolate(); |
| - STACK_CHECK(Nothing<bool>()); |
| + STACK_CHECK(isolate, Nothing<bool>()); |
| Factory* factory = isolate->factory(); |
| Handle<String> trap_name = factory->set_string(); |
| ShouldThrow should_throw = |
| @@ -4989,7 +4978,7 @@ Maybe<bool> JSProxy::DeletePropertyOrElement(Handle<JSProxy> proxy, |
| ShouldThrow should_throw = |
| is_sloppy(language_mode) ? DONT_THROW : THROW_ON_ERROR; |
| Isolate* isolate = proxy->GetIsolate(); |
| - STACK_CHECK(Nothing<bool>()); |
| + STACK_CHECK(isolate, Nothing<bool>()); |
| Factory* factory = isolate->factory(); |
| Handle<String> trap_name = factory->deleteProperty_string(); |
| @@ -6893,7 +6882,7 @@ Maybe<bool> JSProxy::DefineOwnProperty(Isolate* isolate, Handle<JSProxy> proxy, |
| Handle<Object> key, |
| PropertyDescriptor* desc, |
| ShouldThrow should_throw) { |
| - STACK_CHECK(Nothing<bool>()); |
| + STACK_CHECK(isolate, Nothing<bool>()); |
| if (key->IsSymbol() && Handle<Symbol>::cast(key)->IsPrivate()) { |
| return SetPrivateProperty(isolate, proxy, Handle<Symbol>::cast(key), desc, |
| should_throw); |
| @@ -7114,7 +7103,7 @@ Maybe<bool> JSProxy::GetOwnPropertyDescriptor(Isolate* isolate, |
| Handle<Name> name, |
| PropertyDescriptor* desc) { |
| DCHECK(!name->IsPrivate()); |
| - STACK_CHECK(Nothing<bool>()); |
| + STACK_CHECK(isolate, Nothing<bool>()); |
| Handle<String> trap_name = |
| isolate->factory()->getOwnPropertyDescriptor_string(); |
| @@ -7472,7 +7461,7 @@ Maybe<bool> JSReceiver::PreventExtensions(Handle<JSReceiver> object, |
| Maybe<bool> JSProxy::PreventExtensions(Handle<JSProxy> proxy, |
| ShouldThrow should_throw) { |
| Isolate* isolate = proxy->GetIsolate(); |
| - STACK_CHECK(Nothing<bool>()); |
| + STACK_CHECK(isolate, Nothing<bool>()); |
| Factory* factory = isolate->factory(); |
| Handle<String> trap_name = factory->preventExtensions_string(); |
| @@ -7574,7 +7563,7 @@ Maybe<bool> JSReceiver::IsExtensible(Handle<JSReceiver> object) { |
| Maybe<bool> JSProxy::IsExtensible(Handle<JSProxy> proxy) { |
| Isolate* isolate = proxy->GetIsolate(); |
| - STACK_CHECK(Nothing<bool>()); |
| + STACK_CHECK(isolate, Nothing<bool>()); |
| Factory* factory = isolate->factory(); |
| Handle<String> trap_name = factory->isExtensible_string(); |
| @@ -7908,7 +7897,7 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk( |
| ONLY_WRITABLE | ONLY_ENUMERABLE | ONLY_CONFIGURABLE); |
| KeyAccumulator accumulator(isolate, OWN_ONLY, filter); |
| accumulator.NextPrototype(); |
| - copy->CollectOwnPropertyNames(&accumulator, filter); |
| + accumulator.CollectOwnPropertyNames(copy); |
| Handle<FixedArray> names = accumulator.GetKeys(); |
| for (int i = 0; i < names->length(); i++) { |
| DCHECK(names->get(i)->IsName()); |
| @@ -8215,13 +8204,6 @@ static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { |
| } |
| -static Handle<FixedArray> ReduceFixedArrayTo( |
| - Handle<FixedArray> array, int length) { |
| - DCHECK_LE(length, array->length()); |
| - if (array->length() == length) return array; |
| - return array->GetIsolate()->factory()->CopyFixedArrayUpTo(array, length); |
| -} |
| - |
| bool Map::OnlyHasSimpleProperties() { |
| // Wrapped string elements aren't explicitly stored in the elements backing |
| // store, but are loaded indirectly from the underlying string. |
| @@ -8230,404 +8212,6 @@ bool Map::OnlyHasSimpleProperties() { |
| !has_hidden_prototype() && !is_dictionary_map(); |
| } |
| -// static |
| -Handle<FixedArray> JSObject::GetFastEnumPropertyKeys(Isolate* isolate, |
| - Handle<JSObject> object) { |
| - Handle<Map> map(object->map()); |
| - bool cache_enum_length = map->OnlyHasSimpleProperties(); |
| - |
| - Handle<DescriptorArray> descs = |
| - Handle<DescriptorArray>(map->instance_descriptors(), isolate); |
| - int own_property_count = map->EnumLength(); |
| - // If the enum length of the given map is set to kInvalidEnumCache, this |
| - // means that the map itself has never used the present enum cache. The |
| - // first step to using the cache is to set the enum length of the map by |
| - // counting the number of own descriptors that are ENUMERABLE_STRINGS. |
| - if (own_property_count == kInvalidEnumCacheSentinel) { |
| - own_property_count = |
| - map->NumberOfDescribedProperties(OWN_DESCRIPTORS, ENUMERABLE_STRINGS); |
| - } else { |
| - DCHECK( |
| - own_property_count == |
| - map->NumberOfDescribedProperties(OWN_DESCRIPTORS, ENUMERABLE_STRINGS)); |
| - } |
| - |
| - if (descs->HasEnumCache()) { |
| - Handle<FixedArray> keys(descs->GetEnumCache(), isolate); |
| - // In case the number of properties required in the enum are actually |
| - // present, we can reuse the enum cache. Otherwise, this means that the |
| - // enum cache was generated for a previous (smaller) version of the |
| - // Descriptor Array. In that case we regenerate the enum cache. |
| - if (own_property_count <= keys->length()) { |
| - isolate->counters()->enum_cache_hits()->Increment(); |
| - if (cache_enum_length) map->SetEnumLength(own_property_count); |
| - return ReduceFixedArrayTo(keys, own_property_count); |
| - } |
| - } |
| - |
| - if (descs->IsEmpty()) { |
| - isolate->counters()->enum_cache_hits()->Increment(); |
| - if (cache_enum_length) map->SetEnumLength(0); |
| - return isolate->factory()->empty_fixed_array(); |
| - } |
| - |
| - isolate->counters()->enum_cache_misses()->Increment(); |
| - |
| - Handle<FixedArray> storage = |
| - isolate->factory()->NewFixedArray(own_property_count); |
| - Handle<FixedArray> indices = |
| - isolate->factory()->NewFixedArray(own_property_count); |
| - |
| - int size = map->NumberOfOwnDescriptors(); |
| - int index = 0; |
| - |
| - for (int i = 0; i < size; i++) { |
| - PropertyDetails details = descs->GetDetails(i); |
| - if (details.IsDontEnum()) continue; |
| - Object* key = descs->GetKey(i); |
| - if (key->IsSymbol()) continue; |
| - storage->set(index, key); |
| - if (!indices.is_null()) { |
| - if (details.type() != DATA) { |
| - indices = Handle<FixedArray>(); |
| - } else { |
| - FieldIndex field_index = FieldIndex::ForDescriptor(*map, i); |
| - int load_by_field_index = field_index.GetLoadByFieldIndex(); |
| - indices->set(index, Smi::FromInt(load_by_field_index)); |
| - } |
| - } |
| - index++; |
| - } |
| - DCHECK(index == storage->length()); |
| - |
| - DescriptorArray::SetEnumCache(descs, isolate, storage, indices); |
| - if (cache_enum_length) { |
| - map->SetEnumLength(own_property_count); |
| - } |
| - return storage; |
| -} |
| - |
| - |
| -Handle<FixedArray> JSObject::GetEnumPropertyKeys(Handle<JSObject> object) { |
| - Isolate* isolate = object->GetIsolate(); |
| - if (object->HasFastProperties()) { |
| - return GetFastEnumPropertyKeys(isolate, object); |
| - } else if (object->IsJSGlobalObject()) { |
| - Handle<GlobalDictionary> dictionary(object->global_dictionary()); |
| - int length = dictionary->NumberOfEnumElements(); |
| - if (length == 0) { |
| - return isolate->factory()->empty_fixed_array(); |
| - } |
| - Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length); |
| - dictionary->CopyEnumKeysTo(*storage); |
| - return storage; |
| - } else { |
| - Handle<NameDictionary> dictionary(object->property_dictionary()); |
| - int length = dictionary->NumberOfEnumElements(); |
| - if (length == 0) { |
| - return isolate->factory()->empty_fixed_array(); |
| - } |
| - Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length); |
| - dictionary->CopyEnumKeysTo(*storage); |
| - return storage; |
| - } |
| -} |
| - |
| - |
| -enum IndexedOrNamed { kIndexed, kNamed }; |
| - |
| - |
| -// Returns |true| on success, |nothing| on exception. |
| -template <class Callback, IndexedOrNamed type> |
| -static Maybe<bool> GetKeysFromInterceptor(Isolate* isolate, |
| - Handle<JSReceiver> receiver, |
| - Handle<JSObject> object, |
| - PropertyFilter filter, |
| - KeyAccumulator* accumulator) { |
| - if (type == kIndexed) { |
| - if (!object->HasIndexedInterceptor()) return Just(true); |
| - } else { |
| - if (!object->HasNamedInterceptor()) return Just(true); |
| - } |
| - Handle<InterceptorInfo> interceptor(type == kIndexed |
| - ? object->GetIndexedInterceptor() |
| - : object->GetNamedInterceptor(), |
| - isolate); |
| - if ((filter & ONLY_ALL_CAN_READ) && !interceptor->all_can_read()) { |
| - return Just(true); |
| - } |
| - PropertyCallbackArguments args(isolate, interceptor->data(), *receiver, |
| - *object, Object::DONT_THROW); |
| - Handle<JSObject> result; |
| - if (!interceptor->enumerator()->IsUndefined()) { |
| - Callback enum_fun = v8::ToCData<Callback>(interceptor->enumerator()); |
| - const char* log_tag = type == kIndexed ? "interceptor-indexed-enum" |
| - : "interceptor-named-enum"; |
| - LOG(isolate, ApiObjectAccess(log_tag, *object)); |
| - result = args.Call(enum_fun); |
| - } |
| - RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>()); |
| - if (result.is_null()) return Just(true); |
| - DCHECK(result->IsJSArray() || result->HasSloppyArgumentsElements()); |
| - // The accumulator takes care of string/symbol filtering. |
| - if (type == kIndexed) { |
| - accumulator->AddElementKeysFromInterceptor(result); |
| - } else { |
| - accumulator->AddKeys(result, DO_NOT_CONVERT); |
| - } |
| - return Just(true); |
| -} |
| - |
| - |
| -// Returns |true| on success, |false| if prototype walking should be stopped, |
| -// |nothing| if an exception was thrown. |
| -static Maybe<bool> GetKeysFromJSObject(Isolate* isolate, |
| - Handle<JSReceiver> receiver, |
| - Handle<JSObject> object, |
| - PropertyFilter* filter, |
| - KeyCollectionType type, |
| - KeyAccumulator* accumulator) { |
| - accumulator->NextPrototype(); |
| - // Check access rights if required. |
| - if (object->IsAccessCheckNeeded() && |
| - !isolate->MayAccess(handle(isolate->context()), object)) { |
| - // The cross-origin spec says that [[Enumerate]] shall return an empty |
| - // iterator when it doesn't have access... |
| - if (type == INCLUDE_PROTOS) { |
| - return Just(false); |
| - } |
| - // ...whereas [[OwnPropertyKeys]] shall return whitelisted properties. |
| - DCHECK_EQ(OWN_ONLY, type); |
| - *filter = static_cast<PropertyFilter>(*filter | ONLY_ALL_CAN_READ); |
| - } |
| - |
| - JSObject::CollectOwnElementKeys(object, accumulator, *filter); |
| - |
| - // Add the element keys from the interceptor. |
| - Maybe<bool> success = |
| - GetKeysFromInterceptor<v8::IndexedPropertyEnumeratorCallback, kIndexed>( |
| - isolate, receiver, object, *filter, accumulator); |
| - MAYBE_RETURN(success, Nothing<bool>()); |
| - |
| - if (*filter == ENUMERABLE_STRINGS) { |
| - Handle<FixedArray> enum_keys = JSObject::GetEnumPropertyKeys(object); |
| - accumulator->AddKeys(enum_keys, DO_NOT_CONVERT); |
| - } else { |
| - object->CollectOwnPropertyNames(accumulator, *filter); |
| - } |
| - |
| - // Add the property keys from the interceptor. |
| - success = GetKeysFromInterceptor<v8::GenericNamedPropertyEnumeratorCallback, |
| - kNamed>(isolate, receiver, object, *filter, |
| - accumulator); |
| - MAYBE_RETURN(success, Nothing<bool>()); |
| - return Just(true); |
| -} |
| - |
| - |
| -// Helper function for JSReceiver::GetKeys() below. Can be called recursively. |
| -// Returns |true| or |nothing|. |
| -static Maybe<bool> GetKeys_Internal(Isolate* isolate, |
| - Handle<JSReceiver> receiver, |
| - Handle<JSReceiver> object, |
| - KeyCollectionType type, |
| - PropertyFilter filter, |
| - KeyAccumulator* accumulator) { |
| - // Proxies have no hidden prototype and we should not trigger the |
| - // [[GetPrototypeOf]] trap on the last iteration when using |
| - // AdvanceFollowingProxies. |
| - if (type == OWN_ONLY && object->IsJSProxy()) { |
| - MAYBE_RETURN(JSProxy::OwnPropertyKeys(isolate, receiver, |
| - Handle<JSProxy>::cast(object), filter, |
| - accumulator), |
| - Nothing<bool>()); |
| - return Just(true); |
| - } |
| - |
| - PrototypeIterator::WhereToEnd end = type == OWN_ONLY |
| - ? PrototypeIterator::END_AT_NON_HIDDEN |
| - : PrototypeIterator::END_AT_NULL; |
| - for (PrototypeIterator iter(isolate, object, |
| - PrototypeIterator::START_AT_RECEIVER, end); |
| - !iter.IsAtEnd();) { |
| - Handle<JSReceiver> current = |
| - PrototypeIterator::GetCurrent<JSReceiver>(iter); |
| - Maybe<bool> result = Just(false); // Dummy initialization. |
| - if (current->IsJSProxy()) { |
| - result = JSProxy::OwnPropertyKeys(isolate, receiver, |
| - Handle<JSProxy>::cast(current), filter, |
| - accumulator); |
| - } else { |
| - DCHECK(current->IsJSObject()); |
| - result = GetKeysFromJSObject(isolate, receiver, |
| - Handle<JSObject>::cast(current), &filter, |
| - type, accumulator); |
| - } |
| - MAYBE_RETURN(result, Nothing<bool>()); |
| - if (!result.FromJust()) break; // |false| means "stop iterating". |
| - // Iterate through proxies but ignore access checks for the ALL_CAN_READ |
| - // case on API objects for OWN_ONLY keys handlede in GgetKeysFromJSObject. |
| - if (!iter.AdvanceFollowingProxiesIgnoringAccessChecks()) { |
| - return Nothing<bool>(); |
| - } |
| - } |
| - return Just(true); |
| -} |
| - |
| - |
| -// ES6 9.5.12 |
| -// Returns |true| on success, |nothing| in case of exception. |
| -// static |
| -Maybe<bool> JSProxy::OwnPropertyKeys(Isolate* isolate, |
| - Handle<JSReceiver> receiver, |
| - Handle<JSProxy> proxy, |
| - PropertyFilter filter, |
| - KeyAccumulator* accumulator) { |
| - STACK_CHECK(Nothing<bool>()); |
| - // 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. |
| - Handle<Object> handler(proxy->handler(), isolate); |
| - // 2. If handler is null, throw a TypeError exception. |
| - // 3. Assert: Type(handler) is Object. |
| - if (proxy->IsRevoked()) { |
| - isolate->Throw(*isolate->factory()->NewTypeError( |
| - MessageTemplate::kProxyRevoked, isolate->factory()->ownKeys_string())); |
| - return Nothing<bool>(); |
| - } |
| - // 4. Let target be the value of the [[ProxyTarget]] internal slot of O. |
| - Handle<JSReceiver> target(proxy->target(), isolate); |
| - // 5. Let trap be ? GetMethod(handler, "ownKeys"). |
| - Handle<Object> trap; |
| - ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| - isolate, trap, Object::GetMethod(Handle<JSReceiver>::cast(handler), |
| - isolate->factory()->ownKeys_string()), |
| - Nothing<bool>()); |
| - // 6. If trap is undefined, then |
| - if (trap->IsUndefined()) { |
| - // 6a. Return target.[[OwnPropertyKeys]](). |
| - return GetKeys_Internal(isolate, receiver, target, OWN_ONLY, filter, |
| - accumulator); |
| - } |
| - // 7. Let trapResultArray be Call(trap, handler, «target»). |
| - Handle<Object> trap_result_array; |
| - Handle<Object> args[] = {target}; |
| - ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| - isolate, trap_result_array, |
| - Execution::Call(isolate, trap, handler, arraysize(args), args), |
| - Nothing<bool>()); |
| - // 8. Let trapResult be ? CreateListFromArrayLike(trapResultArray, |
| - // «String, Symbol»). |
| - Handle<FixedArray> trap_result; |
| - ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| - isolate, trap_result, |
| - Object::CreateListFromArrayLike(isolate, trap_result_array, |
| - ElementTypes::kStringAndSymbol), |
| - Nothing<bool>()); |
| - // 9. Let extensibleTarget be ? IsExtensible(target). |
| - Maybe<bool> maybe_extensible = JSReceiver::IsExtensible(target); |
| - MAYBE_RETURN(maybe_extensible, Nothing<bool>()); |
| - bool extensible_target = maybe_extensible.FromJust(); |
| - // 10. Let targetKeys be ? target.[[OwnPropertyKeys]](). |
| - Handle<FixedArray> target_keys; |
| - ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, target_keys, |
| - JSReceiver::OwnPropertyKeys(target), |
| - Nothing<bool>()); |
| - // 11. (Assert) |
| - // 12. Let targetConfigurableKeys be an empty List. |
| - // To save memory, we're re-using target_keys and will modify it in-place. |
| - Handle<FixedArray> target_configurable_keys = target_keys; |
| - // 13. Let targetNonconfigurableKeys be an empty List. |
| - Handle<FixedArray> target_nonconfigurable_keys = |
| - isolate->factory()->NewFixedArray(target_keys->length()); |
| - int nonconfigurable_keys_length = 0; |
| - // 14. Repeat, for each element key of targetKeys: |
| - for (int i = 0; i < target_keys->length(); ++i) { |
| - // 14a. Let desc be ? target.[[GetOwnProperty]](key). |
| - PropertyDescriptor desc; |
| - Maybe<bool> found = JSReceiver::GetOwnPropertyDescriptor( |
| - isolate, target, handle(target_keys->get(i), isolate), &desc); |
| - MAYBE_RETURN(found, Nothing<bool>()); |
| - // 14b. If desc is not undefined and desc.[[Configurable]] is false, then |
| - if (found.FromJust() && !desc.configurable()) { |
| - // 14b i. Append key as an element of targetNonconfigurableKeys. |
| - target_nonconfigurable_keys->set(nonconfigurable_keys_length, |
| - target_keys->get(i)); |
| - nonconfigurable_keys_length++; |
| - // The key was moved, null it out in the original list. |
| - target_keys->set(i, Smi::FromInt(0)); |
| - } else { |
| - // 14c. Else, |
| - // 14c i. Append key as an element of targetConfigurableKeys. |
| - // (No-op, just keep it in |target_keys|.) |
| - } |
| - } |
| - accumulator->NextPrototype(); // Prepare for accumulating keys. |
| - // 15. If extensibleTarget is true and targetNonconfigurableKeys is empty, |
| - // then: |
| - if (extensible_target && nonconfigurable_keys_length == 0) { |
| - // 15a. Return trapResult. |
| - return accumulator->AddKeysFromProxy(proxy, trap_result); |
| - } |
| - // 16. Let uncheckedResultKeys be a new List which is a copy of trapResult. |
| - Zone set_zone(isolate->allocator()); |
| - const int kPresent = 1; |
| - const int kGone = 0; |
| - IdentityMap<int> unchecked_result_keys(isolate->heap(), &set_zone); |
| - int unchecked_result_keys_size = 0; |
| - for (int i = 0; i < trap_result->length(); ++i) { |
| - DCHECK(trap_result->get(i)->IsUniqueName()); |
| - Object* key = trap_result->get(i); |
| - int* entry = unchecked_result_keys.Get(key); |
| - if (*entry != kPresent) { |
| - *entry = kPresent; |
| - unchecked_result_keys_size++; |
| - } |
| - } |
| - // 17. Repeat, for each key that is an element of targetNonconfigurableKeys: |
| - for (int i = 0; i < nonconfigurable_keys_length; ++i) { |
| - Object* key = target_nonconfigurable_keys->get(i); |
| - // 17a. If key is not an element of uncheckedResultKeys, throw a |
| - // TypeError exception. |
| - int* found = unchecked_result_keys.Find(key); |
| - if (found == nullptr || *found == kGone) { |
| - isolate->Throw(*isolate->factory()->NewTypeError( |
| - MessageTemplate::kProxyOwnKeysMissing, handle(key, isolate))); |
| - return Nothing<bool>(); |
| - } |
| - // 17b. Remove key from uncheckedResultKeys. |
| - *found = kGone; |
| - unchecked_result_keys_size--; |
| - } |
| - // 18. If extensibleTarget is true, return trapResult. |
| - if (extensible_target) { |
| - return accumulator->AddKeysFromProxy(proxy, trap_result); |
| - } |
| - // 19. Repeat, for each key that is an element of targetConfigurableKeys: |
| - for (int i = 0; i < target_configurable_keys->length(); ++i) { |
| - Object* key = target_configurable_keys->get(i); |
| - if (key->IsSmi()) continue; // Zapped entry, was nonconfigurable. |
| - // 19a. If key is not an element of uncheckedResultKeys, throw a |
| - // TypeError exception. |
| - int* found = unchecked_result_keys.Find(key); |
| - if (found == nullptr || *found == kGone) { |
| - isolate->Throw(*isolate->factory()->NewTypeError( |
| - MessageTemplate::kProxyOwnKeysMissing, handle(key, isolate))); |
| - return Nothing<bool>(); |
| - } |
| - // 19b. Remove key from uncheckedResultKeys. |
| - *found = kGone; |
| - unchecked_result_keys_size--; |
| - } |
| - // 20. If uncheckedResultKeys is not empty, throw a TypeError exception. |
| - if (unchecked_result_keys_size != 0) { |
| - DCHECK_GT(unchecked_result_keys_size, 0); |
| - isolate->Throw(*isolate->factory()->NewTypeError( |
| - MessageTemplate::kProxyOwnKeysNonExtensible)); |
| - return Nothing<bool>(); |
| - } |
| - // 21. Return trapResult. |
| - return accumulator->AddKeysFromProxy(proxy, trap_result); |
| -} |
| - |
| MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, |
| KeyCollectionType type, |
| PropertyFilter filter, |
| @@ -8637,9 +8221,8 @@ MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, |
| Isolate* isolate = object->GetIsolate(); |
| KeyAccumulator accumulator(isolate, type, filter); |
| accumulator.set_filter_proxy_keys(filter_proxy_keys); |
| - MAYBE_RETURN( |
| - GetKeys_Internal(isolate, object, object, type, filter, &accumulator), |
| - MaybeHandle<FixedArray>()); |
| + MAYBE_RETURN(accumulator.GetKeys_Internal(object, object, type), |
| + MaybeHandle<FixedArray>()); |
| Handle<FixedArray> keys = accumulator.GetKeys(keys_conversion); |
| DCHECK(ContainsOnlyValidKeys(keys)); |
| return keys; |
| @@ -8736,8 +8319,7 @@ MaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate, |
| PropertyFilter key_filter = |
| static_cast<PropertyFilter>(filter & ~ONLY_ENUMERABLE); |
| KeyAccumulator accumulator(isolate, OWN_ONLY, key_filter); |
| - MAYBE_RETURN(GetKeys_Internal(isolate, object, object, OWN_ONLY, key_filter, |
| - &accumulator), |
| + MAYBE_RETURN(accumulator.GetKeys_Internal(object, object, OWN_ONLY), |
| MaybeHandle<FixedArray>()); |
| Handle<FixedArray> keys = accumulator.GetKeys(CONVERT_TO_STRING); |
| DCHECK(ContainsOnlyValidKeys(keys)); |
| @@ -14814,7 +14396,7 @@ Maybe<bool> JSProxy::SetPrototype(Handle<JSProxy> proxy, Handle<Object> value, |
| bool from_javascript, |
| ShouldThrow should_throw) { |
| Isolate* isolate = proxy->GetIsolate(); |
| - STACK_CHECK(Nothing<bool>()); |
| + STACK_CHECK(isolate, Nothing<bool>()); |
| Handle<Name> trap_name = isolate->factory()->setPrototypeOf_string(); |
| // 1. Assert: Either Type(V) is Object or Type(V) is Null. |
| DCHECK(value->IsJSReceiver() || value->IsNull()); |
| @@ -15665,31 +15247,6 @@ void FixedArray::SortPairs(FixedArray* numbers, uint32_t len) { |
| } |
| } |
| -void JSObject::CollectOwnPropertyNames(KeyAccumulator* keys, |
| - PropertyFilter filter) { |
| - if (HasFastProperties()) { |
| - int real_size = map()->NumberOfOwnDescriptors(); |
| - Handle<DescriptorArray> descs(map()->instance_descriptors()); |
| - for (int i = 0; i < real_size; i++) { |
| - PropertyDetails details = descs->GetDetails(i); |
| - if ((details.attributes() & filter) != 0) continue; |
| - if (filter & ONLY_ALL_CAN_READ) { |
| - if (details.kind() != kAccessor) continue; |
| - Object* accessors = descs->GetValue(i); |
| - if (!accessors->IsAccessorInfo()) continue; |
| - if (!AccessorInfo::cast(accessors)->all_can_read()) continue; |
| - } |
| - Name* key = descs->GetKey(i); |
| - if (key->FilterKey(filter)) continue; |
| - keys->AddKey(key, DO_NOT_CONVERT); |
| - } |
| - } else if (IsJSGlobalObject()) { |
| - GlobalDictionary::CollectKeysTo(handle(global_dictionary()), keys, filter); |
| - } else { |
| - NameDictionary::CollectKeysTo(handle(property_dictionary()), keys, filter); |
| - } |
| -} |
| - |
| bool JSObject::WasConstructedFromApiFunction() { |
| auto instance_type = map()->instance_type(); |
| bool is_api_object = instance_type == JS_API_OBJECT_TYPE || |
| @@ -15709,15 +15266,6 @@ bool JSObject::WasConstructedFromApiFunction() { |
| return is_api_object; |
| } |
| -void JSObject::CollectOwnElementKeys(Handle<JSObject> object, |
| - KeyAccumulator* keys, |
| - PropertyFilter filter) { |
| - if (filter & SKIP_STRINGS) return; |
| - ElementsAccessor* accessor = object->GetElementsAccessor(); |
| - accessor->CollectElementIndices(object, keys, kMaxUInt32, filter, 0); |
| -} |
| - |
| - |
| MaybeHandle<String> Object::ObjectProtoToString(Isolate* isolate, |
| Handle<Object> object) { |
| if (object->IsUndefined()) return isolate->factory()->undefined_to_string(); |
| @@ -16570,6 +16118,30 @@ template int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, |
| template int NameDictionaryBase<NameDictionary, NameDictionaryShape>::FindEntry( |
| Handle<Name>); |
| +template int Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>:: |
| + NumberOfElementsFilterAttributes(PropertyFilter filter); |
| + |
| +template int Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>:: |
| + NumberOfElementsFilterAttributes(PropertyFilter filter); |
| + |
| +template void Dictionary<GlobalDictionary, GlobalDictionaryShape, |
| + Handle<Name>>::CopyEnumKeysTo(FixedArray* storage); |
| + |
| +template void Dictionary<NameDictionary, NameDictionaryShape, |
| + Handle<Name>>::CopyEnumKeysTo(FixedArray* storage); |
| + |
| +template void |
| +Dictionary<GlobalDictionary, GlobalDictionaryShape, Handle<Name>>:: |
| + CollectKeysTo(Handle<Dictionary<GlobalDictionary, GlobalDictionaryShape, |
| + Handle<Name>>> |
|
Jakob Kummerow
2016/05/03 14:56:13
beautiful! :-)
|
| + dictionary, |
| + KeyAccumulator* keys, PropertyFilter filter); |
| + |
| +template void |
| +Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>::CollectKeysTo( |
| + Handle<Dictionary<NameDictionary, NameDictionaryShape, Handle<Name>>> |
| + dictionary, |
| + KeyAccumulator* keys, PropertyFilter filter); |
| Handle<Object> JSObject::PrepareSlowElementsForSort( |
| Handle<JSObject> object, uint32_t limit) { |