diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-06-17 22:27:04 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-06-25 07:36:30 +0000 |
commit | 53bbda2dfeac39f6f28e507ea9a92965076b65e6 (patch) | |
tree | 7886b3f809dfbee9d16878ccc34f1d07a7f83646 /src | |
parent | 6f98978ef1a79da65dba8c5cf2c1d3d434c13690 (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.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 47 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object_p.h | 8 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4objectproto.cpp | 12 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 2 |
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); } |