aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsruntime/qv4engine.cpp2
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp13
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp6
-rw-r--r--src/qml/qml/qqmlmetatype.cpp6
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp3
-rw-r--r--src/quick/handlers/qquickmultipointhandler.cpp13
-rw-r--r--src/quick/items/qquickevents.cpp38
7 files changed, 35 insertions, 46 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index b9130aa7f8..f374a092b7 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -175,7 +175,7 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
bool ok = false;
maxCallDepth = qEnvironmentVariableIntValue("QV4_MAX_CALL_DEPTH", &ok);
if (!ok || maxCallDepth <= 0) {
-#ifdef QT_NO_DEBUG
+#if defined(QT_NO_DEBUG) && !defined(__SANITIZE_ADDRESS__)
maxCallDepth = 1234;
#else
// no (tail call) optimization is done, so there'll be a lot mare stack frames active
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index c2c3fa0474..99f425293e 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -242,9 +242,6 @@ ReturnedValue Lookup::getter0Inlinegetter0Inline(Lookup *l, ExecutionEngine *eng
return o->inlinePropertyDataWithOffset(l->objectLookupTwoClasses.offset)->asReturnedValue();
if (l->objectLookupTwoClasses.ic2 == o->internalClass)
return o->inlinePropertyDataWithOffset(l->objectLookupTwoClasses.offset2)->asReturnedValue();
- Value obj = Value::fromHeapObject(o);
- Value str = Value::fromHeapObject(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
- return static_cast<Object &>(obj).get(&static_cast<String &>(str));
}
l->getter = getterFallback;
return getterFallback(l, engine, object);
@@ -260,9 +257,6 @@ ReturnedValue Lookup::getter0Inlinegetter0MemberData(Lookup *l, ExecutionEngine
return o->inlinePropertyDataWithOffset(l->objectLookupTwoClasses.offset)->asReturnedValue();
if (l->objectLookupTwoClasses.ic2 == o->internalClass)
return o->memberData->values.data()[l->objectLookupTwoClasses.offset2].asReturnedValue();
- Value obj = Value::fromHeapObject(o);
- Value str = Value::fromHeapObject(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
- return static_cast<Object &>(obj).get(&static_cast<String &>(str));
}
l->getter = getterFallback;
return getterFallback(l, engine, object);
@@ -278,9 +272,6 @@ ReturnedValue Lookup::getter0MemberDatagetter0MemberData(Lookup *l, ExecutionEng
return o->memberData->values.data()[l->objectLookupTwoClasses.offset].asReturnedValue();
if (l->objectLookupTwoClasses.ic2 == o->internalClass)
return o->memberData->values.data()[l->objectLookupTwoClasses.offset2].asReturnedValue();
- Value obj = Value::fromHeapObject(o);
- Value str = Value::fromHeapObject(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
- return static_cast<Object &>(obj).get(&static_cast<String &>(str));
}
l->getter = getterFallback;
return getterFallback(l, engine, object);
@@ -296,9 +287,7 @@ ReturnedValue Lookup::getterProtoTwoClasses(Lookup *l, ExecutionEngine *engine,
return l->protoLookupTwoClasses.data->asReturnedValue();
if (l->protoLookupTwoClasses.protoId2 == o->internalClass->protoId)
return l->protoLookupTwoClasses.data2->asReturnedValue();
- Value obj = Value::fromHeapObject(o);
- Value str = Value::fromHeapObject(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
- return static_cast<Object &>(obj).get(&static_cast<String &>(str));
+ return getterFallback(l, engine, object);
}
l->getter = getterFallback;
return getterFallback(l, engine, object);
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index e5a718f5c9..e81c90dd1a 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -560,9 +560,9 @@ void QObjectWrapper::setProperty(ExecutionEngine *engine, QObject *object, QQmlP
QQmlContextData *callingQmlContext = scope.engine->callingQmlContext();
if (!QQmlPropertyPrivate::write(object, *property, v, callingQmlContext)) {
- const char *valueType = nullptr;
- if (v.userType() == QVariant::Invalid) valueType = "null";
- else valueType = QMetaType::typeName(v.userType());
+ const char *valueType = (v.userType() == QMetaType::UnknownType)
+ ? "an unknown type"
+ : QMetaType::typeName(v.userType());
const char *targetTypeName = QMetaType::typeName(property->propType());
if (!targetTypeName)
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 980f8469f1..01da5923d9 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -76,6 +76,8 @@ public:
const QQmlMetaTypeData *operator->() const { return data; }
operator const QQmlMetaTypeData *() const { return data; }
+ bool isValid() const { return data != nullptr; }
+
private:
QMutexLocker locker;
LockedData *data = nullptr;
@@ -1206,6 +1208,10 @@ void QQmlMetaType::freeUnusedTypesAndCaches()
{
QQmlMetaTypeDataPtr data;
+ // in case this is being called during program exit, `data` might be destructed already
+ if (!data.isValid())
+ return;
+
bool deletedAtLeastOneType;
do {
deletedAtLeastOneType = false;
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index 3e72f5b324..236daac75c 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -95,9 +95,8 @@ QObject* QQmlTypeWrapper::singletonObject() const
QVariant QQmlTypeWrapper::toVariant() const
{
- // Only Singleton type wrappers can be converted to a variant.
if (!isSingleton())
- return QVariant();
+ return QVariant::fromValue<QObject *>(d()->object);
QQmlEnginePrivate *e = QQmlEnginePrivate::get(engine()->qmlEngine());
const QQmlType type = d()->type();
diff --git a/src/quick/handlers/qquickmultipointhandler.cpp b/src/quick/handlers/qquickmultipointhandler.cpp
index 5c10ecce75..0afc9997aa 100644
--- a/src/quick/handlers/qquickmultipointhandler.cpp
+++ b/src/quick/handlers/qquickmultipointhandler.cpp
@@ -70,14 +70,15 @@ bool QQuickMultiPointHandler::wantsPointerEvent(QQuickPointerEvent *event)
if (!QQuickPointerDeviceHandler::wantsPointerEvent(event))
return false;
-#if QT_CONFIG(gestures)
- if (event->asPointerNativeGestureEvent())
- return true;
-#endif
-
if (event->asPointerScrollEvent())
return false;
+ bool ret = false;
+#if QT_CONFIG(gestures)
+ if (event->asPointerNativeGestureEvent() && event->point(0)->state() != QQuickEventPoint::Released)
+ ret = true;
+#endif
+
// If points were pressed or released within parentItem, reset stored state
// and check eligible points again. This class of handlers is intended to
// handle a specific number of points, so a differing number of points will
@@ -97,7 +98,7 @@ bool QQuickMultiPointHandler::wantsPointerEvent(QQuickPointerEvent *event)
return true;
}
- const bool ret = (candidatePoints.size() >= minimumPointCount() && candidatePoints.size() <= maximumPointCount());
+ ret = ret || (candidatePoints.size() >= minimumPointCount() && candidatePoints.size() <= maximumPointCount());
if (ret) {
const int c = candidatePoints.count();
d->currentPoints.resize(c);
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index c43eab6b8a..28b217b7b3 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -1135,10 +1135,10 @@ void QQuickEventTouchPoint::reset(const QTouchEvent::TouchPoint &tp, ulong times
struct PointVelocityData {
QVector2D velocity;
QPointF pos;
- ulong timestamp;
+ ulong timestamp = 0;
};
-typedef QMap<quint64, PointVelocityData*> PointDataForPointIdMap;
+typedef QMap<quint64, PointVelocityData> PointDataForPointIdMap;
Q_GLOBAL_STATIC(PointDataForPointIdMap, g_previousPointData)
static const int PointVelocityAgeLimit = 500; // milliseconds
@@ -1149,42 +1149,36 @@ static const int PointVelocityAgeLimit = 500; // milliseconds
*/
QVector2D QQuickEventPoint::estimatedVelocity() const
{
- PointVelocityData *prevPoint = g_previousPointData->value(m_pointId);
- if (!prevPoint) {
+ auto prevPointIt = g_previousPointData->find(m_pointId);
+ auto end = g_previousPointData->end();
+ if (prevPointIt == end) {
// cleanup events older than PointVelocityAgeLimit
- auto end = g_previousPointData->end();
for (auto it = g_previousPointData->begin(); it != end; ) {
- PointVelocityData *data = it.value();
- if (m_timestamp - data->timestamp > PointVelocityAgeLimit) {
+ if (m_timestamp - it->timestamp > PointVelocityAgeLimit)
it = g_previousPointData->erase(it);
- delete data;
- } else {
+ else
++it;
- }
}
- // TODO optimize: stop this dynamic memory thrashing
- prevPoint = new PointVelocityData;
- prevPoint->velocity = QVector2D();
- prevPoint->timestamp = 0;
- prevPoint->pos = QPointF();
- g_previousPointData->insert(m_pointId, prevPoint);
+ prevPointIt = g_previousPointData->insert(m_pointId, PointVelocityData());
}
- const ulong timeElapsed = m_timestamp - prevPoint->timestamp;
+
+ auto &prevPoint = prevPointIt.value();
+ const ulong timeElapsed = m_timestamp - prevPoint.timestamp;
if (timeElapsed == 0) // in case we call estimatedVelocity() twice on the same QQuickEventPoint
return m_velocity;
QVector2D newVelocity;
- if (prevPoint->timestamp != 0)
- newVelocity = QVector2D(m_scenePos - prevPoint->pos)/timeElapsed;
+ if (prevPoint.timestamp != 0)
+ newVelocity = QVector2D(m_scenePos - prevPoint.pos) / timeElapsed;
// VERY simple kalman filter: does a weighted average
// where the older velocities get less and less significant
static const float KalmanGain = 0.7f;
QVector2D filteredVelocity = newVelocity * KalmanGain + m_velocity * (1.0f - KalmanGain);
- prevPoint->velocity = filteredVelocity;
- prevPoint->pos = m_scenePos;
- prevPoint->timestamp = m_timestamp;
+ prevPoint.velocity = filteredVelocity;
+ prevPoint.pos = m_scenePos;
+ prevPoint.timestamp = m_timestamp;
return filteredVelocity;
}