aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/ftw/qhashedstring.cpp2
-rw-r--r--src/qml/qml/ftw/qstringhash_p.h60
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp2
-rw-r--r--src/qml/qml/qqmlbinding.cpp4
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp5
-rw-r--r--src/qml/qml/qqmlcomponent.cpp2
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp8
-rw-r--r--src/qml/qml/qqmldata_p.h2
-rw-r--r--src/qml/qml/qqmldatablob.cpp3
-rw-r--r--src/qml/qml/qqmlengine.cpp47
-rw-r--r--src/qml/qml/qqmlextensionplugin.cpp2
-rw-r--r--src/qml/qml/qqmlimport.cpp67
-rw-r--r--src/qml/qml/qqmlimport_p.h12
-rw-r--r--src/qml/qml/qqmlinfo.cpp3
-rw-r--r--src/qml/qml/qqmllocale.cpp30
-rw-r--r--src/qml/qml/qqmllocale_p.h13
-rw-r--r--src/qml/qml/qqmlmetaobject.cpp8
-rw-r--r--src/qml/qml/qqmlmetatype.cpp35
-rw-r--r--src/qml/qml/qqmlmetatype_p.h2
-rw-r--r--src/qml/qml/qqmlmetatypedata_p.h4
-rw-r--r--src/qml/qml/qqmlmoduleregistration.cpp18
-rw-r--r--src/qml/qml/qqmlmoduleregistration.h7
-rw-r--r--src/qml/qml/qqmlnotifier.cpp4
-rw-r--r--src/qml/qml/qqmlproperty.cpp4
-rw-r--r--src/qml/qml/qqmlproperty_p.h4
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp11
-rw-r--r--src/qml/qml/qqmltype.cpp36
-rw-r--r--src/qml/qml/qqmltype_p.h1
-rw-r--r--src/qml/qml/qqmltype_p_p.h12
-rw-r--r--src/qml/qml/qqmltypecompiler.cpp10
-rw-r--r--src/qml/qml/qqmltypeloader.cpp19
-rw-r--r--src/qml/qml/qqmltypeloaderqmldircontent.cpp1
-rw-r--r--src/qml/qml/qqmltypemodule.cpp8
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp145
-rw-r--r--src/qml/qml/qqmlvmemetaobject_p.h20
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp42
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp21
37 files changed, 408 insertions, 266 deletions
diff --git a/src/qml/qml/ftw/qhashedstring.cpp b/src/qml/qml/ftw/qhashedstring.cpp
index 7a8fdd0a14..bbe374044d 100644
--- a/src/qml/qml/ftw/qhashedstring.cpp
+++ b/src/qml/qml/ftw/qhashedstring.cpp
@@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE
// Copy of QString's qMemCompare
bool QHashedString::compare(const QChar *lhs, const QChar *rhs, int length)
{
- Q_ASSERT(lhs && rhs);
+ Q_ASSERT((lhs && rhs) || !length);
const quint16 *a = (const quint16 *)lhs;
const quint16 *b = (const quint16 *)rhs;
diff --git a/src/qml/qml/ftw/qstringhash_p.h b/src/qml/qml/ftw/qstringhash_p.h
index f9435b4919..fc73fdfa50 100644
--- a/src/qml/qml/ftw/qstringhash_p.h
+++ b/src/qml/qml/ftw/qstringhash_p.h
@@ -54,25 +54,31 @@
#include <private/qhashedstring_p.h>
#include <private/qprimefornumbits_p.h>
-#include <QtCore/qglobal.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qstring.h>
QT_BEGIN_NAMESPACE
+static inline QString::DataPointer &mutableStringData(const QHashedString &key)
+{
+ return const_cast<QHashedString &>(key).data_ptr();
+}
+
class QStringHashData;
class QStringHashNode
{
public:
QStringHashNode()
- : ckey(nullptr)
{
}
QStringHashNode(const QHashedString &key)
: length(key.length()), hash(key.hash()), symbolId(0)
+ , arrayData(mutableStringData(key).d_ptr())
+ , strData(mutableStringData(key).data())
{
- strData = const_cast<QHashedString &>(key).data_ptr();
+ arrayData->ref();
setQString(true);
- strData->ref.ref();
}
QStringHashNode(const QHashedCStringRef &key)
@@ -81,15 +87,21 @@ public:
}
QStringHashNode(const QStringHashNode &o)
- : length(o.length), hash(o.hash), symbolId(o.symbolId), ckey(o.ckey)
+ : length(o.length), hash(o.hash), symbolId(o.symbolId), arrayData(o.arrayData)
{
setQString(o.isQString());
- if (isQString()) { strData->ref.ref(); }
+ if (isQString()) {
+ strData = o.strData;
+ arrayData->ref();
+ } else {
+ ckey = o.ckey;
+ }
}
~QStringHashNode()
{
- if (isQString()) { if (!strData->ref.deref()) free(strData); }
+ if (isQString() && !arrayData->deref())
+ QTypedArrayData<ushort>::deallocate(arrayData);
}
QFlagPointer<QStringHashNode> next;
@@ -98,15 +110,18 @@ public:
quint32 hash = 0;
quint32 symbolId = 0;
+ QTypedArrayData<ushort> *arrayData = nullptr;
union {
- const char *ckey;
- QStringData *strData;
+ const char *ckey = nullptr;
+ ushort *strData;
};
inline QHashedString key() const
{
- if (isQString())
- return QHashedString(QString((QChar *)strData->data(), length), hash);
+ if (isQString()) {
+ arrayData->ref();
+ return QHashedString(QString(QStringPrivate(arrayData, strData, length)), hash);
+ }
return QHashedString(QString::fromLatin1(ckey, length), hash);
}
@@ -114,16 +129,14 @@ public:
bool isQString() const { return next.flag(); }
void setQString(bool v) { if (v) next.setFlag(); else next.clearFlag(); }
- inline char *cStrData() const { return (char *)ckey; }
- inline quint16 *utf16Data() const { return (quint16 *)strData->data(); }
+ inline qsizetype size() const { return length; }
+ inline const char *cStrData() const { return ckey; }
+ inline const quint16 *utf16Data() const { return strData; }
inline bool equals(const QV4::Value &string) const {
QString s = string.toQStringNoThrow();
if (isQString()) {
- QStringDataPtr dd;
- dd.ptr = strData;
- strData->ref.ref();
- return QString(dd) == s;
+ return QStringView(utf16Data(), length) == s;
} else {
return QLatin1String(cStrData(), length) == s;
}
@@ -133,10 +146,7 @@ public:
if (length != string->d()->length() || hash != string->hashValue())
return false;
if (isQString()) {
- QStringDataPtr dd;
- dd.ptr = strData;
- strData->ref.ref();
- return QString(dd) == string->toQString();
+ return QStringView(utf16Data(), length) == string->toQString();
} else {
return QLatin1String(cStrData(), length) == string->toQString();
}
@@ -510,8 +520,9 @@ void QStringHash<T>::initializeNode(Node *node, const QHashedString &key)
{
node->length = key.length();
node->hash = key.hash();
- node->strData = const_cast<QHashedString &>(key).data_ptr();
- node->strData->ref.ref();
+ node->arrayData = mutableStringData(key).d_ptr();
+ node->strData = mutableStringData(key).data();
+ node->arrayData->ref();
node->setQString(true);
}
@@ -547,10 +558,11 @@ typename QStringHash<T>::Node *QStringHash<T>::takeNode(const Node &o)
Node *rv = nodePool->nodes + nodePool->used++;
rv->length = o.length;
rv->hash = o.hash;
+ rv->arrayData = o.arrayData;
if (o.isQString()) {
rv->strData = o.strData;
- rv->strData->ref.ref();
rv->setQString(true);
+ rv->arrayData->ref();
} else {
rv->ckey = o.ckey;
}
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index adb036e2d0..7f80fe5e1c 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -127,7 +127,7 @@ void QQmlApplicationEnginePrivate::finishLoad(QQmlComponent *c)
switch (c->status()) {
case QQmlComponent::Error:
qWarning() << "QQmlApplicationEngine failed to load component";
- qWarning() << qPrintable(c->errorString());
+ warning(c->errors());
q->objectCreated(nullptr, c->url());
break;
case QQmlComponent::Ready: {
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index 112e5b558a..162adf8364 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -54,6 +54,8 @@
#include <private/qv4variantobject_p.h>
#include <private/qv4jscall_p.h>
+#include <qtqml_tracepoints_p.h>
+
#include <QVariant>
#include <QtCore/qdebug.h>
#include <QVector>
@@ -182,6 +184,8 @@ void QQmlBinding::update(QQmlPropertyData::WriteFlags flags)
if (canUseAccessor())
flags.setFlag(QQmlPropertyData::BypassInterceptor);
+ Q_TRACE_SCOPE(QQmlBinding, engine, function() ? function()->name()->toQString() : QString(),
+ sourceLocation().sourceFile, sourceLocation().line, sourceLocation().column);
QQmlBindingProfiler prof(QQmlEnginePrivate::get(engine)->profiler, function());
doUpdate(watcher, flags, scope);
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index ff01e737ca..b347bb3829 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -60,6 +60,7 @@
#include <QtCore/qdebug.h>
+#include <qtqml_tracepoints_p.h>
QT_BEGIN_NAMESPACE
@@ -352,6 +353,10 @@ void QQmlBoundSignal_callback(QQmlNotifierEndpoint *e, void **a)
QQmlEngine *engine;
if (s->m_expression && (engine = s->m_expression->engine())) {
+ Q_TRACE_SCOPE(QQmlHandlingSignal, engine,
+ s->m_expression->function() ? s->m_expression->function()->name()->toQString() : QString(),
+ s->m_expression->sourceLocation().sourceFile, s->m_expression->sourceLocation().line,
+ s->m_expression->sourceLocation().column);
QQmlHandlingSignalProfiler prof(QQmlEnginePrivate::get(engine)->profiler, s->m_expression);
s->m_expression->evaluate(a);
if (s->m_expression && s->m_expression->hasError()) {
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 1d5f974d5c..279998b5de 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -376,7 +376,7 @@ bool QQmlComponentPrivate::setInitialProperty(QObject *component, const QString&
{
QQmlProperty prop = QQmlComponentPrivate::removePropertyFromRequired(component, name, requiredProperties());
QQmlPropertyPrivate *privProp = QQmlPropertyPrivate::get(prop);
- if (!prop.isValid() || !privProp->writeValueProperty(value, nullptr)) {
+ if (!prop.isValid() || !privProp->writeValueProperty(value, {})) {
QQmlError error{};
error.setUrl(url);
error.setDescription(QLatin1String("Could not set property %1").arg(name));
diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp
index a5f34dafdf..87f7fffe41 100644
--- a/src/qml/qml/qqmlcustomparser.cpp
+++ b/src/qml/qml/qqmlcustomparser.cpp
@@ -108,12 +108,6 @@ void QQmlCustomParser::error(const QV4::CompiledData::Location &location, const
exceptions << error;
}
-struct StaticQtMetaObject : public QObject
-{
- static const QMetaObject *get()
- { return &staticQtMetaObject; }
-};
-
/*!
If \a script is a simple enumeration expression (eg. Text.AlignLeft),
returns the integer equivalent (eg. 1), and sets \a ok to true.
@@ -164,7 +158,7 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
}
QByteArray enumValue = script.mid(dot + 1);
- const QMetaObject *mo = StaticQtMetaObject::get();
+ const QMetaObject *mo = &Qt::staticMetaObject;
int i = mo->enumeratorCount();
while (i--) {
int v = mo->enumerator(i).keyToValue(enumValue.constData(), ok);
diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h
index 299476f5c8..ee31cb38d9 100644
--- a/src/qml/qml/qqmldata_p.h
+++ b/src/qml/qml/qqmldata_p.h
@@ -335,7 +335,7 @@ bool QQmlData::wasDeleted(const QObject *object)
return true;
const QObjectPrivate *priv = QObjectPrivate::get(object);
- if (!priv || priv->wasDeleted)
+ if (!priv || priv->wasDeleted || priv->isDeletingChildren)
return true;
const QQmlData *ddata = QQmlData::get(object);
diff --git a/src/qml/qml/qqmldatablob.cpp b/src/qml/qml/qqmldatablob.cpp
index 750fc6de50..1ab6002f0a 100644
--- a/src/qml/qml/qqmldatablob.cpp
+++ b/src/qml/qml/qqmldatablob.cpp
@@ -45,6 +45,8 @@
#include <QtQml/qqmlengine.h>
+#include <qtqml_tracepoints_p.h>
+
#ifdef DATABLOB_DEBUG
#define ASSERT_CALLBACK() do { if (!m_typeLoader || !m_typeLoader->m_thread->isThisThread()) qFatal("QQmlDataBlob: An API call was made outside a callback"); } while (false)
#else
@@ -559,6 +561,7 @@ void QQmlDataBlob::notifyAllWaitingOnMe()
void QQmlDataBlob::notifyComplete(QQmlDataBlob *blob)
{
Q_ASSERT(blob->status() == Error || blob->status() == Complete);
+ Q_TRACE_SCOPE(QQmlCompiling, blob->url());
QQmlCompilingProfiler prof(typeLoader()->profiler(), blob);
m_inCallback = true;
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index bde4df1340..f11959b7fb 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -197,25 +197,6 @@ int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject,
bool QQmlEnginePrivate::qml_debugging_enabled = false;
bool QQmlEnginePrivate::s_designerMode = false;
-void QQmlEnginePrivate::defineModule()
-{
- const char uri[] = "QtQml";
-
- qmlRegisterTypesAndRevisions<
- QObjectForeign,
-#if QT_CONFIG(qml_animation)
- QQmlTimer,
-#endif
-#if QT_CONFIG(qml_locale)
- QQmlLocale,
-#endif
- QQmlComponent,
- QQmlBind,
- QQmlConnections,
- QQmlLoggingCategory
- >(uri, 2);
-}
-
bool QQmlEnginePrivate::designerMode()
{
return s_designerMode;
@@ -783,10 +764,12 @@ void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int in
// QQmlEngine to emit signals from a different thread. These signals are then automatically
// marshalled back onto the QObject's thread and handled by QML from there. This is tested
// by the qqmlecmascript::threadSignal() autotest.
- if (ddata->notifyList &&
- QThread::currentThreadId() != QObjectPrivate::get(object)->getThreadData()->threadId.loadRelaxed()) {
+ if (!ddata->notifyList)
+ return;
- if (!QObjectPrivate::get(object)->getThreadData()->thread.loadAcquire())
+ auto objectThreadData = QObjectPrivate::get(object)->threadData.loadRelaxed();
+ if (QThread::currentThreadId() != objectThreadData->threadId.loadRelaxed()) {
+ if (!objectThreadData->thread.loadAcquire())
return;
QMetaMethod m = QMetaObjectPrivate::signal(object->metaObject(), index);
@@ -818,7 +801,7 @@ void QQmlData::signalEmitted(QAbstractDeclarativeData *, QObject *object, int in
QQmlThreadNotifierProxyObject *mpo = new QQmlThreadNotifierProxyObject;
mpo->target = object;
- mpo->moveToThread(QObjectPrivate::get(object)->getThreadData()->thread.loadAcquire());
+ mpo->moveToThread(objectThreadData->thread.loadAcquire());
QCoreApplication::postEvent(mpo, ev.take());
} else {
@@ -1002,8 +985,6 @@ QQmlEngine::~QQmlEngine()
Q_D(QQmlEngine);
QJSEnginePrivate::removeFromDebugServer(this);
- d->typeLoader.invalidate();
-
// Emit onDestruction signals for the root context before
// we destroy the contexts, engine, Singleton Types etc. that
// may be required to handle the destruction signal.
@@ -1013,12 +994,14 @@ QQmlEngine::~QQmlEngine()
// we do this here and not in the private dtor since otherwise a crash can
// occur (if we are the QObject parent of the QObject singleton instance)
// XXX TODO: performance -- store list of singleton types separately?
- QList<QQmlType> singletonTypes = QQmlMetaType::qmlSingletonTypes();
+ const QList<QQmlType> singletonTypes = QQmlMetaType::qmlSingletonTypes();
for (const QQmlType &currType : singletonTypes)
d->destroySingletonInstance(currType);
delete d->rootContext;
d->rootContext = nullptr;
+
+ d->typeLoader.invalidate();
}
/*! \fn void QQmlEngine::quit()
@@ -1595,6 +1578,9 @@ static QObject *resolveAttachedProperties(QQmlAttachedPropertiesFunc pf, QQmlDat
}
#if QT_DEPRECATED_SINCE(5, 14)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
+
QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create)
{
QQmlData *data = QQmlData::get(object, create);
@@ -1605,7 +1591,9 @@ QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool cre
return nullptr;
QQmlEnginePrivate *engine = QQmlEnginePrivate::get(data->context);
- return resolveAttachedProperties(QQmlMetaType::attachedPropertiesFuncById(engine, id), data,
+
+ const QQmlType type = QQmlMetaType::qmlType(id, QQmlMetaType::TypeIdCategory::QmlType);
+ return resolveAttachedProperties(type.attachedPropertiesFunction(engine), data,
const_cast<QObject *>(object), create);
}
@@ -1622,6 +1610,8 @@ QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object,
return qmlAttachedPropertiesObjectById(*idCache, object, create);
}
+
+QT_WARNING_POP
#endif
QQmlAttachedPropertiesFunc qmlAttachedPropertiesFunction(QObject *object,
@@ -1650,6 +1640,8 @@ QObject *qmlAttachedPropertiesObject(QObject *object, QQmlAttachedPropertiesFunc
} // namespace QtQml
#if QT_DEPRECATED_SINCE(5, 1)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
// Also define symbols outside namespace to keep binary compatibility with Qt 5.0
@@ -1680,6 +1672,7 @@ Q_QML_EXPORT QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *o
return QtQml::qmlAttachedPropertiesObject(idCache, object, attachedMetaObject, create);
}
+QT_WARNING_POP
#endif // QT_DEPRECATED_SINCE(5, 1)
class QQmlDataExtended {
diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp
index 26364661a8..7a62c967e7 100644
--- a/src/qml/qml/qqmlextensionplugin.cpp
+++ b/src/qml/qml/qqmlextensionplugin.cpp
@@ -127,8 +127,6 @@ void QQmlExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
}
/*!
- \fn void QQmlEngineExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
-
Initializes the extension from the \a uri using the \a engine. Here an application
plugin might, for example, expose some data or objects to QML,
as context properties on the engine's root context.
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 21ca24d38b..7da0685872 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -245,9 +245,9 @@ public:
QQmlTypeLoader *typeLoader;
- static bool locateQmldir(const QString &uri, int vmaj, int vmin,
- QQmlImportDatabase *database,
- QString *outQmldirFilePath, QString *outUrl);
+ static QQmlImports::LocalQmldirResult locateLocalQmldir(
+ const QString &uri, int vmaj, int vmin, QQmlImportDatabase *database,
+ QString *outQmldirFilePath, QString *outUrl);
static bool validateQmldirVersion(const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri, int vmaj, int vmin,
QList<QQmlError> *errors);
@@ -1076,7 +1076,13 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath,
if (qmldirPluginCount == 0)
return true;
- if (!database->qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(qmldirFilePath)) {
+ if (database->qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(qmldirFilePath)) {
+ if ((vmaj >= 0 && vmin >= 0)
+ ? !QQmlMetaType::isModule(uri, vmaj, vmin)
+ : !QQmlMetaType::isAnyModule(uri)) {
+ QQmlMetaType::qmlRegisterModuleTypes(uri, vmaj);
+ }
+ } else {
// First search for listed qmldir plugins dynamically. If we cannot resolve them all, we continue
// searching static plugins that has correct metadata uri. Note that since we only know the uri
// for a static plugin, and not the filename, we cannot know which static plugin belongs to which
@@ -1237,8 +1243,9 @@ Locates the qmldir file for \a uri version \a vmaj.vmin. Returns true if found,
and fills in outQmldirFilePath and outQmldirUrl appropriately. Otherwise returns
false.
*/
-bool QQmlImportsPrivate::locateQmldir(const QString &uri, int vmaj, int vmin, QQmlImportDatabase *database,
- QString *outQmldirFilePath, QString *outQmldirPathUrl)
+QQmlImports::LocalQmldirResult QQmlImportsPrivate::locateLocalQmldir(
+ const QString &uri, int vmaj, int vmin, QQmlImportDatabase *database,
+ QString *outQmldirFilePath, QString *outQmldirPathUrl)
{
Q_ASSERT(vmaj >= 0 && vmin >= 0); // Versions are always specified for libraries
@@ -1246,20 +1253,21 @@ bool QQmlImportsPrivate::locateQmldir(const QString &uri, int vmaj, int vmin, QQ
QQmlImportDatabase::QmldirCache *cacheHead = nullptr;
{
- QQmlImportDatabase::QmldirCache **cachePtr = database->qmldirCache.value(uri);
- if (cachePtr) {
- cacheHead = *cachePtr;
- QQmlImportDatabase::QmldirCache *cache = cacheHead;
- while (cache) {
- if (cache->versionMajor == vmaj && cache->versionMinor == vmin) {
- *outQmldirFilePath = cache->qmldirFilePath;
- *outQmldirPathUrl = cache->qmldirPathUrl;
- return !cache->qmldirFilePath.isEmpty();
+ QQmlImportDatabase::QmldirCache **cachePtr = database->qmldirCache.value(uri);
+ if (cachePtr) {
+ cacheHead = *cachePtr;
+ QQmlImportDatabase::QmldirCache *cache = cacheHead;
+ while (cache) {
+ if (cache->versionMajor == vmaj && cache->versionMinor == vmin) {
+ *outQmldirFilePath = cache->qmldirFilePath;
+ *outQmldirPathUrl = cache->qmldirPathUrl;
+ return cache->qmldirFilePath.isEmpty() ? QQmlImports::QmldirNotFound
+ : QQmlImports::QmldirFound;
+ }
+ cache = cache->next;
}
- cache = cache->next;
}
}
- }
QQmlTypeLoader &typeLoader = QQmlEnginePrivate::get(database->engine)->typeLoader;
@@ -1269,12 +1277,17 @@ bool QQmlImportsPrivate::locateQmldir(const QString &uri, int vmaj, int vmin, QQ
interceptor ? QQmlImportDatabase::LocalOrRemote : QQmlImportDatabase::Local);
// Search local import paths for a matching version
- const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(uri, localImportPaths, vmaj, vmin);
+ const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(
+ uri, localImportPaths, vmaj, vmin);
+ bool pathTurnedRemote = false;
for (QString qmldirPath : qmlDirPaths) {
if (interceptor) {
- qmldirPath = QQmlFile::urlToLocalFileOrQrc(
- interceptor->intercept(QQmlImports::urlFromLocalFileOrQrcOrUrl(qmldirPath),
- QQmlAbstractUrlInterceptor::QmldirFile));
+ const QUrl intercepted = interceptor->intercept(
+ QQmlImports::urlFromLocalFileOrQrcOrUrl(qmldirPath),
+ QQmlAbstractUrlInterceptor::QmldirFile);
+ qmldirPath = QQmlFile::urlToLocalFileOrQrc(intercepted);
+ if (!pathTurnedRemote && qmldirPath.isEmpty() && !QQmlFile::isLocalFile(intercepted))
+ pathTurnedRemote = true;
}
QString absoluteFilePath = typeLoader.absoluteFilePath(qmldirPath);
@@ -1297,7 +1310,7 @@ bool QQmlImportsPrivate::locateQmldir(const QString &uri, int vmaj, int vmin, QQ
*outQmldirFilePath = absoluteFilePath;
*outQmldirPathUrl = url;
- return true;
+ return QQmlImports::QmldirFound;
}
}
@@ -1307,7 +1320,7 @@ bool QQmlImportsPrivate::locateQmldir(const QString &uri, int vmaj, int vmin, QQ
cache->next = cacheHead;
database->qmldirCache.insert(uri, cache);
- return false;
+ return pathTurnedRemote ? QQmlImports::QmldirInterceptedToRemote : QQmlImports::QmldirNotFound;
}
bool QQmlImportsPrivate::validateQmldirVersion(const QQmlTypeLoaderQmldirContent &qmldir, const QString &uri, int vmaj, int vmin,
@@ -1701,11 +1714,11 @@ bool QQmlImports::updateQmldirContent(QQmlImportDatabase *importDb,
return d->updateQmldirContent(uri, prefix, qmldirIdentifier, qmldirUrl, importDb, errors);
}
-bool QQmlImports::locateQmldir(QQmlImportDatabase *importDb,
- const QString& uri, int vmaj, int vmin,
- QString *qmldirFilePath, QString *url)
+QQmlImports::LocalQmldirResult QQmlImports::locateLocalQmldir(
+ QQmlImportDatabase *importDb, const QString &uri, int vmaj, int vmin,
+ QString *qmldirFilePath, QString *url)
{
- return d->locateQmldir(uri, vmaj, vmin, importDb, qmldirFilePath, url);
+ return d->locateLocalQmldir(uri, vmaj, vmin, importDb, qmldirFilePath, url);
}
bool QQmlImports::isLocal(const QString &url)
diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h
index 7cf1ae61b9..1f44b22deb 100644
--- a/src/qml/qml/qqmlimport_p.h
+++ b/src/qml/qml/qqmlimport_p.h
@@ -163,9 +163,15 @@ public:
const QString &uri, const QString &prefix,
const QString &qmldirIdentifier, const QString &qmldirUrl, QList<QQmlError> *errors);
- bool locateQmldir(QQmlImportDatabase *,
- const QString &uri, int vmaj, int vmin,
- QString *qmldirFilePath, QString *url);
+ enum LocalQmldirResult {
+ QmldirFound,
+ QmldirNotFound,
+ QmldirInterceptedToRemote
+ };
+
+ LocalQmldirResult locateLocalQmldir(
+ QQmlImportDatabase *, const QString &uri, int vmaj, int vmin,
+ QString *qmldirFilePath, QString *url);
void populateCache(QQmlTypeNameCache *cache) const;
diff --git a/src/qml/qml/qqmlinfo.cpp b/src/qml/qml/qqmlinfo.cpp
index 2bfd2d5bb4..dd401bdb20 100644
--- a/src/qml/qml/qqmlinfo.cpp
+++ b/src/qml/qml/qqmlinfo.cpp
@@ -57,7 +57,6 @@ QT_BEGIN_NAMESPACE
/*!
\fn QQmlInfo QtQml::qmlDebug(const QObject *object)
- \relates QtQml
\since 5.9
Prints debug messages that include the file and line number for the
@@ -91,7 +90,6 @@ QT_BEGIN_NAMESPACE
/*!
\fn QQmlInfo QtQml::qmlInfo(const QObject *object)
- \relates QtQml
Prints informational messages that include the file and line number for the
specified QML \a object.
@@ -119,7 +117,6 @@ QT_BEGIN_NAMESPACE
/*!
\fn QQmlInfo QtQml::qmlWarning(const QObject *object)
- \relates QtQml
\since 5.9
Prints warning messages that include the file and line number for the
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index dca13ac8d4..1743410776 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -478,6 +478,23 @@ ReturnedValue QQmlLocaleData::method_get_firstDayOfWeek(const QV4::FunctionObjec
RETURN_RESULT(fdow);
}
+ReturnedValue QQmlLocaleData::method_get_numberOptions(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) {
+ QV4::Scope scope(b);
+ const QLocale *locale = getThisLocale(scope, thisObject);
+ if (!locale)
+ return Encode::undefined();
+ int numberOptions = int(locale->numberOptions());
+ RETURN_RESULT(numberOptions);
+}
+
+ReturnedValue QQmlLocaleData::method_set_numberOptions(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) {
+ QV4::Scope scope(b);
+ QLocale *locale = getThisLocale(scope, thisObject);
+ int const numberOptions = argc ? int(argv[0].toNumber()) : QLocale::DefaultNumberOptions;
+ locale->setNumberOptions(QLocale::NumberOptions {numberOptions});
+ return Encode::undefined();
+}
+
ReturnedValue QQmlLocaleData::method_get_measurementSystem(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
QV4::Scope scope(b);
@@ -701,6 +718,7 @@ QV4LocaleDataDeletable::QV4LocaleDataDeletable(QV4::ExecutionEngine *engine)
o->defineAccessorProperty(QStringLiteral("amText"), QQmlLocaleData::method_get_amText, nullptr);
o->defineAccessorProperty(QStringLiteral("measurementSystem"), QQmlLocaleData::method_get_measurementSystem, nullptr);
o->defineAccessorProperty(QStringLiteral("exponential"), QQmlLocaleData::method_get_exponential, nullptr);
+ o->defineAccessorProperty(QStringLiteral("numberOptions"), QQmlLocaleData::method_get_numberOptions, QQmlLocaleData::method_set_numberOptions);
prototype.set(engine, o);
}
@@ -817,7 +835,7 @@ QV4::ReturnedValue QQmlLocale::locale(ExecutionEngine *engine, const QString &lo
{
QLocale qlocale;
if (!localeName.isEmpty())
- qlocale = localeName;
+ qlocale = QLocale(localeName);
return wrap(engine, qlocale);
}
@@ -873,6 +891,16 @@ ReturnedValue QQmlLocale::method_localeCompare(const QV4::FunctionObject *b, con
*/
/*!
+ \qmlproperty enumeration QtQml::Locale::NumberOption
+
+ Holds a set of options for number-to-string and
+ string-to-number conversions.
+
+ \sa Number::toLocaleString()
+ \sa Number::fromLocaleString()
+*/
+
+/*!
\qmlproperty string QtQml::Locale::percent
Holds the percent character of this locale.
diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h
index 10e0dfcc38..1d6fdb12a7 100644
--- a/src/qml/qml/qqmllocale_p.h
+++ b/src/qml/qml/qqmllocale_p.h
@@ -131,6 +131,16 @@ public:
Saturday = Qt::Saturday
};
Q_ENUM(DayOfWeek)
+ enum NumberOptions {
+ DefaultNumberOptions = QLocale::DefaultNumberOptions,
+ OmitGroupSeparator = QLocale::OmitGroupSeparator,
+ RejectGroupSeparator = QLocale::RejectGroupSeparator,
+ OmitLeadingZeroInExponent = QLocale::OmitLeadingZeroInExponent,
+ RejectLeadingZeroInExponent = QLocale::RejectLeadingZeroInExponent,
+ IncludeTrailingZeroesAfterDot = QLocale::IncludeTrailingZeroesAfterDot,
+ RejectTrailingZeroesAfterDot = QLocale::RejectTrailingZeroesAfterDot
+ };
+ Q_ENUM(NumberOptions)
static QV4::ReturnedValue locale(QV4::ExecutionEngine *engine, const QString &localeName);
static QV4::ReturnedValue wrap(QV4::ExecutionEngine *engine, const QLocale &locale);
@@ -200,6 +210,9 @@ struct QQmlLocaleData : public QV4::Object
static QV4::ReturnedValue method_get_exponential(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
static QV4::ReturnedValue method_get_amText(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
static QV4::ReturnedValue method_get_pmText(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+
+ static QV4::ReturnedValue method_get_numberOptions(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_numberOptions(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
};
}
diff --git a/src/qml/qml/qqmlmetaobject.cpp b/src/qml/qml/qqmlmetaobject.cpp
index a967f46b12..a87865fd81 100644
--- a/src/qml/qml/qqmlmetaobject.cpp
+++ b/src/qml/qml/qqmlmetaobject.cpp
@@ -44,12 +44,6 @@
QT_BEGIN_NAMESPACE
-struct StaticQtMetaObject : public QObject
-{
- static const QMetaObject *get()
- { return &staticQtMetaObject; }
-};
-
static bool isNamedEnumeratorInScope(const QMetaObject *resolvedMetaObject, const QByteArray &scope,
const QByteArray &name)
{
@@ -74,7 +68,7 @@ static bool isNamedEnumerator(const QMetaObject *metaObj, const QByteArray &scop
}
if (scope == "Qt")
- return isNamedEnumeratorInScope(StaticQtMetaObject::get(), scope, name);
+ return isNamedEnumeratorInScope(&Qt::staticMetaObject, scope, name);
if (isNamedEnumeratorInScope(metaObj, scope, name))
return true;
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index b8c17c9374..f506cdece3 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -273,11 +273,25 @@ void QQmlMetaType::qmlInsertModuleRegistration(const QString &uri, int majorVers
const QQmlMetaTypeData::VersionedUri versionedUri(uri, majorVersion);
QQmlMetaTypeDataPtr data;
if (data->moduleTypeRegistrationFunctions.contains(versionedUri))
- qFatal("Canot add multiple registrations for %s %d", qPrintable(uri), majorVersion);
+ qFatal("Cannot add multiple registrations for %s %d", qPrintable(uri), majorVersion);
else
data->moduleTypeRegistrationFunctions.insert(versionedUri, registerFunction);
}
+void QQmlMetaType::qmlRemoveModuleRegistration(const QString &uri, int majorVersion)
+{
+ const QQmlMetaTypeData::VersionedUri versionedUri(uri, majorVersion);
+ QQmlMetaTypeDataPtr data;
+
+ if (!data.isValid())
+ return; // shutdown/deletion race. Not a problem.
+
+ if (!data->moduleTypeRegistrationFunctions.contains(versionedUri))
+ qFatal("Cannot remove multiple registrations for %s %d", qPrintable(uri), majorVersion);
+ else
+ data->moduleTypeRegistrationFunctions.remove(versionedUri);
+}
+
bool QQmlMetaType::qmlRegisterModuleTypes(const QString &uri, int majorVersion)
{
QQmlMetaTypeDataPtr data;
@@ -329,7 +343,6 @@ QQmlType QQmlMetaType::registerInterface(const QQmlPrivate::RegisterInterface &t
data->idToType.insert(priv->typeId, priv);
data->idToType.insert(priv->listId, priv);
- // XXX No insertMulti, so no multi-version interfaces?
if (!priv->elementName.isEmpty())
data->nameToType.insert(priv->elementName, priv);
@@ -414,10 +427,10 @@ void addTypeToData(QQmlTypePrivate *type, QQmlMetaTypeData *data)
Q_ASSERT(type);
if (!type->elementName.isEmpty())
- data->nameToType.insertMulti(type->elementName, type);
+ data->nameToType.insert(type->elementName, type);
if (type->baseMetaObject)
- data->metaObjectToType.insertMulti(type->baseMetaObject, type);
+ data->metaObjectToType.insert(type->baseMetaObject, type);
if (type->typeId) {
data->idToType.insert(type->typeId, type);
@@ -492,7 +505,7 @@ QQmlType QQmlMetaType::registerCompositeSingletonType(const QQmlPrivate::Registe
addTypeToData(priv, data);
QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType);
- files->insertMulti(QQmlTypeLoader::normalize(type.url), priv);
+ files->insert(QQmlTypeLoader::normalize(type.url), priv);
return QQmlType(priv);
}
@@ -513,7 +526,7 @@ QQmlType QQmlMetaType::registerCompositeType(const QQmlPrivate::RegisterComposit
addTypeToData(priv, data);
QQmlMetaTypeData::Files *files = fileImport ? &(data->urlToType) : &(data->urlToNonFileImportType);
- files->insertMulti(QQmlTypeLoader::normalize(type.url), priv);
+ files->insert(QQmlTypeLoader::normalize(type.url), priv);
return QQmlType(priv);
}
@@ -797,7 +810,7 @@ QQmlType QQmlMetaType::typeForUrl(const QString &urlString,
data->registerType(priv);
addTypeToData(priv, data);
- data->urlToType.insertMulti(url, priv);
+ data->urlToType.insert(url, priv);
return QQmlType(priv);
}
@@ -927,11 +940,11 @@ int QQmlMetaType::attachedPropertiesFuncId(QQmlEnginePrivate *engine, const QMet
for (auto it = data->metaObjectToType.constFind(mo), end = data->metaObjectToType.constEnd();
it != end && it.key() == mo; ++it) {
- const QQmlType type(it.value());
- if (type.attachedPropertiesFunction(engine))
- return type.attachedPropertiesId(engine);
+ if (const QQmlTypePrivate *type = it.value()) {
+ if (const QQmlTypePrivate *base = type->attachedPropertiesBase(engine))
+ return base->index;
+ }
}
-
return -1;
}
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index ed4675046d..80126cbffb 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -200,6 +200,8 @@ public:
static void qmlInsertModuleRegistration(const QString &uri, int majorVersion,
void (*registerFunction)());
+ static void qmlRemoveModuleRegistration(const QString &uri, int majorVersion);
+
static bool qmlRegisterModuleTypes(const QString &uri, int majorVersion);
};
diff --git a/src/qml/qml/qqmlmetatypedata_p.h b/src/qml/qml/qqmlmetatypedata_p.h
index f193e51f5a..e51d4ca1a4 100644
--- a/src/qml/qml/qqmlmetatypedata_p.h
+++ b/src/qml/qml/qqmlmetatypedata_p.h
@@ -71,7 +71,7 @@ struct QQmlMetaTypeData
QSet<QQmlType> undeletableTypes;
typedef QHash<int, QQmlTypePrivate *> Ids;
Ids idToType;
- typedef QHash<QHashedStringRef, QQmlTypePrivate *> Names;
+ typedef QMultiHash<QHashedStringRef, QQmlTypePrivate *> Names;
Names nameToType;
typedef QHash<QUrl, QQmlTypePrivate *> Files; //For file imported composite types only
Files urlToType;
@@ -79,7 +79,7 @@ struct QQmlMetaTypeData
// singleton types. This way we can locate any
// of them by url, even if it was registered as
// a module via QQmlPrivate::RegisterCompositeType
- typedef QHash<const QMetaObject *, QQmlTypePrivate *> MetaObjects;
+ typedef QMultiHash<const QMetaObject *, QQmlTypePrivate *> MetaObjects;
MetaObjects metaObjectToType;
typedef QHash<int, QQmlMetaType::StringConverter> StringConverters;
StringConverters stringConverters;
diff --git a/src/qml/qml/qqmlmoduleregistration.cpp b/src/qml/qml/qqmlmoduleregistration.cpp
index bb82ec1d95..b7bc3555a6 100644
--- a/src/qml/qml/qqmlmoduleregistration.cpp
+++ b/src/qml/qml/qqmlmoduleregistration.cpp
@@ -39,16 +39,28 @@
#include <QtQml/private/qqmlmetatype_p.h>
#include <QtQml/qqmlmoduleregistration.h>
-#include <QtCore/qglobalstatic.h>
QT_BEGIN_NAMESPACE
+struct QQmlModuleRegistrationPrivate
+{
+ const QString uri;
+ const int majorVersion;
+};
+
QQmlModuleRegistration::QQmlModuleRegistration(
const char *uri, int majorVersion,
- void (*registerFunction)())
+ void (*registerFunction)()) :
+ d(new QQmlModuleRegistrationPrivate { QString::fromUtf8(uri), majorVersion })
{
- QQmlMetaType::qmlInsertModuleRegistration(QString::fromUtf8(uri), majorVersion,
+ QQmlMetaType::qmlInsertModuleRegistration(d->uri, d->majorVersion,
registerFunction);
}
+QQmlModuleRegistration::~QQmlModuleRegistration()
+{
+ QQmlMetaType::qmlRemoveModuleRegistration(d->uri, d->majorVersion);
+ delete d;
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlmoduleregistration.h b/src/qml/qml/qqmlmoduleregistration.h
index 8924724b48..6f553a2823 100644
--- a/src/qml/qml/qqmlmoduleregistration.h
+++ b/src/qml/qml/qqmlmoduleregistration.h
@@ -44,13 +44,16 @@
QT_BEGIN_NAMESPACE
+struct QQmlModuleRegistrationPrivate;
class Q_QML_EXPORT QQmlModuleRegistration
{
Q_DISABLE_COPY_MOVE(QQmlModuleRegistration)
-
public:
QQmlModuleRegistration(const char *uri, int majorVersion, void (*registerFunction)());
- ~QQmlModuleRegistration() = default;
+ ~QQmlModuleRegistration();
+
+private:
+ QQmlModuleRegistrationPrivate *d = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlnotifier.cpp b/src/qml/qml/qqmlnotifier.cpp
index fe839a50dc..df3731684a 100644
--- a/src/qml/qml/qqmlnotifier.cpp
+++ b/src/qml/qml/qqmlnotifier.cpp
@@ -118,8 +118,8 @@ void QQmlNotifierEndpoint::connect(QObject *source, int sourceSignal, QQmlEngine
disconnect();
Q_ASSERT(engine);
- if (QObjectPrivate::get(source)->getThreadData()->threadId.loadRelaxed() !=
- QObjectPrivate::get(engine)->getThreadData()->threadId.loadRelaxed()) {
+ if (QObjectPrivate::get(source)->threadData.loadRelaxed()->threadId.loadRelaxed() !=
+ QObjectPrivate::get(engine)->threadData.loadRelaxed()->threadId.loadRelaxed()) {
QString sourceName;
QDebug(&sourceName) << source;
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 27667de678..871bec1c17 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -785,7 +785,7 @@ static void removeOldBinding(QObject *object, QQmlPropertyIndex index, QQmlPrope
return;
if (!(flags & QQmlPropertyPrivate::DontEnable))
- oldBinding->setEnabled(false, nullptr);
+ oldBinding->setEnabled(false, {});
oldBinding->removeFromObject();
}
@@ -1451,7 +1451,7 @@ QQmlMetaObject QQmlPropertyPrivate::rawMetaObjectForType(QQmlEnginePrivate *engi
*/
bool QQmlProperty::write(const QVariant &value) const
{
- return QQmlPropertyPrivate::write(*this, value, nullptr);
+ return QQmlPropertyPrivate::write(*this, value, {});
}
/*!
diff --git a/src/qml/qml/qqmlproperty_p.h b/src/qml/qml/qqmlproperty_p.h
index 285c34d7fa..8abd83d7b4 100644
--- a/src/qml/qml/qqmlproperty_p.h
+++ b/src/qml/qml/qqmlproperty_p.h
@@ -107,9 +107,9 @@ public:
static bool writeValueProperty(QObject *,
const QQmlPropertyData &, const QQmlPropertyData &valueTypeData,
const QVariant &, QQmlContextData *,
- QQmlPropertyData::WriteFlags flags = nullptr);
+ QQmlPropertyData::WriteFlags flags = {});
static bool write(QObject *, const QQmlPropertyData &, const QVariant &,
- QQmlContextData *, QQmlPropertyData::WriteFlags flags = nullptr);
+ QQmlContextData *, QQmlPropertyData::WriteFlags flags = {});
static void findAliasTarget(QObject *, QQmlPropertyIndex, QObject **, QQmlPropertyIndex *);
enum BindingFlag {
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index 69957ab282..6336ff28b3 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -1052,13 +1052,10 @@ static inline const QMetaObjectPrivate *priv(const uint* data)
static inline const QByteArray stringData(const QMetaObject *mo, int index)
{
- Q_ASSERT(priv(mo->d.data)->revision >= 7);
- const QByteArrayDataPtr data = { const_cast<QByteArrayData*>(&mo->d.stringdata[index]) };
- Q_ASSERT(data.ptr->ref.isStatic());
- Q_ASSERT(data.ptr->alloc == 0);
- Q_ASSERT(data.ptr->capacityReserved == 0);
- Q_ASSERT(data.ptr->size >= 0);
- return data;
+ uint offset = mo->d.stringdata[2*index];
+ uint length = mo->d.stringdata[2*index + 1];
+ const char *string = reinterpret_cast<const char *>(mo->d.stringdata) + offset;
+ return QByteArray::fromRawData(string, length);
}
bool QQmlPropertyCache::isDynamicMetaObject(const QMetaObject *mo)
diff --git a/src/qml/qml/qqmltype.cpp b/src/qml/qml/qqmltype.cpp
index 874bcd4bca..4a211ffa53 100644
--- a/src/qml/qml/qqmltype.cpp
+++ b/src/qml/qml/qqmltype.cpp
@@ -618,28 +618,16 @@ int QQmlType::metaObjectRevision() const
QQmlAttachedPropertiesFunc QQmlType::attachedPropertiesFunction(QQmlEnginePrivate *engine) const
{
- if (!d)
- return nullptr;
- if (d->regType == CppType)
- return d->extraData.cd->attachedPropertiesFunc;
-
- QQmlType base;
- if (d->regType == CompositeType)
- base = d->resolveCompositeBaseType(engine);
- return base.attachedPropertiesFunction(engine);
+ if (const QQmlTypePrivate *base = d->attachedPropertiesBase(engine))
+ return base->extraData.cd->attachedPropertiesFunc;
+ return nullptr;
}
const QMetaObject *QQmlType::attachedPropertiesType(QQmlEnginePrivate *engine) const
{
- if (!d)
- return nullptr;
- if (d->regType == CppType)
- return d->extraData.cd->attachedPropertiesType;
-
- QQmlType base;
- if (d->regType == CompositeType)
- base = d->resolveCompositeBaseType(engine);
- return base.attachedPropertiesType(engine);
+ if (const QQmlTypePrivate *base = d->attachedPropertiesBase(engine))
+ return base->extraData.cd->attachedPropertiesType;
+ return nullptr;
}
#if QT_DEPRECATED_SINCE(5, 14)
@@ -650,15 +638,9 @@ Qt 4.7 and QtQuick 1.0).
*/
int QQmlType::attachedPropertiesId(QQmlEnginePrivate *engine) const
{
- if (!d)
- return -1;
- if (d->regType == CppType)
- return d->extraData.cd->attachedPropertiesType ? d->index : -1;
-
- QQmlType base;
- if (d->regType == CompositeType)
- base = d->resolveCompositeBaseType(engine);
- return base.attachedPropertiesId(engine);
+ if (const QQmlTypePrivate *base = d->attachedPropertiesBase(engine))
+ return base->index;
+ return -1;
}
#endif
diff --git a/src/qml/qml/qqmltype_p.h b/src/qml/qml/qqmltype_p.h
index ec27b38a73..af134b21f1 100644
--- a/src/qml/qml/qqmltype_p.h
+++ b/src/qml/qml/qqmltype_p.h
@@ -182,6 +182,7 @@ public:
};
private:
+ friend class QQmlTypePrivate;
friend uint qHash(const QQmlType &t, uint seed);
QQmlRefPointer<const QQmlTypePrivate> d;
};
diff --git a/src/qml/qml/qqmltype_p_p.h b/src/qml/qml/qqmltype_p_p.h
index 6a2d961de8..51f776178c 100644
--- a/src/qml/qml/qqmltype_p_p.h
+++ b/src/qml/qml/qqmltype_p_p.h
@@ -82,6 +82,18 @@ public:
}
}
+ const QQmlTypePrivate *attachedPropertiesBase(QQmlEnginePrivate *engine) const
+ {
+ for (const QQmlTypePrivate *d = this; d; d = d->resolveCompositeBaseType(engine).d.data()) {
+ if (d->regType == QQmlType::CppType)
+ return d->extraData.cd->attachedPropertiesType ? d : nullptr;
+
+ if (d->regType != QQmlType::CompositeType)
+ return nullptr;
+ }
+ return nullptr;
+ }
+
bool isComposite() const
{
return regType == QQmlType::CompositeType || regType == QQmlType::CompositeSingletonType;
diff --git a/src/qml/qml/qqmltypecompiler.cpp b/src/qml/qml/qqmltypecompiler.cpp
index 7b4cf1a580..b4d56c9e49 100644
--- a/src/qml/qml/qqmltypecompiler.cpp
+++ b/src/qml/qml/qqmltypecompiler.cpp
@@ -530,12 +530,6 @@ bool QQmlEnumTypeResolver::resolveEnumBindings()
return true;
}
-struct StaticQtMetaObject : public QObject
-{
- static const QMetaObject *get()
- { return &staticQtMetaObject; }
-};
-
bool QQmlEnumTypeResolver::assignEnumToBinding(QmlIR::Binding *binding, const QStringRef &enumName, int enumValue, bool isQtObject)
{
if (enumName.length() > 0 && enumName[0].isLower() && !isQtObject) {
@@ -626,7 +620,7 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj,
value = type.enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue), &ok);
} else {
QByteArray enumName = enumValue.toUtf8();
- const QMetaObject *metaObject = StaticQtMetaObject::get();
+ const QMetaObject *metaObject = &Qt::staticMetaObject;
for (int ii = metaObject->enumeratorCount() - 1; !ok && ii >= 0; --ii) {
QMetaEnum e = metaObject->enumerator(ii);
value = e.keyToValue(enumName.constData(), &ok);
@@ -655,7 +649,7 @@ int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, const QStringRef &e
return type.enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue.constData(), enumValue.length()), ok);
}
- const QMetaObject *mo = StaticQtMetaObject::get();
+ const QMetaObject *mo = &Qt::staticMetaObject;
int i = mo->enumeratorCount();
const QByteArray ba = enumValue.toUtf8();
while (i--) {
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index b164f5873c..2de158884b 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -51,6 +51,8 @@
#include <QtQml/qqmlextensioninterface.h>
#include <QtQml/qqmlfile.h>
+#include <qtqml_tracepoints_p.h>
+
#include <QtCore/qdir.h>
#include <QtCore/qdiriterator.h>
#include <QtCore/qfile.h>
@@ -436,6 +438,7 @@ void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QString &fileName)
void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::SourceCodeData &d)
{
+ Q_TRACE_SCOPE(QQmlCompiling, blob->url());
QQmlCompilingProfiler prof(profiler(), blob);
blob->m_inCallback = true;
@@ -455,6 +458,7 @@ void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::SourceCodeD
void QQmlTypeLoader::setCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit)
{
+ Q_TRACE_SCOPE(QQmlCompiling, blob->url());
QQmlCompilingProfiler prof(profiler(), blob);
blob->m_inCallback = true;
@@ -573,8 +577,10 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo
QString qmldirFilePath;
QString qmldirUrl;
- if (m_importCache.locateQmldir(importDatabase, import->uri, import->majorVersion, import->minorVersion,
- &qmldirFilePath, &qmldirUrl)) {
+ const QQmlImports::LocalQmldirResult qmldirResult = m_importCache.locateLocalQmldir(
+ importDatabase, import->uri, import->majorVersion, import->minorVersion,
+ &qmldirFilePath, &qmldirUrl);
+ if (qmldirResult == QQmlImports::QmldirFound) {
// This is a local library import
if (!m_importCache.addLibraryImport(importDatabase, import->uri, import->qualifier, import->majorVersion,
import->minorVersion, qmldirFilePath, qmldirUrl, false, errors))
@@ -599,7 +605,9 @@ bool QQmlTypeLoader::Blob::addImport(QQmlTypeLoader::Blob::PendingImportPtr impo
} else {
// Is this a module?
if (QQmlMetaType::isAnyModule(import->uri)
- || QQmlMetaType::qmlRegisterModuleTypes(import->uri, import->majorVersion)) {
+ || (qmldirResult != QQmlImports::QmldirInterceptedToRemote
+ && QQmlMetaType::qmlRegisterModuleTypes(import->uri,
+ import->majorVersion))) {
if (!m_importCache.addLibraryImport(importDatabase, import->uri, import->qualifier, import->majorVersion,
import->minorVersion, QString(), QString(), false, errors))
return false;
@@ -710,7 +718,7 @@ bool QQmlTypeLoader::Blob::isDebugging() const
bool QQmlTypeLoader::Blob::diskCacheEnabled() const
{
- return (!disableDiskCache() || forceDiskCache()) && !isDebugging();
+ return (!disableDiskCache() && !isDebugging()) || forceDiskCache();
}
bool QQmlTypeLoader::Blob::qmldirDataAvailable(const QQmlRefPointer<QQmlQmldirData> &data, QList<QQmlError> *errors)
@@ -1129,7 +1137,8 @@ void QQmlTypeLoader::setQmldirContent(const QString &url, const QString &content
m_importQmlDirCache.insert(url, qmldir);
}
- qmldir->setContent(url, content);
+ if (!qmldir->hasContent())
+ qmldir->setContent(url, content);
}
/*!
diff --git a/src/qml/qml/qqmltypeloaderqmldircontent.cpp b/src/qml/qml/qqmltypeloaderqmldircontent.cpp
index 8e983db756..860971d296 100644
--- a/src/qml/qml/qqmltypeloaderqmldircontent.cpp
+++ b/src/qml/qml/qqmltypeloaderqmldircontent.cpp
@@ -74,6 +74,7 @@ QString QQmlTypeLoaderQmldirContent::typeNamespace() const
void QQmlTypeLoaderQmldirContent::setContent(const QString &location, const QString &content)
{
+ Q_ASSERT(!m_hasContent);
m_hasContent = true;
m_location = location;
m_parser.parse(content);
diff --git a/src/qml/qml/qqmltypemodule.cpp b/src/qml/qml/qqmltypemodule.cpp
index 9c9bf3e48f..9d6f269030 100644
--- a/src/qml/qml/qqmltypemodule.cpp
+++ b/src/qml/qml/qqmltypemodule.cpp
@@ -97,10 +97,14 @@ void QQmlTypeModule::add(QQmlTypePrivate *type)
QList<QQmlTypePrivate *> &list = d->typeHash[type->elementName];
for (int ii = 0; ii < list.count(); ++ii) {
- Q_ASSERT(list.at(ii));
- if (list.at(ii)->version_min < type->version_min) {
+ QQmlTypePrivate *in_list = list.at(ii);
+ Q_ASSERT(in_list);
+ if (in_list->version_min < type->version_min) {
list.insert(ii, type);
return;
+ } else if (in_list->version_min == type->version_min) {
+ list[ii] = type;
+ return;
}
}
list.append(type);
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index 9b5490b6e5..42a90e234c 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -62,30 +62,78 @@
QT_BEGIN_NAMESPACE
+class ResolvedList
+{
+ Q_DISABLE_COPY_MOVE(ResolvedList)
+
+public:
+ ResolvedList(QQmlListProperty<QObject> *prop) :
+ m_metaObject(static_cast<QQmlVMEMetaObject *>(QObjectPrivate::get(prop->object)->metaObject)),
+ m_id(quintptr(prop->data))
+ {
+ Q_ASSERT(m_metaObject);
+ Q_ASSERT(m_metaObject->object == prop->object);
+ Q_ASSERT(m_id <= quintptr(std::numeric_limits<int>::max() - m_metaObject->methodOffset()));
+
+ // readPropertyAsList() with checks transformed into Q_ASSERT
+ // and without allocation.
+ if (m_metaObject->propertyAndMethodStorage.isUndefined() &&
+ m_metaObject->propertyAndMethodStorage.valueRef()) {
+ return;
+ }
+
+ if (auto *md = static_cast<QV4::MemberData *>(
+ m_metaObject->propertyAndMethodStorage.asManaged())) {
+ const auto *v = (md->data() + m_id)->as<QV4::VariantObject>();
+ Q_ASSERT(v);
+ Q_ASSERT(v->d());
+ QVariant &data = v->d()->data();
+ Q_ASSERT(data.userType() == qMetaTypeId<QVector<QQmlGuard<QObject>>>());
+ m_list = static_cast<QVector<QQmlGuard<QObject>> *>(data.data());
+ Q_ASSERT(m_list);
+ }
+ }
+
+ ~ResolvedList() = default;
+
+ QQmlVMEMetaObject *metaObject() const { return m_metaObject; }
+ QVector<QQmlGuard<QObject>> *list() const { return m_list; }
+ quintptr id() const { return m_id; }
+
+ void activateSignal() const
+ {
+ m_metaObject->activate(m_metaObject->object, int(m_id + m_metaObject->methodOffset()),
+ nullptr);
+ }
+
+private:
+ QQmlVMEMetaObject *m_metaObject = nullptr;
+ QVector<QQmlGuard<QObject>> *m_list = nullptr;
+ quintptr m_id = 0;
+};
+
static void list_append(QQmlListProperty<QObject> *prop, QObject *o)
{
- QList<QObject *> *list = static_cast<QList<QObject *> *>(prop->data);
- list->append(o);
- static_cast<QQmlVMEMetaObject *>(prop->dummy1)->activate(prop->object, reinterpret_cast<quintptr>(prop->dummy2), nullptr);
+ const ResolvedList resolved(prop);
+ resolved.list()->append(o);
+ resolved.activateSignal();
}
static int list_count(QQmlListProperty<QObject> *prop)
{
- QList<QObject *> *list = static_cast<QList<QObject *> *>(prop->data);
- return list->count();
+ return ResolvedList(prop).list()->count();
}
static QObject *list_at(QQmlListProperty<QObject> *prop, int index)
{
- QList<QObject *> *list = static_cast<QList<QObject *> *>(prop->data);
- return list->at(index);
+ return ResolvedList(prop).list()->at(index);
}
static void list_clear(QQmlListProperty<QObject> *prop)
{
- QList<QObject *> *list = static_cast<QList<QObject *> *>(prop->data);
- list->clear();
- static_cast<QQmlVMEMetaObject *>(prop->dummy1)->activate(prop->object, reinterpret_cast<quintptr>(prop->dummy2), nullptr);
+ const ResolvedList resolved(prop);
+ resolved.list()->clear();
+ resolved.activateSignal();
}
QQmlVMEVariantQObjectPtr::QQmlVMEVariantQObjectPtr()
@@ -401,57 +449,20 @@ void QQmlVMEMetaObject::writeProperty(int id, double v)
void QQmlVMEMetaObject::writeProperty(int id, const QString& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
- if (md)
- md->set(engine, id, engine->newString(v));
-}
-
-void QQmlVMEMetaObject::writeProperty(int id, const QUrl& v)
-{
- QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
- if (md)
- md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
-}
-
-void QQmlVMEMetaObject::writeProperty(int id, const QDate& v)
-{
- QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
- if (md)
- md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
-}
-
-void QQmlVMEMetaObject::writeProperty(int id, const QDateTime& v)
-{
- QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
- if (md)
- md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
-}
-
-void QQmlVMEMetaObject::writeProperty(int id, const QPointF& v)
-{
- QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
- if (md)
- md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
-}
-
-void QQmlVMEMetaObject::writeProperty(int id, const QSizeF& v)
-{
- QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
- if (md)
- md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
-}
-
-void QQmlVMEMetaObject::writeProperty(int id, const QRectF& v)
-{
- QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
- if (md)
- md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
+ if (md) {
+ QV4::Scope scope(engine);
+ QV4::Scoped<QV4::MemberData>(scope, md)->set(engine, id, engine->newString(v));
+ }
}
void QQmlVMEMetaObject::writeProperty(int id, QObject* v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
- if (md)
- md->set(engine, id, QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(engine, v)));
+ if (md) {
+ QV4::Scope scope(engine);
+ QV4::Scoped<QV4::MemberData>(scope, md)->set(engine, id, QV4::Value::fromReturnedValue(
+ QV4::QObjectWrapper::wrap(engine, v)));
+ }
QQmlVMEVariantQObjectPtr *guard = getQObjectGuardForProperty(id);
if (v && !guard) {
@@ -598,7 +609,7 @@ QObject* QQmlVMEMetaObject::readPropertyAsQObject(int id) const
return wrapper->object();
}
-QList<QObject *> *QQmlVMEMetaObject::readPropertyAsList(int id) const
+QVector<QQmlGuard<QObject>> *QQmlVMEMetaObject::readPropertyAsList(int id) const
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (!md)
@@ -606,12 +617,12 @@ QList<QObject *> *QQmlVMEMetaObject::readPropertyAsList(int id) const
QV4::Scope scope(engine);
QV4::Scoped<QV4::VariantObject> v(scope, *(md->data() + id));
- if (!v || (int)v->d()->data().userType() != qMetaTypeId<QList<QObject *> >()) {
- QVariant variant(QVariant::fromValue(QList<QObject*>()));
+ if (!v || (int)v->d()->data().userType() != qMetaTypeId<QVector<QQmlGuard<QObject>> >()) {
+ QVariant variant(QVariant::fromValue(QVector<QQmlGuard<QObject>>()));
v = engine->newVariantObject(variant);
md->set(engine, id, v);
}
- return static_cast<QList<QObject *> *>(v->d()->data().data());
+ return static_cast<QVector<QQmlGuard<QObject>> *>(v->d()->data().data());
}
QRectF QQmlVMEMetaObject::readPropertyAsRectF(int id) const
@@ -720,13 +731,11 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
break;
case QV4::CompiledData::BuiltinType::InvalidBuiltin:
if (property.isList) {
- QList<QObject *> *list = readPropertyAsList(id);
- QQmlListProperty<QObject> *p = static_cast<QQmlListProperty<QObject> *>(a[0]);
- *p = QQmlListProperty<QObject>(object, list,
- list_append, list_count, list_at,
- list_clear);
- p->dummy1 = this;
- p->dummy2 = reinterpret_cast<void *>(quintptr(methodOffset() + id));
+ readPropertyAsList(id); // Initializes if necessary
+ *static_cast<QQmlListProperty<QObject> *>(a[0])
+ = QQmlListProperty<QObject>(
+ object, reinterpret_cast<void *>(quintptr(id)),
+ list_append, list_count, list_at, list_clear);
} else {
*reinterpret_cast<QObject **>(a[0]) = readPropertyAsQObject(id);
}
@@ -877,7 +886,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
int rv = QMetaObject::metacall(valueType, c, valueTypePropertyIndex, a);
if (c == QMetaObject::WriteProperty)
- valueType->write(target, coreIndex, nullptr);
+ valueType->write(target, coreIndex, {});
return rv;
} else {
diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h
index 5025987586..e17701a968 100644
--- a/src/qml/qml/qqmlvmemetaobject_p.h
+++ b/src/qml/qml/qqmlvmemetaobject_p.h
@@ -188,18 +188,24 @@ public:
QDateTime readPropertyAsDateTime(int id);
QRectF readPropertyAsRectF(int id) const;
QObject *readPropertyAsQObject(int id) const;
- QList<QObject *> *readPropertyAsList(int id) const;
+ QVector<QQmlGuard<QObject> > *readPropertyAsList(int id) const;
void writeProperty(int id, int v);
void writeProperty(int id, bool v);
void writeProperty(int id, double v);
void writeProperty(int id, const QString& v);
- void writeProperty(int id, const QPointF& v);
- void writeProperty(int id, const QSizeF& v);
- void writeProperty(int id, const QUrl& v);
- void writeProperty(int id, const QDate& v);
- void writeProperty(int id, const QDateTime& v);
- void writeProperty(int id, const QRectF& v);
+
+ template<typename VariantCompatible>
+ void writeProperty(int id, const VariantCompatible &v)
+ {
+ QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
+ if (md) {
+ QV4::Scope scope(engine);
+ QV4::Scoped<QV4::MemberData>(scope, md)->set(engine, id, engine->newVariantObject(
+ QVariant::fromValue(v)));
+ }
+ }
+
void writeProperty(int id, QObject *v);
void ensureQObjectWrapper();
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index 4db0562c0e..2afbdb616b 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -54,6 +54,7 @@
#include <QtCore/qobject.h>
#include <QtQml/qjsvalue.h>
#include <QtQml/qjsengine.h>
+#include <QtQml/qqmlfile.h>
#include <QtNetwork/qnetworkreply.h>
#include <QtCore/qtextcodec.h>
#include <QtCore/qxmlstream.h>
@@ -77,6 +78,8 @@ using namespace QV4;
QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(xhrDump, QML_XHR_DUMP);
+DEFINE_BOOL_CONFIG_OPTION(xhrFileWrite, QML_XHR_ALLOW_FILE_WRITE);
+DEFINE_BOOL_CONFIG_OPTION(xhrFileRead, QML_XHR_ALLOW_FILE_READ);
struct QQmlXMLHttpRequestData {
QQmlXMLHttpRequestData();
@@ -1195,6 +1198,37 @@ void QQmlXMLHttpRequest::fillHeadersList()
void QQmlXMLHttpRequest::requestFromUrl(const QUrl &url)
{
QNetworkRequest request = m_request;
+
+ if (QQmlFile::isLocalFile(url)) {
+ if (m_method == QLatin1String("PUT"))
+ {
+ if (!xhrFileWrite()) {
+ if (qEnvironmentVariableIsSet("QML_XHR_ALLOW_FILE_WRITE")) {
+ qWarning("XMLHttpRequest: Tried to use PUT on a local file despite being disabled.");
+ return;
+ } else {
+ qWarning("XMLHttpRequest: Using PUT on a local file is dangerous "
+ "and will be disabled by default in a future Qt version."
+ "Set QML_XHR_ALLOW_FILE_WRITE to 1 if you wish to continue using this feature.");
+ }
+ }
+ } else if (m_method == QLatin1String("GET")) {
+ if (!xhrFileRead()) {
+ if (qEnvironmentVariableIsSet("QML_XHR_ALLOW_FILE_READ")) {
+ qWarning("XMLHttpRequest: Tried to use GET on a local file despite being disabled.");
+ return;
+ } else {
+ qWarning("XMLHttpRequest: Using GET on a local file is dangerous "
+ "and will be disabled by default in a future Qt version."
+ "Set QML_XHR_ALLOW_FILE_READ to 1 if you wish to continue using this feature.");
+ }
+ }
+ } else {
+ qWarning("XMLHttpRequest: Unsupported method used on a local file");
+ return;
+ }
+ }
+
request.setUrl(url);
if(m_method == QLatin1String("POST") ||
m_method == QLatin1String("PUT")) {
@@ -1389,13 +1423,17 @@ void QQmlXMLHttpRequest::finished()
QVariant redirect = m_network->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (redirect.isValid()) {
QUrl url = m_network->url().resolved(redirect.toUrl());
- if (url.scheme() != QLatin1String("file")) {
+ if (!QQmlFile::isLocalFile(url)) {
// See http://www.ietf.org/rfc/rfc2616.txt, section 10.3.4 "303 See Other":
// Result of 303 redirection should be a new "GET" request.
const QVariant code = m_network->attribute(QNetworkRequest::HttpStatusCodeAttribute);
if (code.isValid() && code.toInt() == 303 && m_method != QLatin1String("GET"))
m_method = QStringLiteral("GET");
destroyNetwork();
+
+ // Discard redirect response body
+ m_responseEntityBody = QByteArray();
+
requestFromUrl(url);
return;
}
@@ -1647,7 +1685,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
Scope scope(f->engine());
const QQmlXMLHttpRequestCtor *ctor = static_cast<const QQmlXMLHttpRequestCtor *>(f);
- QQmlXMLHttpRequest *r = new QQmlXMLHttpRequest(scope.engine->qmlEngine()->networkAccessManager(), scope.engine);
+ QQmlXMLHttpRequest *r = new QQmlXMLHttpRequest(scope.engine->networkAccessManager(scope.engine), scope.engine);
Scoped<QQmlXMLHttpRequestWrapper> w(scope, scope.engine->memoryManager->allocate<QQmlXMLHttpRequestWrapper>(r));
ScopedObject proto(scope, ctor->d()->proto);
w->setPrototypeUnchecked(proto);
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index d634a48443..2c1956553f 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -93,12 +93,6 @@ DEFINE_OBJECT_VTABLE(QtObject);
return scope.engine->throwTypeError(QString::fromUtf8(msg)); \
} while (false)
-struct StaticQtMetaObject : public QObject
-{
- static const QMetaObject *get()
- { return &staticQtMetaObject; }
-};
-
void Heap::QtObject::init(QQmlEngine *qmlEngine)
{
Heap::Object::init();
@@ -177,7 +171,7 @@ ReturnedValue QtObject::findAndAdd(const QString *name, bool &foundProperty) con
ScopedString key(scope);
ScopedValue value(scope);
- const QMetaObject *qtMetaObject = StaticQtMetaObject::get();
+ const QMetaObject *qtMetaObject = &Qt::staticMetaObject;
for (int enumCount = qtMetaObject->enumeratorCount(); d()->enumeratorIterator < enumCount;
++d()->enumeratorIterator) {
QMetaEnum enumerator = qtMetaObject->enumerator(d()->enumeratorIterator);
@@ -1553,11 +1547,12 @@ static QString jsStack(QV4::ExecutionEngine *engine) {
return stack;
}
-static QString serializeArray(Object *array, ExecutionEngine *v4) {
+static QString serializeArray(Object *array, ExecutionEngine *v4, QSet<QV4::Heap::Object *> &alreadySeen) {
Scope scope(v4);
ScopedValue val(scope);
QString result;
+ alreadySeen.insert(array->d());
result += QLatin1Char('[');
const uint length = array->getLength();
for (uint i = 0; i < length; ++i) {
@@ -1565,12 +1560,15 @@ static QString serializeArray(Object *array, ExecutionEngine *v4) {
result += QLatin1Char(',');
val = array->get(i);
if (val->isManaged() && val->managed()->isArrayLike())
- result += serializeArray(val->objectValue(), v4);
+ if (!alreadySeen.contains(val->objectValue()->d()))
+ result += serializeArray(val->objectValue(), v4, alreadySeen);
+ else
+ result += QLatin1String("[Circular]");
else
result += val->toQStringNoThrow();
}
result += QLatin1Char(']');
-
+ alreadySeen.remove(array->d());
return result;
};
@@ -1600,8 +1598,9 @@ static ReturnedValue writeToConsole(const FunctionObject *b, const Value *, cons
if (i != start)
result.append(QLatin1Char(' '));
+ QSet<QV4::Heap::Object *> alreadySeenElements;
if (argv[i].isManaged() && argv[i].managed()->isArrayLike())
- result.append(serializeArray(argv[i].objectValue(), v4));
+ result.append(serializeArray(argv[i].objectValue(), v4, alreadySeenElements));
else
result.append(argv[i].toQStringNoThrow());
}