Merge remote-tracking branch 'origin/5.13' into dev

Conflicts:
	src/qml/compiler/qv4compilercontext.cpp
	src/qml/qml/qqmlmetatype.cpp

Change-Id: I02e0216961b92ff68a3f91a70edc33fe9e8db147
This commit is contained in:
Qt Forward Merge Bot 2019-04-28 01:00:07 +02:00 committed by Ulf Hermann
commit 23f988fe48
13 changed files with 81 additions and 49 deletions

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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();

View File

@ -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);

View File

@ -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;
}

View File

@ -0,0 +1,15 @@
import QtQml 2.0
QtObject {
id: root
property QtObject target: QtObject {
Component.onCompleted: {
root.connections.target = root.target.Component
}
}
property Connections connections: Connections {
ignoreUnknownSignals: true
}
}

View File

@ -301,6 +301,8 @@ private slots:
void polymorphicFunctionLookup();
void anchorsToParentInPropertyChanges();
void typeWrapperToVariant();
private:
QQmlEngine engine;
QStringList defaultImportPathList;
@ -5087,6 +5089,19 @@ void tst_qqmllanguage::anchorsToParentInPropertyChanges()
QTRY_COMPARE(o->property("edgeWidth").toInt(), 200);
}
void tst_qqmllanguage::typeWrapperToVariant()
{
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("typeWrapperToVariant.qml"));
VERIFY_ERRORS(0);
QScopedPointer<QObject> o(component.create());
QVERIFY(!o.isNull());
QObject *connections = qvariant_cast<QObject *>(o->property("connections"));
QVERIFY(connections);
QObject *target = qvariant_cast<QObject *>(connections->property("target"));
QVERIFY(target);
}
QTEST_MAIN(tst_qqmllanguage)
#include "tst_qqmllanguage.moc"

View File

@ -1,3 +1,6 @@
[openglContextCreatedSignal]
opensuse-42.3
opensuse-leap
# QTBUG-62177
[attachedProperty]
osx

View File

@ -0,0 +1,3 @@
[tabKey]
opensuse-42.3
opensuse-leap

View File

@ -40,7 +40,9 @@ QQmlDataTest::QQmlDataTest() :
m_dataDirectory(QTest::qFindTestData("data", QT_QMLTEST_DATADIR, 0)),
#endif
m_dataDirectoryUrl(QUrl::fromLocalFile(m_dataDirectory + QLatin1Char('/')))
m_dataDirectoryUrl(m_dataDirectory.startsWith(QLatin1Char(':'))
? QUrl(QLatin1String("qrc") + m_dataDirectory)
: QUrl::fromLocalFile(m_dataDirectory + QLatin1Char('/')))
{
m_instance = this;
}
@ -54,7 +56,8 @@ void QQmlDataTest::initTestCase()
{
QVERIFY2(!m_dataDirectory.isEmpty(), "'data' directory not found");
m_directory = QFileInfo(m_dataDirectory).absolutePath();
QVERIFY2(QDir::setCurrent(m_directory), qPrintable(QLatin1String("Could not chdir to ") + m_directory));
if (m_dataDirectoryUrl.scheme() != QLatin1String("qrc"))
QVERIFY2(QDir::setCurrent(m_directory), qPrintable(QLatin1String("Could not chdir to ") + m_directory));
}
QString QQmlDataTest::testFile(const QString &fileName) const

View File

@ -3,4 +3,8 @@ INCLUDEPATH += $$PWD
HEADERS += $$PWD/util.h
SOURCES += $$PWD/util.cpp
DEFINES += QT_QMLTEST_DATADIR=\\\"$${_PRO_FILE_PWD_}/data\\\"
android|ios {
DEFINES += QT_QMLTEST_DATADIR=\\\":/data\\\"
} else {
DEFINES += QT_QMLTEST_DATADIR=\\\"$${_PRO_FILE_PWD_}/data\\\"
}