diff options
author | Tarja Sundqvist <[email protected]> | 2024-11-08 15:36:12 +0200 |
---|---|---|
committer | Tarja Sundqvist <[email protected]> | 2024-11-08 15:36:12 +0200 |
commit | abe4729ea8db32124c36dc33fc32eb629df03043 (patch) | |
tree | 6c02a1174b4abbcec9a127758b2c406975661312 /src/qml/jsruntime | |
parent | 7c32569ad27b743b6cb50e2bcb67c9ca1674f238 (diff) | |
parent | 7550f26e156b3bca5f4b6a9711352c2aa0ba8463 (diff) |
Merge tag 'v5.15.16-lts' into tqtc/lts-5.15-opensourcev5.15.16-lts-lgpl5.15
Qt 5.15.16-lts release
Change-Id: I2892ad4097deaec565b10357ca61be10048a7c81
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r-- | src/qml/jsruntime/qv4context.cpp | 18 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4identifier.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4identifiertable.cpp | 24 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4identifiertable_p.h | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4internalclass.cpp | 12 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4internalclass_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4module.cpp | 9 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4sequenceobject.cpp | 28 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4string_p.h | 22 |
9 files changed, 94 insertions, 30 deletions
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp index 018571e325..c547c0692d 100644 --- a/src/qml/jsruntime/qv4context.cpp +++ b/src/qml/jsruntime/qv4context.cpp @@ -334,9 +334,14 @@ ReturnedValue ExecutionContext::getProperty(String *name) case Heap::ExecutionContext::Type_CallContext: { Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx); - uint index = c->internalClass->indexOfValueOrGetter(id); - if (index < UINT_MAX) + const uint index = c->internalClass->indexOfValueOrGetter(id); + if (index < c->locals.alloc) return c->locals[index].asReturnedValue(); + + // TODO: We should look up the module imports here, but those are part of the CU: + // imports[index - c->locals.size]; + // See QTBUG-118478 + Q_FALLTHROUGH(); } case Heap::ExecutionContext::Type_WithContext: @@ -384,9 +389,14 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base) case Heap::ExecutionContext::Type_CallContext: { Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx); - uint index = c->internalClass->indexOfValueOrGetter(id); - if (index < UINT_MAX) + const uint index = c->internalClass->indexOfValueOrGetter(id); + if (index < c->locals.alloc) return c->locals[index].asReturnedValue(); + + // TODO: We should look up the module imports here, but those are part of the CU: + // imports[index - c->locals.size]; + // See QTBUG-118478 + Q_FALLTHROUGH(); } case Heap::ExecutionContext::Type_GlobalContext: { diff --git a/src/qml/jsruntime/qv4identifier.cpp b/src/qml/jsruntime/qv4identifier.cpp index c3d7165f71..266ed17c18 100644 --- a/src/qml/jsruntime/qv4identifier.cpp +++ b/src/qml/jsruntime/qv4identifier.cpp @@ -152,7 +152,7 @@ const IdentifierHashEntry *IdentifierHash::lookup(const QString &str) const if (!d) return nullptr; - PropertyKey id = d->identifierTable->asPropertyKey(str); + PropertyKey id = d->identifierTable->asPropertyKey(str, IdentifierTable::ForceConversionToId); return lookup(id); } @@ -169,7 +169,7 @@ const IdentifierHashEntry *IdentifierHash::lookup(String *str) const const PropertyKey IdentifierHash::toIdentifier(const QString &str) const { Q_ASSERT(d); - return d->identifierTable->asPropertyKey(str); + return d->identifierTable->asPropertyKey(str, IdentifierTable::ForceConversionToId); } const PropertyKey IdentifierHash::toIdentifier(Heap::String *str) const diff --git a/src/qml/jsruntime/qv4identifiertable.cpp b/src/qml/jsruntime/qv4identifiertable.cpp index 21b47c3909..ad6b39e0b1 100644 --- a/src/qml/jsruntime/qv4identifiertable.cpp +++ b/src/qml/jsruntime/qv4identifiertable.cpp @@ -132,16 +132,23 @@ void IdentifierTable::addEntry(Heap::StringOrSymbol *str) -Heap::String *IdentifierTable::insertString(const QString &s) +Heap::String *IdentifierTable::insertString( + const QString &s, IdentifierTable::KeyConversionBehavior conversionBehavior) { uint subtype; - uint hash = String::createHashValue(s.constData(), s.length(), &subtype); + + uint hash = String::createHashValue(s.constData(), s.size(), &subtype); if (subtype == Heap::String::StringType_ArrayIndex) { - Heap::String *str = engine->newString(s); - str->stringHash = hash; - str->subtype = subtype; - return str; + if (Q_UNLIKELY(conversionBehavior == ForceConversionToId)) { + hash = String::createHashValueDisallowingArrayIndex(s.constData(), s.size(), &subtype); + } else { + Heap::String *str = engine->newString(s); + str->stringHash = hash; + str->subtype = subtype; + return str; + } } + uint idx = hash % alloc; while (Heap::StringOrSymbol *e = entriesByHash[idx]) { if (e->stringHash == hash && e->toQString() == s) @@ -278,9 +285,10 @@ void IdentifierTable::sweep() size -= freed; } -PropertyKey IdentifierTable::asPropertyKey(const QString &s) +PropertyKey IdentifierTable::asPropertyKey( + const QString &s, IdentifierTable::KeyConversionBehavior conversionBehavior) { - return insertString(s)->identifier; + return insertString(s, conversionBehavior)->identifier; } PropertyKey IdentifierTable::asPropertyKey(const char *s, int len) diff --git a/src/qml/jsruntime/qv4identifiertable_p.h b/src/qml/jsruntime/qv4identifiertable_p.h index 78e2b6620e..1dda65f2ed 100644 --- a/src/qml/jsruntime/qv4identifiertable_p.h +++ b/src/qml/jsruntime/qv4identifiertable_p.h @@ -75,11 +75,12 @@ struct Q_QML_PRIVATE_EXPORT IdentifierTable void addEntry(Heap::StringOrSymbol *str); public: + enum KeyConversionBehavior { Default, ForceConversionToId }; IdentifierTable(ExecutionEngine *engine, int numBits = 8); ~IdentifierTable(); - Heap::String *insertString(const QString &s); + Heap::String *insertString(const QString &s, KeyConversionBehavior conversionBehavior); Heap::Symbol *insertSymbol(const QString &s); PropertyKey asPropertyKey(const Heap::String *str) { @@ -91,7 +92,7 @@ public: return asPropertyKey(str->d()); } - PropertyKey asPropertyKey(const QString &s); + PropertyKey asPropertyKey(const QString &s, KeyConversionBehavior conversionBehavior = Default); PropertyKey asPropertyKey(const char *s, int len); PropertyKey asPropertyKeyImpl(const Heap::String *str); diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp index 904c6a5eaf..d6211bab1a 100644 --- a/src/qml/jsruntime/qv4internalclass.cpp +++ b/src/qml/jsruntime/qv4internalclass.cpp @@ -329,9 +329,15 @@ void InternalClass::destroy() Base::destroy(); } -QString InternalClass::keyAt(uint index) const -{ - return nameMap.at(index).toQString(); +ReturnedValue InternalClass::keyAt(uint index) const +{ + PropertyKey key = nameMap.at(index); + if (!key.isValid()) + return Encode::undefined(); + if (key.isArrayIndex()) + return Encode(key.asArrayIndex()); + Q_ASSERT(key.isStringOrSymbol()); + return key.asStringOrSymbol()->asReturnedValue(); } void InternalClass::changeMember(QV4::Object *object, PropertyKey id, PropertyAttributes data, InternalClassEntry *entry) diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h index a5a1471cf1..5fe97e8029 100644 --- a/src/qml/jsruntime/qv4internalclass_p.h +++ b/src/qml/jsruntime/qv4internalclass_p.h @@ -344,7 +344,7 @@ struct InternalClass : Base { void init(InternalClass *other); void destroy(); - Q_QML_PRIVATE_EXPORT QString keyAt(uint index) const; + Q_QML_PRIVATE_EXPORT ReturnedValue keyAt(uint index) const; Q_REQUIRED_RESULT InternalClass *nonExtensible(); static void addMember(QV4::Object *object, PropertyKey id, PropertyAttributes data, InternalClassEntry *entry); diff --git a/src/qml/jsruntime/qv4module.cpp b/src/qml/jsruntime/qv4module.cpp index 08a1900383..8f148994e3 100644 --- a/src/qml/jsruntime/qv4module.cpp +++ b/src/qml/jsruntime/qv4module.cpp @@ -258,9 +258,12 @@ OwnPropertyKeyIterator *Module::virtualOwnPropertyKeys(const Object *o, Value *t if (module->d()->unit->isESModule()) { names = module->d()->unit->exportedNames(); } else { - Heap::InternalClass *scopeClass = module->d()->scope->internalClass; - for (uint i = 0; i < scopeClass->size; ++i) - names << scopeClass->keyAt(i); + QV4::Scope scope(module->engine()); + QV4::Scoped<InternalClass> scopeClass(scope, module->d()->scope->internalClass); + for (uint i = 0, end = scopeClass->d()->size; i < end; ++i) { + QV4::ScopedValue key(scope, scopeClass->d()->keyAt(i)); + names << key->toQString(); + } } return new ModuleNamespaceIterator(names); diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index f84718b48f..04b6cfc921 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -261,7 +261,33 @@ struct QQmlSequence : Object { template <typename Container> struct QQmlSequence : public QV4::Object { - V4_OBJECT2(QQmlSequence<Container>, QV4::Object) + // Unroll V4_OBJECT2(QQmlSequence<Container>, QV4::Object) here. + // Newer C++ versions don't tolerate the template argument in Q_DISABLE_COPY. +private: + QQmlSequence() Q_DECL_EQ_DELETE; + Q_DISABLE_COPY(QQmlSequence) +public: + Q_MANAGED_CHECK + typedef QV4::Heap::QQmlSequence<Container> Data; + typedef QV4::Object SuperClass; + static const QV4::VTable static_vtbl; + static inline const QV4::VTable *staticVTable() { return &static_vtbl; } + V4_MANAGED_SIZE_TEST + + QV4::Heap::QQmlSequence<Container> *d_unchecked() const + { + return static_cast<QV4::Heap::QQmlSequence<Container> *>(m()); + } + + QV4::Heap::QQmlSequence<Container> *d() const + { + QV4::Heap::QQmlSequence<Container> *dptr = d_unchecked(); + dptr->_checkIsInitialized(); + return dptr; + } + + Q_STATIC_ASSERT(std::is_trivial< QV4::Heap::QQmlSequence<Container>>::value); + Q_MANAGED_TYPE(QmlSequence) V4_PROTOTYPE(sequencePrototype) V4_NEEDS_DESTROY diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h index 52fe09cd72..55a0ff4316 100644 --- a/src/qml/jsruntime/qv4string_p.h +++ b/src/qml/jsruntime/qv4string_p.h @@ -222,6 +222,12 @@ struct Q_QML_PRIVATE_EXPORT String : public StringOrSymbol { return calculateHashValue(ch, end, subtype); } + static uint createHashValueDisallowingArrayIndex(const QChar *ch, int length, uint *subtype) + { + const QChar *end = ch + length; + return calculateHashValue<String::DisallowArrayIndex>(ch, end, subtype); + } + static uint createHashValue(const char *ch, int length, uint *subtype) { const char *end = ch + length; @@ -235,15 +241,19 @@ protected: static qint64 virtualGetLength(const Managed *m); public: - template <typename T> + enum IndicesBehavior {Default, DisallowArrayIndex}; + template <IndicesBehavior Behavior = Default, typename T> static inline uint calculateHashValue(const T *ch, const T* end, uint *subtype) { // array indices get their number as hash value - uint h = stringToArrayIndex(ch, end); - if (h != UINT_MAX) { - if (subtype) - *subtype = Heap::StringOrSymbol::StringType_ArrayIndex; - return h; + uint h = UINT_MAX; + if (Behavior != DisallowArrayIndex) { + h = stringToArrayIndex(ch, end); + if (h != UINT_MAX) { + if (subtype) + *subtype = Heap::StringOrSymbol::StringType_ArrayIndex; + return h; + } } while (ch < end) { |