aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorTarja Sundqvist <[email protected]>2024-11-08 15:36:12 +0200
committerTarja Sundqvist <[email protected]>2024-11-08 15:36:12 +0200
commitabe4729ea8db32124c36dc33fc32eb629df03043 (patch)
tree6c02a1174b4abbcec9a127758b2c406975661312 /src/qml/jsruntime
parent7c32569ad27b743b6cb50e2bcb67c9ca1674f238 (diff)
parent7550f26e156b3bca5f4b6a9711352c2aa0ba8463 (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.cpp18
-rw-r--r--src/qml/jsruntime/qv4identifier.cpp4
-rw-r--r--src/qml/jsruntime/qv4identifiertable.cpp24
-rw-r--r--src/qml/jsruntime/qv4identifiertable_p.h5
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp12
-rw-r--r--src/qml/jsruntime/qv4internalclass_p.h2
-rw-r--r--src/qml/jsruntime/qv4module.cpp9
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp28
-rw-r--r--src/qml/jsruntime/qv4string_p.h22
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) {