diff options
author | Andy Nichols <andy.nichols@qt.io> | 2016-04-26 11:55:04 +0200 |
---|---|---|
committer | Andy Nichols <andy.nichols@qt.io> | 2016-04-26 11:55:12 +0200 |
commit | e4d56b01b30ad6c8482dab3dab6600676a9d6632 (patch) | |
tree | 6502d7459ec5a44d428e003ff15c6b498fc7f29f /src | |
parent | ed62c8f668bb0f7f17946764d510e286f111688a (diff) | |
parent | 26ecc82374c476ee417ab04c455022f76909ba51 (diff) |
Merge remote-tracking branch 'origin/dev' into scenegraphng
Change-Id: Ib990cfbd43d4a8c0ca412b492d507424cd9e58d4
Diffstat (limited to 'src')
43 files changed, 684 insertions, 277 deletions
diff --git a/src/imports/folderlistmodel/plugin.cpp b/src/imports/folderlistmodel/plugin.cpp index c60538673b..38de232dc0 100644 --- a/src/imports/folderlistmodel/plugin.cpp +++ b/src/imports/folderlistmodel/plugin.cpp @@ -59,7 +59,7 @@ class QmlFolderListModelPlugin : public QQmlExtensionPlugin public: QmlFolderListModelPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); } - virtual void registerTypes(const char *uri) + void registerTypes(const char *uri) Q_DECL_OVERRIDE { Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.folderlistmodel")); #ifndef QT_NO_DIRMODEL diff --git a/src/imports/layouts/plugin.cpp b/src/imports/layouts/plugin.cpp index 248b12ac31..64d687cf3b 100644 --- a/src/imports/layouts/plugin.cpp +++ b/src/imports/layouts/plugin.cpp @@ -61,7 +61,7 @@ public: { initResources(); } - virtual void registerTypes(const char *uri) + void registerTypes(const char *uri) Q_DECL_OVERRIDE { Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Layouts")); Q_UNUSED(uri); diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp index da1817d309..8780dcc757 100644 --- a/src/imports/localstorage/plugin.cpp +++ b/src/imports/localstorage/plugin.cpp @@ -761,7 +761,7 @@ public: { initResources(); } - void registerTypes(const char *uri) + void registerTypes(const char *uri) Q_DECL_OVERRIDE { Q_ASSERT(QLatin1String(uri) == "QtQuick.LocalStorage"); qmlRegisterSingletonType<QQuickLocalStorage>(uri, 2, 0, "LocalStorage", module_api_factory); diff --git a/src/imports/models/plugin.cpp b/src/imports/models/plugin.cpp index 9f96ace8fe..046d69cbc5 100644 --- a/src/imports/models/plugin.cpp +++ b/src/imports/models/plugin.cpp @@ -78,7 +78,7 @@ class QtQmlModelsPlugin : public QQmlExtensionPlugin Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") public: QtQmlModelsPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); } - virtual void registerTypes(const char *uri) + void registerTypes(const char *uri) Q_DECL_OVERRIDE { Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQml.Models")); Q_UNUSED(uri); diff --git a/src/imports/particles/plugin.cpp b/src/imports/particles/plugin.cpp index 0698f34020..22eea16d4c 100644 --- a/src/imports/particles/plugin.cpp +++ b/src/imports/particles/plugin.cpp @@ -57,7 +57,7 @@ class QtQuick2ParticlesPlugin : public QQmlExtensionPlugin Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") public: QtQuick2ParticlesPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); } - virtual void registerTypes(const char *uri) + void registerTypes(const char *uri) Q_DECL_OVERRIDE { Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Particles")); Q_UNUSED(uri); diff --git a/src/imports/qtquick2/plugin.cpp b/src/imports/qtquick2/plugin.cpp index 315ad0ce58..1e3ff255f8 100644 --- a/src/imports/qtquick2/plugin.cpp +++ b/src/imports/qtquick2/plugin.cpp @@ -57,7 +57,7 @@ class QtQuick2Plugin : public QQmlExtensionPlugin Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") public: QtQuick2Plugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); } - virtual void registerTypes(const char *uri) + void registerTypes(const char *uri) Q_DECL_OVERRIDE { Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick")); Q_UNUSED(uri); diff --git a/src/imports/settings/plugin.cpp b/src/imports/settings/plugin.cpp index c97c2b066e..ce498774d2 100644 --- a/src/imports/settings/plugin.cpp +++ b/src/imports/settings/plugin.cpp @@ -58,7 +58,7 @@ class QmlSettingsPlugin : public QQmlExtensionPlugin public: QmlSettingsPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); } - virtual void registerTypes(const char *uri) + void registerTypes(const char *uri) Q_DECL_OVERRIDE { Q_ASSERT(QByteArray(uri) == QByteArray("Qt.labs.settings")); qmlRegisterType<QQmlSettings>(uri, 1, 0, "Settings"); diff --git a/src/imports/statemachine/plugin.cpp b/src/imports/statemachine/plugin.cpp index db79751b69..c061607f40 100644 --- a/src/imports/statemachine/plugin.cpp +++ b/src/imports/statemachine/plugin.cpp @@ -63,7 +63,7 @@ class QtQmlStateMachinePlugin : public QQmlExtensionPlugin public: QtQmlStateMachinePlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); } - void registerTypes(const char *uri) + void registerTypes(const char *uri) Q_DECL_OVERRIDE { qmlRegisterType<State>(uri, 1, 0, "State"); qmlRegisterType<StateMachine>(uri, 1, 0, "StateMachine"); diff --git a/src/imports/statemachine/statemachine.h b/src/imports/statemachine/statemachine.h index 8a05acfbde..59a810f387 100644 --- a/src/imports/statemachine/statemachine.h +++ b/src/imports/statemachine/statemachine.h @@ -48,8 +48,6 @@ QT_BEGIN_NAMESPACE -class QQmlOpenMetaObject; - class StateMachine : public QStateMachine, public QQmlParserStatus { Q_OBJECT diff --git a/src/imports/testlib/main.cpp b/src/imports/testlib/main.cpp index 26ce79c92b..1632d7ba64 100644 --- a/src/imports/testlib/main.cpp +++ b/src/imports/testlib/main.cpp @@ -151,7 +151,7 @@ class QTestQmlModule : public QQmlExtensionPlugin public: QTestQmlModule(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); } - virtual void registerTypes(const char *uri) + void registerTypes(const char *uri) Q_DECL_OVERRIDE { Q_ASSERT(QLatin1String(uri) == QLatin1String("QtTest")); qmlRegisterType<QuickTestResult, 0>(uri,1,0,"TestResult"); @@ -159,10 +159,6 @@ public: qmlRegisterType<QuickTestEvent>(uri,1,0,"TestEvent"); qmlRegisterType<QuickTestUtil>(uri,1,0,"TestUtil"); } - - void initializeEngine(QQmlEngine *, const char *) - { - } }; QT_END_NAMESPACE diff --git a/src/imports/window/plugin.cpp b/src/imports/window/plugin.cpp index a0a5724e34..b85ccc6dc7 100644 --- a/src/imports/window/plugin.cpp +++ b/src/imports/window/plugin.cpp @@ -73,7 +73,7 @@ class QtQuick2WindowPlugin : public QQmlExtensionPlugin Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") public: QtQuick2WindowPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); } - virtual void registerTypes(const char *uri) + void registerTypes(const char *uri) Q_DECL_OVERRIDE { Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Window")); Q_UNUSED(uri); diff --git a/src/imports/xmllistmodel/plugin.cpp b/src/imports/xmllistmodel/plugin.cpp index e983b494e1..ca676c36b0 100644 --- a/src/imports/xmllistmodel/plugin.cpp +++ b/src/imports/xmllistmodel/plugin.cpp @@ -58,7 +58,7 @@ class QmlXmlListModelPlugin : public QQmlExtensionPlugin public: QmlXmlListModelPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); } - virtual void registerTypes(const char *uri) + void registerTypes(const char *uri) Q_DECL_OVERRIDE { Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.XmlListModel")); qmlRegisterType<QQuickXmlListModel>(uri,2,0,"XmlListModel"); diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h index 93a7170e68..93043135a4 100644 --- a/src/qml/compiler/qv4instr_moth_p.h +++ b/src/qml/compiler/qv4instr_moth_p.h @@ -81,9 +81,19 @@ QT_BEGIN_NAMESPACE F(SetLookup, setLookup) \ F(StoreQObjectProperty, storeQObjectProperty) \ F(LoadQObjectProperty, loadQObjectProperty) \ + F(LoadQRealQObjectPropertyDirectly, loadQRealQObjectPropertyDirectly) \ + F(LoadQObjectQObjectPropertyDirectly, loadQObjectQObjectPropertyDirectly) \ + F(LoadIntQObjectPropertyDirectly, loadIntQObjectPropertyDirectly) \ + F(LoadBoolQObjectPropertyDirectly, loadBoolQObjectPropertyDirectly) \ + F(LoadQStringQObjectPropertyDirectly, loadQStringQObjectPropertyDirectly) \ F(StoreScopeObjectProperty, storeScopeObjectProperty) \ F(StoreContextObjectProperty, storeContextObjectProperty) \ F(LoadScopeObjectProperty, loadScopeObjectProperty) \ + F(LoadScopeObjectQRealPropertyDirectly, loadScopeObjectQRealPropertyDirectly) \ + F(LoadScopeObjectQObjectPropertyDirectly, loadScopeObjectQObjectPropertyDirectly) \ + F(LoadScopeObjectIntPropertyDirectly, loadScopeObjectIntPropertyDirectly) \ + F(LoadScopeObjectBoolPropertyDirectly, loadScopeObjectBoolPropertyDirectly) \ + F(LoadScopeObjectQStringPropertyDirectly, loadScopeObjectQStringPropertyDirectly) \ F(LoadContextObjectProperty, loadContextObjectProperty) \ F(LoadIdObject, loadIdObject) \ F(LoadAttachedQObjectProperty, loadAttachedQObjectProperty) \ @@ -323,6 +333,36 @@ union Instr Param base; Param result; }; + struct instr_loadScopeObjectQRealPropertyDirectly { + MOTH_INSTR_HEADER + Param base; + Param result; + QQmlAccessors *accessors; + }; + struct instr_loadScopeObjectQObjectPropertyDirectly { + MOTH_INSTR_HEADER + Param base; + Param result; + QQmlAccessors *accessors; + }; + struct instr_loadScopeObjectIntPropertyDirectly { + MOTH_INSTR_HEADER + Param base; + Param result; + QQmlAccessors *accessors; + }; + struct instr_loadScopeObjectBoolPropertyDirectly { + MOTH_INSTR_HEADER + Param base; + Param result; + QQmlAccessors *accessors; + }; + struct instr_loadScopeObjectQStringPropertyDirectly { + MOTH_INSTR_HEADER + Param base; + Param result; + QQmlAccessors *accessors; + }; struct instr_loadContextObjectProperty { MOTH_INSTR_HEADER int propertyIndex; @@ -342,6 +382,46 @@ union Instr Param result; bool captureRequired; }; + struct instr_loadQRealQObjectPropertyDirectly { + MOTH_INSTR_HEADER + Param base; + Param result; + QQmlAccessors *accessors; + int coreIndex; + int notifyIndex; + }; + struct instr_loadQObjectQObjectPropertyDirectly { + MOTH_INSTR_HEADER + Param base; + Param result; + QQmlAccessors *accessors; + int coreIndex; + int notifyIndex; + }; + struct instr_loadIntQObjectPropertyDirectly { + MOTH_INSTR_HEADER + Param base; + Param result; + QQmlAccessors *accessors; + int coreIndex; + int notifyIndex; + }; + struct instr_loadBoolQObjectPropertyDirectly { + MOTH_INSTR_HEADER + Param base; + Param result; + QQmlAccessors *accessors; + int coreIndex; + int notifyIndex; + }; + struct instr_loadQStringQObjectPropertyDirectly { + MOTH_INSTR_HEADER + Param base; + Param result; + QQmlAccessors *accessors; + int coreIndex; + int notifyIndex; + }; struct instr_loadAttachedQObjectProperty { MOTH_INSTR_HEADER int propertyIndex; @@ -800,9 +880,19 @@ union Instr instr_loadProperty loadProperty; instr_getLookup getLookup; instr_loadScopeObjectProperty loadScopeObjectProperty; + instr_loadScopeObjectQRealPropertyDirectly loadScopeObjectQRealPropertyDirectly; + instr_loadScopeObjectQObjectPropertyDirectly loadScopeObjectQObjectPropertyDirectly; + instr_loadScopeObjectIntPropertyDirectly loadScopeObjectIntPropertyDirectly; + instr_loadScopeObjectBoolPropertyDirectly loadScopeObjectBoolPropertyDirectly; + instr_loadScopeObjectQStringPropertyDirectly loadScopeObjectQStringPropertyDirectly; instr_loadContextObjectProperty loadContextObjectProperty; instr_loadIdObject loadIdObject; instr_loadQObjectProperty loadQObjectProperty; + instr_loadQRealQObjectPropertyDirectly loadQRealQObjectPropertyDirectly; + instr_loadQObjectQObjectPropertyDirectly loadQObjectQObjectPropertyDirectly; + instr_loadIntQObjectPropertyDirectly loadIntQObjectPropertyDirectly; + instr_loadBoolQObjectPropertyDirectly loadBoolQObjectPropertyDirectly; + instr_loadQStringQObjectPropertyDirectly loadQStringQObjectPropertyDirectly; instr_loadAttachedQObjectProperty loadAttachedQObjectProperty; instr_storeProperty storeProperty; instr_setLookup setLookup; diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index edd8425678..b452c4b3d9 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -46,6 +46,8 @@ #include <private/qv4regexpobject_p.h> #include <private/qv4compileddata_p.h> #include <private/qqmlengine_p.h> +#include "qml/qqmlaccessors_p.h" +#include "qml/qqmlpropertycache_p.h" #undef USE_TYPE_INFO @@ -737,8 +739,51 @@ void InstructionSelection::setQObjectProperty(IR::Expr *source, IR::Expr *target addInstruction(store); } -void InstructionSelection::getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, IR::Expr *target) -{ +void InstructionSelection::getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, + QQmlPropertyData *property, int index, + IR::Expr *target) +{ + if (property && property->hasAccessors() && property->isFullyResolved()) { + if (kind == IR::Member::MemberOfQmlScopeObject) { + if (property->propType == QMetaType::QReal) { + Instruction::LoadScopeObjectQRealPropertyDirectly load; + load.base = getParam(source); + load.accessors = property->accessors; + load.result = getResultParam(target); + addInstruction(load); + return; + } else if (property->isQObject()) { + Instruction::LoadScopeObjectQObjectPropertyDirectly load; + load.base = getParam(source); + load.accessors = property->accessors; + load.result = getResultParam(target); + addInstruction(load); + return; + } else if (property->propType == QMetaType::Int) { + Instruction::LoadScopeObjectIntPropertyDirectly load; + load.base = getParam(source); + load.accessors = property->accessors; + load.result = getResultParam(target); + addInstruction(load); + return; + } else if (property->propType == QMetaType::Bool) { + Instruction::LoadScopeObjectBoolPropertyDirectly load; + load.base = getParam(source); + load.accessors = property->accessors; + load.result = getResultParam(target); + addInstruction(load); + return; + } else if (property->propType == QMetaType::QString) { + Instruction::LoadScopeObjectQStringPropertyDirectly load; + load.base = getParam(source); + load.accessors = property->accessors; + load.result = getResultParam(target); + addInstruction(load); + return; + } + } + } + if (kind == IR::Member::MemberOfQmlScopeObject) { Instruction::LoadScopeObjectProperty load; load.base = getParam(source); @@ -762,8 +807,59 @@ void InstructionSelection::getQmlContextProperty(IR::Expr *source, IR::Member::M } } -void InstructionSelection::getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingletonProperty, int attachedPropertiesId, IR::Expr *target) -{ +void InstructionSelection::getQObjectProperty(IR::Expr *base, QQmlPropertyData *property, bool captureRequired, bool isSingletonProperty, int attachedPropertiesId, IR::Expr *target) +{ + if (property && property->hasAccessors() && property->isFullyResolved()) { + if (!attachedPropertiesId && !isSingletonProperty) { + if (property->propType == QMetaType::QReal) { + Instruction::LoadQRealQObjectPropertyDirectly load; + load.base = getParam(base); + load.accessors = property->accessors; + load.coreIndex = property->coreIndex; + load.notifyIndex = captureRequired ? property->notifyIndex : -1; + load.result = getResultParam(target); + addInstruction(load); + return; + } else if (property->isQObject()) { + Instruction::LoadQObjectQObjectPropertyDirectly load; + load.base = getParam(base); + load.accessors = property->accessors; + load.coreIndex = property->coreIndex; + load.notifyIndex = captureRequired ? property->notifyIndex : -1; + load.result = getResultParam(target); + addInstruction(load); + return; + } else if (property->propType == QMetaType::Int) { + Instruction::LoadIntQObjectPropertyDirectly load; + load.base = getParam(base); + load.accessors = property->accessors; + load.coreIndex = property->coreIndex; + load.notifyIndex = captureRequired ? property->notifyIndex : -1; + load.result = getResultParam(target); + addInstruction(load); + return; + } else if (property->propType == QMetaType::Bool) { + Instruction::LoadBoolQObjectPropertyDirectly load; + load.base = getParam(base); + load.accessors = property->accessors; + load.coreIndex = property->coreIndex; + load.notifyIndex = captureRequired ? property->notifyIndex : -1; + load.result = getResultParam(target); + addInstruction(load); + return; + } else if (property->propType == QMetaType::QString) { + Instruction::LoadQStringQObjectPropertyDirectly load; + load.base = getParam(base); + load.accessors = property->accessors; + load.coreIndex = property->coreIndex; + load.notifyIndex = captureRequired ? property->notifyIndex : -1; + load.result = getResultParam(target); + addInstruction(load); + return; + } + } + } + const int propertyIndex = property->coreIndex; if (attachedPropertiesId != 0) { Instruction::LoadAttachedQObjectProperty load; load.propertyIndex = propertyIndex; diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h index 29d117af38..bf3909682d 100644 --- a/src/qml/compiler/qv4isel_moth_p.h +++ b/src/qml/compiler/qv4isel_moth_p.h @@ -134,8 +134,8 @@ protected: virtual void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &targetName); virtual void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex); virtual void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex); - virtual void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, IR::Expr *target); - virtual void getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target); + virtual void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, QQmlPropertyData *property, int index, IR::Expr *target); + virtual void getQObjectProperty(IR::Expr *base, QQmlPropertyData *property, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target); virtual void getElement(IR::Expr *base, IR::Expr *index, IR::Expr *target); virtual void setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex); virtual void copyValue(IR::Expr *source, IR::Expr *target); diff --git a/src/qml/compiler/qv4isel_p.cpp b/src/qml/compiler/qv4isel_p.cpp index 0ae08160ab..6ba23a0951 100644 --- a/src/qml/compiler/qv4isel_p.cpp +++ b/src/qml/compiler/qv4isel_p.cpp @@ -156,14 +156,15 @@ void IRDecoder::visitMove(IR::Move *s) } } if (m->kind == IR::Member::MemberOfQmlScopeObject || m->kind == IR::Member::MemberOfQmlContextObject) { - getQmlContextProperty(m->base, (IR::Member::MemberKind)m->kind, m->property->coreIndex, s->target); + getQmlContextProperty(m->base, (IR::Member::MemberKind)m->kind, m->property, + m->property->coreIndex, s->target); return; } - getQObjectProperty(m->base, m->property->coreIndex, captureRequired, isSingletonProperty, attachedPropertiesId, s->target); + getQObjectProperty(m->base, m->property, captureRequired, isSingletonProperty, attachedPropertiesId, s->target); #endif // V4_BOOTSTRAP return; } else if (m->kind == IR::Member::MemberOfIdObjectsArray) { - getQmlContextProperty(m->base, (IR::Member::MemberKind)m->kind, m->idIndex, s->target); + getQmlContextProperty(m->base, (IR::Member::MemberKind)m->kind, nullptr, m->idIndex, s->target); return; } else if (m->base->asTemp() || m->base->asConst() || m->base->asArgLocal()) { getProperty(m->base, *m->name, s->target); diff --git a/src/qml/compiler/qv4isel_p.h b/src/qml/compiler/qv4isel_p.h index 88d2071c52..2ee776adf4 100644 --- a/src/qml/compiler/qv4isel_p.h +++ b/src/qml/compiler/qv4isel_p.h @@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE +class QQmlAccessors; class QQmlEnginePrivate; namespace QV4 { @@ -165,8 +166,8 @@ public: // to implement by subclasses: virtual void setActivationProperty(IR::Expr *source, const QString &targetName) = 0; virtual void initClosure(IR::Closure *closure, IR::Expr *target) = 0; virtual void getProperty(IR::Expr *base, const QString &name, IR::Expr *target) = 0; - virtual void getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingletonProperty, int attachedPropertiesId, IR::Expr *target) = 0; - virtual void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, IR::Expr *target) = 0; + virtual void getQObjectProperty(IR::Expr *base, QQmlPropertyData *property, bool captureRequired, bool isSingletonProperty, int attachedPropertiesId, IR::Expr *target) = 0; + virtual void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, QQmlPropertyData *property, int index, IR::Expr *target) = 0; virtual void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &targetName) = 0; virtual void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex) = 0; virtual void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex) = 0; diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp index b28db59190..370dfd0fae 100644 --- a/src/qml/compiler/qv4jsir.cpp +++ b/src/qml/compiler/qv4jsir.cpp @@ -927,12 +927,16 @@ void IRPrinter::visitMember(Member *e) e->base->accept(this); *out << '.' << *e->name; #ifndef V4_BOOTSTRAP - if (e->property) + if (e->property) { *out << " (meta-property " << e->property->coreIndex - << " <" << QMetaType::typeName(e->property->propType) - << ">)"; - else if (e->kind == Member::MemberOfIdObjectsArray) + << " <" << QMetaType::typeName(e->property->propType) << ">"; + if (e->property->hasAccessors() && e->property->isFullyResolved()) { + *out << ", accessible"; + } + *out << ")"; + } else if (e->kind == Member::MemberOfIdObjectsArray) { *out << "(id object " << e->idIndex << ")"; + } #endif } diff --git a/src/qml/doc/src/javascript/functionlist.qdoc b/src/qml/doc/src/javascript/functionlist.qdoc index 7f0e844b65..8b9c33f994 100644 --- a/src/qml/doc/src/javascript/functionlist.qdoc +++ b/src/qml/doc/src/javascript/functionlist.qdoc @@ -174,6 +174,8 @@ \li charAt(pos) \li charCodeAt(pos) \li concat([string1 [, string2 [, ...]]]) + \li endsWith(searchString [, endPosition ]) // ECMAScript 6: Added in Qt 5.8 + \li includes(searchString [, position ]) // ECMAScript 6: Added in 5.8 \li indexOf(searchString ,position) \li lastIndexOf(searchString, position) \li localeCompare(that) @@ -182,6 +184,7 @@ \li search(regexp) \li slice(start, end) \li split(separator, limit) + \li startsWith(searchString [, position ]) // ECMAScript 6: Added in Qt 5.8 \li substring(start, end) \li toLowerCase() \li toLocaleLowerCase() diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp index 149037939b..1f5a247a17 100644 --- a/src/qml/jit/qv4isel_masm.cpp +++ b/src/qml/jit/qv4isel_masm.cpp @@ -49,6 +49,7 @@ #include "qv4assembler_p.h" #include "qv4unop_p.h" #include "qv4binop_p.h" +#include <private/qqmlpropertycache_p.h> #include <QtCore/QBuffer> #include <QtCore/QCoreApplication> @@ -753,8 +754,39 @@ void InstructionSelection::getProperty(IR::Expr *base, const QString &name, IR:: } } -void InstructionSelection::getQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int index, IR::Expr *target) +void InstructionSelection::getQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, QQmlPropertyData *property, int index, IR::Expr *target) { + if (property && property->hasAccessors() && property->isFullyResolved()) { + if (kind == IR::Member::MemberOfQmlScopeObject) { + if (property->propType == QMetaType::QReal) { + generateRuntimeCall(target, accessQmlScopeObjectQRealProperty, + Assembler::PointerToValue(base), + Assembler::TrustedImmPtr(property->accessors)); + return; + } else if (property->isQObject()) { + generateRuntimeCall(target, accessQmlScopeObjectQObjectProperty, + Assembler::PointerToValue(base), + Assembler::TrustedImmPtr(property->accessors)); + return; + } else if (property->propType == QMetaType::Int) { + generateRuntimeCall(target, accessQmlScopeObjectIntProperty, + Assembler::PointerToValue(base), + Assembler::TrustedImmPtr(property->accessors)); + return; + } else if (property->propType == QMetaType::Bool) { + generateRuntimeCall(target, accessQmlScopeObjectBoolProperty, + Assembler::PointerToValue(base), + Assembler::TrustedImmPtr(property->accessors)); + return; + } else if (property->propType == QMetaType::QString) { + generateRuntimeCall(target, accessQmlScopeObjectQStringProperty, + Assembler::PointerToValue(base), + Assembler::TrustedImmPtr(property->accessors)); + return; + } + } + } + if (kind == IR::Member::MemberOfQmlScopeObject) generateRuntimeCall(target, getQmlScopeObjectProperty, Assembler::EngineRegister, Assembler::PointerToValue(base), Assembler::TrustedImm32(index)); else if (kind == IR::Member::MemberOfQmlContextObject) @@ -765,8 +797,51 @@ void InstructionSelection::getQmlContextProperty(IR::Expr *base, IR::Member::Mem Q_ASSERT(false); } -void InstructionSelection::getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target) +void InstructionSelection::getQObjectProperty(IR::Expr *base, QQmlPropertyData *property, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target) { + if (property && property->hasAccessors() && property->isFullyResolved()) { + if (!attachedPropertiesId && !isSingleton) { + const int notifyIndex = captureRequired ? property->notifyIndex : -1; + if (property->propType == QMetaType::QReal) { + generateRuntimeCall(target, accessQObjectQRealProperty, + Assembler::EngineRegister, Assembler::PointerToValue(base), + Assembler::TrustedImmPtr(property->accessors), + Assembler::TrustedImm32(property->coreIndex), + Assembler::TrustedImm32(notifyIndex)); + return; + } else if (property->isQObject()) { + generateRuntimeCall(target, accessQObjectQObjectProperty, + Assembler::EngineRegister, Assembler::PointerToValue(base), + Assembler::TrustedImmPtr(property->accessors), + Assembler::TrustedImm32(property->coreIndex), + Assembler::TrustedImm32(notifyIndex)); + return; + } else if (property->propType == QMetaType::Int) { + generateRuntimeCall(target, accessQObjectIntProperty, + Assembler::EngineRegister, Assembler::PointerToValue(base), + Assembler::TrustedImmPtr(property->accessors), + Assembler::TrustedImm32(property->coreIndex), + Assembler::TrustedImm32(notifyIndex)); + return; + } else if (property->propType == QMetaType::Bool) { + generateRuntimeCall(target, accessQObjectBoolProperty, + Assembler::EngineRegister, Assembler::PointerToValue(base), + Assembler::TrustedImmPtr(property->accessors), + Assembler::TrustedImm32(property->coreIndex), + Assembler::TrustedImm32(notifyIndex)); + return; + } else if (property->propType == QMetaType::QString) { + generateRuntimeCall(target, accessQObjectQStringProperty, + Assembler::EngineRegister, Assembler::PointerToValue(base), + Assembler::TrustedImmPtr(property->accessors), + Assembler::TrustedImm32(property->coreIndex), + Assembler::TrustedImm32(notifyIndex)); + return; + } + } + } + + const int propertyIndex = property->coreIndex; if (attachedPropertiesId != 0) generateRuntimeCall(target, getQmlAttachedProperty, Assembler::EngineRegister, Assembler::TrustedImm32(attachedPropertiesId), Assembler::TrustedImm32(propertyIndex)); else if (isSingleton) diff --git a/src/qml/jit/qv4isel_masm_p.h b/src/qml/jit/qv4isel_masm_p.h index a92196f5f7..db9d440e83 100644 --- a/src/qml/jit/qv4isel_masm_p.h +++ b/src/qml/jit/qv4isel_masm_p.h @@ -124,8 +124,8 @@ protected: virtual void setActivationProperty(IR::Expr *source, const QString &targetName); virtual void initClosure(IR::Closure *closure, IR::Expr *target); virtual void getProperty(IR::Expr *base, const QString &name, IR::Expr *target); - virtual void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, IR::Expr *target); - virtual void getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target); + virtual void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, QQmlPropertyData *property, int index, IR::Expr *target); + virtual void getQObjectProperty(IR::Expr *base, QQmlPropertyData *property, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target); virtual void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &targetName); virtual void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex); virtual void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex); diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp index 131e0a5b0a..6b5b79e458 100644 --- a/src/qml/jit/qv4regalloc.cpp +++ b/src/qml/jit/qv4regalloc.cpp @@ -528,14 +528,14 @@ protected: // IRDecoder addCall(); } - virtual void getQmlContextProperty(IR::Expr *base, IR::Member::MemberKind /*kind*/, int /*index*/, IR::Expr *target) + virtual void getQmlContextProperty(IR::Expr *base, IR::Member::MemberKind /*kind*/, QQmlPropertyData * /*property*/, int /*index*/, IR::Expr *target) { addDef(target); addUses(base->asTemp(), Use::CouldHaveRegister); addCall(); } - virtual void getQObjectProperty(IR::Expr *base, int /*propertyIndex*/, bool /*captureRequired*/, bool /*isSingleton*/, int /*attachedPropertiesId*/, IR::Expr *target) + virtual void getQObjectProperty(IR::Expr *base, QQmlPropertyData * /*property*/, bool /*captureRequired*/, bool /*isSingleton*/, int /*attachedPropertiesId*/, IR::Expr *target) { addDef(target); addUses(base->asTemp(), Use::CouldHaveRegister); diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h index f527afbcc7..0186a8381a 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper_p.h +++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h @@ -59,6 +59,7 @@ #include <private/qqmldata_p.h> #include <private/qqmlpropertycache_p.h> #include <private/qintrusivelist_p.h> +#include <private/qqmlaccessors_p.h> #include <private/qv4value_p.h> #include <private/qv4functionobject_p.h> diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 2abe6eeb06..a974909798 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -1415,6 +1415,116 @@ ReturnedValue Runtime::method_getQmlQObjectProperty(ExecutionEngine *engine, con return QV4::QObjectWrapper::getProperty(scope.engine, wrapper->object(), propertyIndex, captureRequired); } +template <typename PropertyType> +static inline PropertyType getQObjectProperty(QObject *object, ExecutionEngine *engine, QQmlAccessors *accessors, int coreIndex, int notifyIndex) +{ + PropertyType t; + accessors->read(object, &t); + if (notifyIndex != -1) { + QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : 0; + if (ep && ep->propertyCapture) { + if (accessors->notifier) { + QQmlNotifier *n = nullptr; + accessors->notifier(object, &n); + if (n) { + ep->propertyCapture->captureProperty(n); + } + } else { + ep->propertyCapture->captureProperty(object, coreIndex, notifyIndex); + } + } + } + + return t; +} + +ReturnedValue Runtime::method_accessQObjectQRealProperty(ExecutionEngine *engine, + const Value &object, + QQmlAccessors *accessors, int coreIndex, + int notifyIndex) +{ + auto casted = object.as<QObjectWrapper>(); + QObject *o = casted ? casted->object() : nullptr; + if (Q_LIKELY(o)) { + return QV4::Encode(getQObjectProperty<qreal>(o, engine, accessors, coreIndex, notifyIndex)); + } + engine->throwTypeError(QStringLiteral("Cannot read property of null")); + return Encode::undefined(); +} + +ReturnedValue Runtime::method_accessQObjectQObjectProperty(ExecutionEngine *engine, + const Value &object, + QQmlAccessors *accessors, int coreIndex, + int notifyIndex) +{ + auto casted = object.as<QObjectWrapper>(); + QObject *o = casted ? casted->object() : nullptr; + if (Q_LIKELY(o)) { + return QV4::QObjectWrapper::wrap(engine, getQObjectProperty<QObject *>(o, engine, accessors, + coreIndex, + notifyIndex)); + } + + engine->throwTypeError(QStringLiteral("Cannot read property of null")); + return Encode::undefined(); +} + +ReturnedValue Runtime::method_accessQObjectIntProperty(ExecutionEngine *engine, const Value &object, + QQmlAccessors *accessors, int coreIndex, + int notifyIndex) +{ + auto casted = object.as<QObjectWrapper>(); + QObject *o = casted ? casted->object() : nullptr; + if (Q_LIKELY(o)) { + return QV4::Encode(getQObjectProperty<int>(o, engine, accessors, coreIndex, notifyIndex)); + } + engine->throwTypeError(QStringLiteral("Cannot read property of null")); + return Encode::undefined(); +} + +ReturnedValue Runtime::method_accessQObjectBoolProperty(ExecutionEngine *engine, const Value &object, + QQmlAccessors *accessors, int coreIndex, + int notifyIndex) +{ + auto casted = object.as<QObjectWrapper>(); + QObject *o = casted ? casted->object() : nullptr; + if (Q_LIKELY(o)) { + return QV4::Encode(getQObjectProperty<bool>(o, engine, accessors, coreIndex, notifyIndex)); + } + engine->throwTypeError(QStringLiteral("Cannot read property of null")); + return Encode::undefined(); +} + +ReturnedValue Runtime::method_accessQObjectQStringProperty(ExecutionEngine *engine, + const Value &object, + QQmlAccessors *accessors, int coreIndex, + int notifyIndex) +{ + auto casted = object.as<QObjectWrapper>(); + QObject *o = casted ? casted->object() : nullptr; + if (Q_LIKELY(o)) { + return QV4::Encode(engine->newString(getQObjectProperty<QString>(o, engine, accessors, + coreIndex, notifyIndex))); + } + engine->throwTypeError(QStringLiteral("Cannot read property of null")); + return Encode::undefined(); +} + +ReturnedValue Runtime::method_accessQmlScopeObjectQObjectProperty(const Value &context, + QQmlAccessors *accessors) +{ +#ifndef V4_BOOTSTRAP + const QmlContext &c = static_cast<const QmlContext &>(context); + QObject *rv = 0; + accessors->read(c.d()->qml->scopeObject, &rv); + return QV4::QObjectWrapper::wrap(c.engine(), rv); +#else + Q_UNUSED(context); + Q_UNUSED(accessors); + return QV4::Encode::undefined(); +#endif +} + QV4::ReturnedValue Runtime::method_getQmlAttachedProperty(ExecutionEngine *engine, int attachedPropertiesId, int propertyIndex) { QObject *scopeObject = engine->qmlScopeObject(); diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h index d9b46606c9..ffae55995f 100644 --- a/src/qml/jsruntime/qv4runtime_p.h +++ b/src/qml/jsruntime/qv4runtime_p.h @@ -56,8 +56,12 @@ #include "qv4engine_p.h" #include "qv4math_p.h" #include "qv4runtimeapi_p.h" -#include <QtCore/qnumeric.h> +#ifndef V4_BOOTSTRAP +#include <private/qqmlaccessors_p.h> +#include <private/qqmlcontextwrapper_p.h> +#endif +#include <QtCore/qnumeric.h> QT_BEGIN_NAMESPACE @@ -417,6 +421,68 @@ inline Bool Runtime::method_toBoolean(const Value &value) return value.toBoolean(); } +inline ReturnedValue Runtime::method_accessQmlScopeObjectQRealProperty(const Value &context, + QQmlAccessors *accessors) +{ +#ifndef V4_BOOTSTRAP + const QmlContext &c = static_cast<const QmlContext &>(context); + qreal rv = 0; + accessors->read(c.d()->qml->scopeObject, &rv); + return QV4::Encode(rv); +#else + Q_UNUSED(context); + Q_UNUSED(accessors); + return QV4::Encode::undefined(); +#endif +} + +inline ReturnedValue Runtime::method_accessQmlScopeObjectIntProperty(const Value &context, + QQmlAccessors *accessors) +{ +#ifndef V4_BOOTSTRAP + const QmlContext &c = static_cast<const QmlContext &>(context); + int rv = 0; + accessors->read(c.d()->qml->scopeObject, &rv); + return QV4::Encode(rv); +#else + Q_UNUSED(context); + Q_UNUSED(accessors); + return QV4::Encode::undefined(); +#endif +} + +inline ReturnedValue Runtime::method_accessQmlScopeObjectBoolProperty(const Value &context, + QQmlAccessors *accessors) +{ +#ifndef V4_BOOTSTRAP + const QmlContext &c = static_cast<const QmlContext &>(context); + bool rv = false; + accessors->read(c.d()->qml->scopeObject, &rv); + return QV4::Encode(rv); +#else + Q_UNUSED(context); + Q_UNUSED(accessors); + return QV4::Encode::undefined(); +#endif +} + +inline ReturnedValue Runtime::method_accessQmlScopeObjectQStringProperty(ExecutionEngine *engine, + const Value &context, + QQmlAccessors *accessors) +{ +#ifndef V4_BOOTSTRAP + const QmlContext &c = static_cast<const QmlContext &>(context); + QString rv; + accessors->read(c.d()->qml->scopeObject, &rv); + return QV4::Encode(engine->newString(rv)); +#else + Q_UNUSED(engine); + Q_UNUSED(context); + Q_UNUSED(accessors); + return QV4::Encode::undefined(); +#endif +} + } // namespace QV4 QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h index 9eb6a124b4..bf153223a0 100644 --- a/src/qml/jsruntime/qv4runtimeapi_p.h +++ b/src/qml/jsruntime/qv4runtimeapi_p.h @@ -156,6 +156,16 @@ struct Q_QML_PRIVATE_EXPORT Runtime { , INIT_RUNTIME_METHOD(setQmlScopeObjectProperty) , INIT_RUNTIME_METHOD(setQmlContextObjectProperty) , INIT_RUNTIME_METHOD(setQmlQObjectProperty) + , INIT_RUNTIME_METHOD(accessQObjectQRealProperty) + , INIT_RUNTIME_METHOD(accessQObjectQObjectProperty) + , INIT_RUNTIME_METHOD(accessQObjectIntProperty) + , INIT_RUNTIME_METHOD(accessQObjectBoolProperty) + , INIT_RUNTIME_METHOD(accessQObjectQStringProperty) + , INIT_RUNTIME_METHOD(accessQmlScopeObjectQRealProperty) + , INIT_RUNTIME_METHOD(accessQmlScopeObjectQObjectProperty) + , INIT_RUNTIME_METHOD(accessQmlScopeObjectIntProperty) + , INIT_RUNTIME_METHOD(accessQmlScopeObjectBoolProperty) + , INIT_RUNTIME_METHOD(accessQmlScopeObjectQStringProperty) { } // call @@ -292,6 +302,17 @@ struct Q_QML_PRIVATE_EXPORT Runtime { RUNTIME_METHOD(void, setQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)); RUNTIME_METHOD(void, setQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)); RUNTIME_METHOD(void, setQmlQObjectProperty, (ExecutionEngine *engine, const Value &object, int propertyIndex, const Value &value)); + + RUNTIME_METHOD(ReturnedValue, accessQObjectQRealProperty, (ExecutionEngine *engine, const Value &object, QQmlAccessors *accessors, int coreIndex, int notifyIndex)); + RUNTIME_METHOD(ReturnedValue, accessQObjectQObjectProperty, (ExecutionEngine *engine, const Value &object, QQmlAccessors *accessors, int coreIndex, int notifyIndex)); + RUNTIME_METHOD(ReturnedValue, accessQObjectIntProperty, (ExecutionEngine *engine, const Value &object, QQmlAccessors *accessors, int coreIndex, int notifyIndex)); + RUNTIME_METHOD(ReturnedValue, accessQObjectBoolProperty, (ExecutionEngine *engine, const Value &object, QQmlAccessors *accessors, int coreIndex, int notifyIndex)); + RUNTIME_METHOD(ReturnedValue, accessQObjectQStringProperty, (ExecutionEngine *engine, const Value &object, QQmlAccessors *accessors, int coreIndex, int notifyIndex)); + RUNTIME_METHOD(ReturnedValue, accessQmlScopeObjectQRealProperty, (const Value &context, QQmlAccessors *accessors)); + RUNTIME_METHOD(ReturnedValue, accessQmlScopeObjectQObjectProperty, (const Value &context, QQmlAccessors *accessors)); + RUNTIME_METHOD(ReturnedValue, accessQmlScopeObjectIntProperty, (const Value &context, QQmlAccessors *accessors)); + RUNTIME_METHOD(ReturnedValue, accessQmlScopeObjectBoolProperty, (const Value &context, QQmlAccessors *accessors)); + RUNTIME_METHOD(ReturnedValue, accessQmlScopeObjectQStringProperty, (ExecutionEngine *engine, const Value &context, QQmlAccessors *accessors)); }; #undef RUNTIME_METHOD diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index b874766655..b4f04bbc76 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -196,7 +196,9 @@ void StringPrototype::init(ExecutionEngine *engine, Object *ctor) defineDefaultProperty(QStringLiteral("charAt"), method_charAt, 1); defineDefaultProperty(QStringLiteral("charCodeAt"), method_charCodeAt, 1); defineDefaultProperty(QStringLiteral("concat"), method_concat, 1); + defineDefaultProperty(QStringLiteral("endsWith"), method_endsWith, 1); defineDefaultProperty(QStringLiteral("indexOf"), method_indexOf, 1); + defineDefaultProperty(QStringLiteral("includes"), method_includes, 1); defineDefaultProperty(QStringLiteral("lastIndexOf"), method_lastIndexOf, 1); defineDefaultProperty(QStringLiteral("localeCompare"), method_localeCompare, 1); defineDefaultProperty(QStringLiteral("match"), method_match, 1); @@ -204,6 +206,7 @@ void StringPrototype::init(ExecutionEngine *engine, Object *ctor) defineDefaultProperty(QStringLiteral("search"), method_search, 1); defineDefaultProperty(QStringLiteral("slice"), method_slice, 2); defineDefaultProperty(QStringLiteral("split"), method_split, 2); + defineDefaultProperty(QStringLiteral("startsWith"), method_startsWith, 1); defineDefaultProperty(QStringLiteral("substr"), method_substr, 2); defineDefaultProperty(QStringLiteral("substring"), method_substring, 2); defineDefaultProperty(QStringLiteral("toLowerCase"), method_toLowerCase); @@ -293,6 +296,30 @@ ReturnedValue StringPrototype::method_concat(CallContext *context) return context->d()->engine->newString(value)->asReturnedValue(); } +ReturnedValue StringPrototype::method_endsWith(CallContext *context) +{ + QString value = getThisString(context); + if (context->d()->engine->hasException) + return Encode::undefined(); + + QString searchString; + if (context->argc()) { + if (context->args()[0].as<RegExpObject>()) + return context->engine()->throwTypeError(); + searchString = context->args()[0].toQString(); + } + + int pos = value.length(); + if (context->argc() > 1) + pos = (int) context->args()[1].toInteger(); + + if (pos == value.length()) + return Encode(value.endsWith(searchString)); + + QStringRef stringToSearch = value.leftRef(pos); + return Encode(stringToSearch.endsWith(searchString)); +} + ReturnedValue StringPrototype::method_indexOf(CallContext *context) { QString value = getThisString(context); @@ -314,6 +341,35 @@ ReturnedValue StringPrototype::method_indexOf(CallContext *context) return Encode(index); } +ReturnedValue StringPrototype::method_includes(CallContext *context) +{ + QString value = getThisString(context); + if (context->d()->engine->hasException) + return Encode::undefined(); + + QString searchString; + if (context->argc()) { + if (context->args()[0].as<RegExpObject>()) + return context->engine()->throwTypeError(); + searchString = context->args()[0].toQString(); + } + + int pos = 0; + if (context->argc() > 1) { + Scope scope(context); + ScopedValue posArg(scope, context->argument(1)); + pos = (int) posArg->toInteger(); + if (!posArg->isInteger() && posArg->isNumber() && qIsInf(posArg->toNumber())) + pos = value.length(); + } + + if (pos == 0) + return Encode(value.contains(searchString)); + + QStringRef stringToSearch = value.midRef(pos); + return Encode(stringToSearch.contains(searchString)); +} + ReturnedValue StringPrototype::method_lastIndexOf(CallContext *context) { Scope scope(context); @@ -716,6 +772,30 @@ ReturnedValue StringPrototype::method_split(CallContext *ctx) return array.asReturnedValue(); } +ReturnedValue StringPrototype::method_startsWith(CallContext *context) +{ + QString value = getThisString(context); + if (context->d()->engine->hasException) + return Encode::undefined(); + + QString searchString; + if (context->argc()) { + if (context->args()[0].as<RegExpObject>()) + return context->engine()->throwTypeError(); + searchString = context->args()[0].toQString(); + } + + int pos = 0; + if (context->argc() > 1) + pos = (int) context->args()[1].toInteger(); + + if (pos == 0) + return Encode(value.startsWith(searchString)); + + QStringRef stringToSearch = value.midRef(pos); + return Encode(stringToSearch.startsWith(searchString)); +} + ReturnedValue StringPrototype::method_substr(CallContext *context) { const QString value = getThisString(context); diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h index 3930a011e6..fb229d4aff 100644 --- a/src/qml/jsruntime/qv4stringobject_p.h +++ b/src/qml/jsruntime/qv4stringobject_p.h @@ -115,7 +115,9 @@ struct StringPrototype: StringObject static ReturnedValue method_charAt(CallContext *context); static ReturnedValue method_charCodeAt(CallContext *context); static ReturnedValue method_concat(CallContext *context); + static ReturnedValue method_endsWith(CallContext *ctx); static ReturnedValue method_indexOf(CallContext *context); + static ReturnedValue method_includes(CallContext *context); static ReturnedValue method_lastIndexOf(CallContext *context); static ReturnedValue method_localeCompare(CallContext *context); static ReturnedValue method_match(CallContext *context); @@ -123,6 +125,7 @@ struct StringPrototype: StringObject static ReturnedValue method_search(CallContext *ctx); static ReturnedValue method_slice(CallContext *ctx); static ReturnedValue method_split(CallContext *ctx); + static ReturnedValue method_startsWith(CallContext *ctx); static ReturnedValue method_substr(CallContext *context); static ReturnedValue method_substring(CallContext *context); static ReturnedValue method_toLowerCase(CallContext *ctx); diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index ec4509a5cc..9ad21305f7 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -519,6 +519,26 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code STOREVALUE(instr.result, engine->runtime.getQmlQObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired)); MOTH_END_INSTR(LoadQObjectProperty) + MOTH_BEGIN_INSTR(LoadQRealQObjectPropertyDirectly) + STOREVALUE(instr.result, engine->runtime.accessQObjectQRealProperty(engine, VALUE(instr.base), instr.accessors, instr.coreIndex, instr.notifyIndex)); + MOTH_END_INSTR(LoadQRealQObjectPropertyDirectly) + + MOTH_BEGIN_INSTR(LoadQObjectQObjectPropertyDirectly) + STOREVALUE(instr.result, engine->runtime.accessQObjectQObjectProperty(engine, VALUE(instr.base), instr.accessors, instr.coreIndex, instr.notifyIndex)); + MOTH_END_INSTR(LoadQObjectQObjectPropertyDirectly) + + MOTH_BEGIN_INSTR(LoadIntQObjectPropertyDirectly) + STOREVALUE(instr.result, engine->runtime.accessQObjectIntProperty(engine, VALUE(instr.base), instr.accessors, instr.coreIndex, instr.notifyIndex)); + MOTH_END_INSTR(LoadIntQObjectPropertyDirectly) + + MOTH_BEGIN_INSTR(LoadBoolQObjectPropertyDirectly) + STOREVALUE(instr.result, engine->runtime.accessQObjectBoolProperty(engine, VALUE(instr.base), instr.accessors, instr.coreIndex, instr.notifyIndex)); + MOTH_END_INSTR(LoadQRealQObjectPropertyDirectly) + + MOTH_BEGIN_INSTR(LoadQStringQObjectPropertyDirectly) + STOREVALUE(instr.result, engine->runtime.accessQObjectQStringProperty(engine, VALUE(instr.base), instr.accessors, instr.coreIndex, instr.notifyIndex)); + MOTH_END_INSTR(LoadQStringQObjectPropertyDirectly) + MOTH_BEGIN_INSTR(StoreScopeObjectProperty) engine->runtime.setQmlScopeObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source)); CHECK_EXCEPTION; @@ -528,6 +548,26 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code STOREVALUE(instr.result, engine->runtime.getQmlScopeObjectProperty(engine, VALUE(instr.base), instr.propertyIndex)); MOTH_END_INSTR(LoadScopeObjectProperty) + MOTH_BEGIN_INSTR(LoadScopeObjectQRealPropertyDirectly) + STOREVALUE(instr.result, engine->runtime.accessQmlScopeObjectQRealProperty(VALUE(instr.base), instr.accessors)); + MOTH_END_INSTR(LoadScopeObjectQRealPropertyDirectly) + + MOTH_BEGIN_INSTR(LoadScopeObjectQObjectPropertyDirectly) + STOREVALUE(instr.result, engine->runtime.accessQmlScopeObjectQObjectProperty(VALUE(instr.base), instr.accessors)); + MOTH_END_INSTR(LoadScopeObjectQObjectPropertyDirectly) + + MOTH_BEGIN_INSTR(LoadScopeObjectIntPropertyDirectly) + STOREVALUE(instr.result, engine->runtime.accessQmlScopeObjectIntProperty(VALUE(instr.base), instr.accessors)); + MOTH_END_INSTR(LoadScopeObjectIntPropertyDirectly) + + MOTH_BEGIN_INSTR(LoadScopeObjectBoolPropertyDirectly) + STOREVALUE(instr.result, engine->runtime.accessQmlScopeObjectBoolProperty(VALUE(instr.base), instr.accessors)); + MOTH_END_INSTR(LoadScopeObjectBoolPropertyDirectly) + + MOTH_BEGIN_INSTR(LoadScopeObjectQStringPropertyDirectly) + STOREVALUE(instr.result, engine->runtime.accessQmlScopeObjectQStringProperty(engine, VALUE(instr.base), instr.accessors)); + MOTH_END_INSTR(LoadScopeObjectQStringPropertyDirectly) + MOTH_BEGIN_INSTR(StoreContextObjectProperty) engine->runtime.setQmlContextObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source)); CHECK_EXCEPTION; diff --git a/src/qml/qml/ftw/ftw.pri b/src/qml/qml/ftw/ftw.pri index a671cfa12d..addf1d9ff8 100644 --- a/src/qml/qml/ftw/ftw.pri +++ b/src/qml/qml/ftw/ftw.pri @@ -11,7 +11,6 @@ HEADERS += \ $$PWD/qdeletewatcher_p.h \ $$PWD/qrecyclepool_p.h \ $$PWD/qflagpointer_p.h \ - $$PWD/qpointervaluepair_p.h \ $$PWD/qlazilyallocated_p.h \ $$PWD/qqmlnullablevalue_p.h \ diff --git a/src/qml/qml/ftw/qpointervaluepair_p.h b/src/qml/qml/ftw/qpointervaluepair_p.h deleted file mode 100644 index 3d0644039f..0000000000 --- a/src/qml/qml/ftw/qpointervaluepair_p.h +++ /dev/null @@ -1,194 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPOINTERVALUEPAIR_P_H -#define QPOINTERVALUEPAIR_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qglobal.h> -#include <private/qflagpointer_p.h> - -QT_BEGIN_NAMESPACE - -// QPointerValuePair is intended to help reduce the memory consumption of a class. -// In the common case, QPointerValuePair behaves like a pointer. In this mode, it -// consumes the same memory as a regular pointer. -// Additionally, QPointerValuePair can store an arbitrary value type in *addition* -// to the pointer. In this case, it uses slightly more memory than the pointer and -// value type combined. -// Consequently, this class is most useful in cases where a pointer is always stored -// and a value type is rarely stored. -template<typename P, typename V> -class QPointerValuePair { -public: - inline QPointerValuePair(); - inline QPointerValuePair(P *); - inline ~QPointerValuePair(); - - inline bool isNull() const; - - inline bool flag() const; - inline void setFlag(); - inline void clearFlag(); - inline void setFlagValue(bool); - - inline QPointerValuePair<P, V> &operator=(P *); - - inline P *operator->() const; - inline P *operator*() const; - - inline bool hasValue() const; - inline V &value(); - inline const V *constValue() const; - -private: - struct Value { P *pointer; V value; }; - QBiPointer<P, Value> d; -}; - -template<typename P, typename V> -QPointerValuePair<P, V>::QPointerValuePair() -{ -} - -template<typename P, typename V> -QPointerValuePair<P, V>::QPointerValuePair(P *p) -: d(p) -{ -} - -template<typename P, typename V> -QPointerValuePair<P, V>::~QPointerValuePair() -{ - if (d.isT2()) delete d.asT2(); -} - -template<typename P, typename V> -bool QPointerValuePair<P, V>::isNull() const -{ - if (d.isT1()) return 0 == d.asT1(); - else return d.asT2()->pointer == 0; -} - -template<typename P, typename V> -bool QPointerValuePair<P, V>::flag() const -{ - return d.flag(); -} - -template<typename P, typename V> -void QPointerValuePair<P, V>::setFlag() -{ - d.setFlag(); -} - -template<typename P, typename V> -void QPointerValuePair<P, V>::clearFlag() -{ - d.clearFlag(); -} - -template<typename P, typename V> -void QPointerValuePair<P, V>::setFlagValue(bool v) -{ - d.setFlagValue(v); -} - -template<typename P, typename V> -QPointerValuePair<P, V> &QPointerValuePair<P, V>::operator=(P *o) -{ - if (d.isT1()) d = o; - else d.asT2()->pointer = o; - return *this; -} - -template<typename P, typename V> -P *QPointerValuePair<P, V>::operator->() const -{ - if (d.isT1()) return d.asT1(); - else return d.asT2()->pointer; -} - -template<typename P, typename V> -P *QPointerValuePair<P, V>::operator*() const -{ - if (d.isT1()) return d.asT1(); - else return d.asT2()->pointer; -} - -template<typename P, typename V> -bool QPointerValuePair<P, V>::hasValue() const -{ - return d.isT2(); -} - -template<typename P, typename V> -V &QPointerValuePair<P, V>::value() -{ - if (d.isT1()) { - P *p = d.asT1(); - Value *value = new Value; - value->pointer = p; - d = value; - } - - return d.asT2()->value; -} - -// Will return null if hasValue() == false -template<typename P, typename V> -const V *QPointerValuePair<P, V>::constValue() const -{ - if (d.isT2()) return &d.asT2()->value; - else return 0; -} - -QT_END_NAMESPACE - -#endif // QPOINTERVALUEPAIR_P_H diff --git a/src/qml/qml/qqmlabstractbinding_p.h b/src/qml/qml/qqmlabstractbinding_p.h index 674178153a..45221a4bcd 100644 --- a/src/qml/qml/qqmlabstractbinding_p.h +++ b/src/qml/qml/qqmlabstractbinding_p.h @@ -55,7 +55,6 @@ #include <QtCore/qshareddata.h> #include <private/qtqmlglobal_p.h> #include <private/qqmlproperty_p.h> -#include <private/qpointervaluepair_p.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h index 86db88cdf0..45c360f07e 100644 --- a/src/qml/qml/qqmlbinding_p.h +++ b/src/qml/qml/qqmlbinding_p.h @@ -61,7 +61,6 @@ #include <QtCore/QObject> #include <QtCore/QMetaProperty> -#include <private/qpointervaluepair_p.h> #include <private/qqmlabstractbinding_p.h> #include <private/qqmljavascriptexpression_p.h> diff --git a/src/qml/qml/qqmldelayedcallqueue.cpp b/src/qml/qml/qqmldelayedcallqueue.cpp index 250d5f20f3..8d0fb22866 100644 --- a/src/qml/qml/qqmldelayedcallqueue.cpp +++ b/src/qml/qml/qqmldelayedcallqueue.cpp @@ -62,12 +62,13 @@ void QQmlDelayedCallQueue::DelayedFunctionCall::execute(QV4::ExecutionEngine *en QV4::Scope scope(engine); - const int argCount = m_args.count(); + QV4::ArrayObject *array = m_args.as<QV4::ArrayObject>(); + const int argCount = array ? array->getLength() : 0; QV4::ScopedCallData callData(scope, argCount); callData->thisObject = QV4::Encode::undefined(); for (int i = 0; i < argCount; i++) { - callData->args[i] = m_args[i].value(); + callData->args[i] = array->getIndexed(i); } const QV4::FunctionObject *callback = m_function.as<QV4::FunctionObject>(); @@ -175,11 +176,18 @@ QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(QV4::CallCon void QQmlDelayedCallQueue::storeAnyArguments(DelayedFunctionCall &dfc, const QV4::CallData *callData, int offset, QV4::ExecutionEngine *engine) { - dfc.m_args.clear(); - dfc.m_args.reserve(callData->argc - offset); - for (int j = offset; j < callData->argc; j++) { - dfc.m_args.append(QV4::PersistentValue(engine, callData->args[j])); + const int length = callData->argc - offset; + if (length == 0) { + dfc.m_args.clear(); + return; } + QV4::Scope scope(engine); + QV4::ScopedArrayObject array(scope, engine->newArrayObject(length)); + int i = 0; + for (int j = offset; j < callData->argc; ++i, ++j) { + array->putIndexed(i, callData->args[j]); + } + dfc.m_args.set(engine, array); } void QQmlDelayedCallQueue::executeAllExpired_Later() diff --git a/src/qml/qml/qqmldelayedcallqueue_p.h b/src/qml/qml/qqmldelayedcallqueue_p.h index 7eb014cfdf..ef899170a2 100644 --- a/src/qml/qml/qqmldelayedcallqueue_p.h +++ b/src/qml/qml/qqmldelayedcallqueue_p.h @@ -85,7 +85,7 @@ private: void execute(QV4::ExecutionEngine *engine) const; QV4::PersistentValue m_function; - QList<QV4::PersistentValue> m_args; + QV4::PersistentValue m_args; QQmlGuard<QObject> m_objectGuard; bool m_guarded; }; diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 63d3feee1e..99ae367773 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -1900,28 +1900,16 @@ void QQmlEnginePrivate::warning(QQmlEnginePrivate *engine, const QList<QQmlError dumpwarning(error); } -/* - This function should be called after evaluation of the js expression is - complete, and so the scarce resources may be freed safely. - */ -void QQmlEnginePrivate::dereferenceScarceResources() -{ - Q_ASSERT(scarceResourcesRefCount > 0); - scarceResourcesRefCount -= 1; - - // if the refcount is zero, then evaluation of the "top level" - // expression must have completed. We can safely release the - // scarce resources. - if (Q_UNLIKELY(scarceResourcesRefCount == 0)) { - // iterate through the list and release them all. - // note that the actual SRD is owned by the JS engine, - // so we cannot delete the SRD; but we can free the - // memory used by the variant in the SRD. - QV4::ExecutionEngine *engine = QV8Engine::getV4(v8engine()); - while (QV4::ExecutionEngine::ScarceResourceData *sr = engine->scarceResources.first()) { - sr->data = QVariant(); - engine->scarceResources.remove(sr); - } +void QQmlEnginePrivate::cleanupScarceResources() +{ + // iterate through the list and release them all. + // note that the actual SRD is owned by the JS engine, + // so we cannot delete the SRD; but we can free the + // memory used by the variant in the SRD. + QV4::ExecutionEngine *engine = QV8Engine::getV4(v8engine()); + while (QV4::ExecutionEngine::ScarceResourceData *sr = engine->scarceResources.first()) { + sr->data = QVariant(); + engine->scarceResources.remove(sr); } } diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 92eadb0540..440840d3c9 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -267,6 +267,8 @@ private: struct Deletable { Deletable():next(0) {} virtual ~Deletable() {} Deletable *next; }; QFieldList<Deletable, &Deletable::next> toDeleteInEngineThread; void doDeleteInEngineThread(); + + void cleanupScarceResources(); }; /* @@ -279,6 +281,26 @@ inline void QQmlEnginePrivate::referenceScarceResources() scarceResourcesRefCount += 1; } +/* + This function should be called after evaluation of the js expression is + complete, and so the scarce resources may be freed safely. + */ +inline void QQmlEnginePrivate::dereferenceScarceResources() +{ + Q_ASSERT(scarceResourcesRefCount > 0); + scarceResourcesRefCount -= 1; + + // if the refcount is zero, then evaluation of the "top level" + // expression must have completed. We can safely release the + // scarce resources. + if (scarceResourcesRefCount == 0) { + QV4::ExecutionEngine *engine = QV8Engine::getV4(v8engine()); + if (Q_UNLIKELY(!engine->scarceResources.isEmpty())) { + cleanupScarceResources(); + } + } +} + /*! Returns true if the calling thread is the QQmlEngine thread. */ diff --git a/src/qml/qml/qqmlexpression_p.h b/src/qml/qml/qqmlexpression_p.h index 3d1df55a2d..ccc629a3a3 100644 --- a/src/qml/qml/qqmlexpression_p.h +++ b/src/qml/qml/qqmlexpression_p.h @@ -57,7 +57,6 @@ #include <private/qfieldlist_p.h> #include <private/qflagpointer_p.h> #include <private/qdeletewatcher_p.h> -#include <private/qpointervaluepair_p.h> #include <private/qqmljavascriptexpression_p.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h index 64cb1bb242..94479f6c5e 100644 --- a/src/qml/qml/qqmljavascriptexpression_p.h +++ b/src/qml/qml/qqmljavascriptexpression_p.h @@ -54,7 +54,6 @@ #include <QtCore/qglobal.h> #include <QtQml/qqmlerror.h> #include <private/qqmlengine_p.h> -#include <private/qpointervaluepair_p.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index bb39a5e371..4fb84198d9 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -162,6 +162,8 @@ public: overrideIndex >= 0; } bool hasRevision() const { return !(flags & HasAccessors) && revision != 0; } + bool isFullyResolved() const { return !(flags & NotFullyResolved); } + // Returns -1 if not a value type virtual property inline int getValueTypeCoreIndex() const; diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index af94ec757c..e9644839d1 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -117,10 +117,8 @@ class NodeImpl public: NodeImpl() : type(Element), document(0), parent(0) {} virtual ~NodeImpl() { - for (int ii = 0; ii < children.count(); ++ii) - delete children.at(ii); - for (int ii = 0; ii < attributes.count(); ++ii) - delete attributes.at(ii); + qDeleteAll(children); + qDeleteAll(attributes); } // These numbers are copied from the Node IDL definition @@ -160,7 +158,7 @@ class DocumentImpl : public QQmlRefCount, public NodeImpl public: DocumentImpl() : root(0) { type = Document; } virtual ~DocumentImpl() { - if (root) delete root; + delete root; } QString version; diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp index 60175ef310..9cbda4516e 100644 --- a/src/qml/types/qqmllistmodel.cpp +++ b/src/qml/types/qqmllistmodel.cpp @@ -79,13 +79,16 @@ static bool isMemoryUsed(const char *mem) static QString roleTypeName(ListLayout::Role::DataType t) { - QString result; - const char *roleTypeNames[] = { "String", "Number", "Bool", "List", "QObject", "VariantMap", "DateTime" }; + static const QString roleTypeNames[] = { + QStringLiteral("String"), QStringLiteral("Number"), QStringLiteral("Bool"), + QStringLiteral("List"), QStringLiteral("QObject"), QStringLiteral("VariantMap"), + QStringLiteral("DateTime") + }; if (t > ListLayout::Role::Invalid && t < ListLayout::Role::MaxDataType) - result = QString::fromLatin1(roleTypeNames[t]); + return roleTypeNames[t]; - return result; + return QString(); } const ListLayout::Role &ListLayout::getRoleOrCreate(const QString &key, Role::DataType type) diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index fec9beedf6..8bf854aac2 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -2809,7 +2809,7 @@ void QQuickTextInputPrivate::updateDisplayText(bool forceUpdate) // characters) QChar* uc = str.data(); for (int i = 0; i < (int)str.length(); ++i) { - if ((uc[i] < 0x20 && uc[i] != 0x09) + if ((uc[i].unicode() < 0x20 && uc[i] != QChar::Tabulation) || uc[i] == QChar::LineSeparator || uc[i] == QChar::ParagraphSeparator || uc[i] == QChar::ObjectReplacementCharacter) |