From 53adb5bbc659f4ae78427b0b1925bf9732d8a6e5 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Tue, 19 Jun 2018 21:29:01 +0200 Subject: Unify deleteProperty and deleteIndexedProperty vtable methods Change-Id: I25245818c6ff2104642594476cb9684bac824f29 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4argumentsobject.cpp | 4 ++-- src/qml/jsruntime/qv4argumentsobject_p.h | 2 +- src/qml/jsruntime/qv4arrayobject.cpp | 20 ++++++++-------- src/qml/jsruntime/qv4context.cpp | 2 +- src/qml/jsruntime/qv4identifier.cpp | 7 ++++++ src/qml/jsruntime/qv4identifier_p.h | 1 + src/qml/jsruntime/qv4object.cpp | 40 +++++++++++--------------------- src/qml/jsruntime/qv4object_p.h | 16 ++++--------- src/qml/jsruntime/qv4proxy.cpp | 15 ++++-------- src/qml/jsruntime/qv4proxy_p.h | 3 +-- src/qml/jsruntime/qv4runtime.cpp | 7 +++--- src/qml/jsruntime/qv4sequenceobject.cpp | 10 ++++++-- src/qml/jsruntime/qv4stringobject.cpp | 18 +++++++------- src/qml/jsruntime/qv4stringobject_p.h | 2 +- 14 files changed, 68 insertions(+), 79 deletions(-) (limited to 'src/qml/jsruntime') diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp index 3fa680bfef..907d2ebfc8 100644 --- a/src/qml/jsruntime/qv4argumentsobject.cpp +++ b/src/qml/jsruntime/qv4argumentsobject.cpp @@ -194,12 +194,12 @@ bool ArgumentsObject::putIndexed(Managed *m, uint index, const Value &value) return true; } -bool ArgumentsObject::deleteIndexedProperty(Managed *m, uint index) +bool ArgumentsObject::deleteProperty(Managed *m, Identifier id) { ArgumentsObject *args = static_cast(m); if (!args->fullyCreated()) args->fullyCreate(); - return Object::deleteIndexedProperty(m, index); + return Object::deleteProperty(m, id); } PropertyAttributes ArgumentsObject::getOwnProperty(Managed *m, Identifier id, Property *p) diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h index 2518b4642a..79175b8767 100644 --- a/src/qml/jsruntime/qv4argumentsobject_p.h +++ b/src/qml/jsruntime/qv4argumentsobject_p.h @@ -149,7 +149,7 @@ struct ArgumentsObject: Object { bool defineOwnProperty(ExecutionEngine *engine, uint index, const Property *desc, PropertyAttributes attrs); static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty); static bool putIndexed(Managed *m, uint index, const Value &value); - static bool deleteIndexedProperty(Managed *m, uint index); + static bool deleteProperty(Managed *m, Identifier id); static PropertyAttributes getOwnProperty(Managed *m, Identifier id, Property *p); static qint64 getLength(const Managed *m); diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index a82628e249..481dfd22c6 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -450,7 +450,7 @@ ReturnedValue ArrayPrototype::method_copyWithin(const FunctionObject *b, const V instance->setIndexed(to, fromVal, QV4::Object::DoThrowOnRejection); CHECK_EXCEPTION(); } else { - bool didDelete = instance->deleteIndexedProperty(to); + bool didDelete = instance->deleteProperty(Identifier::fromArrayIndex(to)); CHECK_EXCEPTION(); if (!didDelete) { return scope.engine->throwTypeError(); @@ -624,7 +624,7 @@ ReturnedValue ArrayPrototype::method_pop(const FunctionObject *b, const Value *t ScopedValue result(scope, instance->getIndexed(len - 1)); CHECK_EXCEPTION(); - if (!instance->deleteIndexedProperty(len - 1)) + if (!instance->deleteProperty(Identifier::fromArrayIndex(len - 1))) return scope.engine->throwTypeError(); if (instance->isArrayObject()) @@ -715,12 +715,12 @@ ReturnedValue ArrayPrototype::method_reverse(const FunctionObject *b, const Valu if (hiExists) ok = instance->putIndexed(lo, hval); else - ok = instance->deleteIndexedProperty(lo); + ok = instance->deleteProperty(Identifier::fromArrayIndex(lo)); if (ok) { if (loExists) ok = instance->putIndexed(hi, lval); else - ok = instance->deleteIndexedProperty(hi); + ok = instance->deleteProperty(Identifier::fromArrayIndex(hi)); } if (!ok) return scope.engine->throwTypeError(); @@ -763,11 +763,11 @@ ReturnedValue ArrayPrototype::method_shift(const FunctionObject *b, const Value if (exists) ok = instance->putIndexed(k - 1, v); else - ok = instance->deleteIndexedProperty(k - 1); + ok = instance->deleteProperty(Identifier::fromArrayIndex(k - 1)); if (!ok) return scope.engine->throwTypeError(); } - bool ok = instance->deleteIndexedProperty(len - 1); + bool ok = instance->deleteProperty(Identifier::fromArrayIndex(len - 1)); if (!ok) return scope.engine->throwTypeError(); } @@ -891,12 +891,12 @@ ReturnedValue ArrayPrototype::method_splice(const FunctionObject *b, const Value if (exists) ok = instance->putIndexed(k + itemCount, v); else - ok = instance->deleteIndexedProperty(k + itemCount); + ok = instance->deleteProperty(Identifier::fromArrayIndex(k + itemCount)); if (!ok) return scope.engine->throwTypeError(); } for (uint k = len; k > len - deleteCount + itemCount; --k) { - if (!instance->deleteIndexedProperty(k - 1)) + if (!instance->deleteProperty(Identifier::fromArrayIndex(k - 1))) return scope.engine->throwTypeError(); } } else if (itemCount > deleteCount) { @@ -909,7 +909,7 @@ ReturnedValue ArrayPrototype::method_splice(const FunctionObject *b, const Value if (exists) ok = instance->putIndexed(k + itemCount - 1, v); else - ok = instance->deleteIndexedProperty(k + itemCount - 1); + ok = instance->deleteProperty(Identifier::fromArrayIndex(k + itemCount - 1)); if (!ok) return scope.engine->throwTypeError(); --k; @@ -949,7 +949,7 @@ ReturnedValue ArrayPrototype::method_unshift(const FunctionObject *b, const Valu if (exists) ok = instance->putIndexed(k + argc - 1, v); else - ok = instance->deleteIndexedProperty(k + argc - 1); + ok = instance->deleteProperty(Identifier::fromArrayIndex(k + argc - 1)); if (!ok) return scope.engine->throwTypeError(); } diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 03a56cb173..ebe0ce53ea 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -210,7 +210,7 @@ bool ExecutionContext::deleteProperty(String *name) Scope scope(this); ScopedObject object(scope, ctx->activation); if (object && object->hasProperty(name->toPropertyKey())) - return object->deleteProperty(name); + return object->deleteProperty(name->toPropertyKey()); } break; } diff --git a/src/qml/jsruntime/qv4identifier.cpp b/src/qml/jsruntime/qv4identifier.cpp index 08e480e8c2..7efd980139 100644 --- a/src/qml/jsruntime/qv4identifier.cpp +++ b/src/qml/jsruntime/qv4identifier.cpp @@ -54,6 +54,13 @@ bool Identifier::isSymbol() const return isValid() && !asHeapObject()->internalClass->vtable->isString && asHeapObject()->internalClass->vtable->isStringOrSymbol; } +Heap::StringOrSymbol *Identifier::toStringOrSymbol(ExecutionEngine *e) +{ + if (isArrayIndex()) + return Primitive::fromUInt32(asArrayIndex()).toString(e); + return static_cast(asHeapObject()); +} + QString Identifier::toQString() const { if (isArrayIndex()) diff --git a/src/qml/jsruntime/qv4identifier_p.h b/src/qml/jsruntime/qv4identifier_p.h index fd4ff75974..58eddcc4bb 100644 --- a/src/qml/jsruntime/qv4identifier_p.h +++ b/src/qml/jsruntime/qv4identifier_p.h @@ -77,6 +77,7 @@ struct Identifier bool isSymbol() const; Q_QML_EXPORT QString toQString() const; + Heap::StringOrSymbol *toStringOrSymbol(ExecutionEngine *e); bool operator ==(const Identifier &other) const { return id == other.id; } bool operator !=(const Identifier &other) const { return id != other.id; } diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index ba6d8f9c77..e09022b60f 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -344,14 +344,9 @@ bool Object::putIndexed(Managed *m, uint index, const Value &value) return static_cast(m)->internalPutIndexed(index, value); } -bool Object::deleteProperty(Managed *m, StringOrSymbol *name) +bool Object::deleteProperty(Managed *m, Identifier id) { - return static_cast(m)->internalDeleteProperty(name); -} - -bool Object::deleteIndexedProperty(Managed *m, uint index) -{ - return static_cast(m)->internalDeleteIndexedProperty(index); + return static_cast(m)->internalDeleteProperty(id); } void Object::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *pd, PropertyAttributes *attrs) @@ -636,17 +631,23 @@ bool Object::internalPutIndexed(uint index, const Value &value) } // Section 8.12.7 -bool Object::internalDeleteProperty(StringOrSymbol *name) +bool Object::internalDeleteProperty(Identifier id) { if (internalClass()->engine->hasException) return false; - uint idx = name->asArrayIndex(); - if (idx != UINT_MAX) - return deleteIndexedProperty(idx); + if (id.isArrayIndex()) { + uint index = id.asArrayIndex(); + Scope scope(engine()); + if (scope.engine->hasException) + return false; - name->makeIdentifier(); - Identifier id = name->identifier(); + Scoped ad(scope, arrayData()); + if (!ad || ad->vtable()->del(this, index)) + return true; + + return false; + } uint memberIdx = internalClass()->find(id); if (memberIdx != UINT_MAX) { @@ -660,19 +661,6 @@ bool Object::internalDeleteProperty(StringOrSymbol *name) return true; } -bool Object::internalDeleteIndexedProperty(uint index) -{ - Scope scope(engine()); - if (scope.engine->hasException) - return false; - - Scoped ad(scope, arrayData()); - if (!ad || ad->vtable()->del(this, index)) - return true; - - return false; -} - // Section 8.12.9 bool Object::__defineOwnProperty__(ExecutionEngine *engine, StringOrSymbol *name, const Property *p, PropertyAttributes attrs) { diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 6ec7452ca6..07866b4e16 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -173,8 +173,7 @@ struct ObjectVTable ReturnedValue (*getIndexed)(const Managed *, uint index, bool *hasProperty); bool (*put)(Managed *, StringOrSymbol *name, const Value &value); bool (*putIndexed)(Managed *, uint index, const Value &value); - bool (*deleteProperty)(Managed *m, StringOrSymbol *name); - bool (*deleteIndexedProperty)(Managed *m, uint index); + bool (*deleteProperty)(Managed *m, Identifier id); bool (*hasProperty)(const Managed *m, Identifier id); PropertyAttributes (*getOwnProperty)(Managed *m, Identifier id, Property *p); bool (*isExtensible)(const Managed *); @@ -197,7 +196,6 @@ const QV4::ObjectVTable classname::static_vtbl = \ put, \ putIndexed, \ deleteProperty, \ - deleteIndexedProperty, \ hasProperty, \ getOwnProperty, \ isExtensible, \ @@ -427,10 +425,8 @@ public: return ret; } - bool deleteProperty(StringOrSymbol *name) - { return vtable()->deleteProperty(this, name); } - bool deleteIndexedProperty(uint index) - { return vtable()->deleteIndexedProperty(this, index); } + bool deleteProperty(Identifier id) + { return vtable()->deleteProperty(this, id); } void advanceIterator(ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes) { vtable()->advanceIterator(this, it, name, index, p, attributes); } qint64 getLength() const { return vtable()->getLength(this); } @@ -444,8 +440,7 @@ protected: static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty); static bool put(Managed *m, StringOrSymbol *name, const Value &value); 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 deleteProperty(Managed *m, Identifier id); static bool hasProperty(const Managed *m, Identifier id); static PropertyAttributes getOwnProperty(Managed *m, Identifier id, Property *p); static bool isExtensible(const Managed *m); @@ -461,8 +456,7 @@ private: ReturnedValue internalGetIndexed(uint index, bool *hasProperty) const; bool internalPut(StringOrSymbol *name, const Value &value); bool internalPutIndexed(uint index, const Value &value); - bool internalDeleteProperty(StringOrSymbol *name); - bool internalDeleteIndexedProperty(uint index); + bool internalDeleteProperty(Identifier id); friend struct ObjectIterator; friend struct ObjectPrototype; diff --git a/src/qml/jsruntime/qv4proxy.cpp b/src/qml/jsruntime/qv4proxy.cpp index 1e0c452430..06ed889c60 100644 --- a/src/qml/jsruntime/qv4proxy.cpp +++ b/src/qml/jsruntime/qv4proxy.cpp @@ -150,7 +150,7 @@ bool ProxyObject::putIndexed(Managed *m, uint index, const Value &value) return put(m, name, value); } -bool ProxyObject::deleteProperty(Managed *m, StringOrSymbol *name) +bool ProxyObject::deleteProperty(Managed *m, Identifier id) { Scope scope(m); const ProxyObject *o = static_cast(m); @@ -165,20 +165,20 @@ bool ProxyObject::deleteProperty(Managed *m, StringOrSymbol *name) if (scope.hasException()) return Encode::undefined(); if (trap->isNullOrUndefined()) - return target->deleteProperty(name); + return target->deleteProperty(id); if (!trap->isFunctionObject()) return scope.engine->throwTypeError(); JSCallData cdata(scope, 3, nullptr, handler); cdata.args[0] = target; - cdata.args[1] = name; + cdata.args[1] = id.toStringOrSymbol(scope.engine); cdata.args[2] = o->d(); // ### fix receiver handling ScopedValue trapResult(scope, static_cast(trap.ptr)->call(cdata)); if (!trapResult->toBoolean()) return false; ScopedProperty targetDesc(scope); - PropertyAttributes attributes = target->getOwnProperty(name->toPropertyKey(), targetDesc); + PropertyAttributes attributes = target->getOwnProperty(id, targetDesc); if (attributes == Attr_Invalid) return true; if (!attributes.isConfigurable()) @@ -186,13 +186,6 @@ bool ProxyObject::deleteProperty(Managed *m, StringOrSymbol *name) return true; } -bool ProxyObject::deleteIndexedProperty(Managed *m, uint index) -{ - Scope scope(m); - ScopedString name(scope, Primitive::fromUInt32(index).toString(scope.engine)); - return deleteProperty(m, name); -} - bool ProxyObject::hasProperty(const Managed *m, Identifier id) { Scope scope(m); diff --git a/src/qml/jsruntime/qv4proxy_p.h b/src/qml/jsruntime/qv4proxy_p.h index cbabc7e5d9..c249b9671c 100644 --- a/src/qml/jsruntime/qv4proxy_p.h +++ b/src/qml/jsruntime/qv4proxy_p.h @@ -89,8 +89,7 @@ struct ProxyObject: Object { static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty); static bool put(Managed *m, StringOrSymbol *name, const Value &value); 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 deleteProperty(Managed *m, Identifier id); static bool hasProperty(const Managed *m, Identifier id); static PropertyAttributes getOwnProperty(Managed *m, Identifier id, Property *p); static bool isExtensible(const Managed *m); diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index a5249fcc7e..04aff9cad0 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -331,12 +331,13 @@ bool Runtime::method_deleteProperty(ExecutionEngine *engine, const Value &base, uint n = index.asArrayIndex(); if (n < UINT_MAX) - return o->deleteIndexedProperty(n); + return o->deleteProperty(Identifier::fromArrayIndex(n)); - ScopedStringOrSymbol name(scope, index.toPropertyKey(engine)); + Scoped key(scope, index.toPropertyKey(engine)); if (engine->hasException) return false; - return o->deleteProperty(name); + Identifier id = key->toPropertyKey(); + return o->deleteProperty(id); } bool Runtime::method_deleteName(ExecutionEngine *engine, int nameIndex) diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index f0aa39b786..f6f8e51e19 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -569,8 +569,14 @@ public: { return static_cast *>(that)->containerPutIndexed(index, value); } static QV4::PropertyAttributes queryIndexed(const QV4::Managed *that, uint index) { return static_cast *>(that)->containerQueryIndexed(index); } - static bool deleteIndexedProperty(QV4::Managed *that, uint index) - { return static_cast *>(that)->containerDeleteIndexedProperty(index); } + static bool deleteProperty(QV4::Managed *that, Identifier id) + { + if (id.isArrayIndex()) { + uint index = id.asArrayIndex(); + return static_cast *>(that)->containerDeleteIndexedProperty(index); + } + return Object::deleteProperty(that, id); + } static bool isEqualTo(Managed *that, Managed *other) { return static_cast *>(that)->containerIsEqualTo(other); } static void advanceIterator(Managed *that, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attrs) diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index b9e04db28f..b21506b11e 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -97,16 +97,16 @@ uint Heap::StringObject::length() const return string->length(); } -bool StringObject::deleteIndexedProperty(Managed *m, uint index) +bool StringObject::deleteProperty(Managed *m, Identifier id) { - ExecutionEngine *v4 = static_cast(m)->engine(); - Scope scope(v4); - Scoped o(scope, m->as()); - Q_ASSERT(!!o); - - if (index < static_cast(o->d()->string->toQString().length())) - return false; - return true; + Q_ASSERT(m->as()); + if (id.isArrayIndex()) { + StringObject *o = static_cast(m); + uint index = id.asArrayIndex(); + if (index < static_cast(o->d()->string->toQString().length())) + return false; + } + return Object::deleteProperty(m, id); } void StringObject::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attrs) diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h index b9e09ecff0..af53be0ada 100644 --- a/src/qml/jsruntime/qv4stringobject_p.h +++ b/src/qml/jsruntime/qv4stringobject_p.h @@ -100,7 +100,7 @@ struct StringObject: Object { using Object::getOwnProperty; protected: - static bool deleteIndexedProperty(Managed *m, uint index); + static bool deleteProperty(Managed *m, Identifier id); static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attrs); static PropertyAttributes getOwnProperty(Managed *m, Identifier id, Property *p); }; -- cgit v1.2.3