[cleanup] Introduce PropertyFilter
Split out of PropertyAttributes, and used for all filtering purposes. Also moved PropertyAttributes into the v8::internal:: namespace. No change in behavior intended. Review URL: https://codereview.chromium.org/1492653004 Cr-Commit-Position: refs/heads/master@{#32525}
This commit is contained in:
parent
411c5b7fb0
commit
4a246c1fff
44
src/api.cc
44
src/api.cc
@ -932,7 +932,7 @@ void Template::Set(v8::Local<Name> name, v8::Local<Data> value,
|
||||
// TODO(dcarney): split api to allow values of v8::Value or v8::TemplateInfo.
|
||||
i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
|
||||
Utils::OpenHandle(*value),
|
||||
static_cast<PropertyAttributes>(attribute));
|
||||
static_cast<i::PropertyAttributes>(attribute));
|
||||
}
|
||||
|
||||
|
||||
@ -953,7 +953,7 @@ void Template::SetAccessorProperty(
|
||||
i::ApiNatives::AddAccessorProperty(
|
||||
isolate, templ, Utils::OpenHandle(*name),
|
||||
Utils::OpenHandle(*getter, true), Utils::OpenHandle(*setter, true),
|
||||
static_cast<PropertyAttributes>(attribute));
|
||||
static_cast<i::PropertyAttributes>(attribute));
|
||||
}
|
||||
|
||||
|
||||
@ -1108,7 +1108,7 @@ static i::Handle<i::AccessorInfo> SetAccessorInfoProperties(
|
||||
obj->set_name(*Utils::OpenHandle(*name));
|
||||
if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
|
||||
if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
|
||||
obj->set_property_attributes(static_cast<PropertyAttributes>(attributes));
|
||||
obj->set_property_attributes(static_cast<i::PropertyAttributes>(attributes));
|
||||
if (!signature.IsEmpty()) {
|
||||
obj->set_expected_receiver_type(*Utils::OpenHandle(*signature));
|
||||
}
|
||||
@ -1330,7 +1330,7 @@ void Template::SetIntrinsicDataProperty(Local<Name> name, Intrinsic intrinsic,
|
||||
i::HandleScope scope(isolate);
|
||||
i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
|
||||
intrinsic,
|
||||
static_cast<PropertyAttributes>(attribute));
|
||||
static_cast<i::PropertyAttributes>(attribute));
|
||||
}
|
||||
|
||||
|
||||
@ -3531,7 +3531,7 @@ Maybe<bool> v8::Object::DefineOwnProperty(v8::Local<v8::Context> context,
|
||||
MUST_USE_RESULT
|
||||
static i::MaybeHandle<i::Object> DefineObjectProperty(
|
||||
i::Handle<i::JSObject> js_object, i::Handle<i::Object> key,
|
||||
i::Handle<i::Object> value, PropertyAttributes attrs) {
|
||||
i::Handle<i::Object> value, i::PropertyAttributes attrs) {
|
||||
i::Isolate* isolate = js_object->GetIsolate();
|
||||
bool success = false;
|
||||
i::LookupIterator it = i::LookupIterator::PropertyOrElement(
|
||||
@ -3551,7 +3551,8 @@ Maybe<bool> v8::Object::ForceSet(v8::Local<v8::Context> context,
|
||||
auto value_obj = Utils::OpenHandle(*value);
|
||||
has_pending_exception =
|
||||
DefineObjectProperty(self, key_obj, value_obj,
|
||||
static_cast<PropertyAttributes>(attribs)).is_null();
|
||||
static_cast<i::PropertyAttributes>(attribs))
|
||||
.is_null();
|
||||
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
|
||||
return Just(true);
|
||||
}
|
||||
@ -3569,7 +3570,8 @@ bool v8::Object::ForceSet(v8::Local<Value> key, v8::Local<Value> value,
|
||||
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
|
||||
has_pending_exception =
|
||||
DefineObjectProperty(self, key_obj, value_obj,
|
||||
static_cast<PropertyAttributes>(attribs)).is_null();
|
||||
static_cast<i::PropertyAttributes>(attribs))
|
||||
.is_null();
|
||||
EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, false);
|
||||
return true;
|
||||
}
|
||||
@ -3639,8 +3641,8 @@ Maybe<PropertyAttribute> v8::Object::GetPropertyAttributes(
|
||||
auto result = i::JSReceiver::GetPropertyAttributes(self, key_name);
|
||||
has_pending_exception = result.IsNothing();
|
||||
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
|
||||
if (result.FromJust() == ABSENT) {
|
||||
return Just(static_cast<PropertyAttribute>(NONE));
|
||||
if (result.FromJust() == i::ABSENT) {
|
||||
return Just(static_cast<PropertyAttribute>(i::NONE));
|
||||
}
|
||||
return Just(static_cast<PropertyAttribute>(result.FromJust()));
|
||||
}
|
||||
@ -3649,7 +3651,7 @@ Maybe<PropertyAttribute> v8::Object::GetPropertyAttributes(
|
||||
PropertyAttribute v8::Object::GetPropertyAttributes(v8::Local<Value> key) {
|
||||
auto context = ContextFromHeapObject(Utils::OpenHandle(this));
|
||||
return GetPropertyAttributes(context, key)
|
||||
.FromMaybe(static_cast<PropertyAttribute>(NONE));
|
||||
.FromMaybe(static_cast<PropertyAttribute>(i::NONE));
|
||||
}
|
||||
|
||||
|
||||
@ -3728,8 +3730,10 @@ MaybeLocal<Array> v8::Object::GetPropertyNames(Local<Context> context) {
|
||||
PREPARE_FOR_EXECUTION(context, "v8::Object::GetPropertyNames()", Array);
|
||||
auto self = Utils::OpenHandle(this);
|
||||
i::Handle<i::FixedArray> value;
|
||||
has_pending_exception = !i::JSReceiver::GetKeys(
|
||||
self, i::JSReceiver::INCLUDE_PROTOS).ToHandle(&value);
|
||||
has_pending_exception =
|
||||
!i::JSReceiver::GetKeys(self, i::JSReceiver::INCLUDE_PROTOS,
|
||||
i::ENUMERABLE_STRINGS)
|
||||
.ToHandle(&value);
|
||||
RETURN_ON_FAILED_EXECUTION(Array);
|
||||
// Because we use caching to speed up enumeration it is important
|
||||
// to never change the result of the basic enumeration function so
|
||||
@ -3750,8 +3754,9 @@ MaybeLocal<Array> v8::Object::GetOwnPropertyNames(Local<Context> context) {
|
||||
PREPARE_FOR_EXECUTION(context, "v8::Object::GetOwnPropertyNames()", Array);
|
||||
auto self = Utils::OpenHandle(this);
|
||||
i::Handle<i::FixedArray> value;
|
||||
has_pending_exception = !i::JSReceiver::GetKeys(
|
||||
self, i::JSReceiver::OWN_ONLY).ToHandle(&value);
|
||||
has_pending_exception = !i::JSReceiver::GetKeys(self, i::JSReceiver::OWN_ONLY,
|
||||
i::ENUMERABLE_STRINGS)
|
||||
.ToHandle(&value);
|
||||
RETURN_ON_FAILED_EXECUTION(Array);
|
||||
// Because we use caching to speed up enumeration it is important
|
||||
// to never change the result of the basic enumeration function so
|
||||
@ -4004,7 +4009,7 @@ void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
|
||||
if (setter_i.is_null()) setter_i = isolate->factory()->null_value();
|
||||
i::JSObject::DefineAccessor(i::Handle<i::JSObject>::cast(self),
|
||||
v8::Utils::OpenHandle(*name), getter_i, setter_i,
|
||||
static_cast<PropertyAttributes>(attribute));
|
||||
static_cast<i::PropertyAttributes>(attribute));
|
||||
}
|
||||
|
||||
|
||||
@ -4149,10 +4154,11 @@ v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(
|
||||
i::LookupIterator it = i::LookupIterator::PropertyOrElement(
|
||||
isolate, self, key_obj, proto,
|
||||
i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
|
||||
Maybe<PropertyAttributes> result = i::JSReceiver::GetPropertyAttributes(&it);
|
||||
Maybe<i::PropertyAttributes> result =
|
||||
i::JSReceiver::GetPropertyAttributes(&it);
|
||||
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
|
||||
if (!it.IsFound()) return Nothing<PropertyAttribute>();
|
||||
if (result.FromJust() == ABSENT) return Just(None);
|
||||
if (result.FromJust() == i::ABSENT) return Just(None);
|
||||
return Just(static_cast<PropertyAttribute>(result.FromJust()));
|
||||
}
|
||||
|
||||
@ -4199,8 +4205,8 @@ Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
|
||||
auto result = i::JSReceiver::GetPropertyAttributes(&it);
|
||||
RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
|
||||
if (!it.IsFound()) return Nothing<PropertyAttribute>();
|
||||
if (result.FromJust() == ABSENT) {
|
||||
return Just(static_cast<PropertyAttribute>(NONE));
|
||||
if (result.FromJust() == i::ABSENT) {
|
||||
return Just(static_cast<PropertyAttribute>(i::NONE));
|
||||
}
|
||||
return Just<PropertyAttribute>(
|
||||
static_cast<PropertyAttribute>(result.FromJust()));
|
||||
|
@ -1615,10 +1615,9 @@ BUILTIN(ReflectOwnKeys) {
|
||||
|
||||
Handle<FixedArray> keys;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, keys,
|
||||
JSReceiver::GetKeys(Handle<JSReceiver>::cast(target),
|
||||
JSReceiver::OWN_ONLY, INCLUDE_SYMBOLS,
|
||||
CONVERT_TO_STRING, IGNORE_ENUMERABILITY));
|
||||
isolate, keys, JSReceiver::GetKeys(Handle<JSReceiver>::cast(target),
|
||||
JSReceiver::OWN_ONLY, ALL_PROPERTIES,
|
||||
CONVERT_TO_STRING));
|
||||
return *isolate->factory()->NewJSArrayWithElements(keys);
|
||||
}
|
||||
|
||||
|
@ -760,7 +760,7 @@ void ScopeIterator::CopyContextLocalsToScopeObject(
|
||||
// TODO(verwaest): Use AddDataProperty instead.
|
||||
JSObject::SetOwnPropertyIgnoreAttributes(
|
||||
scope_object, handle(String::cast(scope_info->get(i + start))), value,
|
||||
::NONE)
|
||||
NONE)
|
||||
.Check();
|
||||
}
|
||||
}
|
||||
@ -771,7 +771,8 @@ bool ScopeIterator::CopyContextExtensionToScopeObject(
|
||||
JSReceiver::KeyCollectionType type) {
|
||||
Handle<FixedArray> keys;
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
||||
isolate_, keys, JSReceiver::GetKeys(extension, type), false);
|
||||
isolate_, keys, JSReceiver::GetKeys(extension, type, ENUMERABLE_STRINGS),
|
||||
false);
|
||||
|
||||
for (int i = 0; i < keys->length(); i++) {
|
||||
// Names of variables introduced by eval are strings.
|
||||
|
@ -506,7 +506,7 @@ class ElementsAccessorBase : public ElementsAccessor {
|
||||
if (IsFastPackedElementsKind(kind())) return true;
|
||||
for (uint32_t i = start; i < end; i++) {
|
||||
if (!ElementsAccessorSubclass::HasElementImpl(holder, i, backing_store,
|
||||
NONE)) {
|
||||
ALL_PROPERTIES)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -533,14 +533,14 @@ class ElementsAccessorBase : public ElementsAccessor {
|
||||
|
||||
bool HasElement(Handle<JSObject> holder, uint32_t index,
|
||||
Handle<FixedArrayBase> backing_store,
|
||||
PropertyAttributes filter) final {
|
||||
PropertyFilter filter) final {
|
||||
return ElementsAccessorSubclass::HasElementImpl(holder, index,
|
||||
backing_store, filter);
|
||||
}
|
||||
|
||||
static bool HasElementImpl(Handle<JSObject> holder, uint32_t index,
|
||||
Handle<FixedArrayBase> backing_store,
|
||||
PropertyAttributes filter) {
|
||||
PropertyFilter filter) {
|
||||
return ElementsAccessorSubclass::GetEntryForIndexImpl(
|
||||
*holder, *backing_store, index, filter) != kMaxUInt32;
|
||||
}
|
||||
@ -857,7 +857,7 @@ class ElementsAccessorBase : public ElementsAccessor {
|
||||
static void CollectElementIndicesImpl(Handle<JSObject> object,
|
||||
Handle<FixedArrayBase> backing_store,
|
||||
KeyAccumulator* keys, uint32_t range,
|
||||
PropertyAttributes filter,
|
||||
PropertyFilter filter,
|
||||
uint32_t offset) {
|
||||
uint32_t length = 0;
|
||||
if (object->IsJSArray()) {
|
||||
@ -878,7 +878,7 @@ class ElementsAccessorBase : public ElementsAccessor {
|
||||
void CollectElementIndices(Handle<JSObject> object,
|
||||
Handle<FixedArrayBase> backing_store,
|
||||
KeyAccumulator* keys, uint32_t range,
|
||||
PropertyAttributes filter, uint32_t offset) final {
|
||||
PropertyFilter filter, uint32_t offset) final {
|
||||
ElementsAccessorSubclass::CollectElementIndicesImpl(
|
||||
object, backing_store, keys, range, filter, offset);
|
||||
};
|
||||
@ -921,8 +921,7 @@ class ElementsAccessorBase : public ElementsAccessor {
|
||||
|
||||
static uint32_t GetEntryForIndexImpl(JSObject* holder,
|
||||
FixedArrayBase* backing_store,
|
||||
uint32_t index,
|
||||
PropertyAttributes filter) {
|
||||
uint32_t index, PropertyFilter filter) {
|
||||
if (IsHoleyElementsKind(kind())) {
|
||||
return index < ElementsAccessorSubclass::GetCapacityImpl(holder,
|
||||
backing_store) &&
|
||||
@ -942,8 +941,8 @@ class ElementsAccessorBase : public ElementsAccessor {
|
||||
|
||||
uint32_t GetEntryForIndex(JSObject* holder, FixedArrayBase* backing_store,
|
||||
uint32_t index) final {
|
||||
return ElementsAccessorSubclass::GetEntryForIndexImpl(holder, backing_store,
|
||||
index, NONE);
|
||||
return ElementsAccessorSubclass::GetEntryForIndexImpl(
|
||||
holder, backing_store, index, ALL_PROPERTIES);
|
||||
}
|
||||
|
||||
static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
|
||||
@ -1105,13 +1104,12 @@ class DictionaryElementsAccessor
|
||||
}
|
||||
|
||||
static uint32_t GetEntryForIndexImpl(JSObject* holder, FixedArrayBase* store,
|
||||
uint32_t index,
|
||||
PropertyAttributes filter) {
|
||||
uint32_t index, PropertyFilter filter) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store);
|
||||
int entry = dictionary->FindEntry(index);
|
||||
if (entry == SeededNumberDictionary::kNotFound) return kMaxUInt32;
|
||||
if (filter != NONE) {
|
||||
if (filter != ALL_PROPERTIES) {
|
||||
PropertyDetails details = dictionary->DetailsAt(entry);
|
||||
PropertyAttributes attr = details.attributes();
|
||||
if ((attr & filter) != 0) return kMaxUInt32;
|
||||
@ -1127,7 +1125,7 @@ class DictionaryElementsAccessor
|
||||
static void CollectElementIndicesImpl(Handle<JSObject> object,
|
||||
Handle<FixedArrayBase> backing_store,
|
||||
KeyAccumulator* keys, uint32_t range,
|
||||
PropertyAttributes filter,
|
||||
PropertyFilter filter,
|
||||
uint32_t offset) {
|
||||
Handle<SeededNumberDictionary> dictionary =
|
||||
Handle<SeededNumberDictionary>::cast(backing_store);
|
||||
@ -1810,8 +1808,7 @@ class TypedElementsAccessor
|
||||
|
||||
static uint32_t GetEntryForIndexImpl(JSObject* holder,
|
||||
FixedArrayBase* backing_store,
|
||||
uint32_t index,
|
||||
PropertyAttributes filter) {
|
||||
uint32_t index, PropertyFilter filter) {
|
||||
return index < AccessorClass::GetCapacityImpl(holder, backing_store)
|
||||
? index
|
||||
: kMaxUInt32;
|
||||
@ -1945,8 +1942,7 @@ class SloppyArgumentsElementsAccessor
|
||||
|
||||
static uint32_t GetEntryForIndexImpl(JSObject* holder,
|
||||
FixedArrayBase* parameters,
|
||||
uint32_t index,
|
||||
PropertyAttributes filter) {
|
||||
uint32_t index, PropertyFilter filter) {
|
||||
FixedArray* parameter_map = FixedArray::cast(parameters);
|
||||
Object* probe = GetParameterMapArg(parameter_map, index);
|
||||
if (!probe->IsTheHole()) return index;
|
||||
|
@ -47,10 +47,10 @@ class ElementsAccessor {
|
||||
// all but DICTIONARY_ELEMENTS and SLOW_SLOPPY_ARGUMENTS_ELEMENTS.
|
||||
virtual bool HasElement(Handle<JSObject> holder, uint32_t index,
|
||||
Handle<FixedArrayBase> backing_store,
|
||||
PropertyAttributes filter = NONE) = 0;
|
||||
PropertyFilter filter = ALL_PROPERTIES) = 0;
|
||||
|
||||
inline bool HasElement(Handle<JSObject> holder, uint32_t index,
|
||||
PropertyAttributes filter = NONE) {
|
||||
PropertyFilter filter = ALL_PROPERTIES) {
|
||||
return HasElement(holder, index, handle(holder->elements()), filter);
|
||||
}
|
||||
|
||||
@ -120,13 +120,13 @@ class ElementsAccessor {
|
||||
Handle<FixedArrayBase> backing_store,
|
||||
KeyAccumulator* keys,
|
||||
uint32_t range = kMaxUInt32,
|
||||
PropertyAttributes filter = NONE,
|
||||
PropertyFilter filter = ALL_PROPERTIES,
|
||||
uint32_t offset = 0) = 0;
|
||||
|
||||
inline void CollectElementIndices(Handle<JSObject> object,
|
||||
KeyAccumulator* keys,
|
||||
uint32_t range = kMaxUInt32,
|
||||
PropertyAttributes filter = NONE,
|
||||
PropertyFilter filter = ALL_PROPERTIES,
|
||||
uint32_t offset = 0) {
|
||||
CollectElementIndices(object, handle(object->elements()), keys, range,
|
||||
filter, offset);
|
||||
|
@ -2419,7 +2419,8 @@ void MarkCompactCollector::TrimEnumCache(Map* map,
|
||||
DescriptorArray* descriptors) {
|
||||
int live_enum = map->EnumLength();
|
||||
if (live_enum == kInvalidEnumCacheSentinel) {
|
||||
live_enum = map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM);
|
||||
live_enum =
|
||||
map->NumberOfDescribedProperties(OWN_DESCRIPTORS, ENUMERABLE_STRINGS);
|
||||
}
|
||||
if (live_enum == 0) return descriptors->ClearEnumCache();
|
||||
|
||||
|
@ -273,8 +273,7 @@ define COMPILATION_TYPE_JSON = 2;
|
||||
# Matches Messages::kNoLineNumberInfo from v8.h
|
||||
define kNoLineNumberInfo = 0;
|
||||
|
||||
# Matches PropertyAttributes from property-details.h
|
||||
define PROPERTY_ATTRIBUTES_NONE = 0;
|
||||
# Deprecated, do not use. Will be replaced by PropertyFilter.
|
||||
define PROPERTY_ATTRIBUTES_STRING = 8;
|
||||
define PROPERTY_ATTRIBUTES_SYMBOLIC = 16;
|
||||
define PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL = 32;
|
||||
|
@ -568,7 +568,7 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject(
|
||||
Handle<FixedArray> contents;
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
||||
isolate_, contents,
|
||||
JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY),
|
||||
JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY, ENUMERABLE_STRINGS),
|
||||
EXCEPTION);
|
||||
|
||||
for (int i = 0; i < contents->length(); i++) {
|
||||
|
@ -99,7 +99,8 @@ bool KeyAccumulator::AddKey(Object* key, AddKeyConversion convert) {
|
||||
|
||||
bool KeyAccumulator::AddKey(Handle<Object> key, AddKeyConversion convert) {
|
||||
if (key->IsSymbol()) {
|
||||
if (filter_ == SKIP_SYMBOLS) return false;
|
||||
if (filter_ & SKIP_SYMBOLS) return false;
|
||||
if (Handle<Symbol>::cast(key)->is_private()) return false;
|
||||
return AddSymbolKey(key);
|
||||
}
|
||||
// Make sure we do not add keys to a proxy-level (see AddKeysFromProxy).
|
||||
@ -221,17 +222,20 @@ void KeyAccumulator::AddKeysFromProxy(Handle<JSObject> array_like) {
|
||||
|
||||
MaybeHandle<FixedArray> FilterProxyKeys(Isolate* isolate, Handle<JSProxy> owner,
|
||||
Handle<FixedArray> keys,
|
||||
KeyFilter filter,
|
||||
Enumerability enum_policy) {
|
||||
if (filter == INCLUDE_SYMBOLS && enum_policy == IGNORE_ENUMERABILITY) {
|
||||
PropertyFilter filter) {
|
||||
if (filter == ALL_PROPERTIES) {
|
||||
// Nothing to do.
|
||||
return keys;
|
||||
}
|
||||
int store_position = 0;
|
||||
for (int i = 0; i < keys->length(); ++i) {
|
||||
Handle<Name> key(Name::cast(keys->get(i)), isolate);
|
||||
if (filter == SKIP_SYMBOLS && key->IsSymbol()) continue; // Skip this key.
|
||||
if (enum_policy == RESPECT_ENUMERABILITY) {
|
||||
if (key->IsSymbol()) {
|
||||
if ((filter & SKIP_SYMBOLS) || Handle<Symbol>::cast(key)->is_private()) {
|
||||
continue; // Skip this key.
|
||||
}
|
||||
}
|
||||
if (filter & ONLY_ENUMERABLE) {
|
||||
PropertyDescriptor desc;
|
||||
bool found =
|
||||
JSProxy::GetOwnPropertyDescriptor(isolate, owner, key, &desc);
|
||||
@ -252,11 +256,9 @@ MaybeHandle<FixedArray> FilterProxyKeys(Isolate* isolate, Handle<JSProxy> owner,
|
||||
|
||||
// Returns "false" in case of exception, "true" on success.
|
||||
bool KeyAccumulator::AddKeysFromProxy(Handle<JSProxy> proxy,
|
||||
Handle<FixedArray> keys, KeyFilter filter,
|
||||
Enumerability enum_policy) {
|
||||
Handle<FixedArray> keys) {
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
||||
isolate_, keys,
|
||||
FilterProxyKeys(isolate_, proxy, keys, filter, enum_policy), false);
|
||||
isolate_, keys, FilterProxyKeys(isolate_, proxy, keys, filter_), false);
|
||||
// Proxies define a complete list of keys with no distinction of
|
||||
// elements and properties, which breaks the normal assumption for the
|
||||
// KeyAccumulator.
|
||||
|
@ -31,8 +31,7 @@ enum AddKeyConversion { DO_NOT_CONVERT, CONVERT_TO_ARRAY_INDEX, PROXY_MAGIC };
|
||||
// are more compact and allow for reasonably fast includes check.
|
||||
class KeyAccumulator final BASE_EMBEDDED {
|
||||
public:
|
||||
explicit KeyAccumulator(Isolate* isolate,
|
||||
KeyFilter filter = KeyFilter::SKIP_SYMBOLS)
|
||||
KeyAccumulator(Isolate* isolate, PropertyFilter filter)
|
||||
: isolate_(isolate), filter_(filter) {}
|
||||
~KeyAccumulator();
|
||||
|
||||
@ -44,8 +43,7 @@ class KeyAccumulator final BASE_EMBEDDED {
|
||||
void AddKeys(Handle<JSObject> array,
|
||||
AddKeyConversion convert = DO_NOT_CONVERT);
|
||||
void AddKeysFromProxy(Handle<JSObject> array);
|
||||
bool AddKeysFromProxy(Handle<JSProxy> proxy, Handle<FixedArray> keys,
|
||||
KeyFilter filter, Enumerability enum_policy);
|
||||
bool AddKeysFromProxy(Handle<JSProxy> proxy, Handle<FixedArray> keys);
|
||||
void AddElementKeysFromInterceptor(Handle<JSObject> array);
|
||||
// Jump to the next level, pushing the current |levelLength_| to
|
||||
// |levelLengths_| and adding a new list to |elements_|.
|
||||
@ -63,7 +61,7 @@ class KeyAccumulator final BASE_EMBEDDED {
|
||||
void SortCurrentElementsListRemoveDuplicates();
|
||||
|
||||
Isolate* isolate_;
|
||||
KeyFilter filter_;
|
||||
PropertyFilter filter_;
|
||||
// |elements_| contains the sorted element keys (indices) per level.
|
||||
std::vector<std::vector<uint32_t>*> elements_;
|
||||
// |protoLengths_| contains the total number of keys (elements + properties)
|
||||
|
@ -280,19 +280,12 @@ bool Object::KeyEquals(Object* second) {
|
||||
}
|
||||
|
||||
|
||||
bool Object::FilterKey(PropertyAttributes filter) {
|
||||
if ((filter & SYMBOLIC) && IsSymbol()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((filter & PRIVATE_SYMBOL) && IsSymbol() &&
|
||||
Symbol::cast(this)->is_private()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((filter & STRING) && !IsSymbol()) {
|
||||
return true;
|
||||
bool Object::FilterKey(PropertyFilter filter) {
|
||||
if (IsSymbol()) {
|
||||
if (filter & SKIP_SYMBOLS) return true;
|
||||
if (Symbol::cast(this)->is_private()) return true;
|
||||
}
|
||||
if ((filter & SKIP_STRINGS) && !IsSymbol()) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
124
src/objects.cc
124
src/objects.cc
@ -6118,10 +6118,11 @@ Object* JSReceiver::DefineProperties(Isolate* isolate, Handle<Object> object,
|
||||
Handle<FixedArray> keys;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, keys,
|
||||
JSReceiver::GetKeys(props, JSReceiver::OWN_ONLY, INCLUDE_SYMBOLS));
|
||||
JSReceiver::GetKeys(props, JSReceiver::OWN_ONLY, ALL_PROPERTIES));
|
||||
// 6. Let descriptors be an empty List.
|
||||
int capacity = keys->length();
|
||||
std::vector<PropertyDescriptor> descriptors(capacity);
|
||||
size_t descriptors_index = 0;
|
||||
// 7. Repeat for each element nextKey of keys in List order,
|
||||
for (int i = 0; i < keys->length(); ++i) {
|
||||
Handle<Object> next_key(keys->get(i), isolate);
|
||||
@ -6136,24 +6137,24 @@ Object* JSReceiver::DefineProperties(Isolate* isolate, Handle<Object> object,
|
||||
PropertyAttributes attrs = maybe.FromJust();
|
||||
// 7c. If propDesc is not undefined and propDesc.[[Enumerable]] is true:
|
||||
if (attrs == ABSENT) continue;
|
||||
// GetKeys() only returns enumerable keys.
|
||||
DCHECK((attrs & DONT_ENUM) == 0);
|
||||
if (attrs & DONT_ENUM) continue;
|
||||
// 7c i. Let descObj be Get(props, nextKey).
|
||||
// 7c ii. ReturnIfAbrupt(descObj).
|
||||
Handle<Object> desc_obj;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, desc_obj,
|
||||
Object::GetProperty(&it));
|
||||
// 7c iii. Let desc be ToPropertyDescriptor(descObj).
|
||||
success = PropertyDescriptor::ToPropertyDescriptor(isolate, desc_obj,
|
||||
&descriptors[i]);
|
||||
success = PropertyDescriptor::ToPropertyDescriptor(
|
||||
isolate, desc_obj, &descriptors[descriptors_index]);
|
||||
// 7c iv. ReturnIfAbrupt(desc).
|
||||
if (!success) return isolate->heap()->exception();
|
||||
// 7c v. Append the pair (a two element List) consisting of nextKey and
|
||||
// desc to the end of descriptors.
|
||||
descriptors[i].set_name(next_key);
|
||||
descriptors[descriptors_index].set_name(next_key);
|
||||
descriptors_index++;
|
||||
}
|
||||
// 8. For each pair from descriptors in list order,
|
||||
for (size_t i = 0; i < descriptors.size(); ++i) {
|
||||
for (size_t i = 0; i < descriptors_index; ++i) {
|
||||
PropertyDescriptor* desc = &descriptors[i];
|
||||
// 8a. Let P be the first element of pair.
|
||||
// 8b. Let desc be the second element of pair.
|
||||
@ -7717,10 +7718,10 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
|
||||
isolate->factory()->NewFixedArray(copy->NumberOfOwnProperties());
|
||||
copy->GetOwnPropertyNames(*names, 0);
|
||||
for (int i = 0; i < names->length(); i++) {
|
||||
DCHECK(names->get(i)->IsString());
|
||||
Handle<String> key_string(String::cast(names->get(i)));
|
||||
DCHECK(names->get(i)->IsName());
|
||||
Handle<Name> name(Name::cast(names->get(i)));
|
||||
Maybe<PropertyAttributes> maybe =
|
||||
JSReceiver::GetOwnPropertyAttributes(copy, key_string);
|
||||
JSReceiver::GetOwnPropertyAttributes(copy, name);
|
||||
DCHECK(maybe.IsJust());
|
||||
PropertyAttributes attributes = maybe.FromJust();
|
||||
// Only deep copy fields from the object literal expression.
|
||||
@ -7728,7 +7729,7 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
|
||||
// an array.
|
||||
if (attributes != NONE) continue;
|
||||
Handle<Object> value =
|
||||
Object::GetProperty(copy, key_string).ToHandleChecked();
|
||||
Object::GetProperty(copy, name).ToHandleChecked();
|
||||
if (value->IsJSObject()) {
|
||||
Handle<JSObject> result;
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
@ -7737,7 +7738,7 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
|
||||
JSObject);
|
||||
if (copying) {
|
||||
// Creating object copy for literals. No strict mode needed.
|
||||
JSObject::SetProperty(copy, key_string, result, SLOPPY).Assert();
|
||||
JSObject::SetProperty(copy, name, result, SLOPPY).Assert();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7941,7 +7942,7 @@ bool JSReceiver::IsSimpleEnum() {
|
||||
|
||||
|
||||
int Map::NumberOfDescribedProperties(DescriptorFlag which,
|
||||
PropertyAttributes filter) {
|
||||
PropertyFilter filter) {
|
||||
int result = 0;
|
||||
DescriptorArray* descs = instance_descriptors();
|
||||
int limit = which == ALL_DESCRIPTORS
|
||||
@ -8006,14 +8007,14 @@ Handle<FixedArray> GetFastEnumPropertyKeys(Isolate* isolate,
|
||||
// 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 not DONT_ENUM or
|
||||
// SYMBOLIC.
|
||||
// counting the number of own descriptors that are ENUMERABLE_STRINGS.
|
||||
if (own_property_count == kInvalidEnumCacheSentinel) {
|
||||
own_property_count =
|
||||
map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_SHOW);
|
||||
map->NumberOfDescribedProperties(OWN_DESCRIPTORS, ENUMERABLE_STRINGS);
|
||||
} else {
|
||||
DCHECK(own_property_count ==
|
||||
map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_SHOW));
|
||||
DCHECK(
|
||||
own_property_count ==
|
||||
map->NumberOfDescribedProperties(OWN_DESCRIPTORS, ENUMERABLE_STRINGS));
|
||||
}
|
||||
|
||||
if (descs->HasEnumCache()) {
|
||||
@ -8101,8 +8102,7 @@ Handle<FixedArray> JSObject::GetEnumPropertyKeys(Handle<JSObject> object,
|
||||
|
||||
|
||||
static bool GetKeysFromJSObject(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
Handle<JSObject> object, KeyFilter filter,
|
||||
Enumerability enum_policy,
|
||||
Handle<JSObject> object, PropertyFilter filter,
|
||||
KeyAccumulator* accumulator) {
|
||||
accumulator->NextPrototype();
|
||||
// Check access rights if required.
|
||||
@ -8114,11 +8114,7 @@ static bool GetKeysFromJSObject(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
return false;
|
||||
}
|
||||
|
||||
PropertyAttributes attr_filter = static_cast<PropertyAttributes>(
|
||||
(enum_policy == RESPECT_ENUMERABILITY ? DONT_ENUM : NONE) |
|
||||
PRIVATE_SYMBOL);
|
||||
|
||||
JSObject::CollectOwnElementKeys(object, accumulator, attr_filter);
|
||||
JSObject::CollectOwnElementKeys(object, accumulator, filter);
|
||||
|
||||
// Add the element keys from the interceptor.
|
||||
if (object->HasIndexedInterceptor()) {
|
||||
@ -8130,9 +8126,7 @@ static bool GetKeysFromJSObject(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, false);
|
||||
}
|
||||
|
||||
if (filter == SKIP_SYMBOLS) {
|
||||
if (enum_policy == IGNORE_ENUMERABILITY) UNIMPLEMENTED();
|
||||
|
||||
if (filter == ENUMERABLE_STRINGS) {
|
||||
// We can cache the computed property keys if access checks are
|
||||
// not needed and no interceptors are involved.
|
||||
//
|
||||
@ -8154,8 +8148,7 @@ static bool GetKeysFromJSObject(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
JSObject::GetEnumPropertyKeys(object, cache_enum_length);
|
||||
accumulator->AddKeys(enum_keys);
|
||||
} else {
|
||||
DCHECK(filter == INCLUDE_SYMBOLS);
|
||||
object->CollectOwnPropertyNames(accumulator, attr_filter);
|
||||
object->CollectOwnPropertyNames(accumulator, filter);
|
||||
}
|
||||
|
||||
// Add the property keys from the interceptor.
|
||||
@ -8176,7 +8169,7 @@ static bool GetKeysFromJSObject(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
static bool GetKeys_Internal(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
Handle<JSReceiver> object,
|
||||
JSReceiver::KeyCollectionType type,
|
||||
KeyFilter filter, Enumerability enum_policy,
|
||||
PropertyFilter filter,
|
||||
KeyAccumulator* accumulator) {
|
||||
PrototypeIterator::WhereToEnd end = type == JSReceiver::OWN_ONLY
|
||||
? PrototypeIterator::END_AT_NON_HIDDEN
|
||||
@ -8191,7 +8184,7 @@ static bool GetKeys_Internal(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
if (type == JSReceiver::OWN_ONLY) {
|
||||
result = JSProxy::OwnPropertyKeys(isolate, receiver,
|
||||
Handle<JSProxy>::cast(current),
|
||||
filter, enum_policy, accumulator);
|
||||
filter, accumulator);
|
||||
} else {
|
||||
DCHECK(type == JSReceiver::INCLUDE_PROTOS);
|
||||
result = JSProxy::Enumerate(
|
||||
@ -8201,7 +8194,7 @@ static bool GetKeys_Internal(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
DCHECK(current->IsJSObject());
|
||||
result = GetKeysFromJSObject(isolate, receiver,
|
||||
Handle<JSObject>::cast(current), filter,
|
||||
enum_policy, accumulator);
|
||||
accumulator);
|
||||
}
|
||||
if (!result) {
|
||||
if (isolate->has_pending_exception()) {
|
||||
@ -8243,7 +8236,7 @@ bool JSProxy::Enumerate(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
if (trap->IsUndefined()) {
|
||||
// 6a. Return target.[[Enumerate]]().
|
||||
return GetKeys_Internal(isolate, receiver, target, INCLUDE_PROTOS,
|
||||
SKIP_SYMBOLS, RESPECT_ENUMERABILITY, accumulator);
|
||||
ENUMERABLE_STRINGS, accumulator);
|
||||
}
|
||||
// The "proxy_enumerate" helper calls the trap (steps 7 - 9), which returns
|
||||
// a generator; it then iterates over that generator until it's exhausted
|
||||
@ -8324,8 +8317,7 @@ static MaybeHandle<FixedArray> CreateListFromArrayLike_StringSymbol(
|
||||
// Returns "false" in case of exception.
|
||||
// static
|
||||
bool JSProxy::OwnPropertyKeys(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
Handle<JSProxy> proxy, KeyFilter filter,
|
||||
Enumerability enum_policy,
|
||||
Handle<JSProxy> proxy, PropertyFilter filter,
|
||||
KeyAccumulator* accumulator) {
|
||||
// 1. Let handler be the value of the [[ProxyHandler]] internal slot of O.
|
||||
Handle<Object> handler(proxy->handler(), isolate);
|
||||
@ -8349,7 +8341,7 @@ bool JSProxy::OwnPropertyKeys(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
if (trap->IsUndefined()) {
|
||||
// 6a. Return target.[[OwnPropertyKeys]]().
|
||||
return GetKeys_Internal(isolate, receiver, target, OWN_ONLY, filter,
|
||||
enum_policy, accumulator);
|
||||
accumulator);
|
||||
}
|
||||
// 7. Let trapResultArray be Call(trap, handler, «target»).
|
||||
Handle<Object> trap_result_array;
|
||||
@ -8371,8 +8363,8 @@ bool JSProxy::OwnPropertyKeys(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
Handle<FixedArray> target_keys;
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
||||
isolate, target_keys,
|
||||
JSReceiver::GetKeys(target, JSReceiver::OWN_ONLY, INCLUDE_SYMBOLS,
|
||||
CONVERT_TO_STRING, IGNORE_ENUMERABILITY),
|
||||
JSReceiver::GetKeys(target, JSReceiver::OWN_ONLY, ALL_PROPERTIES,
|
||||
CONVERT_TO_STRING),
|
||||
false);
|
||||
// 11. (Assert)
|
||||
// 12. Let targetConfigurableKeys be an empty List.
|
||||
@ -8408,8 +8400,7 @@ bool JSProxy::OwnPropertyKeys(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
// then:
|
||||
if (extensible_target && nonconfigurable_keys_length == 0) {
|
||||
// 15a. Return trapResult.
|
||||
return accumulator->AddKeysFromProxy(proxy, trap_result, filter,
|
||||
enum_policy);
|
||||
return accumulator->AddKeysFromProxy(proxy, trap_result);
|
||||
}
|
||||
// 16. Let uncheckedResultKeys be a new List which is a copy of trapResult.
|
||||
Zone set_zone;
|
||||
@ -8438,8 +8429,7 @@ bool JSProxy::OwnPropertyKeys(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
}
|
||||
// 18. If extensibleTarget is true, return trapResult.
|
||||
if (extensible_target) {
|
||||
return accumulator->AddKeysFromProxy(proxy, trap_result, filter,
|
||||
enum_policy);
|
||||
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) {
|
||||
@ -8465,20 +8455,18 @@ bool JSProxy::OwnPropertyKeys(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
return false;
|
||||
}
|
||||
// 21. Return trapResult.
|
||||
return accumulator->AddKeysFromProxy(proxy, trap_result, filter, enum_policy);
|
||||
return accumulator->AddKeysFromProxy(proxy, trap_result);
|
||||
}
|
||||
|
||||
|
||||
MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object,
|
||||
KeyCollectionType type,
|
||||
KeyFilter filter,
|
||||
GetKeysConversion keys_conversion,
|
||||
Enumerability enum_policy) {
|
||||
PropertyFilter filter,
|
||||
GetKeysConversion keys_conversion) {
|
||||
USE(ContainsOnlyValidKeys);
|
||||
Isolate* isolate = object->GetIsolate();
|
||||
KeyAccumulator accumulator(isolate, filter);
|
||||
if (!GetKeys_Internal(isolate, object, object, type, filter, enum_policy,
|
||||
&accumulator)) {
|
||||
if (!GetKeys_Internal(isolate, object, object, type, filter, &accumulator)) {
|
||||
DCHECK(isolate->has_pending_exception());
|
||||
return MaybeHandle<FixedArray>();
|
||||
}
|
||||
@ -14446,8 +14434,7 @@ MaybeHandle<Object> JSArray::ObservableSetLength(Handle<JSArray> array,
|
||||
uint32_t old_length = 0;
|
||||
CHECK(old_length_handle->ToArrayLength(&old_length));
|
||||
|
||||
static const PropertyAttributes kNoAttrFilter = NONE;
|
||||
int num_elements = array->NumberOfOwnElements(kNoAttrFilter);
|
||||
int num_elements = array->NumberOfOwnElements(ALL_PROPERTIES);
|
||||
if (num_elements > 0) {
|
||||
if (old_length == static_cast<uint32_t>(num_elements)) {
|
||||
// Simple case for arrays without holes.
|
||||
@ -14459,7 +14446,7 @@ MaybeHandle<Object> JSArray::ObservableSetLength(Handle<JSArray> array,
|
||||
// TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over
|
||||
// the to-be-removed indices twice.
|
||||
Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements);
|
||||
array->GetOwnElementKeys(*keys, kNoAttrFilter);
|
||||
array->GetOwnElementKeys(*keys, ALL_PROPERTIES);
|
||||
while (num_elements-- > 0) {
|
||||
uint32_t index = NumberToUint32(keys->get(num_elements));
|
||||
if (index < new_length) break;
|
||||
@ -15685,13 +15672,13 @@ Maybe<bool> JSObject::HasRealNamedCallbackProperty(Handle<JSObject> object,
|
||||
}
|
||||
|
||||
|
||||
int JSObject::NumberOfOwnProperties(PropertyAttributes filter) {
|
||||
// Private symbols are always filtered out.
|
||||
int JSObject::NumberOfOwnProperties(PropertyFilter filter) {
|
||||
if (HasFastProperties()) {
|
||||
Map* map = this->map();
|
||||
if (filter == NONE) return map->NumberOfOwnDescriptors();
|
||||
if (filter == DONT_SHOW) {
|
||||
// The cached enum length was computed with filter == DONT_SHOW, so
|
||||
// that's the only filter for which it's valid to retrieve it.
|
||||
if (filter == ENUMERABLE_STRINGS) {
|
||||
// The cached enum length was computed with filter == ENUMERABLE_STRING,
|
||||
// so that's the only filter for which it's valid to retrieve it.
|
||||
int result = map->EnumLength();
|
||||
if (result != kInvalidEnumCacheSentinel) return result;
|
||||
}
|
||||
@ -15821,7 +15808,7 @@ void FixedArray::SortPairs(FixedArray* numbers, uint32_t len) {
|
||||
// purpose of this function is to provide reflection information for the object
|
||||
// mirrors.
|
||||
int JSObject::GetOwnPropertyNames(FixedArray* storage, int index,
|
||||
PropertyAttributes filter) {
|
||||
PropertyFilter filter) {
|
||||
DCHECK(storage->length() >= (NumberOfOwnProperties(filter) - index));
|
||||
if (HasFastProperties()) {
|
||||
int start_index = index;
|
||||
@ -15845,7 +15832,7 @@ int JSObject::GetOwnPropertyNames(FixedArray* storage, int index,
|
||||
|
||||
|
||||
void JSObject::CollectOwnPropertyNames(KeyAccumulator* keys,
|
||||
PropertyAttributes filter) {
|
||||
PropertyFilter filter) {
|
||||
if (HasFastProperties()) {
|
||||
int real_size = map()->NumberOfOwnDescriptors();
|
||||
Handle<DescriptorArray> descs(map()->instance_descriptors());
|
||||
@ -15863,7 +15850,7 @@ void JSObject::CollectOwnPropertyNames(KeyAccumulator* keys,
|
||||
}
|
||||
|
||||
|
||||
int JSObject::NumberOfOwnElements(PropertyAttributes filter) {
|
||||
int JSObject::NumberOfOwnElements(PropertyFilter filter) {
|
||||
// Fast case for objects with no elements.
|
||||
if (!IsJSValue() && HasFastElements()) {
|
||||
uint32_t length =
|
||||
@ -15879,13 +15866,13 @@ int JSObject::NumberOfOwnElements(PropertyAttributes filter) {
|
||||
|
||||
|
||||
int JSObject::NumberOfEnumElements() {
|
||||
return NumberOfOwnElements(static_cast<PropertyAttributes>(DONT_ENUM));
|
||||
return NumberOfOwnElements(ONLY_ENUMERABLE);
|
||||
}
|
||||
|
||||
|
||||
void JSObject::CollectOwnElementKeys(Handle<JSObject> object,
|
||||
KeyAccumulator* keys,
|
||||
PropertyAttributes filter) {
|
||||
PropertyFilter filter) {
|
||||
uint32_t string_keys = 0;
|
||||
|
||||
// If this is a String wrapper, add the string indices first,
|
||||
@ -15906,8 +15893,7 @@ void JSObject::CollectOwnElementKeys(Handle<JSObject> object,
|
||||
}
|
||||
|
||||
|
||||
int JSObject::GetOwnElementKeys(FixedArray* storage,
|
||||
PropertyAttributes filter) {
|
||||
int JSObject::GetOwnElementKeys(FixedArray* storage, PropertyFilter filter) {
|
||||
int counter = 0;
|
||||
|
||||
// If this is a String wrapper, add the string indices first,
|
||||
@ -17738,7 +17724,7 @@ Handle<UnseededNumberDictionary> UnseededNumberDictionary::Set(
|
||||
|
||||
template <typename Derived, typename Shape, typename Key>
|
||||
int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes(
|
||||
PropertyAttributes filter) {
|
||||
PropertyFilter filter) {
|
||||
int capacity = this->Capacity();
|
||||
int result = 0;
|
||||
for (int i = 0; i < capacity; i++) {
|
||||
@ -17759,12 +17745,12 @@ bool Dictionary<Derived, Shape, Key>::HasComplexElements() {
|
||||
int capacity = this->Capacity();
|
||||
for (int i = 0; i < capacity; i++) {
|
||||
Object* k = this->KeyAt(i);
|
||||
if (this->IsKey(k) && !k->FilterKey(NONE)) {
|
||||
if (this->IsKey(k) && !k->FilterKey(ALL_PROPERTIES)) {
|
||||
if (this->IsDeleted(i)) continue;
|
||||
PropertyDetails details = this->DetailsAt(i);
|
||||
if (details.type() == ACCESSOR_CONSTANT) return true;
|
||||
PropertyAttributes attr = details.attributes();
|
||||
if (attr & (READ_ONLY | DONT_DELETE | DONT_ENUM)) return true;
|
||||
if (attr & ALL_ATTRIBUTES_MASK) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -17811,7 +17797,7 @@ void Dictionary<Derived, Shape, Key>::CopyEnumKeysTo(FixedArray* storage) {
|
||||
|
||||
template <typename Derived, typename Shape, typename Key>
|
||||
int Dictionary<Derived, Shape, Key>::CopyKeysTo(
|
||||
FixedArray* storage, int index, PropertyAttributes filter,
|
||||
FixedArray* storage, int index, PropertyFilter filter,
|
||||
typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) {
|
||||
DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter));
|
||||
int start_index = index;
|
||||
@ -17836,7 +17822,7 @@ int Dictionary<Derived, Shape, Key>::CopyKeysTo(
|
||||
template <typename Derived, typename Shape, typename Key>
|
||||
void Dictionary<Derived, Shape, Key>::CollectKeysTo(
|
||||
Handle<Dictionary<Derived, Shape, Key> > dictionary, KeyAccumulator* keys,
|
||||
PropertyAttributes filter) {
|
||||
PropertyFilter filter) {
|
||||
int capacity = dictionary->Capacity();
|
||||
Handle<FixedArray> array =
|
||||
keys->isolate()->factory()->NewFixedArray(dictionary->NumberOfElements());
|
||||
|
@ -1098,7 +1098,7 @@ class Object {
|
||||
// 1 all refer to the same property, so this helper will return true.
|
||||
inline bool KeyEquals(Object* other);
|
||||
|
||||
inline bool FilterKey(PropertyAttributes filter);
|
||||
inline bool FilterKey(PropertyFilter filter);
|
||||
|
||||
Handle<HeapType> OptimalType(Isolate* isolate, Representation representation);
|
||||
|
||||
@ -1773,10 +1773,6 @@ enum AccessorComponent {
|
||||
};
|
||||
|
||||
|
||||
enum KeyFilter { SKIP_SYMBOLS, INCLUDE_SYMBOLS };
|
||||
|
||||
enum Enumerability { RESPECT_ENUMERABILITY, IGNORE_ENUMERABILITY };
|
||||
|
||||
enum GetKeysConversion { KEEP_NUMBERS, CONVERT_TO_STRING };
|
||||
|
||||
|
||||
@ -1923,10 +1919,8 @@ class JSReceiver: public HeapObject {
|
||||
// Computes the enumerable keys for a JSObject. Used for implementing
|
||||
// "for (n in object) { }".
|
||||
MUST_USE_RESULT static MaybeHandle<FixedArray> GetKeys(
|
||||
Handle<JSReceiver> object, KeyCollectionType type,
|
||||
KeyFilter filter = SKIP_SYMBOLS,
|
||||
GetKeysConversion keys_conversion = KEEP_NUMBERS,
|
||||
Enumerability enum_policy = RESPECT_ENUMERABILITY);
|
||||
Handle<JSReceiver> object, KeyCollectionType type, PropertyFilter filter,
|
||||
GetKeysConversion keys_conversion = KEEP_NUMBERS);
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
|
||||
@ -2254,25 +2248,25 @@ class JSObject: public JSReceiver {
|
||||
|
||||
// Returns the number of properties on this object filtering out properties
|
||||
// with the specified attributes (ignoring interceptors).
|
||||
int NumberOfOwnProperties(PropertyAttributes filter = NONE);
|
||||
int NumberOfOwnProperties(PropertyFilter filter = ALL_PROPERTIES);
|
||||
// Fill in details for properties into storage starting at the specified
|
||||
// index. Returns the number of properties added.
|
||||
int GetOwnPropertyNames(FixedArray* storage, int index,
|
||||
PropertyAttributes filter = NONE);
|
||||
PropertyFilter filter = ALL_PROPERTIES);
|
||||
void CollectOwnPropertyNames(KeyAccumulator* keys,
|
||||
PropertyAttributes filter = NONE);
|
||||
PropertyFilter filter = ALL_PROPERTIES);
|
||||
|
||||
// Returns the number of properties on this object filtering out properties
|
||||
// with the specified attributes (ignoring interceptors).
|
||||
int NumberOfOwnElements(PropertyAttributes filter);
|
||||
int NumberOfOwnElements(PropertyFilter filter);
|
||||
// Returns the number of enumerable elements (ignoring interceptors).
|
||||
int NumberOfEnumElements();
|
||||
// Returns the number of elements on this object filtering out elements
|
||||
// with the specified attributes (ignoring interceptors).
|
||||
int GetOwnElementKeys(FixedArray* storage, PropertyAttributes filter);
|
||||
int GetOwnElementKeys(FixedArray* storage, PropertyFilter filter);
|
||||
static void CollectOwnElementKeys(Handle<JSObject> object,
|
||||
KeyAccumulator* keys,
|
||||
PropertyAttributes filter);
|
||||
PropertyFilter filter);
|
||||
// Count and fill in the enumerable elements into storage.
|
||||
// (storage->length() == NumberOfEnumElements()).
|
||||
// If storage is NULL, will count the elements without adding
|
||||
@ -3357,12 +3351,11 @@ class Dictionary: public HashTable<Derived, Shape, Key> {
|
||||
|
||||
// Returns the number of elements in the dictionary filtering out properties
|
||||
// with the specified attributes.
|
||||
int NumberOfElementsFilterAttributes(PropertyAttributes filter);
|
||||
int NumberOfElementsFilterAttributes(PropertyFilter filter);
|
||||
|
||||
// Returns the number of enumerable elements in the dictionary.
|
||||
int NumberOfEnumElements() {
|
||||
return NumberOfElementsFilterAttributes(
|
||||
static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC));
|
||||
return NumberOfElementsFilterAttributes(ENUMERABLE_STRINGS);
|
||||
}
|
||||
|
||||
// Returns true if the dictionary contains any elements that are non-writable,
|
||||
@ -3373,12 +3366,12 @@ class Dictionary: public HashTable<Derived, Shape, Key> {
|
||||
|
||||
// Fill in details for properties into storage.
|
||||
// Returns the number of properties added.
|
||||
int CopyKeysTo(FixedArray* storage, int index, PropertyAttributes filter,
|
||||
int CopyKeysTo(FixedArray* storage, int index, PropertyFilter filter,
|
||||
SortMode sort_mode);
|
||||
// Collect the keys into the given KeyAccumulator, in ascending chronological
|
||||
// order of property creation.
|
||||
static void CollectKeysTo(Handle<Dictionary<Derived, Shape, Key> > dictionary,
|
||||
KeyAccumulator* keys, PropertyAttributes filter);
|
||||
KeyAccumulator* keys, PropertyFilter filter);
|
||||
|
||||
// Copies enumerable keys to preallocated fixed array.
|
||||
void CopyEnumKeysTo(FixedArray* storage);
|
||||
@ -5824,7 +5817,7 @@ class Map: public HeapObject {
|
||||
// Returns the number of properties described in instance_descriptors
|
||||
// filtering out properties with the specified attributes.
|
||||
int NumberOfDescribedProperties(DescriptorFlag which = OWN_DESCRIPTORS,
|
||||
PropertyAttributes filter = NONE);
|
||||
PropertyFilter filter = ALL_PROPERTIES);
|
||||
|
||||
DECLARE_CAST(Map)
|
||||
|
||||
@ -9549,8 +9542,7 @@ class JSProxy: public JSReceiver {
|
||||
|
||||
// ES6 9.5.12
|
||||
static bool OwnPropertyKeys(Isolate* isolate, Handle<JSReceiver> receiver,
|
||||
Handle<JSProxy> proxy, KeyFilter filter,
|
||||
Enumerability enum_policy,
|
||||
Handle<JSProxy> proxy, PropertyFilter filter,
|
||||
KeyAccumulator* accumulator);
|
||||
|
||||
MUST_USE_RESULT static MaybeHandle<Object> GetPropertyWithHandler(
|
||||
|
@ -9,21 +9,21 @@
|
||||
#include "src/allocation.h"
|
||||
#include "src/utils.h"
|
||||
|
||||
// Ecma-262 3rd 8.6.1
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// ES6 6.1.7.1
|
||||
enum PropertyAttributes {
|
||||
NONE = v8::None,
|
||||
READ_ONLY = v8::ReadOnly,
|
||||
DONT_ENUM = v8::DontEnum,
|
||||
DONT_DELETE = v8::DontDelete,
|
||||
NONE = ::v8::None,
|
||||
READ_ONLY = ::v8::ReadOnly,
|
||||
DONT_ENUM = ::v8::DontEnum,
|
||||
DONT_DELETE = ::v8::DontDelete,
|
||||
|
||||
ALL_ATTRIBUTES_MASK = READ_ONLY | DONT_ENUM | DONT_DELETE,
|
||||
|
||||
SEALED = DONT_DELETE,
|
||||
FROZEN = SEALED | READ_ONLY,
|
||||
|
||||
STRING = 8, // Used to filter symbols and string names
|
||||
SYMBOLIC = 16,
|
||||
PRIVATE_SYMBOL = 32,
|
||||
|
||||
DONT_SHOW = DONT_ENUM | SYMBOLIC | PRIVATE_SYMBOL,
|
||||
ABSENT = 64, // Used in runtime to indicate a property is absent.
|
||||
// ABSENT can never be stored in or returned from a descriptor's attributes
|
||||
// bitfield. It is only used as a return value meaning the attributes of
|
||||
@ -36,8 +36,20 @@ enum PropertyAttributes {
|
||||
};
|
||||
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
enum PropertyFilter {
|
||||
ALL_PROPERTIES = 0,
|
||||
ONLY_ENUMERABLE = 2,
|
||||
SKIP_STRINGS = 8,
|
||||
SKIP_SYMBOLS = 16,
|
||||
ONLY_ALL_CAN_READ = 32,
|
||||
ENUMERABLE_STRINGS = ONLY_ENUMERABLE | SKIP_SYMBOLS,
|
||||
};
|
||||
// Enable fast comparisons of PropertyAttributes against PropertyFilters.
|
||||
STATIC_ASSERT(ALL_PROPERTIES == static_cast<PropertyFilter>(NONE));
|
||||
STATIC_ASSERT(ONLY_ENUMERABLE == static_cast<PropertyFilter>(DONT_ENUM));
|
||||
STATIC_ASSERT(((SKIP_STRINGS | SKIP_SYMBOLS | ONLY_ALL_CAN_READ) &
|
||||
ALL_ATTRIBUTES_MASK) == 0);
|
||||
|
||||
|
||||
class Smi;
|
||||
template<class> class TypeImpl;
|
||||
|
@ -206,7 +206,7 @@ RUNTIME_FUNCTION(Runtime_GetArrayKeys) {
|
||||
return *isolate->factory()->NewNumberFromUint(Min(actual_length, length));
|
||||
}
|
||||
|
||||
KeyAccumulator accumulator(isolate);
|
||||
KeyAccumulator accumulator(isolate, ALL_PROPERTIES);
|
||||
// No need to separate protoype levels since we only get numbers/element keys
|
||||
for (PrototypeIterator iter(isolate, array,
|
||||
PrototypeIterator::START_AT_RECEIVER);
|
||||
@ -220,7 +220,7 @@ RUNTIME_FUNCTION(Runtime_GetArrayKeys) {
|
||||
}
|
||||
accumulator.NextPrototype();
|
||||
Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter);
|
||||
JSObject::CollectOwnElementKeys(current, &accumulator, NONE);
|
||||
JSObject::CollectOwnElementKeys(current, &accumulator, ALL_PROPERTIES);
|
||||
}
|
||||
// Erase any keys >= length.
|
||||
// TODO(adamk): Remove this step when the contract of %GetArrayKeys
|
||||
|
@ -214,14 +214,13 @@ MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
|
||||
Heap* heap = isolate->heap();
|
||||
Factory* factory = isolate->factory();
|
||||
|
||||
PropertyAttributes attrs;
|
||||
// Get attributes.
|
||||
LookupIterator it = LookupIterator::PropertyOrElement(isolate, obj, name,
|
||||
LookupIterator::HIDDEN);
|
||||
Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it);
|
||||
|
||||
if (!maybe.IsJust()) return MaybeHandle<Object>();
|
||||
attrs = maybe.FromJust();
|
||||
PropertyAttributes attrs = maybe.FromJust();
|
||||
if (attrs == ABSENT) return factory->undefined_value();
|
||||
|
||||
DCHECK(!isolate->has_pending_exception());
|
||||
@ -787,8 +786,8 @@ RUNTIME_FUNCTION(Runtime_GetPropertyNamesFast) {
|
||||
Handle<JSReceiver> object(raw_object);
|
||||
Handle<FixedArray> content;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, content,
|
||||
JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
|
||||
isolate, content, JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS,
|
||||
ENUMERABLE_STRINGS));
|
||||
|
||||
// Test again, since cache may have been built by preceding call.
|
||||
if (object->IsSimpleEnum()) return object->map();
|
||||
@ -810,7 +809,20 @@ RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
|
||||
}
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
|
||||
CONVERT_SMI_ARG_CHECKED(filter_value, 1);
|
||||
PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value);
|
||||
|
||||
// TODO(jkummerow): Temporary compatibility measure. Refactor callers.
|
||||
// Values of filter_value are defined in macros.py.
|
||||
PropertyFilter filter = ALL_PROPERTIES;
|
||||
if (filter_value & 2) {
|
||||
filter = static_cast<PropertyFilter>(filter | ONLY_ENUMERABLE);
|
||||
}
|
||||
if (filter_value & 8) {
|
||||
filter = static_cast<PropertyFilter>(filter | SKIP_STRINGS);
|
||||
}
|
||||
if (filter_value & 16) {
|
||||
filter = static_cast<PropertyFilter>(filter | SKIP_SYMBOLS);
|
||||
}
|
||||
DCHECK(filter_value & 32);
|
||||
|
||||
// Find the number of own properties for each of the objects.
|
||||
int total_property_count = 0;
|
||||
@ -925,9 +937,9 @@ RUNTIME_FUNCTION(Runtime_GetOwnElementNames) {
|
||||
object = PrototypeIterator::GetCurrent<JSObject>(iter);
|
||||
}
|
||||
|
||||
int n = object->NumberOfOwnElements(NONE);
|
||||
int n = object->NumberOfOwnElements(ALL_PROPERTIES);
|
||||
Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
|
||||
object->GetOwnElementKeys(*names, NONE);
|
||||
object->GetOwnElementKeys(*names, ALL_PROPERTIES);
|
||||
return *isolate->factory()->NewJSArrayWithElements(names);
|
||||
}
|
||||
|
||||
@ -991,8 +1003,9 @@ RUNTIME_FUNCTION(Runtime_OwnKeys) {
|
||||
|
||||
Handle<FixedArray> contents;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, contents, JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY,
|
||||
SKIP_SYMBOLS, CONVERT_TO_STRING));
|
||||
isolate, contents,
|
||||
JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY, ENUMERABLE_STRINGS,
|
||||
CONVERT_TO_STRING));
|
||||
return *isolate->factory()->NewJSArrayWithElements(contents);
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ TEST(StressJS) {
|
||||
Handle<DescriptorArray> instance_descriptors(map->instance_descriptors());
|
||||
DCHECK(instance_descriptors->IsEmpty());
|
||||
|
||||
PropertyAttributes attrs = static_cast<PropertyAttributes>(0);
|
||||
PropertyAttributes attrs = NONE;
|
||||
Handle<AccessorInfo> foreign = TestAccessorInfo(isolate, attrs);
|
||||
Map::EnsureDescriptorSlack(map, 1);
|
||||
|
||||
|
@ -10733,8 +10733,8 @@ THREADED_TEST(Regress91517) {
|
||||
// Call the runtime version of GetOwnPropertyNames() on the natively
|
||||
// created object through JavaScript.
|
||||
CHECK(context->Global()->Set(context.local(), v8_str("obj"), o4).FromJust());
|
||||
// PROPERTY_ATTRIBUTES_NONE = 0
|
||||
CompileRun("var names = %GetOwnPropertyNames(obj, 0);");
|
||||
// PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL = 32
|
||||
CompileRun("var names = %GetOwnPropertyNames(obj, 32);");
|
||||
|
||||
ExpectInt32("names.length", 1006);
|
||||
ExpectTrue("names.indexOf(\"baz\") >= 0");
|
||||
@ -10797,8 +10797,8 @@ THREADED_TEST(Regress269562) {
|
||||
// the natively created object through JavaScript.
|
||||
CHECK(context->Global()->Set(context.local(), v8_str("obj"), o2).FromJust());
|
||||
CHECK(context->Global()->Set(context.local(), v8_str("sym"), sym).FromJust());
|
||||
// PROPERTY_ATTRIBUTES_NONE = 0
|
||||
CompileRun("var names = %GetOwnPropertyNames(obj, 0);");
|
||||
// PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL = 32
|
||||
CompileRun("var names = %GetOwnPropertyNames(obj, 32);");
|
||||
|
||||
ExpectInt32("names.length", 7);
|
||||
ExpectTrue("names.indexOf(\"foo\") >= 0");
|
||||
|
@ -118,7 +118,8 @@ class DebugLocalContext {
|
||||
Handle<v8::internal::String> debug_string =
|
||||
factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("debug"));
|
||||
v8::internal::JSObject::SetOwnPropertyIgnoreAttributes(
|
||||
global, debug_string, handle(debug_context->global_proxy()), DONT_ENUM)
|
||||
global, debug_string, handle(debug_context->global_proxy()),
|
||||
v8::internal::DONT_ENUM)
|
||||
.Check();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user