aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-06-03 15:28:51 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2014-06-04 17:02:55 +0200
commit11a11d1280b1634628b9c4a92a0fc420ee8a3a81 (patch)
treeb48d9608ef3f08123cdeea605068342131b32b44 /src/qml
parent52e07d564b65ed6ce26955a676c7692ad67686c1 (diff)
parentfea26bb2941c3f24c4a5f3ad5efc1b85e0123ff3 (diff)
Merge remote-tracking branch 'origin/stable' into dev
The merge conflict is about the removal of "d1" from the register set on ARM, but that was already done in dev in commit ddb33ee9ba9e1344caa9be5dbf4b534c3ede692e The change in src/quick/scenegraph/coreapi/qsgrenderer.cpp with commit 2414f1675eab163b22dcc4e8ded80ed04d06369b was reverted to what it was before, per Laszlo's advice. Conflicts: src/qml/jit/qv4isel_masm.cpp Change-Id: I7bce546c5cdee01e37853a476d82279d4e72948b
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp21
-rw-r--r--src/qml/compiler/qv4compileddata_p.h54
-rw-r--r--src/qml/qml/qqmlimport.cpp18
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp2
-rw-r--r--src/qml/qml/qqmlscriptstring.cpp4
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp5
-rw-r--r--src/qml/types/qqmllistmodel.cpp44
-rw-r--r--src/qml/types/qqmllistmodel_p.h3
-rw-r--r--src/qml/types/qquickworkerscript.cpp54
9 files changed, 140 insertions, 65 deletions
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index 45fdab3fd1..3aad050dff 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -1746,10 +1746,21 @@ QString QQmlPropertyValidator::bindingAsString(int objectIndex, const QV4::Compi
typedef QVarLengthArray<const QV4::CompiledData::Binding *, 8> GroupPropertyVector;
-static bool compareNameIndices(const QV4::CompiledData::Binding *binding, quint32 name)
+struct BindingFinder
{
- return binding->propertyNameIndex < name;
-}
+ bool operator()(quint32 name, const QV4::CompiledData::Binding *binding) const
+ {
+ return name < binding->propertyNameIndex;
+ }
+ bool operator()(const QV4::CompiledData::Binding *binding, quint32 name) const
+ {
+ return binding->propertyNameIndex < name;
+ }
+ bool operator()(const QV4::CompiledData::Binding *lhs, const QV4::CompiledData::Binding *rhs) const
+ {
+ return lhs->propertyNameIndex < rhs->propertyNameIndex;
+ }
+};
bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledData::Binding *instantiatingBinding, bool populatingValueTypeGroupProperty)
{
@@ -1797,7 +1808,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD
return false;
}
- GroupPropertyVector::const_iterator pos = std::lower_bound(groupProperties.constBegin(), groupProperties.constEnd(), binding->propertyNameIndex, compareNameIndices);
+ GroupPropertyVector::const_iterator pos = std::lower_bound(groupProperties.constBegin(), groupProperties.constEnd(), binding->propertyNameIndex, BindingFinder());
groupProperties.insert(pos, binding);
}
@@ -1910,7 +1921,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD
}
if (pd) {
- GroupPropertyVector::const_iterator assignedGroupProperty = std::lower_bound(groupProperties.constBegin(), groupProperties.constEnd(), binding->propertyNameIndex, compareNameIndices);
+ GroupPropertyVector::const_iterator assignedGroupProperty = std::lower_bound(groupProperties.constBegin(), groupProperties.constEnd(), binding->propertyNameIndex, BindingFinder());
const bool assigningToGroupProperty = assignedGroupProperty != groupProperties.constEnd() && !(binding->propertyNameIndex < (*assignedGroupProperty)->propertyNameIndex);
if (!pd->isWritable()
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 6ee23690a6..5fb94af140 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -69,6 +69,10 @@ struct Function;
struct Lookup;
struct RegExp;
+#if defined(Q_CC_MSVC) || defined(Q_CC_GNU)
+#pragma pack(push, 1)
+#endif
+
struct Location
{
qint32 line;
@@ -82,29 +86,6 @@ struct Location
}
};
-struct TypeReference
-{
- TypeReference(const Location &loc)
- : location(loc)
- , needsCreation(false)
- , errorWhenNotFound(false)
- {}
- Location location; // first use
- bool needsCreation : 1; // whether the type needs to be creatable or not
- bool errorWhenNotFound: 1;
-};
-
-// map from name index to location of first use
-struct TypeReferenceMap : QHash<int, TypeReference>
-{
- TypeReference &add(int nameIndex, const Location &loc) {
- Iterator it = find(nameIndex);
- if (it != end())
- return *it;
- return *insert(nameIndex, loc);
- }
-};
-
struct RegExp
{
enum Flags {
@@ -553,6 +534,33 @@ struct QmlUnit
}
};
+#if defined(Q_CC_MSVC) || defined(Q_CC_GNU)
+#pragma pack(pop)
+#endif
+
+struct TypeReference
+{
+ TypeReference(const Location &loc)
+ : location(loc)
+ , needsCreation(false)
+ , errorWhenNotFound(false)
+ {}
+ Location location; // first use
+ bool needsCreation : 1; // whether the type needs to be creatable or not
+ bool errorWhenNotFound: 1;
+};
+
+// map from name index to location of first use
+struct TypeReferenceMap : QHash<int, TypeReference>
+{
+ TypeReference &add(int nameIndex, const Location &loc) {
+ Iterator it = find(nameIndex);
+ if (it != end())
+ return *it;
+ return *insert(nameIndex, loc);
+ }
+};
+
// This is how this hooks into the existing structures:
//VM::Function
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index c0b21a943f..bde61dca9d 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -672,6 +672,8 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader,
exists = QQmlFile::bundleFileExists(qmlUrl, typeLoader->engine());
} else {
exists = !typeLoader->absoluteFilePath(QQmlFile::urlToLocalFileOrQrc(qmlUrl)).isEmpty();
+ if (!exists)
+ exists = QQmlMetaType::findCachedCompilationUnit(QUrl(qmlUrl));
}
if (exists) {
@@ -1849,17 +1851,21 @@ bool QQmlImportDatabase::registerPluginTypes(QObject *instance, const QString &b
// This is an 'identified' module
if (typeNamespace != uri) {
// The namespace for type registrations must match the URI for locating the module
- QQmlError error;
- error.setDescription(tr("Module namespace '%1' does not match import URI '%2'").arg(typeNamespace).arg(uri));
- errors->prepend(error);
+ if (errors) {
+ QQmlError error;
+ error.setDescription(tr("Module namespace '%1' does not match import URI '%2'").arg(typeNamespace).arg(uri));
+ errors->prepend(error);
+ }
return false;
}
if (QQmlMetaType::namespaceContainsRegistrations(typeNamespace)) {
// Other modules have already installed to this namespace
- QQmlError error;
- error.setDescription(tr("Namespace '%1' has already been used for type registration").arg(typeNamespace));
- errors->prepend(error);
+ if (errors) {
+ QQmlError error;
+ error.setDescription(tr("Namespace '%1' has already been used for type registration").arg(typeNamespace));
+ errors->prepend(error);
+ }
return false;
} else {
QQmlMetaType::protectNamespace(typeNamespace);
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index efdf4d86da..65e302d3d9 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -651,7 +651,7 @@ void QQmlObjectCreator::setupBindings(const QBitArray &bindingsToSkip)
QString id = stringAt(_compiledObject->idIndex);
if (!id.isEmpty()) {
QQmlPropertyData *idProperty = _propertyCache->property(QStringLiteral("id"), _qobject, context);
- if (idProperty && idProperty->isWritable()) {
+ if (idProperty && idProperty->isWritable() && idProperty->propType == QMetaType::QString) {
QV4::CompiledData::Binding idBinding;
idBinding.propertyNameIndex = 0; // Not used
idBinding.flags = 0;
diff --git a/src/qml/qml/qqmlscriptstring.cpp b/src/qml/qml/qqmlscriptstring.cpp
index fd710df52f..af9d8ec265 100644
--- a/src/qml/qml/qqmlscriptstring.cpp
+++ b/src/qml/qml/qqmlscriptstring.cpp
@@ -126,7 +126,9 @@ Returns whether the QQmlScriptString is empty.
*/
bool QQmlScriptString::isEmpty() const
{
- return d->script.isEmpty();
+ if (!d->script.isEmpty())
+ return false;
+ return d->bindingId == -1;
}
/*!
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index d0d6839bdc..a7db7d214e 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -980,12 +980,13 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx)
QQmlEngine *engine = v8engine->engine();
QQmlContextData *context = v8engine->callingContext();
+ Q_ASSERT(context);
QQmlContext *effectiveContext = 0;
if (context->isPragmaLibraryContext)
effectiveContext = engine->rootContext();
else
effectiveContext = context->asQQmlContext();
- Q_ASSERT(context && effectiveContext);
+ Q_ASSERT(effectiveContext);
QString qml = ctx->callData->args[0].toQStringNoThrow();
if (qml.isEmpty())
@@ -1086,10 +1087,10 @@ ReturnedValue QtObject::method_createComponent(CallContext *ctx)
QQmlEngine *engine = v8engine->engine();
QQmlContextData *context = v8engine->callingContext();
+ Q_ASSERT(context);
QQmlContextData *effectiveContext = context;
if (context->isPragmaLibraryContext)
effectiveContext = 0;
- Q_ASSERT(context);
QString arg = ctx->callData->args[0].toQStringNoThrow();
if (arg.isEmpty())
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index 1b074efd56..a0148715ce 100644
--- a/src/qml/types/qqmllistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -1694,13 +1694,20 @@ void QQmlListModel::emitItemsChanged(int index, int count, const QVector<int> &r
}
}
+void QQmlListModel::emitItemsAboutToBeRemoved(int index, int count)
+{
+ if (count <= 0 || !m_mainThread)
+ return;
+
+ beginRemoveRows(QModelIndex(), index, index + count - 1);
+}
+
void QQmlListModel::emitItemsRemoved(int index, int count)
{
if (count <= 0)
return;
if (m_mainThread) {
- beginRemoveRows(QModelIndex(), index, index + count - 1);
endRemoveRows();
emit countChanged();
} else {
@@ -1711,13 +1718,20 @@ void QQmlListModel::emitItemsRemoved(int index, int count)
}
}
+void QQmlListModel::emitItemsAboutToBeInserted(int index, int count)
+{
+ if (count <= 0 || !m_mainThread)
+ return;
+
+ beginInsertRows(QModelIndex(), index, index + count - 1);
+}
+
void QQmlListModel::emitItemsInserted(int index, int count)
{
if (count <= 0)
return;
if (m_mainThread) {
- beginInsertRows(QModelIndex(), index, index + count - 1);
endInsertRows();
emit countChanged();
} else {
@@ -1726,13 +1740,20 @@ void QQmlListModel::emitItemsInserted(int index, int count)
}
}
+void QQmlListModel::emitItemsAboutToBeMoved(int from, int to, int n)
+{
+ if (n <= 0 || !m_mainThread)
+ return;
+
+ beginMoveRows(QModelIndex(), from, from + n - 1, QModelIndex(), to > from ? to + n : to);
+}
+
void QQmlListModel::emitItemsMoved(int from, int to, int n)
{
if (n <= 0)
return;
if (m_mainThread) {
- beginMoveRows(QModelIndex(), from, from + n - 1, QModelIndex(), to > from ? to + n : to);
endMoveRows();
} else {
int uid = m_dynamicRoles ? getUid() : m_listModel->getUid();
@@ -1872,6 +1893,8 @@ void QQmlListModel::clear()
{
int cleared = count();
+ emitItemsAboutToBeRemoved(0, cleared);
+
if (m_dynamicRoles) {
for (int i=0 ; i < m_modelObjects.count() ; ++i)
delete m_modelObjects[i];
@@ -1904,6 +1927,8 @@ void QQmlListModel::remove(QQmlV4Function *args)
return;
}
+ emitItemsAboutToBeRemoved(index, removeCount);
+
if (m_dynamicRoles) {
for (int i=0 ; i < removeCount ; ++i)
delete m_modelObjects[index+i];
@@ -1952,6 +1977,7 @@ void QQmlListModel::insert(QQmlV4Function *args)
QV4::ScopedObject argObject(scope);
int objectArrayLength = objectArray->getLength();
+ emitItemsAboutToBeInserted(index, objectArrayLength);
for (int i=0 ; i < objectArrayLength ; ++i) {
argObject = objectArray->getIndexed(i);
@@ -1963,6 +1989,8 @@ void QQmlListModel::insert(QQmlV4Function *args)
}
emitItemsInserted(index, objectArrayLength);
} else if (argObject) {
+ emitItemsAboutToBeInserted(index, 1);
+
if (m_dynamicRoles) {
m_modelObjects.insert(index, DynamicRoleModelNode::create(args->engine()->variantMapFromJS(argObject), this));
} else {
@@ -2001,6 +2029,8 @@ void QQmlListModel::move(int from, int to, int n)
return;
}
+ emitItemsAboutToBeMoved(from, to, n);
+
if (m_dynamicRoles) {
int realFrom = from;
@@ -2056,6 +2086,8 @@ void QQmlListModel::append(QQmlV4Function *args)
int objectArrayLength = objectArray->getLength();
int index = count();
+ emitItemsAboutToBeInserted(index, objectArrayLength);
+
for (int i=0 ; i < objectArrayLength ; ++i) {
argObject = objectArray->getIndexed(i);
@@ -2072,9 +2104,12 @@ void QQmlListModel::append(QQmlV4Function *args)
if (m_dynamicRoles) {
index = m_modelObjects.count();
+ emitItemsAboutToBeInserted(index, 1);
m_modelObjects.append(DynamicRoleModelNode::create(args->engine()->variantMapFromJS(argObject), this));
} else {
- index = m_listModel->append(argObject, args->engine());
+ index = m_listModel->elementCount();
+ emitItemsAboutToBeInserted(index, 1);
+ m_listModel->append(argObject, args->engine());
}
emitItemsInserted(index, 1);
@@ -2169,6 +2204,7 @@ void QQmlListModel::set(int index, const QQmlV4Handle &handle)
if (index == count()) {
+ emitItemsAboutToBeInserted(index, 1);
if (m_dynamicRoles) {
m_modelObjects.append(DynamicRoleModelNode::create(engine()->variantMapFromJS(object), this));
diff --git a/src/qml/types/qqmllistmodel_p.h b/src/qml/types/qqmllistmodel_p.h
index 59cfce81e5..8c12173425 100644
--- a/src/qml/types/qqmllistmodel_p.h
+++ b/src/qml/types/qqmllistmodel_p.h
@@ -144,8 +144,11 @@ private:
static QQmlListModel *createWithOwner(QQmlListModel *newOwner);
void emitItemsChanged(int index, int count, const QVector<int> &roles);
+ void emitItemsAboutToBeRemoved(int index, int count);
void emitItemsRemoved(int index, int count);
+ void emitItemsAboutToBeInserted(int index, int count);
void emitItemsInserted(int index, int count);
+ void emitItemsAboutToBeMoved(int from, int to, int n);
void emitItemsMoved(int from, int to, int n);
};
diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp
index 507e94fb7e..80c4112930 100644
--- a/src/qml/types/qquickworkerscript.cpp
+++ b/src/qml/types/qquickworkerscript.cpp
@@ -382,36 +382,44 @@ void QQuickWorkerScriptEnginePrivate::processLoad(int id, const QUrl &url)
QString fileName = QQmlFile::urlToLocalFileOrQrc(url);
- QFile f(fileName);
- if (f.open(QIODevice::ReadOnly)) {
- QByteArray data = f.readAll();
- QString sourceCode = QString::fromUtf8(data);
- QmlIR::Document::removeScriptPragmas(sourceCode);
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(workerEngine);
+ QV4::Scope scope(v4);
+ QScopedPointer<QV4::Script> program;
- WorkerScript *script = workers.value(id);
- if (!script)
- return;
- script->source = url;
+ WorkerScript *script = workers.value(id);
+ if (!script)
+ return;
+ script->source = url;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(workerEngine);
- QV4::Scope scope(v4);
+ QV4::Scoped<QV4::Object> activation(scope, getWorker(script));
+ if (!activation)
+ return;
- QV4::Scoped<QV4::Object> activation(scope, getWorker(script));
- if (!activation)
+ if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(url)) {
+ QV4::CompiledData::CompilationUnit *jsUnit = cachedUnit->createCompilationUnit();
+ program.reset(new QV4::Script(v4, activation, jsUnit));
+ } else {
+ QFile f(fileName);
+ if (!f.open(QIODevice::ReadOnly)) {
+ qWarning().nospace() << "WorkerScript: Cannot find source file " << url.toString();
return;
+ }
+
+ QByteArray data = f.readAll();
+ QString sourceCode = QString::fromUtf8(data);
+ QmlIR::Document::removeScriptPragmas(sourceCode);
- QV4::Script program(v4, activation, sourceCode, url.toString());
+ program.reset(new QV4::Script(v4, activation, sourceCode, url.toString()));
+ program->parse();
+ }
+
+ if (!v4->hasException)
+ program->run();
+ if (v4->hasException) {
QV4::ExecutionContext *ctx = v4->currentContext();
- program.parse();
- if (!v4->hasException)
- program.run();
- if (v4->hasException) {
- QQmlError error = QV4::ExecutionEngine::catchExceptionAsQmlError(ctx);
- reportScriptException(script, error);
- }
- } else {
- qWarning().nospace() << "WorkerScript: Cannot find source file " << url.toString();
+ QQmlError error = QV4::ExecutionEngine::catchExceptionAsQmlError(ctx);
+ reportScriptException(script, error);
}
}