From a6fb18f1865aff8b96dfba1e341019371b5fa9f2 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 28 Apr 2015 16:53:37 +0200 Subject: Fix uninitialized variables/data * Initialize the indexOfRootObject member * When creating the QV4::CompiledData::String objects, don't include the one ushort _beyond_ the QString, which is random data. Change-Id: I8fe8a465e2713a385504f217b367a62b70ee5fdf Reviewed-by: Lars Knoll --- src/qml/compiler/qqmlirbuilder.cpp | 1 + src/qml/compiler/qv4compileddata_p.h | 2 +- src/qml/compiler/qv4compiler.cpp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/qml') diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index e5d97341b9..c645a29b15 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -290,6 +290,7 @@ void Document::removeScriptPragmas(QString &script) Document::Document(bool debugMode) : jsModule(debugMode) , program(0) + , indexOfRootObject(0) , jsGenerator(&jsModule) , unitFlags(0) { diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index f46e27fe98..48324fbbc4 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -135,7 +135,7 @@ struct String // uint16 strdata[] static int calculateSize(const QString &str) { - return (sizeof(String) + (str.length() + 1) * sizeof(quint16) + 7) & ~0x7; + return (sizeof(String) + str.length() * sizeof(quint16) + 7) & ~0x7; } }; diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp index 285c0070ef..450889c275 100644 --- a/src/qml/compiler/qv4compiler.cpp +++ b/src/qml/compiler/qv4compiler.cpp @@ -78,7 +78,7 @@ void QV4::Compiler::StringTableGenerator::serialize(CompiledData::Unit *unit) QV4::CompiledData::String *s = (QV4::CompiledData::String*)(stringData); s->flags = 0; // ### s->size = qstr.length(); - memcpy(s + 1, qstr.constData(), (qstr.length() + 1)*sizeof(ushort)); + memcpy(s + 1, qstr.constData(), qstr.length()*sizeof(ushort)); stringData += QV4::CompiledData::String::calculateSize(qstr); } -- cgit v1.2.3 From 2fdb6eba0a58b629db32f9eefec2f26df08d3d2e Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 30 Apr 2015 13:20:43 +0200 Subject: Fix passing of locals as function arguments with side-effects Commit 75c22465cf8fe262edfe6178bb9ca19661fb710e regressed in allowing locals and arguments to be passed directly as further arguments to function calls, but that's incorrect when considering var i = 2; testFunction(i, i += 2) where it is instrumental to place the first argument into a temp (making a copy) instead of passing it directly. Change-Id: Iffcf6c6eda92a8fb665982cda1db0b96359cd092 Task-number: QTBUG-45879 Reviewed-by: Lars Knoll --- src/qml/compiler/qv4codegen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/qml') diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index a7b5326861..260db0f0dd 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -538,7 +538,7 @@ IR::Expr *Codegen::subscript(IR::Expr *base, IR::Expr *index) IR::Expr *Codegen::argument(IR::Expr *expr) { - if (expr && !expr->asTemp() && !expr->asArgLocal()) { + if (expr && !expr->asTemp()) { const unsigned t = _block->newTemp(); move(_block->TEMP(t), expr); expr = _block->TEMP(t); -- cgit v1.2.3 From 6c1d99c2490e1af5c42d03cf10e8fe4d2e30c025 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 28 Apr 2015 16:03:07 +0200 Subject: Fix default value for XMLHttpRequest.response property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The default value for responseType is the empty string, for which the expected data type for the response property is a string - same as when the response type is set to "text". In other words: By default the response property should contain the string representation of the data. Task-number: QTBUG-45862 Change-Id: I563160e5cdfbf93aca7e283e455d77a6b9deceb4 Reviewed-by: Pasi Keränen Reviewed-by: Valery Kotov Reviewed-by: Lars Knoll --- src/qml/qml/qqmlxmlhttprequest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/qml') diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index a2c5f09061..2a3ede6a22 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -1982,7 +1982,7 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_get_response(CallContext *ctx) return QV4::Encode(scope.engine->newString(QString())); const QString& responseType = r->responseType(); - if (responseType.compare(QLatin1String("text"), Qt::CaseInsensitive) == 0) { + if (responseType.compare(QLatin1String("text"), Qt::CaseInsensitive) == 0 || responseType.isEmpty()) { return QV4::Encode(scope.engine->newString(r->responseBody())); } else if (responseType.compare(QLatin1String("arraybuffer"), Qt::CaseInsensitive) == 0) { return QV4::Encode(scope.engine->newArrayBuffer(r->rawResponseBody())); -- cgit v1.2.3 From 3b5d37ce3841c4bfdf1c629d33f0e33b881b47fb Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 28 Apr 2015 15:38:09 +0200 Subject: Fix memory corruption when multiple QML engines have JavaScript wrappers for the same QObject It's possible that the same QObject is exposed to multiple JavaScript environments, for which we have this "extra" hack in the form of a QMap. The common case is that QQmlData has a QV4::WeakValue that points to the JS wrapper for the object. However in the rare case of multiple exposure, a map in the other engines stores those references. That map was erroneously storing pointers to temporary values on the JS stack instead of heap pointers. Change-Id: I8587f9921a9b4f9efd288326d00cebc25ad0bc12 Task-number: QTBUG-45051 Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4mm.cpp | 2 +- src/qml/jsruntime/qv4qobjectwrapper.cpp | 22 +++++++++++++--------- src/qml/jsruntime/qv4qobjectwrapper_p.h | 18 +++++++++--------- src/qml/qml/qqmldata_p.h | 4 ++-- 4 files changed, 25 insertions(+), 21 deletions(-) (limited to 'src/qml') diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp index 07408a343c..d5576b400a 100644 --- a/src/qml/jsruntime/qv4mm.cpp +++ b/src/qml/jsruntime/qv4mm.cpp @@ -390,7 +390,7 @@ void MemoryManager::sweep(bool lastSweep) if (MultiplyWrappedQObjectMap *multiplyWrappedQObjects = m_d->engine->m_multiplyWrappedQObjects) { for (MultiplyWrappedQObjectMap::Iterator it = multiplyWrappedQObjects->begin(); it != multiplyWrappedQObjects->end();) { - if (!it.value()->markBit()) + if (!it.value().isNullOrUndefined()) it = multiplyWrappedQObjects->erase(it); else ++it; diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 50efff001d..353f4023ca 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -589,7 +589,7 @@ ReturnedValue QObjectWrapper::wrap(ExecutionEngine *engine, QObject *object) } else if (ddata->jsWrapper.isUndefined() && (ddata->jsEngineId == engine->m_engineId || // We own the QObject ddata->jsEngineId == 0 || // No one owns the QObject - !ddata->hasTaintedV8Object)) { // Someone else has used the QObject, but it isn't tainted + !ddata->hasTaintedV4Object)) { // Someone else has used the QObject, but it isn't tainted QV4::ScopedValue rv(scope, create(engine, object)); ddata->jsWrapper.set(scope.engine, rv); @@ -600,11 +600,11 @@ ReturnedValue QObjectWrapper::wrap(ExecutionEngine *engine, QObject *object) // If this object is tainted, we have to check to see if it is in our // tainted object list ScopedObject alternateWrapper(scope, (Object *)0); - if (engine->m_multiplyWrappedQObjects && ddata->hasTaintedV8Object) + if (engine->m_multiplyWrappedQObjects && ddata->hasTaintedV4Object) alternateWrapper = engine->m_multiplyWrappedQObjects->value(object); // If our tainted handle doesn't exist or has been collected, and there isn't - // a handle in the ddata, we can assume ownership of the ddata->v8object + // a handle in the ddata, we can assume ownership of the ddata->jsWrapper if (ddata->jsWrapper.isUndefined() && !alternateWrapper) { QV4::ScopedValue result(scope, create(engine, object)); ddata->jsWrapper.set(scope.engine, result); @@ -616,8 +616,8 @@ ReturnedValue QObjectWrapper::wrap(ExecutionEngine *engine, QObject *object) alternateWrapper = create(engine, object); if (!engine->m_multiplyWrappedQObjects) engine->m_multiplyWrappedQObjects = new MultiplyWrappedQObjectMap; - engine->m_multiplyWrappedQObjects->insert(object, alternateWrapper); - ddata->hasTaintedV8Object = true; + engine->m_multiplyWrappedQObjects->insert(object, alternateWrapper->d()); + ddata->hasTaintedV4Object = true; } return alternateWrapper.asReturnedValue(); @@ -1908,16 +1908,20 @@ Heap::QmlSignalHandler::QmlSignalHandler(QV4::ExecutionEngine *engine, QObject * DEFINE_OBJECT_VTABLE(QmlSignalHandler); -void MultiplyWrappedQObjectMap::insert(QObject *key, Object *value) +void MultiplyWrappedQObjectMap::insert(QObject *key, Heap::Object *value) { - QHash::insert(key, value); + QV4::WeakValue v; + v.set(value->internalClass->engine, value); + QHash::insert(key, v); connect(key, SIGNAL(destroyed(QObject*)), this, SLOT(removeDestroyedObject(QObject*))); } + + MultiplyWrappedQObjectMap::Iterator MultiplyWrappedQObjectMap::erase(MultiplyWrappedQObjectMap::Iterator it) { disconnect(it.key(), SIGNAL(destroyed(QObject*)), this, SLOT(removeDestroyedObject(QObject*))); - return QHash::erase(it); + return QHash::erase(it); } void MultiplyWrappedQObjectMap::remove(QObject *key) @@ -1930,7 +1934,7 @@ void MultiplyWrappedQObjectMap::remove(QObject *key) void MultiplyWrappedQObjectMap::removeDestroyedObject(QObject *object) { - QHash::remove(object); + QHash::remove(object); } QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h index 1b41ca65c1..5d2378018c 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper_p.h +++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h @@ -173,20 +173,20 @@ struct QmlSignalHandler : public QV4::Object }; class MultiplyWrappedQObjectMap : public QObject, - private QHash + private QHash { Q_OBJECT public: - typedef QHash::ConstIterator ConstIterator; - typedef QHash::Iterator Iterator; + typedef QHash::ConstIterator ConstIterator; + typedef QHash::Iterator Iterator; - ConstIterator begin() const { return QHash::constBegin(); } - Iterator begin() { return QHash::begin(); } - ConstIterator end() const { return QHash::constEnd(); } - Iterator end() { return QHash::end(); } + ConstIterator begin() const { return QHash::constBegin(); } + Iterator begin() { return QHash::begin(); } + ConstIterator end() const { return QHash::constEnd(); } + Iterator end() { return QHash::end(); } - void insert(QObject *key, Object *value); - Object *value(QObject *key) const { return QHash::value(key, 0); } + void insert(QObject *key, Heap::Object *value); + ReturnedValue value(QObject *key) const { return QHash::value(key).value(); } Iterator erase(Iterator it); void remove(QObject *key); diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h index c7654be545..04c42b638d 100644 --- a/src/qml/qml/qqmldata_p.h +++ b/src/qml/qml/qqmldata_p.h @@ -74,7 +74,7 @@ class Q_QML_PRIVATE_EXPORT QQmlData : public QAbstractDeclarativeData public: QQmlData() : ownedByQml1(false), ownMemory(true), ownContext(false), indestructible(true), explicitIndestructibleSet(false), - hasTaintedV8Object(false), isQueuedForDeletion(false), rootObjectInCreation(false), + hasTaintedV4Object(false), isQueuedForDeletion(false), rootObjectInCreation(false), hasVMEMetaObject(false), parentFrozen(false), bindingBitsSize(0), bindingBits(0), notifyList(0), context(0), outerContext(0), bindings(0), signalHandlers(0), nextContextObject(0), prevContextObject(0), lineNumber(0), columnNumber(0), jsEngineId(0), compiledData(0), deferredData(0), @@ -112,7 +112,7 @@ public: quint32 ownContext:1; quint32 indestructible:1; quint32 explicitIndestructibleSet:1; - quint32 hasTaintedV8Object:1; + quint32 hasTaintedV4Object:1; quint32 isQueuedForDeletion:1; /* * rootObjectInCreation should be true only when creating top level CPP and QML objects, -- cgit v1.2.3 From c415e6972b371acc288cd835f5635936215c615f Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 5 May 2015 10:52:34 +0200 Subject: Fix memory corruption in array handling SimpleArrayData's markObjects() implementation did not mark the entries correctly. When the dequeue offset was non-zero, we would end up marking values that may have been garbage collected earlier. Task-number: QTBUG-45888 Change-Id: Iacec350ccc76399ad4d16138af50acf22b2809db Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4arraydata.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/qml') diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp index 737c891f9b..afcfa00905 100644 --- a/src/qml/jsruntime/qv4arraydata.cpp +++ b/src/qml/jsruntime/qv4arraydata.cpp @@ -216,9 +216,8 @@ void ArrayData::ensureAttributes(Object *o) void SimpleArrayData::markObjects(Heap::Base *d, ExecutionEngine *e) { Heap::SimpleArrayData *dd = static_cast(d); - uint l = dd->len; - for (uint i = 0; i < l; ++i) - dd->arrayData[i].mark(e); + for (uint i = 0; i < dd->len; ++i) + dd->arrayData[dd->mappedIndex(i)].mark(e); } ReturnedValue SimpleArrayData::get(const Heap::ArrayData *d, uint index) -- cgit v1.2.3 From c31d6e946d700bb404fdcadaba11ac45c714d60d Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 5 May 2015 13:14:36 +0200 Subject: Avoid uninitialized bytes in QV4::CompiledData When populating the QV4::CompiledData for a JS unit, we memset the malloc'ed data to zero. We should do the same when creating a unit for QML files. We do write all the fields that we use, but due to padding we may end up with bytes that are neither used nor written but still uninitialized. Consequently they should be zero'ed, otherwise serialization will write garbage. Change-Id: I0b093e4dde6789d7236247507221f4f3476ba89d Reviewed-by: Lars Knoll --- src/qml/compiler/qqmlirbuilder.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/qml') diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index c645a29b15..63833504f1 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1319,6 +1319,7 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output) const int totalSize = unitSize + importSize + objectOffsetTableSize + objectsSize + output.jsGenerator.stringTable.sizeOfTableAndData(); char *data = (char*)malloc(totalSize); memcpy(data, jsUnit, unitSize); + memset(data + unitSize, 0, totalSize - unitSize); if (jsUnit != compilationUnit->data) free(jsUnit); jsUnit = 0; -- cgit v1.2.3 From 889f717fc57ea9881ca250b8230742633c1ed5a2 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 7 May 2015 16:22:24 +0200 Subject: Fix memory corruption when sharing QObjects between different QML engines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When marking the JS wrappers for QObject manually, we cannot use ddata->jsWrapper directly but we must respect the case where the same object is exposed to different engines and then we must mark the wrapper that belongs to the engine that is currently collecting garbage. Change-Id: If82883c762ccaf3431e7074243ff2ff703234d66 Task-number: QTBUG-44895 Reviewed-by: Marco Martin Reviewed-by: Jan Kundrát Reviewed-by: Lars Knoll Reviewed-by: Aleix Pol Gonzalez --- src/qml/jsruntime/qv4qobjectwrapper.cpp | 27 ++++++++++++++++++++++++--- src/qml/jsruntime/qv4qobjectwrapper_p.h | 2 ++ src/qml/qml/qqmlvmemetaobject.cpp | 13 +++++++------ 3 files changed, 33 insertions(+), 9 deletions(-) (limited to 'src/qml') diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 353f4023ca..1e4718c208 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -624,6 +624,21 @@ ReturnedValue QObjectWrapper::wrap(ExecutionEngine *engine, QObject *object) } } +void QObjectWrapper::markWrapper(QObject *object, ExecutionEngine *engine) +{ + if (QQmlData::wasDeleted(object)) + return; + + QQmlData *ddata = QQmlData::get(object); + if (!ddata) + return; + + if (ddata->jsEngineId == engine->m_engineId) + ddata->jsWrapper.markOnce(engine); + else if (engine->m_multiplyWrappedQObjects && ddata->hasTaintedV4Object) + engine->m_multiplyWrappedQObjects->mark(object, engine); +} + ReturnedValue QObjectWrapper::getProperty(QObject *object, ExecutionContext *ctx, int propertyIndex, bool captureRequired) { if (QQmlData::wasDeleted(object)) @@ -993,9 +1008,7 @@ static void markChildQObjectsRecursively(QObject *parent, QV4::ExecutionEngine * QObject *child = children.at(i); if (!child) continue; - QQmlData *ddata = QQmlData::get(child, /*create*/false); - if (ddata) - ddata->jsWrapper.markOnce(e); + QObjectWrapper::markWrapper(child, e); markChildQObjectsRecursively(child, e); } } @@ -1932,6 +1945,14 @@ void MultiplyWrappedQObjectMap::remove(QObject *key) erase(it); } +void MultiplyWrappedQObjectMap::mark(QObject *key, ExecutionEngine *engine) +{ + Iterator it = find(key); + if (it == end()) + return; + it->markOnce(engine); +} + void MultiplyWrappedQObjectMap::removeDestroyedObject(QObject *object) { QHash::remove(object); diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h index 5d2378018c..24e8b29e08 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper_p.h +++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h @@ -110,6 +110,7 @@ struct Q_QML_EXPORT QObjectWrapper : public Object static bool setQmlProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, const Value &value); static ReturnedValue wrap(ExecutionEngine *engine, QObject *object); + static void markWrapper(QObject *object, ExecutionEngine *engine); using Object::get; @@ -189,6 +190,7 @@ public: ReturnedValue value(QObject *key) const { return QHash::value(key).value(); } Iterator erase(Iterator it); void remove(QObject *key); + void mark(QObject *key, ExecutionEngine *engine); private Q_SLOTS: void removeDestroyedObject(QObject*); diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 37ff696579..5b1be15869 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -1227,6 +1227,11 @@ void QQmlVMEMetaObject::ensureQObjectWrapper() void QQmlVMEMetaObject::mark(QV4::ExecutionEngine *e) { + QQmlEnginePrivate *ep = (ctxt == 0 || ctxt->engine == 0) ? 0 : QQmlEnginePrivate::get(ctxt->engine); + QV4::ExecutionEngine *v4 = (ep == 0) ? 0 : ep->v4engine(); + if (v4 != e) + return; + varProperties.markOnce(e); // add references created by VMEVariant properties @@ -1234,12 +1239,8 @@ void QQmlVMEMetaObject::mark(QV4::ExecutionEngine *e) for (int ii = 0; ii < maxDataIdx; ++ii) { // XXX TODO: optimize? if (data[ii].dataType() == QMetaType::QObjectStar) { // possible QObject reference. - QObject *ref = data[ii].asQObject(); - if (ref) { - QQmlData *ddata = QQmlData::get(ref); - if (ddata) - ddata->jsWrapper.markOnce(e); - } + if (QObject *ref = data[ii].asQObject()) + QV4::QObjectWrapper::markWrapper(ref, e); } } -- cgit v1.2.3 From a690648c215128d6e0ffe709be08a334f39554e0 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 8 May 2015 12:34:53 +0200 Subject: Add protection against "wrong" marking in debug builds To protect against situations where we accidentally mark an object that belongs to a different engine - there are many possible entry points - this patch adds an assertion in debug builds for this situation. When it happens, it will point more or less directly to the code that tries to push an object to the wrong JS stack for marking. This helped in the investigation of QTBUG-44895 Change-Id: I311b9ff6d282d52e725044b03a62cd77085536be Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4engine.cpp | 9 +++++++++ src/qml/jsruntime/qv4engine_p.h | 7 +++++++ 2 files changed, 16 insertions(+) (limited to 'src/qml') diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index a247f85761..92993259ec 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1623,6 +1623,15 @@ QV4::ReturnedValue ExecutionEngine::metaTypeToJS(int type, const void *data) return 0; } +#ifndef QT_NO_DEBUG +void ExecutionEngine::assertObjectBelongsToEngine(const Value &v) +{ + if (!v.isObject()) + return; + Q_ASSERT(v.objectValue()->engine() == this); +} +#endif + // Converts a JS value to a meta-type. // data must point to a place that can store a value of the given type. // Returns true if conversion succeeded, false otherwise. diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index f01579be71..277cbdf1f5 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -340,6 +340,10 @@ public: bool metaTypeFromJS(const Value &value, int type, void *data); QV4::ReturnedValue metaTypeToJS(int type, const void *data); +#ifndef QT_NO_DEBUG + void assertObjectBelongsToEngine(const Value &v); +#endif + private: QmlExtensions *m_qmlExtensions; }; @@ -381,6 +385,9 @@ void Managed::mark(QV4::ExecutionEngine *engine) Q_ASSERT(inUse()); if (markBit()) return; +#ifndef QT_NO_DEBUG + engine->assertObjectBelongsToEngine(*this); +#endif d()->setMarkBit(); engine->pushForGC(d()); } -- cgit v1.2.3 From d76921e3082cd311207cd4c822ef2d357519b12f Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Mon, 11 May 2015 10:16:37 +0200 Subject: QML: fix mixed debug/release build on OSX. Dyld will take the debug library and link it against the release versions of the frameworks. (Using the debug versions is an option to dyld when starting an application.) This requires all symbols in both debug and release libraries in frameworks to be the same. Change-Id: I6d96bcdf8577f1dffc63c508cb7adc0db2acc486 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4engine.cpp | 6 +----- src/qml/jsruntime/qv4engine_p.h | 2 -- 2 files changed, 1 insertion(+), 7 deletions(-) (limited to 'src/qml') diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 92993259ec..3b89851d81 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1623,14 +1623,10 @@ QV4::ReturnedValue ExecutionEngine::metaTypeToJS(int type, const void *data) return 0; } -#ifndef QT_NO_DEBUG void ExecutionEngine::assertObjectBelongsToEngine(const Value &v) { - if (!v.isObject()) - return; - Q_ASSERT(v.objectValue()->engine() == this); + Q_ASSERT(!v.isObject() || v.objectValue()->engine() == this); } -#endif // Converts a JS value to a meta-type. // data must point to a place that can store a value of the given type. diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 277cbdf1f5..c0c88abaa5 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -340,9 +340,7 @@ public: bool metaTypeFromJS(const Value &value, int type, void *data); QV4::ReturnedValue metaTypeToJS(int type, const void *data); -#ifndef QT_NO_DEBUG void assertObjectBelongsToEngine(const Value &v); -#endif private: QmlExtensions *m_qmlExtensions; -- cgit v1.2.3 From 2cb2c8f9e12fe72bab6e0a627e34d89d9d2689b2 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 19 May 2015 09:16:44 +0200 Subject: MSVC: Fix compiler warning Fix compiler warning introduced in commit d76921e3082cd31: jsruntime\qv4engine.cpp(1626) : warning C4100: 'v' : unreferenced formal parameter Change-Id: I1f2b74f8e3fb14019f6e28b407d0336b0812c573 Reviewed-by: Friedemann Kleint --- src/qml/jsruntime/qv4engine.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/qml') diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 3b89851d81..33559d8e69 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1625,6 +1625,7 @@ QV4::ReturnedValue ExecutionEngine::metaTypeToJS(int type, const void *data) void ExecutionEngine::assertObjectBelongsToEngine(const Value &v) { + Q_UNUSED(v); Q_ASSERT(!v.isObject() || v.objectValue()->engine() == this); } -- cgit v1.2.3 From bf935a5359227066ac066b9e3d96bc48870bc4e7 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 19 May 2015 11:07:43 +0200 Subject: Fix MSVC warning about unused variable Change-Id: I9b2f21dd7cfc82a9da9aa3e4c60d47fa07fdceaf Reviewed-by: Lars Knoll --- src/qml/jsruntime/qv4engine.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/qml') diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 33559d8e69..5e450859ec 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1627,6 +1627,7 @@ void ExecutionEngine::assertObjectBelongsToEngine(const Value &v) { Q_UNUSED(v); Q_ASSERT(!v.isObject() || v.objectValue()->engine() == this); + Q_UNUSED(v); } // Converts a JS value to a meta-type. -- cgit v1.2.3 From 65a28bb1cd871d9332bc0734bc0a2f1a1e1bbeab Mon Sep 17 00:00:00 2001 From: Vishesh Handa Date: Thu, 12 Mar 2015 14:26:00 +0100 Subject: Fix null pointer dereference in QQmlImportNamespace Change-Id: Iaf61f38790b0dfddb924043e0a25eb8a882571c8 Reviewed-by: Simon Hausmann --- src/qml/qml/qqmlimport.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/qml') diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index 906e073cab..5a54609e12 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -653,9 +653,10 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader, } if (candidate != end) { + QQmlType *returnType = getTypeForUrl(componentUrl, type, isCompositeSingleton, 0); if (type_return) - *type_return = getTypeForUrl(componentUrl, type, isCompositeSingleton, 0); - return (*type_return != 0); + *type_return = returnType; + return returnType != 0; } } else if (!isLibrary) { QString qmlUrl; @@ -679,9 +680,10 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader, if (typeRecursionDetected) *typeRecursionDetected = true; } else { + QQmlType *returnType = getTypeForUrl(qmlUrl, type, false, 0); if (type_return) - *type_return = getTypeForUrl(qmlUrl, type, false, 0); - return (*type_return) != 0; + *type_return = returnType; + return returnType != 0; } } } -- cgit v1.2.3 From dad48f0e9cca10528fcaab7ec7d08f678e81b1a9 Mon Sep 17 00:00:00 2001 From: Aleix Pol Date: Sat, 23 May 2015 14:10:36 +0200 Subject: Makes it possible to extract all data from a QML DropArea There's many types that aren't being covered by DropArea API, such as images. getDataAsString is not acceptable, since fromUtf8 chokes on reading non-utf8. This patch introduces getDataAsArrayBuffer method that won't try to convert the data into a QString and simply pass a QV4::ArrayBuffer, that internally keeps a QByteArray. Change-Id: I65411b3d365ee6c5e13effd9167156771ee08a05 Reviewed-by: Simon Hausmann --- src/qml/jsruntime/qv4engine.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/qml') diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 5e450859ec..ba6f5a3b79 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1266,6 +1266,8 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int return ld->d()->locale; if (QV4::DateObject *d = value.asDateObject()) return d->toQDateTime(); + if (QV4::ArrayBuffer *d = value.as()) + return d->asByteArray(); // NOTE: since we convert QTime to JS Date, round trip will change the variant type (to QDateTime)! QV4::ScopedObject o(scope, value); -- cgit v1.2.3 From 4d722de834da30715b344db712ee12054fabe8b6 Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Thu, 28 May 2015 11:07:19 +0200 Subject: Purge use of VisualDataModel from docs where DelegateModel is required MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They are the same types except that VisualDataModel is deprecated and uses a different import statement. Now, references to VisualDataModel are only used where we explicitly refer to the replacement/deprecation. Change-Id: I1e68eb5784235a00233b3882c3d91e21e32af7d1 Reviewed-by: Topi Reiniö --- src/qml/doc/snippets/delegatemodel/visualdatagroup.qml | 11 ++++++----- src/qml/doc/snippets/delegatemodel/visualdatamodel.qml | 3 ++- .../snippets/delegatemodel/visualdatamodel_rootindex/view.qml | 3 ++- src/qml/types/qquickpackage.cpp | 4 ++-- 4 files changed, 12 insertions(+), 9 deletions(-) (limited to 'src/qml') diff --git a/src/qml/doc/snippets/delegatemodel/visualdatagroup.qml b/src/qml/doc/snippets/delegatemodel/visualdatagroup.qml index ca72e16b35..85ac83ae52 100644 --- a/src/qml/doc/snippets/delegatemodel/visualdatagroup.qml +++ b/src/qml/doc/snippets/delegatemodel/visualdatagroup.qml @@ -39,11 +39,12 @@ ****************************************************************************/ //![0] import QtQuick 2.0 +import QtQml.Models 2.2 Rectangle { width: 200; height: 100 - VisualDataModel { + DelegateModel { id: visualModel model: ListModel { ListElement { name: "Apple" } @@ -51,7 +52,7 @@ Rectangle { } groups: [ - VisualDataGroup { name: "selected" } + DelegateModelGroup { name: "selected" } ] delegate: Rectangle { @@ -61,14 +62,14 @@ Rectangle { Text { text: { var text = "Name: " + name - if (item.VisualDataModel.inSelected) - text += " (" + item.VisualDataModel.selectedIndex + ")" + if (item.DelegateModel.inSelected) + text += " (" + item.DelegateModel.selectedIndex + ")" return text; } } MouseArea { anchors.fill: parent - onClicked: item.VisualDataModel.inSelected = !item.VisualDataModel.inSelected + onClicked: item.DelegateModel.inSelected = !item.DelegateModel.inSelected } } } diff --git a/src/qml/doc/snippets/delegatemodel/visualdatamodel.qml b/src/qml/doc/snippets/delegatemodel/visualdatamodel.qml index cf6b5aafb9..438eafeed1 100644 --- a/src/qml/doc/snippets/delegatemodel/visualdatamodel.qml +++ b/src/qml/doc/snippets/delegatemodel/visualdatamodel.qml @@ -39,11 +39,12 @@ ****************************************************************************/ //![0] import QtQuick 2.0 +import QtQml.Models 2.2 Rectangle { width: 200; height: 100 - VisualDataModel { + DelegateModel { id: visualModel model: ListModel { ListElement { name: "Apple" } diff --git a/src/qml/doc/snippets/delegatemodel/visualdatamodel_rootindex/view.qml b/src/qml/doc/snippets/delegatemodel/visualdatamodel_rootindex/view.qml index f4e18f6ac0..719d16ff7d 100644 --- a/src/qml/doc/snippets/delegatemodel/visualdatamodel_rootindex/view.qml +++ b/src/qml/doc/snippets/delegatemodel/visualdatamodel_rootindex/view.qml @@ -39,13 +39,14 @@ ****************************************************************************/ //![0] import QtQuick 2.0 +import QtQml.Models 2.2 ListView { id: view width: 300 height: 400 - model: VisualDataModel { + model: DelegateModel { model: dirModel delegate: Rectangle { diff --git a/src/qml/types/qquickpackage.cpp b/src/qml/types/qquickpackage.cpp index 5fe73ec0e0..69bf058e6f 100644 --- a/src/qml/types/qquickpackage.cpp +++ b/src/qml/types/qquickpackage.cpp @@ -45,8 +45,8 @@ QT_BEGIN_NAMESPACE \ingroup qtquick-views \brief Specifies a collection of named items - The Package class is used in conjunction with - VisualDataModel to enable delegates with a shared context + The Package type is used in conjunction with + DelegateModel to enable delegates with a shared context to be provided to multiple views. Any item within a Package may be assigned a name via the -- cgit v1.2.3