aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-11-28 12:16:17 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2016-11-28 12:16:17 +0000
commit4e1463c20aa6ec52f23e1e5f6426b68edb2255f0 (patch)
treedf3d8f65f0c8df1990c48931c4c0b5063ff6f8c6 /src/qml
parentea9d6955f4c1c1141d0909ddb32abb59c032ac3c (diff)
parent9044800083ccffe4d0b732f8b3b60512f32d8f8a (diff)
Merge "Merge remote-tracking branch 'origin/5.7' into 5.8" into refs/staging/5.8
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qv4ssa.cpp15
-rw-r--r--src/qml/doc/src/javascript/resources.qdoc8
-rw-r--r--src/qml/jit/qv4isel_masm.cpp4
-rw-r--r--src/qml/parser/qqmljsmemorypool_p.h5
-rw-r--r--src/qml/qml/qqmlnotifier.cpp6
-rw-r--r--src/qml/qml/qqmlnotifier_p.h2
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp1
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp2
-rw-r--r--src/qml/types/qqmllistmodel.cpp44
-rw-r--r--src/qml/types/qqmllistmodel_p_p.h2
10 files changed, 69 insertions, 20 deletions
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp
index 3bcc231696..deba41ef9d 100644
--- a/src/qml/compiler/qv4ssa.cpp
+++ b/src/qml/compiler/qv4ssa.cpp
@@ -1838,11 +1838,6 @@ public:
return *this;
}
- bool isEmpty() const
- {
- return worklistSize == 0;
- }
-
unsigned size() const
{
return worklistSize;
@@ -1850,7 +1845,7 @@ public:
Stmt *takeNext(Stmt *last)
{
- if (isEmpty())
+ if (worklistSize == 0)
return 0;
const int startAt = last ? last->id() + 1 : 0;
@@ -1866,6 +1861,10 @@ public:
--worklistSize;
Stmt *s = stmts.at(pos);
Q_ASSERT(s);
+
+ if (removed.at(s->id()))
+ return takeNext(s);
+
return s;
}
@@ -3991,9 +3990,7 @@ void optimizeSSA(StatementWorklist &W, DefUses &defUses, DominatorTree &df)
ExprReplacer replaceUses(defUses, function);
Stmt *s = 0;
- while (!W.isEmpty()) {
- s = W.takeNext(s);
- Q_ASSERT(s);
+ while ((s = W.takeNext(s))) {
if (Phi *phi = s->asPhi()) {
// dead code elimination:
diff --git a/src/qml/doc/src/javascript/resources.qdoc b/src/qml/doc/src/javascript/resources.qdoc
index b831e2ba70..4f9b40f1d7 100644
--- a/src/qml/doc/src/javascript/resources.qdoc
+++ b/src/qml/doc/src/javascript/resources.qdoc
@@ -78,13 +78,13 @@ Rectangle {
\code
// my_button_impl.js
-property var clickCount = 0; // this state is separate for each instance of MyButton
-function onClicked(btn) {
+var clickCount = 0; // this state is separate for each instance of MyButton
+function onClicked(button) {
clickCount += 1;
if ((clickCount % 5) == 0) {
- obj.color = Qt.rgba(1,0,0,1);
+ button.color = Qt.rgba(1,0,0,1);
} else {
- obj.color = Qt.rgba(0,1,0,1);
+ button.color = Qt.rgba(0,1,0,1);
}
}
\endcode
diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp
index 71069d64a5..ed1455b086 100644
--- a/src/qml/jit/qv4isel_masm.cpp
+++ b/src/qml/jit/qv4isel_masm.cpp
@@ -1838,7 +1838,7 @@ bool InstructionSelection::visitCJumpStrictUndefined(IR::Binop *binop,
Assembler::RelationalCondition cond = binop->op == IR::OpStrictEqual ? Assembler::Equal
: Assembler::NotEqual;
- const Assembler::RegisterID tagReg = Assembler::ScratchRegister;
+ const Assembler::RegisterID tagReg = Assembler::ReturnValueRegister;
#ifdef QV4_USE_64_BIT_VALUE_ENCODING
Assembler::Pointer addr = _as->loadAddress(Assembler::ScratchRegister, varSrc);
_as->load64(addr, tagReg);
@@ -1937,7 +1937,7 @@ bool InstructionSelection::visitCJumpNullUndefined(IR::Type nullOrUndef, IR::Bin
Assembler::Pointer tagAddr = _as->loadAddress(Assembler::ScratchRegister, varSrc);
tagAddr.offset += 4;
- const Assembler::RegisterID tagReg = Assembler::ScratchRegister;
+ const Assembler::RegisterID tagReg = Assembler::ReturnValueRegister;
_as->load32(tagAddr, tagReg);
if (binop->op == IR::OpNotEqual)
diff --git a/src/qml/parser/qqmljsmemorypool_p.h b/src/qml/parser/qqmljsmemorypool_p.h
index 08609e2961..536f5d4239 100644
--- a/src/qml/parser/qqmljsmemorypool_p.h
+++ b/src/qml/parser/qqmljsmemorypool_p.h
@@ -122,6 +122,7 @@ private:
_allocatedBlocks *= 2;
_blocks = (char **) realloc(_blocks, sizeof(char *) * _allocatedBlocks);
+ Q_CHECK_PTR(_blocks);
for (int index = _blockCount; index < _allocatedBlocks; ++index)
_blocks[index] = 0;
@@ -129,8 +130,10 @@ private:
char *&block = _blocks[_blockCount];
- if (! block)
+ if (! block) {
block = (char *) malloc(BLOCK_SIZE);
+ Q_CHECK_PTR(block);
+ }
_ptr = block;
_end = _ptr + BLOCK_SIZE;
diff --git a/src/qml/qml/qqmlnotifier.cpp b/src/qml/qml/qqmlnotifier.cpp
index 19f03eae80..185f9687fb 100644
--- a/src/qml/qml/qqmlnotifier.cpp
+++ b/src/qml/qml/qqmlnotifier.cpp
@@ -71,6 +71,12 @@ namespace {
};
}
+void QQmlNotifier::notify(QQmlData *ddata, int notifierIndex)
+{
+ if (QQmlNotifierEndpoint *ep = ddata->notify(notifierIndex))
+ emitNotify(ep, Q_NULLPTR);
+}
+
void QQmlNotifier::emitNotify(QQmlNotifierEndpoint *endpoint, void **a)
{
QVarLengthArray<NotifyListTraversalData> stack;
diff --git a/src/qml/qml/qqmlnotifier_p.h b/src/qml/qml/qqmlnotifier_p.h
index eff9684558..14024c0113 100644
--- a/src/qml/qml/qqmlnotifier_p.h
+++ b/src/qml/qml/qqmlnotifier_p.h
@@ -65,6 +65,8 @@ public:
inline ~QQmlNotifier();
inline void notify();
+ static void notify(QQmlData *ddata, int notifierIndex);
+
private:
friend class QQmlData;
friend class QQmlNotifierEndpoint;
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index b23bc033d1..be93baf9f6 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -390,6 +390,7 @@ ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, String *name, bool *ha
// These four types are the most common used by the value type wrappers
VALUE_TYPE_LOAD(QMetaType::QReal, qreal, qreal);
+ VALUE_TYPE_LOAD(QMetaType::Int || result->isEnum(), int, int);
VALUE_TYPE_LOAD(QMetaType::Int, int, int);
VALUE_TYPE_LOAD(QMetaType::QString, QString, v4->newString);
VALUE_TYPE_LOAD(QMetaType::Bool, bool, bool);
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index cf0fd57773..c8a0463a2d 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -1031,7 +1031,7 @@ ReturnedValue QtObject::method_exit(CallContext *ctx)
/*!
\qmlmethod object Qt::createQmlObject(string qml, object parent, string filepath)
-Returns a new object created from the given \a string of QML which will have the specified \a parent,
+Returns a new object created from the given \a qml string which will have the specified \a parent,
or \c null if there was an error in creating the object.
If \a filepath is specified, it will be used for error reporting for the created object.
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index f7fdbf0d80..2ba164f721 100644
--- a/src/qml/types/qqmllistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -45,10 +45,12 @@
#include <private/qqmlcustomparser_p.h>
#include <private/qqmlengine_p.h>
+#include <private/qqmlnotifier_p.h>
#include <private/qv4object_p.h>
#include <private/qv4dateobject_p.h>
#include <private/qv4objectiterator_p.h>
+#include <private/qv4alloca_p.h>
#include <qqmlcontext.h>
#include <qqmlinfo.h>
@@ -57,6 +59,7 @@
#include <QtCore/qstack.h>
#include <QXmlStreamReader>
#include <QtCore/qdatetime.h>
+#include <QScopedValueRollback>
QT_BEGIN_NAMESPACE
@@ -1265,9 +1268,14 @@ ModelNodeMetaObject *ModelNodeMetaObject::get(QObject *obj)
void ModelNodeMetaObject::updateValues()
{
- if (!m_initialized)
+ const int roleCount = m_model->m_listModel->roleCount();
+ if (!m_initialized) {
+ int *changedRoles = reinterpret_cast<int *>(alloca(roleCount * sizeof(int)));
+ for (int i = 0; i < roleCount; ++i)
+ changedRoles[i] = i;
+ emitDirectNotifies(changedRoles, roleCount);
return;
- int roleCount = m_model->m_listModel->roleCount();
+ }
for (int i=0 ; i < roleCount ; ++i) {
const ListLayout::Role &role = m_model->m_listModel->getExistingRole(i);
QByteArray name = role.name.toUtf8();
@@ -1278,8 +1286,10 @@ void ModelNodeMetaObject::updateValues()
void ModelNodeMetaObject::updateValues(const QVector<int> &roles)
{
- if (!m_initialized)
+ if (!m_initialized) {
+ emitDirectNotifies(roles.constData(), roles.count());
return;
+ }
int roleCount = roles.count();
for (int i=0 ; i < roleCount ; ++i) {
int roleIndex = roles.at(i);
@@ -1309,6 +1319,22 @@ void ModelNodeMetaObject::propertyWritten(int index)
}
}
+// Does the emission of the notifiers when we haven't created the meta-object yet
+void ModelNodeMetaObject::emitDirectNotifies(const int *changedRoles, int roleCount)
+{
+ Q_ASSERT(!m_initialized);
+ QQmlData *ddata = QQmlData::get(object(), /*create*/false);
+ if (!ddata)
+ return;
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(qmlEngine(m_model));
+ if (!ep)
+ return;
+ for (int i = 0; i < roleCount; ++i) {
+ const int changedRole = changedRoles[i];
+ QQmlNotifier::notify(ddata, changedRole);
+ }
+}
+
namespace QV4 {
void ModelObject::put(Managed *m, String *name, const Value &value)
@@ -1338,6 +1364,18 @@ ReturnedValue ModelObject::get(const Managed *m, String *name, bool *hasProperty
return QObjectWrapper::get(m, name, hasProperty);
if (hasProperty)
*hasProperty = true;
+
+ if (QQmlEngine *qmlEngine = that->engine()->qmlEngine()) {
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(qmlEngine);
+ if (ep && ep->propertyCapture) {
+ QObjectPrivate *op = QObjectPrivate::get(that->object());
+ // Temporarily hide the dynamic meta-object, to prevent it from being created when the capture
+ // triggers a QObject::connectNotify() by calling obj->metaObject().
+ QScopedValueRollback<QDynamicMetaObjectData*> metaObjectBlocker(op->metaObject, 0);
+ ep->propertyCapture->captureProperty(that->object(), -1, role->index);
+ }
+ }
+
const int elementIndex = that->d()->m_elementIndex;
QVariant value = that->d()->m_model->data(elementIndex, role->index);
return that->engine()->fromVariant(value);
diff --git a/src/qml/types/qqmllistmodel_p_p.h b/src/qml/types/qqmllistmodel_p_p.h
index 6e17b55e79..5ff8b9671f 100644
--- a/src/qml/types/qqmllistmodel_p_p.h
+++ b/src/qml/types/qqmllistmodel_p_p.h
@@ -153,6 +153,8 @@ private:
setValue(name, val);
}
+ void emitDirectNotifies(const int *changedRoles, int roleCount);
+
void initialize();
bool m_initialized;
};