From bcc9aa7daf197e8f2befe215902443d608e07b6a Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 8 Sep 2018 23:07:31 +0200 Subject: Include symbols in getOwnPropertyKeys And fix getOwnPropertySymbols and getOwnPropertyDescriptors. Change-Id: Ie0e4c3d308ffe8a904e9a6ab9242b2cda59d779f Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4object.cpp | 48 +++++++++++++++++++++------------ src/qml/jsruntime/qv4object_p.h | 1 + src/qml/jsruntime/qv4objectiterator.cpp | 3 ++- src/qml/jsruntime/qv4objectiterator_p.h | 3 ++- src/qml/jsruntime/qv4objectproto.cpp | 24 ++++++++++------- 5 files changed, 51 insertions(+), 28 deletions(-) (limited to 'src/qml/jsruntime') diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 267726d22f..cd9ea66297 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -366,25 +366,39 @@ PropertyKey ObjectOwnPropertyKeyIterator::next(const Object *o, Property *pd, Pr arrayIndex = UINT_MAX; } - while (memberIndex < o->internalClass()->size) { - PropertyKey n = o->internalClass()->nameMap.at(memberIndex); - if (!n.isStringOrSymbol()) { - // accessor properties have a dummy entry with n == 0 - ++memberIndex; - continue; - } + while (true) { + while (memberIndex < o->internalClass()->size) { + PropertyKey n = o->internalClass()->nameMap.at(memberIndex); + if (!n.isStringOrSymbol()) { + // accessor properties have a dummy entry with n == 0 + ++memberIndex; + continue; + } + if (!iterateOverSymbols && n.isSymbol()) { + ++memberIndex; + continue; + } + if (iterateOverSymbols && !n.isSymbol()) { + ++memberIndex; + continue; + } - uint index = memberIndex; - PropertyAttributes a = o->internalClass()->propertyData[memberIndex]; - ++memberIndex; - if (pd) { - pd->value = *o->propertyData(index); - if (a.isAccessor()) - pd->set = *o->propertyData(index + Object::SetterOffset); + uint index = memberIndex; + PropertyAttributes a = o->internalClass()->propertyData[memberIndex]; + ++memberIndex; + if (pd) { + pd->value = *o->propertyData(index); + if (a.isAccessor()) + pd->set = *o->propertyData(index + Object::SetterOffset); + } + if (attrs) + *attrs = a; + return n; } - if (attrs) - *attrs = a; - return n; + if (iterateOverSymbols) + break; + iterateOverSymbols = true; + memberIndex = 0; } return PropertyKey::invalid(); diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 0a27993004..41484660ab 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -392,6 +392,7 @@ struct ObjectOwnPropertyKeyIterator : OwnPropertyKeyIterator { uint arrayIndex = 0; uint memberIndex = 0; + bool iterateOverSymbols = false; SparseArrayNode *arrayNode = nullptr; ~ObjectOwnPropertyKeyIterator() override = default; PropertyKey next(const Object *o, Property *pd = nullptr, PropertyAttributes *attrs = nullptr) override; diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp index 906f6b38a6..e529b8e86b 100644 --- a/src/qml/jsruntime/qv4objectiterator.cpp +++ b/src/qml/jsruntime/qv4objectiterator.cpp @@ -66,7 +66,8 @@ PropertyKey ObjectIterator::next(Property *pd, PropertyAttributes *attrs) object = nullptr; return key; } - if (key->isSymbol() || ((flags & EnumerableOnly) && !attrs->isEnumerable())) + if ((!(flags & WithSymbols) && key->isSymbol()) || + ((flags & EnumerableOnly) && !attrs->isEnumerable())) continue; return key; } diff --git a/src/qml/jsruntime/qv4objectiterator_p.h b/src/qml/jsruntime/qv4objectiterator_p.h index 0a5bcfc7ed..a20ce9cb88 100644 --- a/src/qml/jsruntime/qv4objectiterator_p.h +++ b/src/qml/jsruntime/qv4objectiterator_p.h @@ -61,7 +61,8 @@ struct Q_QML_EXPORT ObjectIterator { enum Flags { NoFlags = 0, - EnumerableOnly = 0x1 + EnumerableOnly = 0x1, + WithSymbols = 0x2 }; ExecutionEngine *engine; diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index 926d246373..a4f960a3b6 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -188,7 +188,7 @@ ReturnedValue ObjectPrototype::method_getOwnPropertyDescriptors(const FunctionOb ScopedObject descriptors(scope, scope.engine->newObject()); - ObjectIterator it(scope, o, ObjectIterator::NoFlags); + ObjectIterator it(scope, o, ObjectIterator::WithSymbols); ScopedProperty pd(scope); PropertyAttributes attrs; ScopedPropertyKey key(scope); @@ -227,15 +227,19 @@ ReturnedValue ObjectPrototype::method_getOwnPropertySymbols(const FunctionObject ScopedObject O(scope, argv[0].toObject(scope.engine)); if (!O) return Encode::undefined(); - Heap::InternalClass *ic = O->d()->internalClass; - ScopedValue n(scope); + ScopedArrayObject array(scope, scope.engine->newArrayObject()); - for (uint i = 0; i < ic->size; ++i) { - PropertyKey id = ic->nameMap.at(i); - n = id.asStringOrSymbol(); - if (!n || !n->isSymbol()) - continue; - array->push_back(n); + if (O) { + ObjectIterator it(scope, O, ObjectIterator::WithSymbols); + ScopedValue name(scope); + while (1) { + name = it.nextPropertyNameAsString(); + if (name->isNull()) + break; + if (!name->isSymbol()) + continue; + array->push_back(name); + } } return array->asReturnedValue(); } @@ -916,6 +920,8 @@ Heap::ArrayObject *ObjectPrototype::getOwnPropertyNames(ExecutionEngine *v4, con name = it.nextPropertyNameAsString(); if (name->isNull()) break; + if (name->isSymbol()) + continue; array->push_back(name); } } -- cgit v1.2.3