diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-06-17 22:06:45 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-06-25 07:36:22 +0000 |
commit | 3e1bb90da4c44455c8c307e01876cc2127bdb15c (patch) | |
tree | 6b9278e2612fe71ce84273857babf8494b8d91bc /src/qml/jsruntime/qv4object.cpp | |
parent | f5a7953df3cb61edc6cc30175ea4f7f1c97deae6 (diff) |
Implement a virtual interface for getOwnProperty
This is required to support Proxy properly, and at the
same time fixes a couple of test failures.
The new interface also replaces the old query and
queryIndexed virtual interfaces, as those where doing
a subset of what getOwnProperty does.
Change-Id: I750e366b475ce971d6d9edf35fa17b7a2b07f771
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4object.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 146 |
1 files changed, 39 insertions, 107 deletions
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 516e9b3c65..50ffd6fae0 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -278,50 +278,6 @@ void Object::insertMember(StringOrSymbol *s, const Property *p, PropertyAttribut } } -// Section 8.12.1 -void Object::getOwnProperty(StringOrSymbol *name, PropertyAttributes *attrs, Property *p) -{ - uint idx = name->asArrayIndex(); - if (idx != UINT_MAX) - return getOwnProperty(idx, attrs, p); - - name->makeIdentifier(); - Identifier id = name->identifier(); - - uint member = internalClass()->find(id); - if (member < UINT_MAX) { - *attrs = internalClass()->propertyData[member]; - if (p) { - p->value = *propertyData(member); - if (attrs->isAccessor()) - p->set = *propertyData(member + SetterOffset); - } - return; - } - - if (attrs) - *attrs = Attr_Invalid; - return; -} - -void Object::getOwnProperty(uint index, PropertyAttributes *attrs, Property *p) -{ - if (arrayData()) { - if (arrayData()->getProperty(index, p, attrs)) - return; - } - if (isStringObject()) { - *attrs = Attr_NotConfigurable|Attr_NotWritable; - if (p) - p->value = static_cast<StringObject *>(this)->getIndex(index); - return; - } - - if (attrs) - *attrs = Attr_Invalid; - return; -} - // Section 8.12.2 PropertyIndex Object::getValueOrSetter(StringOrSymbol *name, PropertyAttributes *attrs) { @@ -378,7 +334,7 @@ bool Object::hasProperty(StringOrSymbol *name) const Scope scope(engine()); ScopedObject o(scope, d()); while (o) { - if (o->hasOwnProperty(name)) + if (o->getOwnProperty(name->toPropertyKey()) != Attr_Invalid) return true; o = o->prototype(); @@ -392,8 +348,8 @@ bool Object::hasProperty(uint index) const Scope scope(engine()); ScopedObject o(scope, d()); while (o) { - if (o->hasOwnProperty(index)) - return true; + if (o->getOwnProperty(Identifier::fromArrayIndex(index)) != Attr_Invalid) + return true; o = o->prototype(); } @@ -401,36 +357,6 @@ bool Object::hasProperty(uint index) const return false; } -bool Object::hasOwnProperty(StringOrSymbol *name) const -{ - uint idx = name->asArrayIndex(); - if (idx != UINT_MAX) - return hasOwnProperty(idx); - - name->makeIdentifier(); - Identifier id = name->identifier(); - - if (internalClass()->find(id) < UINT_MAX) - return true; - if (!query(name).isEmpty()) - return true; - return false; -} - -bool Object::hasOwnProperty(uint index) const -{ - if (arrayData() && !arrayData()->isEmpty(index)) - return true; - - if (isStringObject()) { - if (index < static_cast<const StringObject *>(this)->length()) - return true; - } - if (!queryIndexed(index).isEmpty()) - return true; - return false; -} - ReturnedValue Object::callAsConstructor(const FunctionObject *f, const Value *, int) { return f->engine()->throwTypeError(); @@ -461,36 +387,6 @@ bool Object::putIndexed(Managed *m, uint index, const Value &value) return static_cast<Object *>(m)->internalPutIndexed(index, value); } -PropertyAttributes Object::query(const Managed *m, StringOrSymbol *name) -{ - uint idx = name->asArrayIndex(); - if (idx != UINT_MAX) - return queryIndexed(m, idx); - - name->makeIdentifier(); - Identifier id = name->identifier(); - - const Object *o = static_cast<const Object *>(m); - idx = o->internalClass()->find(id); - if (idx < UINT_MAX) - return o->internalClass()->propertyData[idx]; - - return Attr_Invalid; -} - -PropertyAttributes Object::queryIndexed(const Managed *m, uint index) -{ - const Object *o = static_cast<const Object *>(m); - if (o->arrayData() && !o->arrayData()->isEmpty(index)) - return o->arrayData()->attributes(index); - - if (o->isStringObject()) { - if (index < static_cast<const StringObject *>(o)->length()) - return (Attr_NotWritable|Attr_NotConfigurable); - } - return Attr_Invalid; -} - bool Object::deleteProperty(Managed *m, StringOrSymbol *name) { return static_cast<Object *>(m)->internalDeleteProperty(name); @@ -1105,6 +1001,42 @@ ReturnedValue Object::instanceOf(const Object *typeObject, const Value &var) return Encode(false); } +PropertyAttributes Object::getOwnProperty(Managed *m, Identifier id, Property *p) +{ + PropertyAttributes attrs; + Object *o = static_cast<Object *>(m); + if (id.isArrayIndex()) { + uint index = id.asArrayIndex(); + if (o->arrayData()) { + if (o->arrayData()->getProperty(index, p, &attrs)) + return attrs; + } + if (o->isStringObject()) { + if (index >= static_cast<const StringObject *>(m)->length()) + return Attr_Invalid; + attrs = Attr_NotConfigurable|Attr_NotWritable; + if (p) + p->value = static_cast<StringObject *>(o)->getIndex(index); + return attrs; + } + } else { + Q_ASSERT(id.asHeapObject()); + + uint member = o->internalClass()->find(id); + if (member < UINT_MAX) { + attrs = o->internalClass()->propertyData[member]; + if (p) { + p->value = *o->propertyData(member); + if (attrs.isAccessor()) + p->set = *o->propertyData(member + SetterOffset); + } + return attrs; + } + } + + return Attr_Invalid; +} + bool Object::setArrayLength(uint newLen) { Q_ASSERT(isArrayObject()); |