summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-10-01 21:57:43 +0200
committerSimon Hausmann <simon.hausmann@theqtcompany.com>2016-10-04 12:27:15 +0200
commit0d2fad48fcc50fc3bec2401515b64f966e62c473 (patch)
treeed70612fe1069c681d64aaa63f35034504adc12d /src
parente4134cfd8086a78c61a46fdfb908ade27c8d9840 (diff)
parent3763008370833508104dbf2ed8296e8925207563 (diff)
Merge remote-tracking branch 'origin/5.6' into 5.7
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp5
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp10
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h2
-rw-r--r--src/qml/qml/qqmldata_p.h2
-rw-r--r--src/qml/qml/qqmlengine.cpp11
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp14
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h16
-rw-r--r--src/quick/items/qquickitem.cpp41
-rw-r--r--src/quick/items/qquickitem.h2
-rw-r--r--src/quick/items/qquickitem_p.h4
-rw-r--r--src/quick/items/qquickview.cpp26
-rw-r--r--src/quick/items/qquickview_p.h29
-rw-r--r--src/quick/items/qquickwindowmodule.cpp8
13 files changed, 90 insertions, 80 deletions
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index a211d46153..14bbb189b6 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -44,6 +44,7 @@
#include <qv4objectiterator_p.h>
#include <qv4scopedvalue_p.h>
#include <qv4runtime_p.h>
+#include <qv4variantobject_p.h>
#include "qv4string_p.h"
#include <qstack.h>
@@ -732,6 +733,10 @@ QString Stringify::Str(const QString &key, const Value &v)
return std::isfinite(d) ? value->toQString() : QStringLiteral("null");
}
+ if (const QV4::VariantObject *v = value->as<QV4::VariantObject>()) {
+ return v->d()->data.toString();
+ }
+
o = value->asReturnedValue();
if (o) {
if (!o->as<FunctionObject>()) {
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 462c4f3171..ea3cfabf4d 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -674,8 +674,14 @@ bool QObjectWrapper::isEqualTo(Managed *a, Managed *b)
ReturnedValue QObjectWrapper::create(ExecutionEngine *engine, QObject *object)
{
- if (engine->jsEngine())
- QQmlData::ensurePropertyCache(engine->jsEngine(), object);
+ if (QJSEngine *jsEngine = engine->jsEngine()) {
+ if (QQmlPropertyCache *cache = QQmlData::ensurePropertyCache(jsEngine, object)) {
+ ReturnedValue result = QV4::Encode::null();
+ void *args[] = { &result, &engine };
+ if (cache->callJSFactoryMethod(object, args))
+ return result;
+ }
+ }
return (engine->memoryManager->allocObject<QV4::QObjectWrapper>(object))->asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index f101f352f1..9c5862b80e 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -77,7 +77,7 @@ namespace Heap {
struct QQmlValueTypeWrapper;
-struct QObjectWrapper : Object {
+struct Q_QML_EXPORT QObjectWrapper : Object {
QObjectWrapper(QObject *object);
QPointer<QObject> object;
};
diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h
index ad2456a68d..7ccab5746d 100644
--- a/src/qml/qml/qqmldata_p.h
+++ b/src/qml/qml/qqmldata_p.h
@@ -223,7 +223,7 @@ public:
static inline void flushPendingBinding(QObject *, int coreIndex);
- static void ensurePropertyCache(QJSEngine *engine, QObject *object);
+ static QQmlPropertyCache *ensurePropertyCache(QJSEngine *engine, QObject *object);
private:
// For attachedProperties
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 517324a80f..71795a2539 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -1800,14 +1800,15 @@ void QQmlData::setPendingBindingBit(QObject *obj, int coreIndex)
QQmlData_setBit(this, obj, coreIndex * 2 + 1);
}
-void QQmlData::ensurePropertyCache(QJSEngine *engine, QObject *object)
+QQmlPropertyCache *QQmlData::ensurePropertyCache(QJSEngine *engine, QObject *object)
{
Q_ASSERT(engine);
QQmlData *ddata = QQmlData::get(object, /*create*/true);
- if (ddata->propertyCache)
- return;
- ddata->propertyCache = QJSEnginePrivate::get(engine)->cache(object);
- if (ddata->propertyCache) ddata->propertyCache->addref();
+ if (!ddata->propertyCache){
+ ddata->propertyCache = QJSEnginePrivate::get(engine)->cache(object);
+ if (ddata->propertyCache) ddata->propertyCache->addref();
+ }
+ return ddata->propertyCache;
}
void QQmlEnginePrivate::sendQuit()
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index 0522aa93ee..9c535b8ce8 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -240,7 +240,7 @@ Creates a new empty QQmlPropertyCache.
QQmlPropertyCache::QQmlPropertyCache(QV4::ExecutionEngine *e)
: engine(e), _parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0),
signalHandlerIndexCacheStart(0), _hasPropertyOverrides(false), _ownMetaObject(false),
- _metaObject(0), argumentsCache(0)
+ _metaObject(0), argumentsCache(0), _jsFactoryMethodIndex(-1)
{
Q_ASSERT(engine);
}
@@ -251,7 +251,7 @@ Creates a new QQmlPropertyCache of \a metaObject.
QQmlPropertyCache::QQmlPropertyCache(QV4::ExecutionEngine *e, const QMetaObject *metaObject)
: engine(e), _parent(0), propertyIndexCacheStart(0), methodIndexCacheStart(0),
signalHandlerIndexCacheStart(0), _hasPropertyOverrides(false), _ownMetaObject(false),
- _metaObject(0), argumentsCache(0)
+ _metaObject(0), argumentsCache(0), _jsFactoryMethodIndex(-1)
{
Q_ASSERT(engine);
Q_ASSERT(metaObject);
@@ -524,10 +524,16 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject,
for (int ii = 0; ii < classInfoCount; ++ii) {
int idx = ii + classInfoOffset;
- if (0 == qstrcmp(metaObject->classInfo(idx).name(), "qt_HasQmlAccessors")) {
+ const char * const classInfoName = metaObject->classInfo(idx).name();
+ if (0 == qstrcmp(classInfoName, "qt_HasQmlAccessors")) {
hasFastProperty = true;
- } else if (0 == qstrcmp(metaObject->classInfo(idx).name(), "DefaultProperty")) {
+ } else if (0 == qstrcmp(classInfoName, "DefaultProperty")) {
_defaultPropertyName = QString::fromUtf8(metaObject->classInfo(idx).value());
+ } else if (0 == qstrcmp(classInfoName, "qt_QmlJSWrapperFactoryMethod")) {
+ const char * const factoryMethod = metaObject->classInfo(idx).value();
+ _jsFactoryMethodIndex = metaObject->indexOfSlot(factoryMethod);
+ if (_jsFactoryMethodIndex != -1)
+ _jsFactoryMethodIndex -= metaObject->methodOffset();
}
}
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index 96dbc72f32..830b8398b5 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -80,6 +80,8 @@ class QQmlPropertyCacheCreator;
class QQmlPropertyRawData
{
public:
+ typedef QObjectPrivate::StaticMetaCallFunction StaticMetaCallFunction;
+
enum Flag {
NoFlags = 0x00000000,
ValueTypeFlagMask = 0x0000FFFF, // Flags in valueTypeFlags must fit in this mask
@@ -326,6 +328,8 @@ public:
void toMetaObjectBuilder(QMetaObjectBuilder &);
+ inline bool callJSFactoryMethod(QObject *object, void **args) const;
+
protected:
virtual void destroy();
virtual void clear();
@@ -394,6 +398,7 @@ private:
QByteArray _dynamicStringData;
QString _defaultPropertyName;
QQmlPropertyCacheMethodArguments *argumentsCache;
+ int _jsFactoryMethodIndex;
};
// QQmlMetaObject serves as a wrapper around either QMetaObject or QQmlPropertyCache.
@@ -562,6 +567,17 @@ int QQmlPropertyCache::signalOffset() const
return signalHandlerIndexCacheStart;
}
+bool QQmlPropertyCache::callJSFactoryMethod(QObject *object, void **args) const
+{
+ if (_jsFactoryMethodIndex != -1) {
+ _metaObject->d.static_metacall(object, QMetaObject::InvokeMetaMethod, _jsFactoryMethodIndex, args);
+ return true;
+ }
+ if (_parent)
+ return _parent->callJSFactoryMethod(object, args);
+ return false;
+}
+
QQmlMetaObject::QQmlMetaObject()
{
}
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index aaa7ce04b9..8e53e8b029 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -7067,15 +7067,6 @@ void QQuickItemPrivate::setHasCursorInChild(bool hasCursor)
#endif
}
-void QQuickItemPrivate::markObjects(QV4::ExecutionEngine *e)
-{
- Q_Q(QQuickItem);
- QV4::QObjectWrapper::markWrapper(q, e);
-
- foreach (QQuickItem *child, childItems)
- QQuickItemPrivate::get(child)->markObjects(e);
-}
-
#ifndef QT_NO_CURSOR
/*!
@@ -8256,6 +8247,38 @@ QAccessible::Role QQuickItemPrivate::accessibleRole() const
}
#endif
+// helper code to let a visual parent mark its visual children for the garbage collector
+
+namespace QV4 {
+namespace Heap {
+struct QQuickItemWrapper : public QObjectWrapper {
+ QQuickItemWrapper(QQuickItem *item) : QObjectWrapper(item) {}
+};
+}
+}
+
+struct QQuickItemWrapper : public QV4::QObjectWrapper {
+ V4_OBJECT2(QQuickItemWrapper, QV4::QObjectWrapper)
+ static void markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *e);
+};
+
+DEFINE_OBJECT_VTABLE(QQuickItemWrapper);
+
+void QQuickItemWrapper::markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *e)
+{
+ QObjectWrapper::Data *This = static_cast<QObjectWrapper::Data *>(that);
+ if (QQuickItem *item = static_cast<QQuickItem*>(This->object.data())) {
+ foreach (QQuickItem *child, QQuickItemPrivate::get(item)->childItems)
+ QV4::QObjectWrapper::markWrapper(child, e);
+ }
+ QV4::QObjectWrapper::markObjects(that, e);
+}
+
+quint64 QQuickItemPrivate::_q_createJSWrapper(QV4::ExecutionEngine *engine)
+{
+ return (engine->memoryManager->allocObject<QQuickItemWrapper>(q_func()))->asReturnedValue();
+}
+
QT_END_NAMESPACE
#include <moc_qquickitem.cpp>
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index c5c17615ee..c4ee48fdbd 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -149,6 +149,7 @@ class Q_QUICK_EXPORT QQuickItem : public QObject, public QQmlParserStatus
Q_CLASSINFO("DefaultProperty", "data")
Q_CLASSINFO("qt_HasQmlAccessors", "true")
+ Q_CLASSINFO("qt_QmlJSWrapperFactoryMethod", "_q_createJSWrapper(QV4::ExecutionEngine*)")
public:
enum Flag {
@@ -444,6 +445,7 @@ protected:
private:
Q_PRIVATE_SLOT(d_func(), void _q_resourceObjectDeleted(QObject *))
+ Q_PRIVATE_SLOT(d_func(), quint64 _q_createJSWrapper(QV4::ExecutionEngine *))
friend class QQuickWindow;
friend class QQuickWindowPrivate;
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index fed3e88b68..8cda5f89c6 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -302,6 +302,7 @@ public:
void _q_resourceObjectDeleted(QObject *);
void _q_windowChanged(QQuickWindow *w);
+ quint64 _q_createJSWrapper(QV4::ExecutionEngine *engine);
enum ChangeType {
Geometry = 0x01,
@@ -605,9 +606,6 @@ public:
virtual void mirrorChange() {}
void setHasCursorInChild(bool hasCursor);
-
- // recursive helper to let a visual parent mark its visual children
- void markObjects(QV4::ExecutionEngine *e);
};
/*
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index 3ce96b673d..f8973ebfba 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -51,29 +51,11 @@
#include <QtQml/qqmlengine.h>
#include <private/qqmlengine_p.h>
+#include <private/qv4qobjectwrapper_p.h>
#include <QtCore/qbasictimer.h>
QT_BEGIN_NAMESPACE
-DEFINE_OBJECT_VTABLE(QV4::QQuickRootItemMarker);
-
-QV4::Heap::QQuickRootItemMarker *QV4::QQuickRootItemMarker::create(QQmlEngine *engine, QQuickWindow *window)
-{
- QV4::ExecutionEngine *e = QQmlEnginePrivate::getV4Engine(engine);
- return e->memoryManager->allocObject<QQuickRootItemMarker>(window);
-}
-
-void QV4::QQuickRootItemMarker::markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *e)
-{
- QQuickItem *root = static_cast<QQuickRootItemMarker::Data *>(that)->window->contentItem();
- if (root) {
- QQuickItemPrivate *rootPrivate = QQuickItemPrivate::get(root);
- rootPrivate->markObjects(e);
- }
-
- QV4::Object::markObjects(that, e);
-}
-
void QQuickViewPrivate::init(QQmlEngine* e)
{
Q_Q(QQuickView);
@@ -87,10 +69,10 @@ void QQuickViewPrivate::init(QQmlEngine* e)
engine.data()->setIncubationController(q->incubationController());
{
+ // The content item has CppOwnership policy (set in QQuickWindow). Ensure the presence of a JS
+ // wrapper so that the garbage collector can see the policy.
QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine.data());
- QV4::Scope scope(v4);
- QV4::Scoped<QV4::QQuickRootItemMarker> v(scope, QV4::QQuickRootItemMarker::create(engine.data(), q));
- rootItemMarker.set(v4, v);
+ QV4::QObjectWrapper::wrap(v4, contentItem);
}
}
diff --git a/src/quick/items/qquickview_p.h b/src/quick/items/qquickview_p.h
index 1bbff0de0e..fd033daf2f 100644
--- a/src/quick/items/qquickview_p.h
+++ b/src/quick/items/qquickview_p.h
@@ -108,37 +108,8 @@ public:
QQuickView::ResizeMode resizeMode;
QSize initialSize;
QElapsedTimer frameTimer;
- QV4::PersistentValue rootItemMarker;
};
-namespace QV4 {
-namespace Heap {
-
-struct QQuickRootItemMarker : Object {
- inline QQuickRootItemMarker(QQuickWindow *window)
- : window(window)
- {
- }
-
- QQuickWindow *window;
-};
-
-}
-
-struct QQuickRootItemMarker : public Object
-{
- V4_OBJECT2(QQuickRootItemMarker, Object)
-
- static Heap::QQuickRootItemMarker *create(QQmlEngine *engine, QQuickWindow *window);
-
- static void markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *e);
-
-};
-
-
-
-}
-
QT_END_NAMESPACE
#endif // QQUICKVIEW_P_H
diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp
index c624d162a9..deb44ce34d 100644
--- a/src/quick/items/qquickwindowmodule.cpp
+++ b/src/quick/items/qquickwindowmodule.cpp
@@ -47,6 +47,7 @@
#include <private/qguiapplication_p.h>
#include <private/qqmlengine_p.h>
+#include <private/qv4qobjectwrapper_p.h>
#include <qpa/qplatformintegration.h>
QT_BEGIN_NAMESPACE
@@ -104,12 +105,11 @@ void QQuickWindowQmlImpl::classBegin()
if (e && !e->incubationController())
e->setIncubationController(incubationController());
}
- Q_ASSERT(e);
{
+ // The content item has CppOwnership policy (set in QQuickWindow). Ensure the presence of a JS
+ // wrapper so that the garbage collector can see the policy.
QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(e);
- QV4::Scope scope(v4);
- QV4::ScopedObject v(scope, QV4::QQuickRootItemMarker::create(e, this));
- d->rootItemMarker = v;
+ QV4::QObjectWrapper::wrap(v4, d->contentItem);
}
}