aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4object.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-06-17 22:06:45 +0200
committerLars Knoll <lars.knoll@qt.io>2018-06-25 07:36:22 +0000
commit3e1bb90da4c44455c8c307e01876cc2127bdb15c (patch)
tree6b9278e2612fe71ce84273857babf8494b8d91bc /src/qml/jsruntime/qv4object.cpp
parentf5a7953df3cb61edc6cc30175ea4f7f1c97deae6 (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.cpp146
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());