diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-08-02 15:44:12 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-08-02 20:25:41 +0000 |
commit | 0754f55287f4652382332bce42cd8c7d27846ef1 (patch) | |
tree | 490bbd3c5d66586a1427ba21dde76b2af65230dc /src/qml/jsruntime/qv4stringobject.cpp | |
parent | 57640959320c87850315eae44c783803d113dc85 (diff) |
Introduce a new mechanism to iterate over object properties
The old advanceIterator schema was extremely ugly and in addition
not flexible enough to support the requirements for Proxy.ownKeys
and some of the methods in Object
Implemented a new scheme through a OwnPropertyKeys method in the
Object VTable that creates and returns an iterator object. Ported
QJSValueIterator and for-in to use the new mechanism.
There's still many places where we use the old ObjectIterator (that
relies on advanceIterator). Those will be ported in subsequent
commits.
Change-Id: I091a9bea9ff6b2b63630cc336814700757a718be
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4stringobject.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4stringobject.cpp | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index f2d0d52013..12fed62bcc 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -137,24 +137,58 @@ void StringObject::virtualAdvanceIterator(Managed *m, ObjectIterator *it, Value return Object::virtualAdvanceIterator(m, it, name, index, p, attrs); } + +struct StringObjectOwnPropertyKeyIterator : ObjectOwnPropertyKeyIterator +{ + ~StringObjectOwnPropertyKeyIterator() override = default; + PropertyKey next(const Object *o, Property *pd = nullptr, PropertyAttributes *attrs = nullptr) override; + +}; + +PropertyKey StringObjectOwnPropertyKeyIterator::next(const Object *o, Property *pd, PropertyAttributes *attrs) +{ + const StringObject *s = static_cast<const StringObject *>(o); + uint slen = s->d()->string->toQString().length(); + if (arrayIndex < slen) { + uint index = arrayIndex; + ++arrayIndex; + if (attrs) + *attrs = Attr_NotConfigurable|Attr_NotWritable; + if (pd) + pd->value = s->getIndex(index); + return PropertyKey::fromArrayIndex(index); + } else if (arrayIndex == slen) { + if (s->arrayData()) { + arrayNode = s->sparseBegin(); + // iterate until we're past the end of the string + while (arrayNode && arrayNode->key() < slen) + arrayNode = arrayNode->nextNode(); + } + } + + return ObjectOwnPropertyKeyIterator::next(o, pd, attrs); +} + +OwnPropertyKeyIterator *StringObject::virtualOwnPropertyKeys(const Object *) +{ + return new StringObjectOwnPropertyKeyIterator; +} + PropertyAttributes StringObject::virtualGetOwnProperty(Managed *m, PropertyKey id, Property *p) { PropertyAttributes attributes = Object::virtualGetOwnProperty(m, id, p); if (attributes != Attr_Invalid) return attributes; - Object *o = static_cast<Object *>(m); - if (id.isArrayIndex()) { - uint index = id.asArrayIndex(); - if (o->isStringObject()) { - if (index >= static_cast<const StringObject *>(m)->length()) - return Attr_Invalid; - if (p) - p->value = static_cast<StringObject *>(o)->getIndex(index); - return Attr_NotConfigurable|Attr_NotWritable; - } + StringObject *s = static_cast<StringObject *>(m); + uint slen = s->d()->string->toQString().length(); + uint index = id.asArrayIndex(); + if (index < slen) { + if (p) + p->value = static_cast<StringObject *>(s)->getIndex(index); + return Attr_NotConfigurable|Attr_NotWritable; } - return Attr_Invalid; + return Object::virtualGetOwnProperty(m, id, p); } DEFINE_OBJECT_VTABLE(StringCtor); |