diff options
Diffstat (limited to 'src/qml/qml')
31 files changed, 312 insertions, 234 deletions
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index e12472760f..4fe76ddf29 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -600,7 +600,7 @@ protected: resultMo = resultObject->metaObject(); } } else if (auto variant = result.as<QV4::VariantObject>()) { - QVariant value = variant->d()->data; + QVariant value = variant->d()->data(); QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()); resultMo = QQmlPropertyPrivate::rawMetaObjectForType(ep, value.userType()); if (resultMo.isNull()) diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index b78028dcf9..6ebcd142fb 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -1058,9 +1058,9 @@ namespace QV4 { namespace Heap { struct QmlIncubatorObject : Object { - QmlIncubatorObject(QQmlIncubator::IncubationMode = QQmlIncubator::Asynchronous); - ~QmlIncubatorObject() { parent.destroy(); } - QScopedPointer<QQmlComponentIncubator> incubator; + void init(QQmlIncubator::IncubationMode = QQmlIncubator::Asynchronous); + inline void destroy(); + QQmlComponentIncubator *incubator; QQmlQPointer<QObject> parent; QV4::Value valuemap; QV4::Value statusChanged; @@ -1389,7 +1389,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args) r->d()->qmlContext = v4->qmlContext(); r->d()->parent = parent; - QQmlIncubator *incubator = r->d()->incubator.data(); + QQmlIncubator *incubator = r->d()->incubator; create(*incubator, creationContext()); if (incubator->status() == QQmlIncubator::Null) { @@ -1484,13 +1484,20 @@ QQmlComponentExtension::~QQmlComponentExtension() { } -QV4::Heap::QmlIncubatorObject::QmlIncubatorObject(QQmlIncubator::IncubationMode m) - : valuemap(QV4::Primitive::undefinedValue()) - , statusChanged(QV4::Primitive::undefinedValue()) +void QV4::Heap::QmlIncubatorObject::init(QQmlIncubator::IncubationMode m) { + Object::init(); + valuemap = QV4::Primitive::undefinedValue(); + statusChanged = QV4::Primitive::undefinedValue(); parent.init(); qmlContext = nullptr; - incubator.reset(new QQmlComponentIncubator(this, m)); + incubator = new QQmlComponentIncubator(this, m); +} + +void QV4::Heap::QmlIncubatorObject::destroy() { + delete incubator; + parent.destroy(); + Object::destroy(); } void QV4::QmlIncubatorObject::setInitialState(QObject *o) diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp index 13d708bc17..2418003519 100644 --- a/src/qml/qml/qqmlcontextwrapper.cpp +++ b/src/qml/qml/qqmlcontextwrapper.cpp @@ -61,20 +61,23 @@ using namespace QV4; DEFINE_OBJECT_VTABLE(QmlContextWrapper); -Heap::QmlContextWrapper::QmlContextWrapper(QQmlContextData *context, QObject *scopeObject, bool ownsContext) - : readOnly(true) - , ownsContext(ownsContext) - , isNullWrapper(false) - , context(context) +void Heap::QmlContextWrapper::init(QQmlContextData *context, QObject *scopeObject, bool ownsContext) { + Object::init(); + readOnly = true; + this->ownsContext = ownsContext; + isNullWrapper = false; + this->context = new QQmlGuardedContextData(context); this->scopeObject.init(scopeObject); } -Heap::QmlContextWrapper::~QmlContextWrapper() +void Heap::QmlContextWrapper::destroy() { - if (context && ownsContext) - context->destroy(); + if (*context && ownsContext) + (*context)->destroy(); + delete context; scopeObject.destroy(); + Object::destroy(); } ReturnedValue QmlContextWrapper::qmlScope(ExecutionEngine *v4, QQmlContextData *ctxt, QObject *scope) @@ -120,7 +123,7 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr if (resource->d()->isNullWrapper) return Object::get(m, name, hasProperty); - if (v4->callingQmlContext() != resource->d()->context) + if (v4->callingQmlContext() != *resource->d()->context) return Object::get(m, name, hasProperty); result = Object::get(m, name, &hasProp); diff --git a/src/qml/qml/qqmlcontextwrapper_p.h b/src/qml/qml/qqmlcontextwrapper_p.h index 2b8c16f274..126ffecf0d 100644 --- a/src/qml/qml/qqmlcontextwrapper_p.h +++ b/src/qml/qml/qqmlcontextwrapper_p.h @@ -64,13 +64,13 @@ namespace QV4 { namespace Heap { struct QmlContextWrapper : Object { - QmlContextWrapper(QQmlContextData *context, QObject *scopeObject, bool ownsContext = false); - ~QmlContextWrapper(); + void init(QQmlContextData *context, QObject *scopeObject, bool ownsContext = false); + void destroy(); bool readOnly; bool ownsContext; bool isNullWrapper; - QQmlGuardedContextData context; + QQmlGuardedContextData *context; QQmlQPointer<QObject> scopeObject; }; @@ -89,7 +89,7 @@ struct Q_QML_EXPORT QmlContextWrapper : Object } inline QObject *getScopeObject() const { return d()->scopeObject; } - inline QQmlContextData *getContext() const { return d()->context; } + inline QQmlContextData *getContext() const { return *d()->context; } void setReadOnly(bool b) { d()->readOnly = b; } diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index daa12fae26..c273330a0a 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -70,7 +70,7 @@ #include <QtCore/qthread.h> #include <private/qthread_p.h> -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) #include "qqmlnetworkaccessmanagerfactory.h" #include <QNetworkAccessManager> #include <QtNetwork/qnetworkconfigmanager.h> @@ -660,7 +660,7 @@ QQmlEnginePrivate::QQmlEnginePrivate(QQmlEngine *e) cleanup(0), erroredBindings(0), inProgressCreations(0), workerScriptEngine(0), activeObjectCreator(0), -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) networkAccessManager(0), networkAccessManagerFactory(0), #endif urlInterceptor(0), scarceResourcesRefCount(0), importDatabase(e), typeLoader(e), @@ -1143,7 +1143,7 @@ void QQmlEnginePrivate::registerFinalizeCallback(QObject *obj, int index) } } -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) /*! Sets the \a factory to use for creating QNetworkAccessManager(s). @@ -1210,7 +1210,7 @@ QNetworkAccessManager *QQmlEngine::networkAccessManager() const Q_D(const QQmlEngine); return d->getNetworkAccessManager(); } -#endif // QT_NO_NETWORK +#endif // qml_network /*! diff --git a/src/qml/qml/qqmlengine.h b/src/qml/qml/qqmlengine.h index 3111d1013e..3102a20fac 100644 --- a/src/qml/qml/qqmlengine.h +++ b/src/qml/qml/qqmlengine.h @@ -87,7 +87,7 @@ class QQmlExpression; class QQmlContext; class QQmlType; class QUrl; -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) class QNetworkAccessManager; class QQmlNetworkAccessManagerFactory; #endif @@ -117,7 +117,7 @@ public: bool importPlugin(const QString &filePath, const QString &uri, QList<QQmlError> *errors); -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) void setNetworkAccessManagerFactory(QQmlNetworkAccessManagerFactory *); QQmlNetworkAccessManagerFactory *networkAccessManagerFactory() const; diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 713b03dbf3..916566b6c7 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -162,7 +162,7 @@ public: void registerFinalizeCallback(QObject *obj, int index); QQmlObjectCreator *activeObjectCreator; -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) QNetworkAccessManager *createNetworkAccessManager(QObject *parent) const; QNetworkAccessManager *getNetworkAccessManager() const; mutable QNetworkAccessManager *networkAccessManager; diff --git a/src/qml/qml/qqmlfile.cpp b/src/qml/qml/qqmlfile.cpp index 4769402855..4e4db086b0 100644 --- a/src/qml/qml/qqmlfile.cpp +++ b/src/qml/qml/qqmlfile.cpp @@ -68,7 +68,7 @@ static char assets_string[] = "assets"; class QQmlFilePrivate; -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) class QQmlFileNetworkReply : public QObject { Q_OBJECT @@ -117,12 +117,12 @@ public: Error error; QString errorString; -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) QQmlFileNetworkReply *reply; #endif }; -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) int QQmlFileNetworkReply::finishedIndex = -1; int QQmlFileNetworkReply::downloadProgressIndex = -1; int QQmlFileNetworkReply::networkFinishedIndex = -1; @@ -205,11 +205,11 @@ void QQmlFileNetworkReply::networkDownloadProgress(qint64 a, qint64 b) { emit downloadProgress(a, b); } -#endif // QT_NO_NETWORK +#endif // qml_network QQmlFilePrivate::QQmlFilePrivate() : error(None) -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) , reply(0) #endif { @@ -233,7 +233,7 @@ QQmlFile::QQmlFile(QQmlEngine *e, const QString &url) QQmlFile::~QQmlFile() { -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) delete d->reply; #endif delete d; @@ -273,7 +273,7 @@ QQmlFile::Status QQmlFile::status() const { if (d->url.isEmpty() && d->urlString.isEmpty()) return Null; -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) else if (d->reply) return Loading; #endif @@ -333,7 +333,7 @@ void QQmlFile::load(QQmlEngine *engine, const QUrl &url) d->error = QQmlFilePrivate::NotFound; } } else { -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) d->reply = new QQmlFileNetworkReply(engine, d, url); #else d->error = QQmlFilePrivate::NotFound; @@ -364,7 +364,7 @@ void QQmlFile::load(QQmlEngine *engine, const QString &url) d->error = QQmlFilePrivate::NotFound; } } else { -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) QUrl qurl(url); d->url = qurl; d->urlString = QString(); @@ -388,7 +388,7 @@ void QQmlFile::clear(QObject *) clear(); } -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) bool QQmlFile::connectFinished(QObject *object, const char *method) { if (!d || !d->reply) { diff --git a/src/qml/qml/qqmlfile.h b/src/qml/qml/qqmlfile.h index 3dd683a2cd..aec0981a95 100644 --- a/src/qml/qml/qqmlfile.h +++ b/src/qml/qml/qqmlfile.h @@ -80,7 +80,7 @@ public: void clear(); void clear(QObject *); -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) bool connectFinished(QObject *, const char *); bool connectFinished(QObject *, int); bool connectDownloadProgress(QObject *, const char *); diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp index 425a720867..8aa107dc17 100644 --- a/src/qml/qml/qqmllistwrapper.cpp +++ b/src/qml/qml/qqmllistwrapper.cpp @@ -52,17 +52,19 @@ using namespace QV4; DEFINE_OBJECT_VTABLE(QmlListWrapper); -Heap::QmlListWrapper::QmlListWrapper() +void Heap::QmlListWrapper::init() { + Object::init(); object.init(); QV4::Scope scope(internalClass->engine); QV4::ScopedObject o(scope, this); o->setArrayType(Heap::ArrayData::Custom); } -Heap::QmlListWrapper::~QmlListWrapper() +void Heap::QmlListWrapper::destroy() { object.destroy(); + Object::destroy(); } ReturnedValue QmlListWrapper::create(ExecutionEngine *engine, QObject *object, int propId, int propType) @@ -75,7 +77,7 @@ ReturnedValue QmlListWrapper::create(ExecutionEngine *engine, QObject *object, i Scoped<QmlListWrapper> r(scope, engine->memoryManager->allocObject<QmlListWrapper>()); r->d()->object = object; r->d()->propertyType = propType; - void *args[] = { &r->d()->property, 0 }; + void *args[] = { &r->d()->property(), 0 }; QMetaObject::metacall(object, QMetaObject::ReadProperty, propId, args); return r.asReturnedValue(); } @@ -86,7 +88,7 @@ ReturnedValue QmlListWrapper::create(ExecutionEngine *engine, const QQmlListProp Scoped<QmlListWrapper> r(scope, engine->memoryManager->allocObject<QmlListWrapper>()); r->d()->object = prop.object; - r->d()->property = prop; + r->d()->property() = prop; r->d()->propertyType = propType; return r.asReturnedValue(); } @@ -96,7 +98,7 @@ QVariant QmlListWrapper::toVariant() const if (!d()->object) return QVariant(); - return QVariant::fromValue(QQmlListReferencePrivate::init(d()->property, d()->propertyType, engine()->qmlEngine())); + return QVariant::fromValue(QQmlListReferencePrivate::init(d()->property(), d()->propertyType, engine()->qmlEngine())); } @@ -107,7 +109,7 @@ ReturnedValue QmlListWrapper::get(const Managed *m, String *name, bool *hasPrope QV4::ExecutionEngine *v4 = w->engine(); if (name->equals(v4->id_length()) && !w->d()->object.isNull()) { - quint32 count = w->d()->property.count ? w->d()->property.count(&w->d()->property) : 0; + quint32 count = w->d()->property().count ? w->d()->property().count(&w->d()->property()) : 0; return Primitive::fromUInt32(count).asReturnedValue(); } @@ -126,11 +128,11 @@ ReturnedValue QmlListWrapper::getIndexed(const Managed *m, uint index, bool *has const QmlListWrapper *w = static_cast<const QmlListWrapper *>(m); QV4::ExecutionEngine *v4 = w->engine(); - quint32 count = w->d()->property.count ? w->d()->property.count(&w->d()->property) : 0; - if (index < count && w->d()->property.at) { + quint32 count = w->d()->property().count ? w->d()->property().count(&w->d()->property()) : 0; + if (index < count && w->d()->property().at) { if (hasProperty) *hasProperty = true; - return QV4::QObjectWrapper::wrap(v4, w->d()->property.at(&w->d()->property, index)); + return QV4::QObjectWrapper::wrap(v4, w->d()->property().at(&w->d()->property(), index)); } if (hasProperty) @@ -152,12 +154,12 @@ void QmlListWrapper::advanceIterator(Managed *m, ObjectIterator *it, Value *name *index = UINT_MAX; Q_ASSERT(m->as<QmlListWrapper>()); QmlListWrapper *w = static_cast<QmlListWrapper *>(m); - quint32 count = w->d()->property.count ? w->d()->property.count(&w->d()->property) : 0; + quint32 count = w->d()->property().count ? w->d()->property().count(&w->d()->property()) : 0; if (it->arrayIndex < count) { *index = it->arrayIndex; ++it->arrayIndex; *attrs = QV4::Attr_Data; - p->value = QV4::QObjectWrapper::wrap(w->engine(), w->d()->property.at(&w->d()->property, *index)); + p->value = QV4::QObjectWrapper::wrap(w->engine(), w->d()->property().at(&w->d()->property(), *index)); return; } return QV4::Object::advanceIterator(m, it, name, index, p, attrs); diff --git a/src/qml/qml/qqmllistwrapper_p.h b/src/qml/qml/qqmllistwrapper_p.h index 1107b957c9..d01b332159 100644 --- a/src/qml/qml/qqmllistwrapper_p.h +++ b/src/qml/qml/qqmllistwrapper_p.h @@ -66,11 +66,18 @@ namespace QV4 { namespace Heap { struct QmlListWrapper : Object { - QmlListWrapper(); - ~QmlListWrapper(); + void init(); + void destroy(); QQmlQPointer<QObject> object; - QQmlListProperty<QObject> property; + + QQmlListProperty<QObject> &property() { + return *reinterpret_cast<QQmlListProperty<QObject>*>(propertyData); + } + int propertyType; + +private: + void *propertyData[sizeof(QQmlListProperty<QObject>)/sizeof(void*)]; }; } diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index 76752f509c..6f66475aa5 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -109,16 +109,16 @@ QV4::ReturnedValue QQmlDateExtension::method_toLocaleString(QV4::CallContext *ct if (ctx->argc() == 2) { if (ctx->args()[1].isString()) { QString format = ctx->args()[1].stringValue()->toQString(); - formattedDt = r->d()->locale.toString(dt, format); + formattedDt = r->d()->locale->toString(dt, format); } else if (ctx->args()[1].isNumber()) { quint32 intFormat = ctx->args()[1].toNumber(); QLocale::FormatType format = QLocale::FormatType(intFormat); - formattedDt = r->d()->locale.toString(dt, format); + formattedDt = r->d()->locale->toString(dt, format); } else { V4THROW_ERROR("Locale: Date.toLocaleString(): Invalid datetime format"); } } else { - formattedDt = r->d()->locale.toString(dt, enumFormat); + formattedDt = r->d()->locale->toString(dt, enumFormat); } return ctx->d()->engine->newString(formattedDt)->asReturnedValue(); @@ -154,16 +154,16 @@ QV4::ReturnedValue QQmlDateExtension::method_toLocaleTimeString(QV4::CallContext if (ctx->argc() == 2) { if (ctx->args()[1].isString()) { QString format = ctx->args()[1].stringValue()->toQString(); - formattedTime = r->d()->locale.toString(time, format); + formattedTime = r->d()->locale->toString(time, format); } else if (ctx->args()[1].isNumber()) { quint32 intFormat = ctx->args()[1].toNumber(); QLocale::FormatType format = QLocale::FormatType(intFormat); - formattedTime = r->d()->locale.toString(time, format); + formattedTime = r->d()->locale->toString(time, format); } else { V4THROW_ERROR("Locale: Date.toLocaleTimeString(): Invalid time format"); } } else { - formattedTime = r->d()->locale.toString(time, enumFormat); + formattedTime = r->d()->locale->toString(time, enumFormat); } return ctx->d()->engine->newString(formattedTime)->asReturnedValue(); @@ -199,16 +199,16 @@ QV4::ReturnedValue QQmlDateExtension::method_toLocaleDateString(QV4::CallContext if (ctx->argc() == 2) { if (ctx->args()[1].isString()) { QString format = ctx->args()[1].stringValue()->toQString(); - formattedDate = r->d()->locale.toString(date, format); + formattedDate = r->d()->locale->toString(date, format); } else if (ctx->args()[1].isNumber()) { quint32 intFormat = ctx->args()[1].toNumber(); QLocale::FormatType format = QLocale::FormatType(intFormat); - formattedDate = r->d()->locale.toString(date, format); + formattedDate = r->d()->locale->toString(date, format); } else { V4THROW_ERROR("Locale: Date.loLocaleDateString(): Invalid date format"); } } else { - formattedDate = r->d()->locale.toString(date, enumFormat); + formattedDate = r->d()->locale->toString(date, enumFormat); } return ctx->d()->engine->newString(formattedDate)->asReturnedValue(); @@ -237,16 +237,16 @@ QV4::ReturnedValue QQmlDateExtension::method_fromLocaleString(QV4::CallContext * if (ctx->argc() == 3) { if (ctx->args()[2].isString()) { QString format = ctx->args()[2].stringValue()->toQString(); - dt = r->d()->locale.toDateTime(dateString, format); + dt = r->d()->locale->toDateTime(dateString, format); } else if (ctx->args()[2].isNumber()) { quint32 intFormat = ctx->args()[2].toNumber(); QLocale::FormatType format = QLocale::FormatType(intFormat); - dt = r->d()->locale.toDateTime(dateString, format); + dt = r->d()->locale->toDateTime(dateString, format); } else { V4THROW_ERROR("Locale: Date.fromLocaleString(): Invalid datetime format"); } } else { - dt = r->d()->locale.toDateTime(dateString, enumFormat); + dt = r->d()->locale->toDateTime(dateString, enumFormat); } return QV4::Encode(engine->newDateObject(dt)); @@ -278,16 +278,16 @@ QV4::ReturnedValue QQmlDateExtension::method_fromLocaleTimeString(QV4::CallConte if (ctx->argc() == 3) { if (ctx->args()[2].isString()) { QString format = ctx->args()[2].stringValue()->toQString(); - tm = r->d()->locale.toTime(dateString, format); + tm = r->d()->locale->toTime(dateString, format); } else if (ctx->args()[2].isNumber()) { quint32 intFormat = ctx->args()[2].toNumber(); QLocale::FormatType format = QLocale::FormatType(intFormat); - tm = r->d()->locale.toTime(dateString, format); + tm = r->d()->locale->toTime(dateString, format); } else { V4THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid datetime format"); } } else { - tm = r->d()->locale.toTime(dateString, enumFormat); + tm = r->d()->locale->toTime(dateString, enumFormat); } QDateTime dt; @@ -323,16 +323,16 @@ QV4::ReturnedValue QQmlDateExtension::method_fromLocaleDateString(QV4::CallConte if (ctx->argc() == 3) { if (ctx->args()[2].isString()) { QString format = ctx->args()[2].stringValue()->toQString(); - dt = r->d()->locale.toDate(dateString, format); + dt = r->d()->locale->toDate(dateString, format); } else if (ctx->args()[2].isNumber()) { quint32 intFormat = ctx->args()[2].toNumber(); QLocale::FormatType format = QLocale::FormatType(intFormat); - dt = r->d()->locale.toDate(dateString, format); + dt = r->d()->locale->toDate(dateString, format); } else { V4THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid datetime format"); } } else { - dt = r->d()->locale.toDate(dateString, enumFormat); + dt = r->d()->locale->toDate(dateString, enumFormat); } return QV4::Encode(engine->newDateObject(QDateTime(dt))); @@ -393,7 +393,7 @@ QV4::ReturnedValue QQmlNumberExtension::method_toLocaleString(QV4::CallContext * prec = ctx->args()[2].toInt32(); } - return ctx->d()->engine->newString(r->d()->locale.toString(number, (char)format, prec))->asReturnedValue(); + return ctx->d()->engine->newString(r->d()->locale->toString(number, (char)format, prec))->asReturnedValue(); } QV4::ReturnedValue QQmlNumberExtension::method_toLocaleCurrencyString(QV4::CallContext *ctx) @@ -423,7 +423,7 @@ QV4::ReturnedValue QQmlNumberExtension::method_toLocaleCurrencyString(QV4::CallC symbol = ctx->args()[1].toQStringNoThrow(); } - return ctx->d()->engine->newString(r->d()->locale.toCurrencyString(number, symbol))->asReturnedValue(); + return ctx->d()->engine->newString(r->d()->locale->toCurrencyString(number, symbol))->asReturnedValue(); } QV4::ReturnedValue QQmlNumberExtension::method_fromLocaleString(QV4::CallContext *ctx) @@ -441,7 +441,7 @@ QV4::ReturnedValue QQmlNumberExtension::method_fromLocaleString(QV4::CallContext V4THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments"); GET_LOCALE_DATA_RESOURCE(ctx->args()[0]); - locale = r->d()->locale; + locale = *r->d()->locale; numberIdx = 1; } @@ -813,7 +813,7 @@ QV4::ReturnedValue QQmlLocale::wrap(ExecutionEngine *v4, const QLocale &locale) QV4::Scope scope(v4); QV4LocaleDataDeletable *d = localeV4Data(scope.engine); QV4::Scoped<QQmlLocaleData> wrapper(scope, v4->memoryManager->allocObject<QQmlLocaleData>()); - wrapper->d()->locale = locale; + *wrapper->d()->locale = locale; QV4::ScopedObject p(scope, d->prototype.value()); wrapper->setPrototype(p); return wrapper.asReturnedValue(); diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h index 652a3ca0d4..275f58db7d 100644 --- a/src/qml/qml/qqmllocale_p.h +++ b/src/qml/qml/qqmllocale_p.h @@ -143,8 +143,12 @@ namespace QV4 { namespace Heap { struct QQmlLocaleData : Object { - inline QQmlLocaleData() {} - QLocale locale; + inline void init() { locale = new QLocale; } + void destroy() { + delete locale; + Object::destroy(); + } + QLocale *locale; }; } @@ -161,7 +165,7 @@ struct QQmlLocaleData : public QV4::Object ctx->engine()->throwTypeError(); return 0; } - return &thisObject->d()->locale; + return thisObject->d()->locale; } static QV4::ReturnedValue method_currencySymbol(QV4::CallContext *ctx); diff --git a/src/qml/qml/qqmlloggingcategory.cpp b/src/qml/qml/qqmlloggingcategory.cpp index 88cf14cba0..fd8fb477c7 100644 --- a/src/qml/qml/qqmlloggingcategory.cpp +++ b/src/qml/qml/qqmlloggingcategory.cpp @@ -81,7 +81,7 @@ \note This property needs to be set when declaring the LoggingCategory and cannot be changed later. - \sa QLoggingCategory::name() + \sa QLoggingCategory::categoryName() */ QQmlLoggingCategory::QQmlLoggingCategory(QObject *parent) diff --git a/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp b/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp index c94db8e168..1680253d73 100644 --- a/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp +++ b/src/qml/qml/qqmlnetworkaccessmanagerfactory.cpp @@ -41,7 +41,7 @@ QT_BEGIN_NAMESPACE -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) /*! \class QQmlNetworkAccessManagerFactory @@ -103,6 +103,6 @@ QQmlNetworkAccessManagerFactory::~QQmlNetworkAccessManagerFactory() implementation of this method is reentrant. */ -#endif //QT_NO_NETWORK +#endif // qml_network QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlnetworkaccessmanagerfactory.h b/src/qml/qml/qqmlnetworkaccessmanagerfactory.h index ba3561b9f4..57dec1da29 100644 --- a/src/qml/qml/qqmlnetworkaccessmanagerfactory.h +++ b/src/qml/qml/qqmlnetworkaccessmanagerfactory.h @@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) class QNetworkAccessManager; class Q_QML_EXPORT QQmlNetworkAccessManagerFactory @@ -56,7 +56,7 @@ public: }; -#endif //QT_NO_NETWORK +#endif // qml_network QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index 2543fd069c..672b36ea75 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -246,7 +246,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); } @@ -507,6 +507,11 @@ void QQmlPropertyCache::append(const QMetaObject *metaObject, const char *name = mci.name(); if (0 == qstrcmp(name, "DefaultProperty")) { _defaultPropertyName = QString::fromUtf8(mci.value()); + } else if (0 == qstrcmp(name, "qt_QmlJSWrapperFactoryMethod")) { + const char * const factoryMethod = mci.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 f90945bf57..b820777973 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -431,6 +431,8 @@ public: void toMetaObjectBuilder(QMetaObjectBuilder &); + inline bool callJSFactoryMethod(QObject *object, void **args) const; + static bool determineMetaObjectSizes(const QMetaObject &mo, int *fieldCount, int *stringCount); static bool addToHash(QCryptographicHash &hash, const QMetaObject &mo); @@ -505,6 +507,7 @@ private: QByteArray _dynamicStringData; QString _defaultPropertyName; QQmlPropertyCacheMethodArguments *argumentsCache; + int _jsFactoryMethodIndex; QByteArray _checksum; }; @@ -806,6 +809,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/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index b576366abf..3e599aed6c 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -123,7 +123,7 @@ namespace { }; } -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) // This is a lame object that we need to ensure that slots connected to // QNetworkReply get called in the correct thread (the loader thread). // As QQmlTypeLoader lives in the main thread, and we can't use @@ -143,7 +143,7 @@ public slots: private: QQmlTypeLoader *l; }; -#endif // QT_NO_NETWORK +#endif // qml_network class QQmlTypeLoaderThread : public QQmlThread { @@ -151,10 +151,10 @@ class QQmlTypeLoaderThread : public QQmlThread public: QQmlTypeLoaderThread(QQmlTypeLoader *loader); -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) QNetworkAccessManager *networkAccessManager() const; QQmlTypeLoaderNetworkReplyProxy *networkReplyProxy() const; -#endif // QT_NO_NETWORK +#endif // qml_network void load(QQmlDataBlob *b); void loadAsync(QQmlDataBlob *b); void loadWithStaticData(QQmlDataBlob *b, const QByteArray &); @@ -177,13 +177,13 @@ private: void initializeEngineMain(QQmlExtensionInterface *iface, const char *uri); QQmlTypeLoader *m_loader; -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) mutable QNetworkAccessManager *m_networkAccessManager; mutable QQmlTypeLoaderNetworkReplyProxy *m_networkReplyProxy; -#endif // QT_NO_NETWORK +#endif // qml_network }; -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) QQmlTypeLoaderNetworkReplyProxy::QQmlTypeLoaderNetworkReplyProxy(QQmlTypeLoader *l) : l(l) { @@ -212,7 +212,7 @@ void QQmlTypeLoaderNetworkReplyProxy::manualFinished(QNetworkReply *reply) l->networkReplyProgress(reply, replySize, replySize); l->networkReplyFinished(reply); } -#endif // QT_NO_NETWORK +#endif // qml_network /*! \class QQmlDataBlob @@ -529,7 +529,7 @@ void QQmlDataBlob::done() { } -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) /*! Invoked if there is a network error while fetching this blob. @@ -582,7 +582,7 @@ void QQmlDataBlob::networkError(QNetworkReply::NetworkError networkError) setError(error); } -#endif // QT_NO_NETWORK +#endif // qml_network /*! Called if \a blob, which was previously waited for, has an error. @@ -782,15 +782,15 @@ void QQmlDataBlob::ThreadData::setProgress(quint8 v) QQmlTypeLoaderThread::QQmlTypeLoaderThread(QQmlTypeLoader *loader) : m_loader(loader) -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) , m_networkAccessManager(0), m_networkReplyProxy(0) -#endif // QT_NO_NETWORK +#endif // qml_network { // Do that after initializing all the members. startup(); } -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) QNetworkAccessManager *QQmlTypeLoaderThread::networkAccessManager() const { Q_ASSERT(isThisThread()); @@ -808,7 +808,7 @@ QQmlTypeLoaderNetworkReplyProxy *QQmlTypeLoaderThread::networkReplyProxy() const Q_ASSERT(m_networkReplyProxy); // Must call networkAccessManager() first return m_networkReplyProxy; } -#endif // QT_NO_NETWORK +#endif // qml_network void QQmlTypeLoaderThread::load(QQmlDataBlob *b) { @@ -866,12 +866,12 @@ void QQmlTypeLoaderThread::initializeEngine(QQmlExtensionInterface *iface, void QQmlTypeLoaderThread::shutdownThread() { -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) delete m_networkAccessManager; m_networkAccessManager = 0; delete m_networkReplyProxy; m_networkReplyProxy = 0; -#endif // QT_NO_NETWORK +#endif // qml_network } void QQmlTypeLoaderThread::loadThread(QQmlDataBlob *b) @@ -957,14 +957,14 @@ void QQmlTypeLoader::invalidate() m_thread = 0; } -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) // Need to delete the network replies after // the loader thread is shutdown as it could be // getting new replies while we clear them for (NetworkReplies::Iterator iter = m_networkReplies.begin(); iter != m_networkReplies.end(); ++iter) (*iter)->release(); m_networkReplies.clear(); -#endif // QT_NO_NETWORK +#endif // qml_network } void QQmlTypeLoader::lock() @@ -1138,7 +1138,7 @@ void QQmlTypeLoader::loadThread(QQmlDataBlob *blob) setData(blob, fileName); } else { -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) QNetworkReply *reply = m_thread->networkAccessManager()->get(QNetworkRequest(blob->m_url)); QQmlTypeLoaderNetworkReplyProxy *nrp = m_thread->networkReplyProxy(); blob->addref(); @@ -1156,14 +1156,14 @@ void QQmlTypeLoader::loadThread(QQmlDataBlob *blob) #ifdef DATABLOB_DEBUG qWarning("QQmlDataBlob: requested %s", qPrintable(blob->url().toString())); #endif // DATABLOB_DEBUG -#endif // QT_NO_NETWORK +#endif // qml_network } } #define DATALOADER_MAXIMUM_REDIRECT_RECURSION 16 #define TYPELOADER_MINIMUM_TRIM_THRESHOLD 64 -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) void QQmlTypeLoader::networkReplyFinished(QNetworkReply *reply) { Q_ASSERT(m_thread->isThisThread()); @@ -1219,7 +1219,7 @@ void QQmlTypeLoader::networkReplyProgress(QNetworkReply *reply, m_thread->callDownloadProgressChanged(blob, blob->m_data.progress()); } } -#endif // QT_NO_NETWORK +#endif // qml_network /*! Return the QQmlEngine associated with this loader @@ -1968,12 +1968,11 @@ void QQmlTypeLoader::trimCache() for (TypeCache::Iterator iter = m_typeCache.begin(), end = m_typeCache.end(); iter != end; ++iter) { QQmlTypeData *typeData = iter.value(); - const bool hasError = !typeData->m_compiledData && !typeData->m_errors.isEmpty(); - const bool isNotReferenced = typeData->isComplete() && typeData->m_compiledData - && typeData->m_compiledData->count() == 1; - // typeData->m_compiledData may be set early on in the proccess of loading a file, so it's important - // to check the general loading status of the typeData before making any other decisions. - if (typeData->count() == 1 && (hasError || isNotReferenced)) { + // typeData->m_compiledData may be set early on in the proccess of loading a file, so + // it's important to check the general loading status of the typeData before making any + // other decisions. + if (typeData->count() == 1 && (typeData->isError() || typeData->isComplete()) + && (!typeData->m_compiledData || typeData->m_compiledData->count() == 1)) { // There are no live objects of this type unneededTypes.append(iter); } @@ -3106,8 +3105,14 @@ QByteArray QQmlDataBlob::Data::readAll(QString *error, qint64 *sourceTimeStamp) *error = f.errorString(); return QByteArray(); } - if (sourceTimeStamp) - *sourceTimeStamp = QFileInfo(f).lastModified().toMSecsSinceEpoch(); + if (sourceTimeStamp) { + QDateTime timeStamp = QFileInfo(f).lastModified(); + // Files from the resource system do not have any time stamps, so fall back to the application + // executable. + if (!timeStamp.isValid()) + timeStamp = QFileInfo(QCoreApplication::applicationFilePath()).lastModified(); + *sourceTimeStamp = timeStamp.toMSecsSinceEpoch(); + } QByteArray data(f.size(), Qt::Uninitialized); if (f.read(data.data(), data.length()) != data.length()) { *error = f.errorString(); diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index 12c55e9179..ad5ab3124e 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -51,9 +51,10 @@ // We mean it. // +#include <QtQml/qtqmlglobal.h> #include <QtCore/qobject.h> #include <QtCore/qatomic.h> -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) #include <QtNetwork/qnetworkreply.h> #endif #include <QtQml/qqmlerror.h> @@ -154,7 +155,7 @@ protected: virtual void dataReceived(const Data &) = 0; virtual void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit*) = 0; virtual void done(); -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) virtual void networkError(QNetworkReply::NetworkError); #endif virtual void dependencyError(QQmlDataBlob *); @@ -320,16 +321,16 @@ public: private: friend class QQmlDataBlob; friend class QQmlTypeLoaderThread; -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) friend class QQmlTypeLoaderNetworkReplyProxy; -#endif // QT_NO_NETWORK +#endif // qml_network void shutdownThread(); void loadThread(QQmlDataBlob *); void loadWithStaticDataThread(QQmlDataBlob *, const QByteArray &); void loadWithCachedUnitThread(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit); -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) void networkReplyFinished(QNetworkReply *); void networkReplyProgress(QNetworkReply *, qint64, qint64); @@ -366,7 +367,7 @@ private: QQmlEngine *m_engine; QQmlTypeLoaderThread *m_thread; -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) NetworkReplies m_networkReplies; #endif TypeCache m_typeCache; diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index 28c2588117..5c3ad6b2a6 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -55,17 +55,19 @@ using namespace QV4; DEFINE_OBJECT_VTABLE(QmlTypeWrapper); -Heap::QmlTypeWrapper::QmlTypeWrapper() - : mode(IncludeEnums) +void Heap::QmlTypeWrapper::init() { + Object::init(); + mode = IncludeEnums; object.init(); } -Heap::QmlTypeWrapper::~QmlTypeWrapper() +void Heap::QmlTypeWrapper::destroy() { if (typeNamespace) typeNamespace->release(); object.destroy(); + Object::destroy(); } bool QmlTypeWrapper::isSingleton() const diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h index 7c5105b184..3b0ae04cc1 100644 --- a/src/qml/qml/qqmltypewrapper_p.h +++ b/src/qml/qml/qqmltypewrapper_p.h @@ -71,8 +71,8 @@ struct QmlTypeWrapper : Object { ExcludeEnums }; - QmlTypeWrapper(); - ~QmlTypeWrapper(); + void init(); + void destroy(); TypeNameMode mode; QQmlQPointer<QObject> object; diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index 2625f5af11..43b9e4bd3b 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -63,8 +63,14 @@ namespace Heap { struct QQmlValueTypeReference : QQmlValueTypeWrapper { - QQmlValueTypeReference() { object.init(); } - ~QQmlValueTypeReference() { object.destroy(); } + void init() { + QQmlValueTypeWrapper::init(); + object.init(); + } + void destroy() { + object.destroy(); + QQmlValueTypeWrapper::destroy(); + } QQmlQPointer<QObject> object; int property; }; @@ -74,8 +80,7 @@ struct QQmlValueTypeReference : QQmlValueTypeWrapper struct QQmlValueTypeReference : public QQmlValueTypeWrapper { V4_OBJECT2(QQmlValueTypeReference, QQmlValueTypeWrapper) - - static void destroy(Heap::Base *that); + V4_NEEDS_DESTROY bool readReferenceValue() const; }; @@ -86,12 +91,13 @@ DEFINE_OBJECT_VTABLE(QV4::QQmlValueTypeReference); using namespace QV4; -Heap::QQmlValueTypeWrapper::~QQmlValueTypeWrapper() +void Heap::QQmlValueTypeWrapper::destroy() { if (gadgetPtr) { valueType->metaType.destruct(gadgetPtr); ::operator delete(gadgetPtr); } + Object::destroy(); } void Heap::QQmlValueTypeWrapper::setValue(const QVariant &value) const @@ -140,7 +146,7 @@ bool QQmlValueTypeReference::readReferenceValue() const ::operator delete(d()->gadgetPtr); } d()->gadgetPtr =0; - d()->propertyCache = cache; + d()->setPropertyCache(cache); d()->valueType = QQmlValueTypeFactory::valueType(variantReferenceType); if (!cache) return false; @@ -163,7 +169,7 @@ bool QQmlValueTypeReference::readReferenceValue() const void QQmlValueTypeWrapper::initProto(ExecutionEngine *v4) { - if (v4->valueTypeWrapperPrototype()->d()) + if (v4->valueTypeWrapperPrototype()->d_unchecked()) return; Scope scope(v4); @@ -180,7 +186,7 @@ ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, QObject *obj Scoped<QQmlValueTypeReference> r(scope, engine->memoryManager->allocObject<QQmlValueTypeReference>()); r->d()->object = object; r->d()->property = property; - r->d()->propertyCache = QJSEnginePrivate::get(engine)->cache(metaObject); + r->d()->setPropertyCache(QJSEnginePrivate::get(engine)->cache(metaObject)); r->d()->valueType = QQmlValueTypeFactory::valueType(typeId); r->d()->gadgetPtr = 0; return r->asReturnedValue(); @@ -192,7 +198,7 @@ ReturnedValue QQmlValueTypeWrapper::create(ExecutionEngine *engine, const QVaria initProto(engine); Scoped<QQmlValueTypeWrapper> r(scope, engine->memoryManager->allocObject<QQmlValueTypeWrapper>()); - r->d()->propertyCache = QJSEnginePrivate::get(engine)->cache(metaObject); + r->d()->setPropertyCache(QJSEnginePrivate::get(engine)->cache(metaObject)); r->d()->valueType = QQmlValueTypeFactory::valueType(typeId); r->d()->gadgetPtr = 0; r->d()->setValue(value); @@ -218,19 +224,13 @@ bool QQmlValueTypeWrapper::toGadget(void *data) const return true; } -void QQmlValueTypeWrapper::destroy(Heap::Base *that) -{ - Heap::QQmlValueTypeWrapper *w = static_cast<Heap::QQmlValueTypeWrapper *>(that); - w->Heap::QQmlValueTypeWrapper::~QQmlValueTypeWrapper(); -} - bool QQmlValueTypeWrapper::isEqualTo(Managed *m, Managed *other) { Q_ASSERT(m && m->as<QQmlValueTypeWrapper>() && other); QV4::QQmlValueTypeWrapper *lv = static_cast<QQmlValueTypeWrapper *>(m); if (QV4::VariantObject *rv = other->as<VariantObject>()) - return lv->isEqual(rv->d()->data); + return lv->isEqual(rv->d()->data()); if (QV4::QQmlValueTypeWrapper *v = other->as<QQmlValueTypeWrapper>()) return lv->isEqual(v->toVariant()); @@ -243,7 +243,7 @@ PropertyAttributes QQmlValueTypeWrapper::query(const Managed *m, String *name) Q_ASSERT(m->as<const QQmlValueTypeWrapper>()); const QQmlValueTypeWrapper *r = static_cast<const QQmlValueTypeWrapper *>(m); - QQmlPropertyData *result = r->d()->propertyCache->property(name, 0, 0); + QQmlPropertyData *result = r->d()->propertyCache()->property(name, 0, 0); return result ? Attr_Data : Attr_Invalid; } @@ -259,8 +259,8 @@ void QQmlValueTypeWrapper::advanceIterator(Managed *m, ObjectIterator *it, Value return; } - if (that->d()->propertyCache) { - const QMetaObject *mo = that->d()->propertyCache->createMetaObject(); + if (that->d()->propertyCache()) { + const QMetaObject *mo = that->d()->propertyCache()->createMetaObject(); const int propertyCount = mo->propertyCount(); if (it->arrayIndex < static_cast<uint>(propertyCount)) { Scope scope(that->engine()); @@ -335,7 +335,7 @@ ReturnedValue QQmlValueTypeWrapper::method_toString(CallContext *ctx) } else { result += QString::fromUtf8(QMetaType::typeName(w->d()->valueType->typeId)) + QLatin1Char('('); - const QMetaObject *mo = w->d()->propertyCache->metaObject(); + const QMetaObject *mo = w->d()->propertyCache()->metaObject(); const int propCount = mo->propertyCount(); for (int i = 0; i < propCount; ++i) { if (mo->property(i).isDesignable()) { @@ -362,7 +362,7 @@ ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, String *name, bool *ha return Primitive::undefinedValue().asReturnedValue(); } - QQmlPropertyData *result = r->d()->propertyCache->property(name, 0, 0); + QQmlPropertyData *result = r->d()->propertyCache()->property(name, 0, 0); if (!result) return Object::get(m, name, hasProperty); @@ -381,7 +381,7 @@ ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, String *name, bool *ha return QV4::Encode(constructor(v)); \ } - const QMetaObject *metaObject = r->d()->propertyCache->metaObject(); + const QMetaObject *metaObject = r->d()->propertyCache()->metaObject(); int index = result->coreIndex(); QQmlMetaObject::resolveGadgetMethodOrPropertyIndex(QMetaObject::ReadProperty, &metaObject, &index); @@ -429,8 +429,8 @@ void QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value) writeBackPropertyType = writebackProperty.userType(); } - const QMetaObject *metaObject = r->d()->propertyCache->metaObject(); - const QQmlPropertyData *pd = r->d()->propertyCache->property(name, 0, 0); + const QMetaObject *metaObject = r->d()->propertyCache()->metaObject(); + const QQmlPropertyData *pd = r->d()->propertyCache()->property(name, 0, 0); if (!pd) return; @@ -494,9 +494,4 @@ void QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value) } } -void QQmlValueTypeReference::destroy(Heap::Base *that) -{ - static_cast<Heap::QQmlValueTypeReference*>(that)->Heap::QQmlValueTypeReference::~QQmlValueTypeReference(); -} - QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h index 5ef480061d..fec54df770 100644 --- a/src/qml/qml/qqmlvaluetypewrapper_p.h +++ b/src/qml/qml/qqmlvaluetypewrapper_p.h @@ -66,14 +66,24 @@ namespace QV4 { namespace Heap { struct QQmlValueTypeWrapper : Object { - QQmlValueTypeWrapper() {} - ~QQmlValueTypeWrapper(); - QQmlRefPointer<QQmlPropertyCache> propertyCache; + void init() { Object::init(); } + void destroy(); + QQmlPropertyCache *propertyCache() const { return _propertyCache; } + void setPropertyCache(QQmlPropertyCache *c) { + if (c) + c->addref(); + if (_propertyCache) + _propertyCache->release(); + _propertyCache = c; + } mutable void *gadgetPtr; QQmlValueType *valueType; void setValue(const QVariant &value) const; QVariant toVariant() const; + +private: + QQmlPropertyCache *_propertyCache; }; } @@ -82,7 +92,7 @@ struct Q_QML_EXPORT QQmlValueTypeWrapper : Object { V4_OBJECT2(QQmlValueTypeWrapper, Object) V4_PROTOTYPE(valueTypeWrapperPrototype) - static void destroy(Heap::Base *b); + V4_NEEDS_DESTROY public: diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 6f56931e73..791870b831 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -503,9 +503,9 @@ QUrl QQmlVMEMetaObject::readPropertyAsUrl(int id) const QV4::Scope scope(cache->engine); QV4::ScopedValue sv(scope, *(md->data() + id)); const QV4::VariantObject *v = sv->as<QV4::VariantObject>(); - if (!v || v->d()->data.type() != QVariant::Url) + if (!v || v->d()->data().type() != QVariant::Url) return QUrl(); - return v->d()->data.value<QUrl>(); + return v->d()->data().value<QUrl>(); } QDate QQmlVMEMetaObject::readPropertyAsDate(int id) const @@ -517,9 +517,9 @@ QDate QQmlVMEMetaObject::readPropertyAsDate(int id) const QV4::Scope scope(cache->engine); QV4::ScopedValue sv(scope, *(md->data() + id)); const QV4::VariantObject *v = sv->as<QV4::VariantObject>(); - if (!v || v->d()->data.type() != QVariant::Date) + if (!v || v->d()->data().type() != QVariant::Date) return QDate(); - return v->d()->data.value<QDate>(); + return v->d()->data().value<QDate>(); } QDateTime QQmlVMEMetaObject::readPropertyAsDateTime(int id) @@ -531,9 +531,9 @@ QDateTime QQmlVMEMetaObject::readPropertyAsDateTime(int id) QV4::Scope scope(cache->engine); QV4::ScopedValue sv(scope, *(md->data() + id)); const QV4::VariantObject *v = sv->as<QV4::VariantObject>(); - if (!v || v->d()->data.type() != QVariant::DateTime) + if (!v || v->d()->data().type() != QVariant::DateTime) return QDateTime(); - return v->d()->data.value<QDateTime>(); + return v->d()->data().value<QDateTime>(); } QSizeF QQmlVMEMetaObject::readPropertyAsSizeF(int id) const @@ -545,9 +545,9 @@ QSizeF QQmlVMEMetaObject::readPropertyAsSizeF(int id) const QV4::Scope scope(cache->engine); QV4::ScopedValue sv(scope, *(md->data() + id)); const QV4::VariantObject *v = sv->as<QV4::VariantObject>(); - if (!v || v->d()->data.type() != QVariant::SizeF) + if (!v || v->d()->data().type() != QVariant::SizeF) return QSizeF(); - return v->d()->data.value<QSizeF>(); + return v->d()->data().value<QSizeF>(); } QPointF QQmlVMEMetaObject::readPropertyAsPointF(int id) const @@ -559,9 +559,9 @@ QPointF QQmlVMEMetaObject::readPropertyAsPointF(int id) const QV4::Scope scope(cache->engine); QV4::ScopedValue sv(scope, *(md->data() + id)); const QV4::VariantObject *v = sv->as<QV4::VariantObject>(); - if (!v || v->d()->data.type() != QVariant::PointF) + if (!v || v->d()->data().type() != QVariant::PointF) return QPointF(); - return v->d()->data.value<QPointF>(); + return v->d()->data().value<QPointF>(); } QObject* QQmlVMEMetaObject::readPropertyAsQObject(int id) const @@ -586,12 +586,12 @@ QList<QObject *> *QQmlVMEMetaObject::readPropertyAsList(int id) const QV4::Scope scope(cache->engine); QV4::Scoped<QV4::VariantObject> v(scope, *(md->data() + id)); - if (!v || (int)v->d()->data.userType() != qMetaTypeId<QList<QObject *> >()) { + if (!v || (int)v->d()->data().userType() != qMetaTypeId<QList<QObject *> >()) { QVariant variant(qVariantFromValue(QList<QObject*>())); v = cache->engine->newVariantObject(variant); *(md->data() + id) = v; } - return static_cast<QList<QObject *> *>(v->d()->data.data()); + return static_cast<QList<QObject *> *>(v->d()->data().data()); } QRectF QQmlVMEMetaObject::readPropertyAsRectF(int id) const @@ -603,9 +603,9 @@ QRectF QQmlVMEMetaObject::readPropertyAsRectF(int id) const QV4::Scope scope(cache->engine); QV4::ScopedValue sv(scope, *(md->data() + id)); const QV4::VariantObject *v = sv->as<QV4::VariantObject>(); - if (!v || v->d()->data.type() != QVariant::RectF) + if (!v || v->d()->data().type() != QVariant::RectF) return QRectF(); - return v->d()->data.value<QRectF>(); + return v->d()->data().value<QRectF>(); } #if defined(Q_OS_WINRT) && defined(_M_ARM) @@ -740,7 +740,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) { QVariant propertyAsVariant; if (QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>()) - propertyAsVariant = v->d()->data; + propertyAsVariant = v->d()->data(); QQml_valueTypeProvider()->readValueType(propertyAsVariant, a[0], fallbackMetaType); } break; @@ -816,10 +816,10 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * if (!v) { *(md->data() + id) = cache->engine->newVariantObject(QVariant()); v = (md->data() + id)->as<QV4::VariantObject>(); - QQml_valueTypeProvider()->initValueType(fallbackMetaType, v->d()->data); + QQml_valueTypeProvider()->initValueType(fallbackMetaType, v->d()->data()); } - needActivate = !QQml_valueTypeProvider()->equalValueType(fallbackMetaType, a[0], v->d()->data); - QQml_valueTypeProvider()->writeValueType(fallbackMetaType, a[0], v->d()->data); + needActivate = !QQml_valueTypeProvider()->equalValueType(fallbackMetaType, a[0], v->d()->data()); + QQml_valueTypeProvider()->writeValueType(fallbackMetaType, a[0], v->d()->data()); } break; case QV4::CompiledData::Property::Var: @@ -1009,7 +1009,7 @@ QVariant QQmlVMEMetaObject::readPropertyAsVariant(int id) const return QVariant::fromValue(wrapper->object()); const QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>(); if (v) - return v->d()->data; + return v->d()->data(); return cache->engine->toVariant(*(md->data() + id), -1); } return QVariant(); @@ -1092,8 +1092,8 @@ void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value) if (md) { QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>(); needActivate = (!v || - v->d()->data.userType() != value.userType() || - v->d()->data != value); + v->d()->data().userType() != value.userType() || + v->d()->data() != value); if (v) v->removeVmePropertyReference(); *(md->data() + id) = cache->engine->newVariantObject(value); diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index dd517374a5..b4be709b37 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -70,7 +70,7 @@ using namespace QV4; -#if !defined(QT_NO_XMLSTREAMREADER) && !defined(QT_NO_NETWORK) +#if !defined(QT_NO_XMLSTREAMREADER) && QT_CONFIG(qml_network) #define V4THROW_REFERENCE(string) { \ ScopedObject error(scope, ctx->engine()->newReferenceErrorObject(QStringLiteral(string))); \ @@ -174,33 +174,43 @@ public: namespace Heap { struct NamedNodeMap : Object { - NamedNodeMap(NodeImpl *data, const QList<NodeImpl *> &list); - ~NamedNodeMap() { + void init(NodeImpl *data, const QList<NodeImpl *> &list); + void destroy() { + delete listPtr; if (d) d->release(); + Object::destroy(); } - QList<NodeImpl *> list; // Only used in NamedNodeMap + QList<NodeImpl *> &list() { + if (listPtr == nullptr) + listPtr = new QList<NodeImpl *>; + return *listPtr; + } + + QList<NodeImpl *> *listPtr; // Only used in NamedNodeMap NodeImpl *d; }; struct NodeList : Object { - NodeList(NodeImpl *data); - ~NodeList() { + void init(NodeImpl *data); + void destroy() { if (d) d->release(); + Object::destroy(); } NodeImpl *d; }; struct NodePrototype : Object { - NodePrototype(); + void init(); }; struct Node : Object { - Node(NodeImpl *data); - ~Node() { + void init(NodeImpl *data); + void destroy() { if (d) d->release(); + Object::destroy(); } NodeImpl *d; }; @@ -221,10 +231,11 @@ public: static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty); }; -Heap::NamedNodeMap::NamedNodeMap(NodeImpl *data, const QList<NodeImpl *> &list) - : list(list) - , d(data) +void Heap::NamedNodeMap::init(NodeImpl *data, const QList<NodeImpl *> &list) { + Object::init(); + d = data; + this->list() = list; if (d) d->addref(); } @@ -246,9 +257,10 @@ public: }; -Heap::NodeList::NodeList(NodeImpl *data) - : d(data) +void Heap::NodeList::init(NodeImpl *data) { + Object::init(); + d = data; if (d) d->addref(); } @@ -287,8 +299,9 @@ public: }; -Heap::NodePrototype::NodePrototype() +void Heap::NodePrototype::init() { + Object::init(); Scope scope(internalClass->engine); ScopedObject o(scope, this); @@ -320,9 +333,10 @@ struct Node : public Object bool isNull() const; }; -Heap::Node::Node(NodeImpl *data) - : d(data) +void Heap::Node::init(NodeImpl *data) { + Object::init(); + d = data; if (d) d->addref(); } @@ -878,10 +892,10 @@ ReturnedValue NamedNodeMap::getIndexed(const Managed *m, uint index, bool *hasPr const NamedNodeMap *r = static_cast<const NamedNodeMap *>(m); QV4::ExecutionEngine *v4 = r->engine(); - if ((int)index < r->d()->list.count()) { + if ((int)index < r->d()->list().count()) { if (hasProperty) *hasProperty = true; - return Node::create(v4, r->d()->list.at(index)); + return Node::create(v4, r->d()->list().at(index)); } if (hasProperty) *hasProperty = false; @@ -896,14 +910,14 @@ ReturnedValue NamedNodeMap::get(const Managed *m, String *name, bool *hasPropert name->makeIdentifier(v4); if (name->equals(v4->id_length())) - return Primitive::fromInt32(r->d()->list.count()).asReturnedValue(); + return Primitive::fromInt32(r->d()->list().count()).asReturnedValue(); QString str = name->toQString(); - for (int ii = 0; ii < r->d()->list.count(); ++ii) { - if (r->d()->list.at(ii)->name == str) { + for (int ii = 0; ii < r->d()->list().count(); ++ii) { + if (r->d()->list().at(ii)->name == str) { if (hasProperty) *hasProperty = true; - return Node::create(v4, r->d()->list.at(ii)); + return Node::create(v4, r->d()->list().at(ii)); } } @@ -1588,15 +1602,20 @@ namespace QV4 { namespace Heap { struct QQmlXMLHttpRequestWrapper : Object { - QQmlXMLHttpRequestWrapper(QQmlXMLHttpRequest *request); - ~QQmlXMLHttpRequestWrapper() { + void init(QQmlXMLHttpRequest *request) { + Object::init(); + this->request = request; + } + + void destroy() { delete request; + Object::destroy(); } QQmlXMLHttpRequest *request; }; struct QQmlXMLHttpRequestCtor : FunctionObject { - QQmlXMLHttpRequestCtor(ExecutionEngine *engine); + void init(ExecutionEngine *engine); Pointer<Object> proto; }; @@ -1609,11 +1628,6 @@ struct QQmlXMLHttpRequestWrapper : public Object V4_NEEDS_DESTROY }; -Heap::QQmlXMLHttpRequestWrapper::QQmlXMLHttpRequestWrapper(QQmlXMLHttpRequest *request) - : request(request) -{ -} - struct QQmlXMLHttpRequestCtor : public FunctionObject { V4_OBJECT2(QQmlXMLHttpRequestCtor, FunctionObject) @@ -1665,9 +1679,9 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject DEFINE_OBJECT_VTABLE(QQmlXMLHttpRequestWrapper); -Heap::QQmlXMLHttpRequestCtor::QQmlXMLHttpRequestCtor(ExecutionEngine *engine) - : Heap::FunctionObject(engine->rootContext(), QStringLiteral("XMLHttpRequest")) +void Heap::QQmlXMLHttpRequestCtor::init(ExecutionEngine *engine) { + Heap::FunctionObject::init(engine->rootContext(), QStringLiteral("XMLHttpRequest")); Scope scope(engine); Scoped<QV4::QQmlXMLHttpRequestCtor> ctor(scope, this); @@ -2043,6 +2057,6 @@ void *qt_add_qmlxmlhttprequest(ExecutionEngine *v4) QT_END_NAMESPACE -#endif // QT_NO_XMLSTREAMREADER && QT_NO_NETWORK +#endif // QT_NO_XMLSTREAMREADER && qml_network #include <qqmlxmlhttprequest.moc> diff --git a/src/qml/qml/qqmlxmlhttprequest_p.h b/src/qml/qml/qqmlxmlhttprequest_p.h index df30873915..fdb6194537 100644 --- a/src/qml/qml/qqmlxmlhttprequest_p.h +++ b/src/qml/qml/qqmlxmlhttprequest_p.h @@ -55,7 +55,7 @@ #include <QtCore/qglobal.h> #include <private/qqmlglobal_p.h> -#if !defined(QT_NO_XMLSTREAMREADER) && !defined(QT_NO_NETWORK) +#if !defined(QT_NO_XMLSTREAMREADER) && QT_CONFIG(qml_network) QT_BEGIN_NAMESPACE @@ -64,7 +64,7 @@ void qt_rem_qmlxmlhttprequest(QV4::ExecutionEngine *engine, void *); QT_END_NAMESPACE -#endif // QT_NO_XMLSTREAMREADER && QT_NO_NETWORK +#endif // QT_NO_XMLSTREAMREADER && qml_network #endif // QQMLXMLHTTPREQUEST_P_H diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 222b61ae49..cf0fd57773 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -91,10 +91,11 @@ struct StaticQtMetaObject : public QObject { return &staticQtMetaObject; } }; -Heap::QtObject::QtObject(QQmlEngine *qmlEngine) - : enumeratorIterator(0) - , keyIterator(0) +void Heap::QtObject::init(QQmlEngine *qmlEngine) { + Heap::Object::init(); + enumeratorIterator = 0; + keyIterator = 0; Scope scope(internalClass->engine); ScopedObject o(scope, this); @@ -1302,17 +1303,18 @@ ReturnedValue QtObject::method_locale(CallContext *ctx) return QQmlLocale::locale(ctx->engine(), code); } -Heap::QQmlBindingFunction::QQmlBindingFunction(const QV4::FunctionObject *originalFunction) - : QV4::Heap::FunctionObject(originalFunction->scope(), originalFunction->name()) +void Heap::QQmlBindingFunction::init(const QV4::FunctionObject *originalFunction) { + QV4::Heap::FunctionObject::init(originalFunction->scope(), originalFunction->name()); + bindingLocation = new QQmlSourceLocation; this->originalFunction = originalFunction->d(); } void QQmlBindingFunction::initBindingLocation() { QV4::StackFrame frame = engine()->currentStackFrame(); - d()->bindingLocation.sourceFile = frame.source; - d()->bindingLocation.line = frame.line; + d()->bindingLocation->sourceFile = frame.source; + d()->bindingLocation->line = frame.line; } void QQmlBindingFunction::call(const Managed *that, Scope &scope, CallData *callData) @@ -1436,8 +1438,9 @@ ReturnedValue QtObject::method_get_styleHints(CallContext *ctx) } -QV4::Heap::ConsoleObject::ConsoleObject() +void QV4::Heap::ConsoleObject::init() { + Object::init(); QV4::Scope scope(internalClass->engine); QV4::ScopedObject o(scope, this); @@ -1559,6 +1562,8 @@ static QV4::ReturnedValue writeToConsole(ConsoleLogTypes logType, CallContext *c return QV4::Encode::undefined(); } +DEFINE_OBJECT_VTABLE(ConsoleObject); + QV4::ReturnedValue ConsoleObject::method_error(CallContext *ctx) { return writeToConsole(Error, ctx); diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h index 8c0759679a..7602a92582 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h +++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h @@ -64,7 +64,7 @@ namespace QV4 { namespace Heap { struct QtObject : Object { - QtObject(QQmlEngine *qmlEngine); + void init(QQmlEngine *qmlEngine); QObject *platform; QObject *application; @@ -77,14 +77,18 @@ struct QtObject : Object { }; struct ConsoleObject : Object { - ConsoleObject(); + void init(); }; struct QQmlBindingFunction : FunctionObject { - QQmlBindingFunction(const QV4::FunctionObject *originalFunction); + void init(const QV4::FunctionObject *originalFunction); + void destroy() { + delete bindingLocation; + Object::destroy(); + } Pointer<FunctionObject> originalFunction; // Set when the binding is created later - QQmlSourceLocation bindingLocation; + QQmlSourceLocation *bindingLocation; }; } @@ -145,9 +149,7 @@ private: struct ConsoleObject : Object { - typedef Heap::ConsoleObject Data; - const Data *d() const { return static_cast<const Data *>(Object::d()); } - Data *d() { return static_cast<Data *>(Object::d()); } + V4_OBJECT2(ConsoleObject, Object) static ReturnedValue method_error(CallContext *ctx); static ReturnedValue method_log(CallContext *ctx); diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index f15020f6c9..b0599dd0a2 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -160,8 +160,10 @@ QV8Engine::~QV8Engine() qDeleteAll(m_extensionData); m_extensionData.clear(); +#if !defined(QT_NO_XMLSTREAMREADER) && QT_CONFIG(qml_network) qt_rem_qmlxmlhttprequest(m_v4Engine, m_xmlHttpRequestData); m_xmlHttpRequestData = 0; +#endif delete m_listModelData; m_listModelData = 0; @@ -169,7 +171,7 @@ QV8Engine::~QV8Engine() delete m_v4Engine; } -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) QNetworkAccessManager *QV8Engine::networkAccessManager() { return QQmlEnginePrivate::get(m_engine)->getNetworkAccessManager(); @@ -193,7 +195,7 @@ void QV8Engine::initializeGlobal() QQmlDateExtension::registerExtension(m_v4Engine); QQmlNumberExtension::registerExtension(m_v4Engine); -#if !defined(QT_NO_XMLSTREAMREADER) && !defined(QT_NO_NETWORK) +#if !defined(QT_NO_XMLSTREAMREADER) && QT_CONFIG(qml_network) qt_add_domexceptions(m_v4Engine); m_xmlHttpRequestData = qt_add_qmlxmlhttprequest(m_v4Engine); #endif diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index 390831609b..0cbe34fd30 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -188,7 +188,7 @@ public: void freezeObject(const QV4::Value &value); -#ifndef QT_NO_NETWORK +#if QT_CONFIG(qml_network) // Return the network access manager for this engine. By default this returns the network // access manager of the QQmlEngine. It is overridden in the case of a threaded v8 // instance (like in WorkerScript). |