aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-06-17 22:27:04 +0200
committerLars Knoll <lars.knoll@qt.io>2018-06-25 07:36:30 +0000
commit53bbda2dfeac39f6f28e507ea9a92965076b65e6 (patch)
tree7886b3f809dfbee9d16878ccc34f1d07a7f83646 /src
parent6f98978ef1a79da65dba8c5cf2c1d3d434c13690 (diff)
Add virtual interface for hasProperty
This is required to correctly support Proxy Change-Id: I95ec17e919915290a05ad9501cd649452ab82135 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsapi/qjsvalue.cpp4
-rw-r--r--src/qml/jsruntime/qv4context.cpp4
-rw-r--r--src/qml/jsruntime/qv4object.cpp47
-rw-r--r--src/qml/jsruntime/qv4object_p.h8
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp12
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp2
6 files changed, 32 insertions, 45 deletions
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index 63b10adf2b..aaac4e0a9a 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -1269,8 +1269,8 @@ bool QJSValue::hasProperty(const QString &name) const
if (!o)
return false;
- ScopedString s(scope, engine->newIdentifier(name));
- return o->hasProperty(s);
+ ScopedString s(scope, engine->newString(name));
+ return o->hasProperty(s->toPropertyKey());
}
/*!
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 61657477b0..03a56cb173 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -209,7 +209,7 @@ bool ExecutionContext::deleteProperty(String *name)
if (ctx->activation) {
Scope scope(this);
ScopedObject object(scope, ctx->activation);
- if (object && object->hasProperty(name))
+ if (object && object->hasProperty(name->toPropertyKey()))
return object->deleteProperty(name);
}
break;
@@ -236,7 +236,7 @@ ExecutionContext::Error ExecutionContext::setProperty(String *name, const Value
case Heap::ExecutionContext::Type_WithContext: {
Scope scope(v4);
ScopedObject w(scope, ctx->activation);
- if (w->hasProperty(name)) {
+ if (w->hasProperty(name->toPropertyKey())) {
if (!w->put(name, value))
return TypeError;
return NoError;
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 50ffd6fae0..618970b940 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -325,38 +325,6 @@ PropertyIndex Object::getValueOrSetter(uint index, PropertyAttributes *attrs)
return { nullptr, 0 };
}
-bool Object::hasProperty(StringOrSymbol *name) const
-{
- uint idx = name->asArrayIndex();
- if (idx != UINT_MAX)
- return hasProperty(idx);
-
- Scope scope(engine());
- ScopedObject o(scope, d());
- while (o) {
- if (o->getOwnProperty(name->toPropertyKey()) != Attr_Invalid)
- return true;
-
- o = o->prototype();
- }
-
- return false;
-}
-
-bool Object::hasProperty(uint index) const
-{
- Scope scope(engine());
- ScopedObject o(scope, d());
- while (o) {
- if (o->getOwnProperty(Identifier::fromArrayIndex(index)) != Attr_Invalid)
- return true;
-
- o = o->prototype();
- }
-
- return false;
-}
-
ReturnedValue Object::callAsConstructor(const FunctionObject *f, const Value *, int)
{
return f->engine()->throwTypeError();
@@ -1001,6 +969,21 @@ ReturnedValue Object::instanceOf(const Object *typeObject, const Value &var)
return Encode(false);
}
+bool Object::hasProperty(const Managed *m, Identifier id)
+{
+ Scope scope(m->engine());
+ ScopedObject o(scope, m);
+ ScopedProperty p(scope);
+ while (o) {
+ if (o->getOwnProperty(id, p) != Attr_Invalid)
+ return true;
+
+ o = o->prototype();
+ }
+
+ return false;
+}
+
PropertyAttributes Object::getOwnProperty(Managed *m, Identifier id, Property *p)
{
PropertyAttributes attrs;
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index a08ea851cd..9354ae0571 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -175,6 +175,7 @@ struct ObjectVTable
bool (*putIndexed)(Managed *, uint index, const Value &value);
bool (*deleteProperty)(Managed *m, StringOrSymbol *name);
bool (*deleteIndexedProperty)(Managed *m, uint index);
+ bool (*hasProperty)(const Managed *m, Identifier id);
PropertyAttributes (*getOwnProperty)(Managed *m, Identifier id, Property *p);
qint64 (*getLength)(const Managed *m);
void (*advanceIterator)(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
@@ -193,6 +194,7 @@ const QV4::ObjectVTable classname::static_vtbl = \
putIndexed, \
deleteProperty, \
deleteIndexedProperty, \
+ hasProperty, \
getOwnProperty, \
getLength, \
advanceIterator, \
@@ -248,8 +250,9 @@ struct Q_QML_EXPORT Object: Managed {
PropertyIndex getValueOrSetter(StringOrSymbol *name, PropertyAttributes *attrs);
PropertyIndex getValueOrSetter(uint index, PropertyAttributes *attrs);
- bool hasProperty(StringOrSymbol *name) const;
- bool hasProperty(uint index) const;
+ bool hasProperty(Identifier id) const {
+ return vtable()->hasProperty(this, id);
+ }
bool __defineOwnProperty__(ExecutionEngine *engine, uint index, StringOrSymbol *member, const Property *p, PropertyAttributes attrs);
bool __defineOwnProperty__(ExecutionEngine *engine, StringOrSymbol *name, const Property *p, PropertyAttributes attrs);
@@ -433,6 +436,7 @@ protected:
static bool putIndexed(Managed *m, uint index, const Value &value);
static bool deleteProperty(Managed *m, StringOrSymbol *name);
static bool deleteIndexedProperty(Managed *m, uint index);
+ static bool hasProperty(const Managed *m, Identifier id);
static PropertyAttributes getOwnProperty(Managed *m, Identifier id, Property *p);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
static qint64 getLength(const Managed *m);
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index 8525ad9438..72b2816dd9 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -737,13 +737,13 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionEngine *engine, const Value
desc->set = Primitive::emptyValue();
ScopedValue tmp(scope);
- if (o->hasProperty(engine->id_enumerable()))
+ if (o->hasProperty(engine->id_enumerable()->toPropertyKey()))
attrs->setEnumerable((tmp = o->get(engine->id_enumerable()))->toBoolean());
- if (o->hasProperty(engine->id_configurable()))
+ if (o->hasProperty(engine->id_configurable()->toPropertyKey()))
attrs->setConfigurable((tmp = o->get(engine->id_configurable()))->toBoolean());
- if (o->hasProperty(engine->id_get())) {
+ if (o->hasProperty(engine->id_get()->toPropertyKey())) {
ScopedValue get(scope, o->get(engine->id_get()));
FunctionObject *f = get->as<FunctionObject>();
if (f || get->isUndefined()) {
@@ -755,7 +755,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionEngine *engine, const Value
attrs->setType(PropertyAttributes::Accessor);
}
- if (o->hasProperty(engine->id_set())) {
+ if (o->hasProperty(engine->id_set()->toPropertyKey())) {
ScopedValue set(scope, o->get(engine->id_set()));
FunctionObject *f = set->as<FunctionObject>();
if (f || set->isUndefined()) {
@@ -767,7 +767,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionEngine *engine, const Value
attrs->setType(PropertyAttributes::Accessor);
}
- if (o->hasProperty(engine->id_writable())) {
+ if (o->hasProperty(engine->id_writable()->toPropertyKey())) {
if (attrs->isAccessor()) {
engine->throwTypeError();
return;
@@ -777,7 +777,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionEngine *engine, const Value
desc->value = Primitive::undefinedValue();
}
- if (o->hasProperty(engine->id_value())) {
+ if (o->hasProperty(engine->id_value()->toPropertyKey())) {
if (attrs->isAccessor()) {
engine->throwTypeError();
return;
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 8759a72074..a5249fcc7e 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -374,7 +374,7 @@ QV4::ReturnedValue Runtime::method_in(ExecutionEngine *engine, const Value &left
ScopedStringOrSymbol s(scope, left.toPropertyKey(engine));
if (scope.hasException())
return Encode::undefined();
- bool r = ro->hasProperty(s);
+ bool r = ro->hasProperty(s->toPropertyKey());
return Encode(r);
}