diff options
Diffstat (limited to 'src/qml')
63 files changed, 415 insertions, 744 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 16c4cb28ed..d871a9add5 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -339,6 +339,7 @@ IRBuilder::IRBuilder(const QSet<QString> &illegalNames) : illegalNames(illegalNames) , _object(0) , _propertyDeclaration(0) + , pool(0) , jsGenerator(0) { } diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index cde7a2acb4..3ce3e04969 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -1244,7 +1244,7 @@ int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, const QByteArray &e imports->resolveType(scope, &type, 0, 0, 0); if (!type) return -1; - return type ? type->enumValue(compiler->enginePrivate(), QHashedCStringRef(enumValue.constData(), enumValue.length()), ok) : -1; + return type->enumValue(compiler->enginePrivate(), QHashedCStringRef(enumValue.constData(), enumValue.length()), ok); } const QMetaObject *mo = StaticQtMetaObject::get(); diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp index 98b53c6b3b..f49a440572 100644 --- a/src/qml/compiler/qv4jsir.cpp +++ b/src/qml/compiler/qv4jsir.cpp @@ -558,7 +558,7 @@ Expr *BasicBlock::CONST(Type type, double value) } else if (type == NullType) { value = 0; } else if (type == UndefinedType) { - value = qSNaN(); + value = qQNaN(); } e->init(type, value); diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index 89101ad756..28437a1d3c 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -2771,7 +2771,7 @@ void convertConst(Const *c, Type targetType) break; case NullType: case UndefinedType: - c->value = qSNaN(); + c->value = qQNaN(); c->type = targetType; default: Q_UNIMPLEMENTED(); diff --git a/src/qml/debugger/qqmlabstractprofileradapter_p.h b/src/qml/debugger/qqmlabstractprofileradapter_p.h index bfd1561d3d..c723224985 100644 --- a/src/qml/debugger/qqmlabstractprofileradapter_p.h +++ b/src/qml/debugger/qqmlabstractprofileradapter_p.h @@ -58,9 +58,10 @@ class Q_QML_PRIVATE_EXPORT QQmlAbstractProfilerAdapter : public QObject, public Q_OBJECT public: - QQmlAbstractProfilerAdapter(QQmlProfilerService *service) : - service(service), waiting(true), featuresEnabled(0) {} + QQmlAbstractProfilerAdapter(QObject *parent = 0) : + QObject(parent), service(0), waiting(true), featuresEnabled(0) {} virtual ~QQmlAbstractProfilerAdapter() {} + void setService(QQmlProfilerService *new_service) { service = new_service; } virtual qint64 sendMessages(qint64 until, QList<QByteArray> &messages) = 0; @@ -96,6 +97,15 @@ private: quint64 featuresEnabled; }; +class Q_QML_PRIVATE_EXPORT QQmlAbstractProfilerAdapterFactory : public QObject +{ + Q_OBJECT +public: + virtual QQmlAbstractProfilerAdapter *create(const QString &key) = 0; +}; + +#define QQmlAbstractProfilerAdapterFactory_iid "org.qt-project.Qt.QQmlAbstractProfilerAdapterFactory" + QT_END_NAMESPACE #endif // QQMLABSTRACTPROFILERADAPTER_P_H diff --git a/src/qml/debugger/qqmldebug.cpp b/src/qml/debugger/qqmldebug.cpp index 35dc110e9a..b308f5aa29 100644 --- a/src/qml/debugger/qqmldebug.cpp +++ b/src/qml/debugger/qqmldebug.cpp @@ -33,6 +33,7 @@ #include "qqmldebug.h" #include "qqmldebugconnector_p.h" +#include "qqmldebugserviceinterfaces_p.h" #include <private/qqmlengine_p.h> @@ -52,10 +53,64 @@ QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool printWarning) } /*! + * Retrieves the plugin keys of the debugger services provided by default. The debugger services + * enable a debug client to use a Qml/JavaScript debugger, in order to set breakpoints, pause + * execution, evaluate expressions and similar debugging tasks. + * \return List of plugin keys of default debugger services. + */ +QStringList QQmlDebuggingEnabler::debuggerServices() +{ + return QStringList() << QV4DebugService::s_key << QQmlEngineDebugService::s_key + << QDebugMessageService::s_key; +} + +/*! + * Retrieves the plugin keys of the inspector services provided by default. The inspector services + * enable a debug client to use a visual inspector tool for Qt Quick. + * \return List of plugin keys of default inspector services. + */ +QStringList QQmlDebuggingEnabler::inspectorServices() +{ + return QStringList() << QQmlInspectorService::s_key; +} + +/*! + * Retrieves the names of the profiler services provided by default. The profiler services enable a + * debug client to use a profiler and track the time taken by various QML and JavaScript constructs, + * as well as the QtQuick SceneGraph. + * \return List of plugin keys of default profiler services. + */ +QStringList QQmlDebuggingEnabler::profilerServices() +{ + return QStringList() << QQmlProfilerService::s_key << QQmlEngineControlService::s_key; +} + +/*! + * Restricts the services available from the debug connector. The connector will scan plugins in the + * "qmltooling" subdirectory of the default plugin path. If this function is not called before the + * debug connector is enabled, all services found that way will be available to any client. If this + * function is called, only the services with plugin keys given in \a services will be available. + * + * Use this method to disable debugger and inspector services when profiling to get better + * performance and more realistic profiles. The debugger service will put any JavaScript engine it + * connects to into interpreted mode, disabling the JIT compiler. + * + * \sa debuggerServices(), profilerServices(), inspectorServices() + */ +void QQmlDebuggingEnabler::setServices(const QStringList &services) +{ +#ifndef QQML_NO_DEBUG_PROTOCOL + QQmlDebugConnector::setServices(services); +#else + Q_UNUSED(services); +#endif +} + +/*! * \enum QQmlDebuggingEnabler::StartMode * - * Defines the debug server's start behavior. You can interrupt QML engines starting while a debug - * client is connecting, in order to set breakpoints in or profile startup code. + * Defines the debug connector's start behavior. You can interrupt QML engines starting while a + * debug client is connecting, in order to set breakpoints in or profile startup code. * * \value DoNotWaitForClient Run any QML engines as usual while the debug services are connecting. * \value WaitForClient If a QML engine starts while the debug services are connecting, @@ -63,13 +118,13 @@ QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool printWarning) */ /*! - * Enables debugging for QML engines created after calling this function. The debug server will + * Enables debugging for QML engines created after calling this function. The debug connector will * listen on \a port at \a hostName and block the QML engine until it receives a connection if * \a mode is \c WaitForClient. If \a mode is not specified it won't block and if \a hostName is not - * specified it will listen on all available interfaces. You can only start one debug server at a - * time. A debug server may have already been started if the -qmljsdebugger= command line argument - * was given. This method returns \c true if a new debug server was successfully started, or - * \c false otherwise. + * specified it will listen on all available interfaces. You can only start one debug connector at a + * time. A debug connector may have already been started if the -qmljsdebugger= command line + * argument was given. This method returns \c true if a new debug connector was successfully + * started, or \c false otherwise. */ bool QQmlDebuggingEnabler::startTcpDebugServer(int port, StartMode mode, const QString &hostName) { @@ -85,7 +140,7 @@ bool QQmlDebuggingEnabler::startTcpDebugServer(int port, StartMode mode, const Q } #else Q_UNUSED(port); - Q_UNUSED(block); + Q_UNUSED(mode); Q_UNUSED(hostName); #endif return false; @@ -94,12 +149,12 @@ bool QQmlDebuggingEnabler::startTcpDebugServer(int port, StartMode mode, const Q /*! * \since 5.6 * - * Enables debugging for QML engines created after calling this function. The debug server will + * Enables debugging for QML engines created after calling this function. The debug connector will * connect to a debugger waiting on a local socket at the given \a socketFileName and block the QML * engine until the connection is established if \a mode is \c WaitForClient. If \a mode is not - * specified it will not block. You can only start one debug server at a time. A debug server may - * have already been started if the -qmljsdebugger= command line argument was given. This method - * returns \c true if a new debug server was successfully started, or \c false otherwise. + * specified it will not block. You can only start one debug connector at a time. A debug connector + * may have already been started if the -qmljsdebugger= command line argument was given. This method + * returns \c true if a new debug connector was successfully started, or \c false otherwise. */ bool QQmlDebuggingEnabler::connectToLocalDebugger(const QString &socketFileName, StartMode mode) { @@ -114,7 +169,7 @@ bool QQmlDebuggingEnabler::connectToLocalDebugger(const QString &socketFileName, } #else Q_UNUSED(fileName); - Q_UNUSED(block); + Q_UNUSED(mode); #endif return false; } diff --git a/src/qml/debugger/qqmldebug.h b/src/qml/debugger/qqmldebug.h index 5d65982a49..6316ebd195 100644 --- a/src/qml/debugger/qqmldebug.h +++ b/src/qml/debugger/qqmldebug.h @@ -48,6 +48,13 @@ struct Q_QML_EXPORT QQmlDebuggingEnabler }; QQmlDebuggingEnabler(bool printWarning = true); + + static QStringList debuggerServices(); + static QStringList inspectorServices(); + static QStringList profilerServices(); + + static void setServices(const QStringList &services); + static bool startTcpDebugServer(int port, StartMode mode = DoNotWaitForClient, const QString &hostName = QString()); static bool connectToLocalDebugger(const QString &socketFileName, diff --git a/src/qml/debugger/qqmldebugconnector.cpp b/src/qml/debugger/qqmldebugconnector.cpp index 64a8a49bb9..7d9f462fe2 100644 --- a/src/qml/debugger/qqmldebugconnector.cpp +++ b/src/qml/debugger/qqmldebugconnector.cpp @@ -39,6 +39,7 @@ #include <QtCore/QDir> #include <QtCore/QDebug> #include <QtCore/QJsonArray> +#include <QtCore/QDataStream> #include <private/qcoreapplication_p.h> #include <private/qqmlengine_p.h> @@ -56,6 +57,8 @@ Q_QML_IMPORT_DEBUG_PLUGIN(QQmlInspectorServiceFactory) Q_QML_IMPORT_DEBUG_PLUGIN(QQmlProfilerServiceFactory) Q_QML_IMPORT_DEBUG_PLUGIN(QQmlDebuggerServiceFactory) +int QQmlDebugConnector::s_dataStreamVersion = QDataStream::Qt_4_7; + struct QQmlDebugConnectorParams { QString pluginKey; QStringList services; diff --git a/src/qml/debugger/qqmldebugconnector_p.h b/src/qml/debugger/qqmldebugconnector_p.h index f5f5a87b56..8549810438 100644 --- a/src/qml/debugger/qqmldebugconnector_p.h +++ b/src/qml/debugger/qqmldebugconnector_p.h @@ -35,6 +35,7 @@ #define QQMLDEBUGCONNECTOR_H #include <QtQml/qtqmlglobal.h> +#include <QtQml/qjsengine.h> #include <QtCore/QVariantList> #include <private/qqmldebugservice_p.h> @@ -60,13 +61,18 @@ public: static void setPluginKey(const QString &key); static void setServices(const QStringList &services); static QQmlDebugConnector *instance(); + static int dataStreamVersion() + { + return s_dataStreamVersion; + } virtual bool blockingMode() const = 0; virtual QQmlDebugService *service(const QString &name) const = 0; - virtual void addEngine(QQmlEngine *engine) = 0; - virtual void removeEngine(QQmlEngine *engine) = 0; + virtual void addEngine(QJSEngine *engine) = 0; + virtual void removeEngine(QJSEngine *engine) = 0; + virtual bool hasEngine(QJSEngine *engine) = 0; virtual bool addService(const QString &name, QQmlDebugService *service) = 0; virtual bool removeService(const QString &name) = 0; @@ -82,6 +88,7 @@ public: protected: static QString commandLineArguments(); + static int s_dataStreamVersion; }; class Q_QML_PRIVATE_EXPORT QQmlDebugConnectorFactory : public QObject { diff --git a/src/qml/debugger/qqmldebugservice.cpp b/src/qml/debugger/qqmldebugservice.cpp index 0b07f320ec..f46a924d5e 100644 --- a/src/qml/debugger/qqmldebugservice.cpp +++ b/src/qml/debugger/qqmldebugservice.cpp @@ -182,50 +182,24 @@ void QQmlDebugService::messageReceived(const QByteArray &) { } -void QQmlDebugService::engineAboutToBeAdded(QQmlEngine *engine) +void QQmlDebugService::engineAboutToBeAdded(QJSEngine *engine) { emit attachedToEngine(engine); } -void QQmlDebugService::engineAboutToBeRemoved(QQmlEngine *engine) +void QQmlDebugService::engineAboutToBeRemoved(QJSEngine *engine) { emit detachedFromEngine(engine); } -void QQmlDebugService::engineAdded(QQmlEngine *) +void QQmlDebugService::engineAdded(QJSEngine *) { } -void QQmlDebugService::engineRemoved(QQmlEngine *) +void QQmlDebugService::engineRemoved(QJSEngine *) { } -int QQmlDebugStream::s_dataStreamVersion = QDataStream::Qt_4_7; - -QQmlDebugStream::QQmlDebugStream() - : QDataStream() -{ - setVersion(s_dataStreamVersion); -} - -QQmlDebugStream::QQmlDebugStream(QIODevice *d) - : QDataStream(d) -{ - setVersion(s_dataStreamVersion); -} - -QQmlDebugStream::QQmlDebugStream(QByteArray *ba, QIODevice::OpenMode flags) - : QDataStream(ba, flags) -{ - setVersion(s_dataStreamVersion); -} - -QQmlDebugStream::QQmlDebugStream(const QByteArray &ba) - : QDataStream(ba) -{ - setVersion(s_dataStreamVersion); -} - QT_END_NAMESPACE #include "qqmldebugservice.moc" diff --git a/src/qml/debugger/qqmldebugservice_p.h b/src/qml/debugger/qqmldebugservice_p.h index 3d692133cc..0fcf5459ef 100644 --- a/src/qml/debugger/qqmldebugservice_p.h +++ b/src/qml/debugger/qqmldebugservice_p.h @@ -35,7 +35,6 @@ #define QQMLDEBUGSERVICE_H #include <QtCore/qobject.h> -#include <QtCore/qdatastream.h> #include <QtCore/qhash.h> #include <private/qtqmlglobal_p.h> @@ -53,7 +52,7 @@ QT_BEGIN_NAMESPACE -class QQmlEngine; +class QJSEngine; class QQmlDebugServicePrivate; class Q_QML_PRIVATE_EXPORT QQmlDebugService : public QObject @@ -76,10 +75,10 @@ public: virtual void stateChanged(State); virtual void messageReceived(const QByteArray &); - virtual void engineAboutToBeAdded(QQmlEngine *); - virtual void engineAboutToBeRemoved(QQmlEngine *); - virtual void engineAdded(QQmlEngine *); - virtual void engineRemoved(QQmlEngine *); + virtual void engineAboutToBeAdded(QJSEngine *); + virtual void engineAboutToBeRemoved(QJSEngine *); + virtual void engineAdded(QJSEngine *); + virtual void engineRemoved(QJSEngine *); static const QHash<int, QObject *> &objectsForIds(); static int idForObject(QObject *); @@ -89,24 +88,13 @@ protected: explicit QQmlDebugService(const QString &, float version, QObject *parent = 0); signals: - void attachedToEngine(QQmlEngine *); - void detachedFromEngine(QQmlEngine *); + void attachedToEngine(QJSEngine *); + void detachedFromEngine(QJSEngine *); void messageToClient(const QString &name, const QByteArray &message); void messagesToClient(const QString &name, const QList<QByteArray> &messages); }; -class Q_QML_PRIVATE_EXPORT QQmlDebugStream : public QDataStream -{ -public: - static int s_dataStreamVersion; - - QQmlDebugStream(); - explicit QQmlDebugStream(QIODevice *d); - QQmlDebugStream(QByteArray *ba, QIODevice::OpenMode flags); - QQmlDebugStream(const QByteArray &ba); -}; - QT_END_NAMESPACE #endif // QQMLDEBUGSERVICE_H diff --git a/src/qml/debugger/qqmldebugserviceinterfaces.cpp b/src/qml/debugger/qqmldebugserviceinterfaces.cpp index 199c682748..e0968b2656 100644 --- a/src/qml/debugger/qqmldebugserviceinterfaces.cpp +++ b/src/qml/debugger/qqmldebugserviceinterfaces.cpp @@ -39,6 +39,8 @@ const QString QV4DebugService::s_key = QStringLiteral("V8Debugger"); const QString QQmlEngineDebugService::s_key = QStringLiteral("QmlDebugger"); const QString QQmlInspectorService::s_key = QStringLiteral("QmlInspector"); const QString QQmlProfilerService::s_key = QStringLiteral("CanvasFrameRate"); +const QString QDebugMessageService::s_key = QStringLiteral("DebugMessages"); +const QString QQmlEngineControlService::s_key = QStringLiteral("EngineControl"); const QString QQmlNativeDebugService::s_key = QStringLiteral("NativeQmlDebugger"); QT_END_NAMESPACE diff --git a/src/qml/debugger/qqmldebugserviceinterfaces_p.h b/src/qml/debugger/qqmldebugserviceinterfaces_p.h index 6391bc6218..1b45392680 100644 --- a/src/qml/debugger/qqmldebugserviceinterfaces_p.h +++ b/src/qml/debugger/qqmldebugserviceinterfaces_p.h @@ -60,6 +60,8 @@ class Q_QML_PRIVATE_EXPORT QV4DebugService : protected QQmlDebugService { Q_OBJECT public: + static const QString s_key; + virtual void signalEmitted(const QString &signal) = 0; protected: @@ -67,20 +69,20 @@ protected: QV4DebugService(float version, QObject *parent = 0) : QQmlDebugService(s_key, version, parent) {} - - static const QString s_key; }; class Q_QML_PRIVATE_EXPORT QQmlProfilerService : protected QQmlDebugService { Q_OBJECT public: + static const QString s_key; + virtual void addGlobalProfiler(QQmlAbstractProfilerAdapter *profiler) = 0; virtual void removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler) = 0; - virtual void startProfiling(QQmlEngine *engine, + virtual void startProfiling(QJSEngine *engine, quint64 features = std::numeric_limits<quint64>::max()) = 0; - virtual void stopProfiling(QQmlEngine *engine) = 0; + virtual void stopProfiling(QJSEngine *engine) = 0; virtual void dataReady(QQmlAbstractProfilerAdapter *profiler) = 0; @@ -89,15 +91,15 @@ protected: QQmlProfilerService(float version, QObject *parent = 0) : QQmlDebugService(s_key, version, parent) {} - - static const QString s_key; }; class Q_QML_PRIVATE_EXPORT QQmlEngineDebugService : protected QQmlDebugService { Q_OBJECT public: - virtual void objectCreated(QQmlEngine *engine, QObject *object) = 0; + static const QString s_key; + + virtual void objectCreated(QJSEngine *engine, QObject *object) = 0; virtual void setStatesDelegate(QQmlDebugStatesDelegate *) = 0; protected: @@ -107,14 +109,14 @@ protected: QQmlDebugService(s_key, version, parent) {} QQmlBoundSignal *nextSignal(QQmlBoundSignal *prev) { return prev->m_nextSignal; } - - static const QString s_key; }; class Q_QML_PRIVATE_EXPORT QQmlInspectorService : protected QQmlDebugService { Q_OBJECT public: + static const QString s_key; + virtual void addView(QObject *) = 0; virtual void removeView(QObject *) = 0; @@ -123,8 +125,35 @@ protected: QQmlInspectorService(float version, QObject *parent = 0) : QQmlDebugService(s_key, version, parent) {} +}; + +class Q_QML_PRIVATE_EXPORT QDebugMessageService : protected QQmlDebugService +{ + Q_OBJECT +public: + static const QString s_key; + + virtual void synchronizeTime(const QElapsedTimer &otherTimer) = 0; + +protected: + friend class QQmlDebugConnector; + + QDebugMessageService(float version, QObject *parent = 0) : + QQmlDebugService(s_key, version, parent) {} +}; +class Q_QML_PRIVATE_EXPORT QQmlEngineControlService : protected QQmlDebugService +{ + Q_OBJECT +public: static const QString s_key; + +protected: + friend class QQmlDebugConnector; + + QQmlEngineControlService(float version, QObject *parent = 0) : + QQmlDebugService(s_key, version, parent) {} + }; class Q_QML_PRIVATE_EXPORT QQmlNativeDebugService : protected QQmlDebugService diff --git a/src/qml/debugger/qqmlprofilerdefinitions_p.h b/src/qml/debugger/qqmlprofilerdefinitions_p.h index 1213b67b3c..ce708132f8 100644 --- a/src/qml/debugger/qqmlprofilerdefinitions_p.h +++ b/src/qml/debugger/qqmlprofilerdefinitions_p.h @@ -89,9 +89,6 @@ struct QQmlProfilerDefinitions { enum BindingType { QmlBinding, - V8Binding, - V4Binding, - MaximumBindingType }; @@ -126,8 +123,8 @@ struct QQmlProfilerDefinitions { typedef QV4::Profiling::MemoryType MemoryType; enum ProfileFeature { - ProfileJavaScript = QV4::Profiling::FeatureFunctionCall, - ProfileMemory = QV4::Profiling::FeatureMemoryAllocation, + ProfileJavaScript, + ProfileMemory, ProfilePixmapCache, ProfileSceneGraph, ProfileAnimations, @@ -137,9 +134,25 @@ struct QQmlProfilerDefinitions { ProfileBinding, ProfileHandlingSignal, ProfileInputEvents, + ProfileDebugMessages, MaximumProfileFeature }; + + enum InputEventType { + InputKeyPress, + InputKeyRelease, + InputKeyUnknown, + + InputMousePress, + InputMouseRelease, + InputMouseMove, + InputMouseDoubleClick, + InputMouseWheel, + InputMouseUnknown, + + MaximumInputEventType + }; }; QT_END_NAMESPACE diff --git a/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc b/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc index 9eb792bd2e..71db34695c 100644 --- a/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc +++ b/src/qml/doc/src/qmllanguageref/syntax/imports.qdoc @@ -291,6 +291,7 @@ default locations to be searched by the engine. By default, this list contains: \li The directory of the current file \li The location specified by QLibraryInfo::Qml2ImportsPath \li Paths specified by the \c QML2_IMPORT_PATH environment variable +\li The qrc:/qt-project.org/imports path inside the resources. \endlist Additional import paths can be added through QQmlEngine::addImportPath() or the diff --git a/src/qml/jit/qv4binop.cpp b/src/qml/jit/qv4binop.cpp index 8b051fcb3d..ee4611525c 100644 --- a/src/qml/jit/qv4binop.cpp +++ b/src/qml/jit/qv4binop.cpp @@ -341,8 +341,8 @@ bool Binop::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *ta case IR::OpBitXor: case IR::OpAdd: case IR::OpMul: - break; inplaceOpWithAddress = true; + break; default: break; } diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp index 5ccbccebad..80dce129c7 100644 --- a/src/qml/jsapi/qjsengine.cpp +++ b/src/qml/jsapi/qjsengine.cpp @@ -43,6 +43,7 @@ #include "private/qv4script_p.h" #include "private/qv4runtime_p.h" #include <private/qqmlbuiltinfunctions_p.h> +#include <private/qqmldebugconnector_p.h> #include <QtCore/qdatetime.h> #include <QtCore/qmetaobject.h> @@ -251,6 +252,7 @@ QJSEngine::QJSEngine() : QObject(*new QJSEnginePrivate, 0) , d(new QV8Engine(this)) { + QJSEnginePrivate::addToDebugServer(this); } /*! @@ -264,6 +266,7 @@ QJSEngine::QJSEngine(QObject *parent) : QObject(*new QJSEnginePrivate, parent) , d(new QV8Engine(this)) { + QJSEnginePrivate::addToDebugServer(this); } /*! @@ -284,6 +287,7 @@ QJSEngine::QJSEngine(QJSEnginePrivate &dd, QObject *parent) */ QJSEngine::~QJSEngine() { + QJSEnginePrivate::removeFromDebugServer(this); delete d; } @@ -671,6 +675,26 @@ QJSEnginePrivate::~QJSEnginePrivate() (*iter)->release(); } +void QJSEnginePrivate::addToDebugServer(QJSEngine *q) +{ + if (QCoreApplication::instance()->thread() != q->thread()) + return; + + QQmlDebugConnector *server = QQmlDebugConnector::instance(); + if (!server || server->hasEngine(q)) + return; + + server->open(); + server->addEngine(q); +} + +void QJSEnginePrivate::removeFromDebugServer(QJSEngine *q) +{ + QQmlDebugConnector *server = QQmlDebugConnector::instance(); + if (server && server->hasEngine(q)) + server->removeEngine(q); +} + QQmlPropertyCache *QJSEnginePrivate::createCache(const QMetaObject *mo) { if (!mo->superClass()) { diff --git a/src/qml/jsapi/qjsengine_p.h b/src/qml/jsapi/qjsengine_p.h index 8fdec08085..1fb8dc6fb2 100644 --- a/src/qml/jsapi/qjsengine_p.h +++ b/src/qml/jsapi/qjsengine_p.h @@ -70,6 +70,9 @@ public: QJSEnginePrivate() : mutex(QMutex::Recursive) {} ~QJSEnginePrivate(); + static void addToDebugServer(QJSEngine *q); + static void removeFromDebugServer(QJSEngine *q); + // Locker locks the QQmlEnginePrivate data structures for read and write, if necessary. // Currently, locking is only necessary if the threaded loader is running concurrently. If it is // either idle, or is running with the main thread blocked, no locking is necessary. This way diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index a49b98c921..30d79e13d5 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -1147,6 +1147,9 @@ void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value) bool QJSValue::deleteProperty(const QString &name) { QV4::ExecutionEngine *engine = QJSValuePrivate::engine(this); + if (!engine) + return false; + Scope scope(engine); ScopedObject o(scope, QJSValuePrivate::getValue(this)); if (!o) diff --git a/src/qml/jsapi/qjsvalueiterator_p.h b/src/qml/jsapi/qjsvalueiterator_p.h index dfc5e18cd6..4aa41fdefa 100644 --- a/src/qml/jsapi/qjsvalueiterator_p.h +++ b/src/qml/jsapi/qjsvalueiterator_p.h @@ -50,8 +50,6 @@ QT_BEGIN_NAMESPACE -class QV8Engine; - class QJSValueIteratorPrivate { public: diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri index 5ffdebe328..503b40e8ae 100644 --- a/src/qml/jsruntime/jsruntime.pri +++ b/src/qml/jsruntime/jsruntime.pri @@ -112,5 +112,3 @@ valgrind { } ios: DEFINES += ENABLE_ASSEMBLER_WX_EXCLUSIVE=1 - -include(../../3rdparty/double-conversion/double-conversion.pri) diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp index 8901834e76..cd28c03fa3 100644 --- a/src/qml/jsruntime/qv4dataview.cpp +++ b/src/qml/jsruntime/qv4dataview.cpp @@ -285,7 +285,7 @@ ReturnedValue DataViewPrototype::method_setFloat(CallContext *ctx) return scope.engine->throwTypeError(); idx += v->d()->byteOffset; - double val = ctx->argc() >= 2 ? ctx->args()[1].toNumber() : qSNaN(); + double val = ctx->argc() >= 2 ? ctx->args()[1].toNumber() : qQNaN(); bool littleEndian = ctx->argc() < 3 ? false : ctx->args()[2].toBoolean(); if (sizeof(T) == 4) { diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index a6e1f47d91..d414ec2084 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -198,7 +198,7 @@ static inline double MonthFromTime(double t) else if (d < 365.0 + l) return 11; - return qSNaN(); // ### assert? + return qQNaN(); // ### assert? } static inline double DateFromTime(double t) @@ -222,7 +222,7 @@ static inline double DateFromTime(double t) case 11: return d - 333.0 - l; } - return qSNaN(); // ### assert + return qQNaN(); // ### assert } static inline double WeekDay(double t) @@ -254,7 +254,7 @@ static inline double DayFromMonth(double month, double leap) case 11: return 334.0 + leap; } - return qSNaN(); // ### assert? + return qQNaN(); // ### assert? } static double MakeDay(double year, double month, double day) @@ -333,7 +333,7 @@ static inline double currentTime() static inline double TimeClip(double t) { if (! qIsFinite(t) || fabs(t) > 8.64e15) - return qSNaN(); + return qQNaN(); return Primitive::toInteger(t); } @@ -538,7 +538,7 @@ static inline double ParseString(const QString &s) } } if (!dt.isValid()) - return qSNaN(); + return qQNaN(); return dt.toMSecsSinceEpoch(); } @@ -630,7 +630,7 @@ DEFINE_OBJECT_VTABLE(DateObject); Heap::DateObject::DateObject(const QDateTime &date) { - this->date = date.isValid() ? date.toMSecsSinceEpoch() : qSNaN(); + this->date = date.isValid() ? date.toMSecsSinceEpoch() : qQNaN(); } QDateTime DateObject::toQDateTime() const @@ -764,7 +764,7 @@ double DatePrototype::getThisDate(ExecutionContext *ctx) ReturnedValue DatePrototype::method_parse(CallContext *ctx) { if (!ctx->argc()) - return Encode(qSNaN()); + return Encode(qQNaN()); return Encode(ParseString(ctx->args()[0].toQString())); } @@ -994,7 +994,7 @@ ReturnedValue DatePrototype::method_setTime(CallContext *ctx) if (!self) return ctx->engine()->throwTypeError(); - double t = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double t = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); self->setDate(TimeClip(t)); return Encode(self->date()); } @@ -1007,7 +1007,7 @@ ReturnedValue DatePrototype::method_setMilliseconds(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = LocalTime(self->date()); - double ms = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double ms = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); self->setDate(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms))))); return Encode(self->date()); } @@ -1019,7 +1019,7 @@ ReturnedValue DatePrototype::method_setUTCMilliseconds(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = self->date(); - double ms = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double ms = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); self->setDate(TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))); return Encode(self->date()); } @@ -1031,7 +1031,7 @@ ReturnedValue DatePrototype::method_setSeconds(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = LocalTime(self->date()); - double sec = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double sec = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double ms = (ctx->argc() < 2) ? msFromTime(t) : ctx->args()[1].toNumber(); t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms)))); self->setDate(t); @@ -1045,7 +1045,7 @@ ReturnedValue DatePrototype::method_setUTCSeconds(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = self->date(); - double sec = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double sec = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double ms = (ctx->argc() < 2) ? msFromTime(t) : ctx->args()[1].toNumber(); t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))); self->setDate(t); @@ -1059,7 +1059,7 @@ ReturnedValue DatePrototype::method_setMinutes(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = LocalTime(self->date()); - double min = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double min = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double sec = (ctx->argc() < 2) ? SecFromTime(t) : ctx->args()[1].toNumber(); double ms = (ctx->argc() < 3) ? msFromTime(t) : ctx->args()[2].toNumber(); t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms)))); @@ -1074,7 +1074,7 @@ ReturnedValue DatePrototype::method_setUTCMinutes(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = self->date(); - double min = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double min = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double sec = (ctx->argc() < 2) ? SecFromTime(t) : ctx->args()[1].toNumber(); double ms = (ctx->argc() < 3) ? msFromTime(t) : ctx->args()[2].toNumber(); t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))); @@ -1089,7 +1089,7 @@ ReturnedValue DatePrototype::method_setHours(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = LocalTime(self->date()); - double hour = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double hour = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double min = (ctx->argc() < 2) ? MinFromTime(t) : ctx->args()[1].toNumber(); double sec = (ctx->argc() < 3) ? SecFromTime(t) : ctx->args()[2].toNumber(); double ms = (ctx->argc() < 4) ? msFromTime(t) : ctx->args()[3].toNumber(); @@ -1105,7 +1105,7 @@ ReturnedValue DatePrototype::method_setUTCHours(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = self->date(); - double hour = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double hour = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double min = (ctx->argc() < 2) ? MinFromTime(t) : ctx->args()[1].toNumber(); double sec = (ctx->argc() < 3) ? SecFromTime(t) : ctx->args()[2].toNumber(); double ms = (ctx->argc() < 4) ? msFromTime(t) : ctx->args()[3].toNumber(); @@ -1121,7 +1121,7 @@ ReturnedValue DatePrototype::method_setDate(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = LocalTime(self->date()); - double date = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double date = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t)))); self->setDate(t); return Encode(self->date()); @@ -1134,7 +1134,7 @@ ReturnedValue DatePrototype::method_setUTCDate(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = self->date(); - double date = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double date = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); t = TimeClip(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t))); self->setDate(t); return Encode(self->date()); @@ -1147,7 +1147,7 @@ ReturnedValue DatePrototype::method_setMonth(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = LocalTime(self->date()); - double month = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double month = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double date = (ctx->argc() < 2) ? DateFromTime(t) : ctx->args()[1].toNumber(); t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t)))); self->setDate(t); @@ -1161,7 +1161,7 @@ ReturnedValue DatePrototype::method_setUTCMonth(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = self->date(); - double month = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double month = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double date = (ctx->argc() < 2) ? DateFromTime(t) : ctx->args()[1].toNumber(); t = TimeClip(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))); self->setDate(t); @@ -1179,10 +1179,10 @@ ReturnedValue DatePrototype::method_setYear(CallContext *ctx) t = 0; else t = LocalTime(t); - double year = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double year = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double r; if (std::isnan(year)) { - r = qSNaN(); + r = qQNaN(); } else { if ((Primitive::toInteger(year) >= 0) && (Primitive::toInteger(year) <= 99)) year += 1900; @@ -1201,7 +1201,7 @@ ReturnedValue DatePrototype::method_setUTCFullYear(CallContext *ctx) return ctx->engine()->throwTypeError(); double t = self->date(); - double year = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double year = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double month = (ctx->argc() < 2) ? MonthFromTime(t) : ctx->args()[1].toNumber(); double date = (ctx->argc() < 3) ? DateFromTime(t) : ctx->args()[2].toNumber(); t = TimeClip(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))); @@ -1218,7 +1218,7 @@ ReturnedValue DatePrototype::method_setFullYear(CallContext *ctx) double t = LocalTime(self->date()); if (std::isnan(t)) t = 0; - double year = ctx->argc() ? ctx->args()[0].toNumber() : qSNaN(); + double year = ctx->argc() ? ctx->args()[0].toNumber() : qQNaN(); double month = (ctx->argc() < 2) ? MonthFromTime(t) : ctx->args()[1].toNumber(); double date = (ctx->argc() < 3) ? DateFromTime(t) : ctx->args()[2].toNumber(); t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t)))); diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h index 2eaa837666..eb048b1e99 100644 --- a/src/qml/jsruntime/qv4dateobject_p.h +++ b/src/qml/jsruntime/qv4dateobject_p.h @@ -59,7 +59,7 @@ namespace Heap { struct DateObject : Object { DateObject() { - date = qSNaN(); + date = qQNaN(); } DateObject(const Value &date) diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp index 7706a40da6..b04bcd33e7 100644 --- a/src/qml/jsruntime/qv4debugging.cpp +++ b/src/qml/jsruntime/qv4debugging.cpp @@ -51,290 +51,4 @@ QT_BEGIN_NAMESPACE -using namespace QV4; -using namespace QV4::Debugging; - -V4Debugger::JavaScriptJob::JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr, - const QString &script) - : engine(engine) - , frameNr(frameNr) - , script(script) - , resultIsException(false) -{} - -void V4Debugger::JavaScriptJob::run() -{ - Scope scope(engine); - - ExecutionContextSaver saver(scope); - - ExecutionContext *ctx = engine->currentContext; - if (frameNr > 0) { - for (int i = 0; i < frameNr; ++i) { - ctx = engine->parentContext(ctx); - } - engine->pushContext(ctx); - } - - QV4::Script script(ctx, this->script); - script.strictMode = ctx->d()->strictMode; - // In order for property lookups in QML to work, we need to disable fast v4 lookups. That - // is a side-effect of inheritContext. - script.inheritContext = true; - script.parse(); - QV4::ScopedValue result(scope); - if (!scope.engine->hasException) - result = script.run(); - if (scope.engine->hasException) { - result = scope.engine->catchException(); - resultIsException = true; - } - handleResult(result); -} - -bool V4Debugger::JavaScriptJob::hasExeption() const -{ - return resultIsException; -} - -class EvalJob: public V4Debugger::JavaScriptJob -{ - bool result; - -public: - EvalJob(QV4::ExecutionEngine *engine, const QString &script) - : V4Debugger::JavaScriptJob(engine, /*frameNr*/-1, script) - , result(false) - {} - - virtual void handleResult(QV4::ScopedValue &result) - { - this->result = result->toBoolean(); - } - - bool resultAsBoolean() const - { - return result; - } -}; - -V4Debugger::V4Debugger(QV4::ExecutionEngine *engine) - : m_engine(engine) - , m_state(Running) - , m_stepping(NotStepping) - , m_pauseRequested(false) - , m_haveBreakPoints(false) - , m_breakOnThrow(false) - , m_returnedValue(engine, Primitive::undefinedValue()) - , m_gatherSources(0) - , m_runningJob(0) -{ - qMetaTypeId<V4Debugger*>(); - qMetaTypeId<PauseReason>(); -} - -void V4Debugger::pause() -{ - QMutexLocker locker(&m_lock); - if (m_state == Paused) - return; - m_pauseRequested = true; -} - -void V4Debugger::resume(Speed speed) -{ - QMutexLocker locker(&m_lock); - if (m_state != Paused) - return; - - if (!m_returnedValue.isUndefined()) - m_returnedValue.set(m_engine, Encode::undefined()); - - m_currentContext.set(m_engine, *m_engine->currentContext); - m_stepping = speed; - m_runningCondition.wakeAll(); -} - -void V4Debugger::addBreakPoint(const QString &fileName, int lineNumber, const QString &condition) -{ - QMutexLocker locker(&m_lock); - m_breakPoints.insert(DebuggerBreakPoint(fileName.mid(fileName.lastIndexOf('/') + 1), lineNumber), condition); - m_haveBreakPoints = true; -} - -void V4Debugger::removeBreakPoint(const QString &fileName, int lineNumber) -{ - QMutexLocker locker(&m_lock); - m_breakPoints.remove(DebuggerBreakPoint(fileName.mid(fileName.lastIndexOf('/') + 1), lineNumber)); - m_haveBreakPoints = !m_breakPoints.isEmpty(); -} - -void V4Debugger::setBreakOnThrow(bool onoff) -{ - QMutexLocker locker(&m_lock); - - m_breakOnThrow = onoff; -} - -V4Debugger::ExecutionState V4Debugger::currentExecutionState() const -{ - ExecutionState state; - state.fileName = getFunction()->sourceFile(); - state.lineNumber = engine()->current->lineNumber; - - return state; -} - -QVector<StackFrame> V4Debugger::stackTrace(int frameLimit) const -{ - return m_engine->stackTrace(frameLimit); -} - -void V4Debugger::maybeBreakAtInstruction() -{ - if (m_runningJob) // do not re-enter when we're doing a job for the debugger. - return; - - QMutexLocker locker(&m_lock); - - if (m_gatherSources) { - m_gatherSources->run(); - delete m_gatherSources; - m_gatherSources = 0; - } - - switch (m_stepping) { - case StepOver: - if (m_currentContext.asManaged()->d() != m_engine->current) - break; - // fall through - case StepIn: - pauseAndWait(Step); - return; - case StepOut: - case NotStepping: - break; - } - - if (m_pauseRequested) { // Serve debugging requests from the agent - m_pauseRequested = false; - pauseAndWait(PauseRequest); - } else if (m_haveBreakPoints) { - if (Function *f = getFunction()) { - const int lineNumber = engine()->current->lineNumber; - if (reallyHitTheBreakPoint(f->sourceFile(), lineNumber)) - pauseAndWait(BreakPoint); - } - } -} - -void V4Debugger::enteringFunction() -{ - if (m_runningJob) - return; - QMutexLocker locker(&m_lock); - - if (m_stepping == StepIn) { - m_currentContext.set(m_engine, *m_engine->currentContext); - } -} - -void V4Debugger::leavingFunction(const ReturnedValue &retVal) -{ - if (m_runningJob) - return; - Q_UNUSED(retVal); // TODO - - QMutexLocker locker(&m_lock); - - if (m_stepping != NotStepping && m_currentContext.asManaged()->d() == m_engine->current) { - m_currentContext.set(m_engine, *m_engine->parentContext(m_engine->currentContext)); - m_stepping = StepOver; - m_returnedValue.set(m_engine, retVal); - } -} - -void V4Debugger::aboutToThrow() -{ - if (!m_breakOnThrow) - return; - - if (m_runningJob) // do not re-enter when we're doing a job for the debugger. - return; - - QMutexLocker locker(&m_lock); - pauseAndWait(Throwing); -} - -Function *V4Debugger::getFunction() const -{ - Scope scope(m_engine); - ExecutionContext *context = m_engine->currentContext; - ScopedFunctionObject function(scope, context->getFunctionObject()); - if (function) - return function->function(); - else - return context->d()->engine->globalCode; -} - -void V4Debugger::pauseAndWait(PauseReason reason) -{ - if (m_runningJob) - return; - - m_state = Paused; - emit debuggerPaused(this, reason); - - while (true) { - m_runningCondition.wait(&m_lock); - if (m_runningJob) { - m_runningJob->run(); - m_jobIsRunning.wakeAll(); - } else { - break; - } - } - - m_state = Running; -} - -bool V4Debugger::reallyHitTheBreakPoint(const QString &filename, int linenr) -{ - BreakPoints::iterator it = m_breakPoints.find(DebuggerBreakPoint(filename.mid(filename.lastIndexOf('/') + 1), linenr)); - if (it == m_breakPoints.end()) - return false; - QString condition = it.value(); - if (condition.isEmpty()) - return true; - - Q_ASSERT(m_runningJob == 0); - EvalJob evilJob(m_engine, condition); - m_runningJob = &evilJob; - m_runningJob->run(); - m_runningJob = 0; - - return evilJob.resultAsBoolean(); -} - -void V4Debugger::runInEngine(V4Debugger::Job *job) -{ - QMutexLocker locker(&m_lock); - runInEngine_havingLock(job); -} - -void V4Debugger::runInEngine_havingLock(V4Debugger::Job *job) -{ - Q_ASSERT(job); - Q_ASSERT(m_runningJob == 0); - - m_runningJob = job; - m_runningCondition.wakeAll(); - m_jobIsRunning.wait(&m_lock); - m_runningJob = 0; -} - -V4Debugger::Job::~Job() -{ -} - QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4debugging_p.h b/src/qml/jsruntime/qv4debugging_p.h index fdc9cac24f..3a3ecef918 100644 --- a/src/qml/jsruntime/qv4debugging_p.h +++ b/src/qml/jsruntime/qv4debugging_p.h @@ -31,8 +31,8 @@ ** ****************************************************************************/ -#ifndef DEBUGGING_H -#define DEBUGGING_H +#ifndef QV4DEBUGGING_H +#define QV4DEBUGGING_H // // W A R N I N G @@ -46,50 +46,13 @@ // #include "qv4global_p.h" -#include "qv4engine_p.h" -#include "qv4context_p.h" -#include "qv4scopedvalue_p.h" - -#include <QHash> -#include <QThread> -#include <QMutex> -#include <QWaitCondition> - -#include <QtCore/QJsonObject> +#include <QtCore/qobject.h> QT_BEGIN_NAMESPACE namespace QV4 { - -struct Function; - namespace Debugging { -enum PauseReason { - PauseRequest, - BreakPoint, - Throwing, - Step -}; - -struct DebuggerBreakPoint { - DebuggerBreakPoint(const QString &fileName, int line) - : fileName(fileName), lineNumber(line) - {} - QString fileName; - int lineNumber; -}; -inline uint qHash(const DebuggerBreakPoint &b, uint seed = 0) Q_DECL_NOTHROW -{ - return qHash(b.fileName, seed) ^ b.lineNumber; -} -inline bool operator==(const DebuggerBreakPoint &a, const DebuggerBreakPoint &b) -{ - return a.lineNumber == b.lineNumber && a.fileName == b.fileName; -} - -typedef QHash<DebuggerBreakPoint, QString> BreakPoints; - class Q_QML_EXPORT Debugger : public QObject { Q_OBJECT @@ -103,123 +66,9 @@ public: virtual void aboutToThrow() = 0; }; -class Q_QML_EXPORT V4Debugger : public Debugger -{ - Q_OBJECT -public: - class Q_QML_EXPORT Job - { - public: - virtual ~Job() = 0; - virtual void run() = 0; - }; - - class Q_QML_EXPORT JavaScriptJob: public Job - { - QV4::ExecutionEngine *engine; - int frameNr; - const QString &script; - bool resultIsException; - - public: - JavaScriptJob(QV4::ExecutionEngine *engine, int frameNr, const QString &script); - void run(); - bool hasExeption() const; - - protected: - virtual void handleResult(QV4::ScopedValue &result) = 0; - }; - - enum State { - Running, - Paused - }; - - enum Speed { - FullThrottle = 0, - StepOut, - StepOver, - StepIn, - - NotStepping = FullThrottle - }; - - V4Debugger(ExecutionEngine *engine); - - ExecutionEngine *engine() const - { return m_engine; } - - void pause(); - void resume(Speed speed); - - State state() const { return m_state; } - - void addBreakPoint(const QString &fileName, int lineNumber, const QString &condition = QString()); - void removeBreakPoint(const QString &fileName, int lineNumber); - - void setBreakOnThrow(bool onoff); - - // used for testing - struct ExecutionState - { - QString fileName; - int lineNumber; - }; - ExecutionState currentExecutionState() const; - - bool pauseAtNextOpportunity() const { - return m_pauseRequested || m_haveBreakPoints || m_gatherSources || m_stepping >= StepOver; - } - - QVector<StackFrame> stackTrace(int frameLimit = -1) const; - QVector<Heap::ExecutionContext::ContextType> getScopeTypes(int frame = 0) const; - - Function *getFunction() const; - void runInEngine(Job *job); - -public: // compile-time interface - void maybeBreakAtInstruction(); - -public: // execution hooks - void enteringFunction(); - void leavingFunction(const ReturnedValue &retVal); - void aboutToThrow(); - -signals: - void sourcesCollected(QV4::Debugging::V4Debugger *self, const QStringList &sources, int seq); - void debuggerPaused(QV4::Debugging::V4Debugger *self, QV4::Debugging::PauseReason reason); - -private: - // requires lock to be held - void pauseAndWait(PauseReason reason); - bool reallyHitTheBreakPoint(const QString &filename, int linenr); - void runInEngine_havingLock(V4Debugger::Job *job); - -private: - QV4::ExecutionEngine *m_engine; - QV4::PersistentValue m_currentContext; - QMutex m_lock; - QWaitCondition m_runningCondition; - State m_state; - Speed m_stepping; - bool m_pauseRequested; - bool m_haveBreakPoints; - bool m_breakOnThrow; - - BreakPoints m_breakPoints; - QV4::PersistentValue m_returnedValue; - - Job *m_gatherSources; - Job *m_runningJob; - QWaitCondition m_jobIsRunning; -}; - } // namespace Debugging } // namespace QV4 QT_END_NAMESPACE -Q_DECLARE_METATYPE(QV4::Debugging::Debugger*) -Q_DECLARE_METATYPE(QV4::Debugging::PauseReason) - -#endif // DEBUGGING_H +#endif // QV4DEBUGGING_H diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp index 110a2c9089..b4733356ac 100644 --- a/src/qml/jsruntime/qv4globalobject.cpp +++ b/src/qml/jsruntime/qv4globalobject.cpp @@ -302,7 +302,7 @@ static QString decode(const QString &input, DecodeMode decodeMode, bool *ok) ++r; } if (*r) - output.append(input.mid(start, i - start + 1)); + output.append(input.midRef(start, i - start + 1)); else output.append(QChar(b)); } else { diff --git a/src/qml/jsruntime/qv4identifier_p.h b/src/qml/jsruntime/qv4identifier_p.h index 605b06c685..ff93b70ff9 100644 --- a/src/qml/jsruntime/qv4identifier_p.h +++ b/src/qml/jsruntime/qv4identifier_p.h @@ -103,8 +103,6 @@ struct IdentifierHashBase inline IdentifierHashBase &operator=(const IdentifierHashBase &other); bool isEmpty() const { return !d; } - // ### - void reserve(int) {} inline int count() const; bool contains(const Identifier *i) const; diff --git a/src/qml/jsruntime/qv4include_p.h b/src/qml/jsruntime/qv4include_p.h index 3e3cf5e770..497566e7eb 100644 --- a/src/qml/jsruntime/qv4include_p.h +++ b/src/qml/jsruntime/qv4include_p.h @@ -58,7 +58,6 @@ QT_BEGIN_NAMESPACE class QQmlEngine; class QNetworkAccessManager; class QNetworkReply; -class QV8Engine; class QV4Include : public QObject { Q_OBJECT diff --git a/src/qml/jsruntime/qv4math_p.h b/src/qml/jsruntime/qv4math_p.h index cf627bcc5d..51031356bc 100644 --- a/src/qml/jsruntime/qv4math_p.h +++ b/src/qml/jsruntime/qv4math_p.h @@ -47,6 +47,7 @@ #include <qglobal.h> #include <QtCore/qnumeric.h> +#include <QtCore/private/qnumeric_p.h> #include <cmath> #if defined(Q_CC_GNU) @@ -59,84 +60,30 @@ QT_BEGIN_NAMESPACE namespace QV4 { -#if defined(Q_CC_GNU) && defined(Q_PROCESSOR_X86) - static inline QMLJS_READONLY ReturnedValue add_int32(int a, int b) { - quint8 overflow = 0; - int aa = a; - - asm ("addl %2, %1\n" - "seto %0" - : "=q" (overflow), "=r" (aa) - : "r" (b), "1" (aa) - : "cc" - ); - if (Q_UNLIKELY(overflow)) + int result; + if (Q_UNLIKELY(add_overflow(a, b, &result))) return Primitive::fromDouble(static_cast<double>(a) + b).asReturnedValue(); - return Primitive::fromInt32(aa).asReturnedValue(); + return Primitive::fromInt32(result).asReturnedValue(); } static inline QMLJS_READONLY ReturnedValue sub_int32(int a, int b) { - quint8 overflow = 0; - int aa = a; - - asm ("subl %2, %1\n" - "seto %0" - : "=q" (overflow), "=r" (aa) - : "r" (b), "1" (aa) - : "cc" - ); - if (Q_UNLIKELY(overflow)) + int result; + if (Q_UNLIKELY(sub_overflow(a, b, &result))) return Primitive::fromDouble(static_cast<double>(a) - b).asReturnedValue(); - return Primitive::fromInt32(aa).asReturnedValue(); + return Primitive::fromInt32(result).asReturnedValue(); } static inline QMLJS_READONLY ReturnedValue mul_int32(int a, int b) { - quint8 overflow = 0; - int aa = a; - - asm ("imul %2, %1\n" - "setc %0" - : "=q" (overflow), "=r" (aa) - : "r" (b), "1" (aa) - : "cc" - ); - if (Q_UNLIKELY(overflow)) + int result; + if (Q_UNLIKELY(mul_overflow(a, b, &result))) return Primitive::fromDouble(static_cast<double>(a) * b).asReturnedValue(); - return Primitive::fromInt32(aa).asReturnedValue(); -} - -#else - -static inline QMLJS_READONLY ReturnedValue add_int32(int a, int b) -{ - qint64 result = static_cast<qint64>(a) + b; - if (Q_UNLIKELY(result > INT_MAX || result < INT_MIN)) - return Primitive::fromDouble(static_cast<double>(a) + b).asReturnedValue(); - return Primitive::fromInt32(static_cast<int>(result)).asReturnedValue(); + return Primitive::fromInt32(result).asReturnedValue(); } -static inline QMLJS_READONLY ReturnedValue sub_int32(int a, int b) -{ - qint64 result = static_cast<qint64>(a) - b; - if (Q_UNLIKELY(result > INT_MAX || result < INT_MIN)) - return Primitive::fromDouble(static_cast<double>(a) - b).asReturnedValue(); - return Primitive::fromInt32(static_cast<int>(result)).asReturnedValue(); -} - -static inline QMLJS_READONLY ReturnedValue mul_int32(int a, int b) -{ - qint64 result = static_cast<qint64>(a) * b; - if (Q_UNLIKELY(result > INT_MAX || result < INT_MIN)) - return Primitive::fromDouble(static_cast<double>(a) * b).asReturnedValue(); - return Primitive::fromInt32(static_cast<int>(result)).asReturnedValue(); -} - -#endif - } QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp index 3d3ac84576..ada073fbd4 100644 --- a/src/qml/jsruntime/qv4mathobject.cpp +++ b/src/qml/jsruntime/qv4mathobject.cpp @@ -96,7 +96,7 @@ static double copySign(double x, double y) ReturnedValue MathObject::method_abs(CallContext *context) { if (!context->argc()) - return Encode(qSNaN()); + return Encode(qQNaN()); if (context->args()[0].isInteger()) { int i = context->args()[0].integerValue(); @@ -114,7 +114,7 @@ ReturnedValue MathObject::method_acos(CallContext *context) { double v = context->argc() ? context->args()[0].toNumber() : 2; if (v > 1) - return Encode(qSNaN()); + return Encode(qQNaN()); return Encode(std::acos(v)); } @@ -123,14 +123,14 @@ ReturnedValue MathObject::method_asin(CallContext *context) { double v = context->argc() ? context->args()[0].toNumber() : 2; if (v > 1) - return Encode(qSNaN()); + return Encode(qQNaN()); else return Encode(std::asin(v)); } ReturnedValue MathObject::method_atan(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); if (v == 0.0) return Encode(v); else @@ -139,8 +139,8 @@ ReturnedValue MathObject::method_atan(CallContext *context) ReturnedValue MathObject::method_atan2(CallContext *context) { - double v1 = context->argc() ? context->args()[0].toNumber() : qSNaN(); - double v2 = context->argc() > 1 ? context->args()[1].toNumber() : qSNaN(); + double v1 = context->argc() ? context->args()[0].toNumber() : qQNaN(); + double v2 = context->argc() > 1 ? context->args()[1].toNumber() : qQNaN(); if ((v1 < 0) && qIsFinite(v1) && qIsInf(v2) && (copySign(1.0, v2) == 1.0)) return Encode(copySign(0, -1.0)); @@ -157,7 +157,7 @@ ReturnedValue MathObject::method_atan2(CallContext *context) ReturnedValue MathObject::method_ceil(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); if (v < 0.0 && v > -1.0) return Encode(copySign(0, -1.0)); else @@ -166,13 +166,13 @@ ReturnedValue MathObject::method_ceil(CallContext *context) ReturnedValue MathObject::method_cos(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); return Encode(std::cos(v)); } ReturnedValue MathObject::method_exp(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); if (qIsInf(v)) { if (copySign(1.0, v) == -1.0) return Encode(0); @@ -185,15 +185,15 @@ ReturnedValue MathObject::method_exp(CallContext *context) ReturnedValue MathObject::method_floor(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); return Encode(std::floor(v)); } ReturnedValue MathObject::method_log(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); if (v < 0) - return Encode(qSNaN()); + return Encode(qQNaN()); else return Encode(std::log(v)); } @@ -224,16 +224,16 @@ ReturnedValue MathObject::method_min(CallContext *context) ReturnedValue MathObject::method_pow(CallContext *context) { - double x = context->argc() > 0 ? context->args()[0].toNumber() : qSNaN(); - double y = context->argc() > 1 ? context->args()[1].toNumber() : qSNaN(); + double x = context->argc() > 0 ? context->args()[0].toNumber() : qQNaN(); + double y = context->argc() > 1 ? context->args()[1].toNumber() : qQNaN(); if (std::isnan(y)) - return Encode(qSNaN()); + return Encode(qQNaN()); if (y == 0) { return Encode(1); } else if (((x == 1) || (x == -1)) && std::isinf(y)) { - return Encode(qSNaN()); + return Encode(qQNaN()); } else if (((x == 0) && copySign(1.0, x) == 1.0) && (y < 0)) { return Encode(qInf()); } else if ((x == 0) && copySign(1.0, x) == -1.0) { @@ -269,7 +269,7 @@ ReturnedValue MathObject::method_pow(CallContext *context) return Encode(std::pow(x, y)); } // ### - return Encode(qSNaN()); + return Encode(qQNaN()); } Q_GLOBAL_STATIC(QThreadStorage<bool *>, seedCreatedStorage); @@ -290,26 +290,26 @@ ReturnedValue MathObject::method_random(CallContext *context) ReturnedValue MathObject::method_round(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); v = copySign(std::floor(v + 0.5), v); return Encode(v); } ReturnedValue MathObject::method_sin(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); return Encode(std::sin(v)); } ReturnedValue MathObject::method_sqrt(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); return Encode(std::sqrt(v)); } ReturnedValue MathObject::method_tan(CallContext *context) { - double v = context->argc() ? context->args()[0].toNumber() : qSNaN(); + double v = context->argc() ? context->args()[0].toNumber() : qQNaN(); if (v == 0.0) return Encode(v); else diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp index 4ae30a7f35..5006c8c2cd 100644 --- a/src/qml/jsruntime/qv4numberobject.cpp +++ b/src/qml/jsruntime/qv4numberobject.cpp @@ -39,13 +39,31 @@ #include <QtCore/qmath.h> #include <QtCore/QDebug> #include <cassert> -#include <double-conversion.h> using namespace QV4; DEFINE_OBJECT_VTABLE(NumberCtor); DEFINE_OBJECT_VTABLE(NumberObject); +struct NumberLocaleHolder : public NumberLocale +{ + NumberLocaleHolder() {} +}; + +Q_GLOBAL_STATIC(NumberLocaleHolder, numberLocaleHolder) + +NumberLocale::NumberLocale() : QLocale(QLocale::C), + // -128 means shortest string that can accurately represent the number. + defaultDoublePrecision(0xffffff80) +{ + setNumberOptions(QLocale::OmitGroupSeparator | QLocale::OmitLeadingZeroInExponent); +} + +const NumberLocale *NumberLocale::instance() +{ + return numberLocaleHolder(); +} + Heap::NumberCtor::NumberCtor(QV4::ExecutionContext *scope) : Heap::FunctionObject(scope, QStringLiteral("Number")) { @@ -71,7 +89,7 @@ void NumberPrototype::init(ExecutionEngine *engine, Object *ctor) ctor->defineReadonlyProperty(engine->id_prototype(), (o = this)); ctor->defineReadonlyProperty(engine->id_length(), Primitive::fromInt32(1)); - ctor->defineReadonlyProperty(QStringLiteral("NaN"), Primitive::fromDouble(qSNaN())); + ctor->defineReadonlyProperty(QStringLiteral("NaN"), Primitive::fromDouble(qQNaN())); ctor->defineReadonlyProperty(QStringLiteral("NEGATIVE_INFINITY"), Primitive::fromDouble(-qInf())); ctor->defineReadonlyProperty(QStringLiteral("POSITIVE_INFINITY"), Primitive::fromDouble(qInf())); ctor->defineReadonlyProperty(QStringLiteral("MAX_VALUE"), Primitive::fromDouble(1.7976931348623158e+308)); @@ -201,15 +219,9 @@ ReturnedValue NumberPrototype::method_toFixed(CallContext *ctx) str = QStringLiteral("NaN"); else if (qIsInf(v)) str = QString::fromLatin1(v < 0 ? "-Infinity" : "Infinity"); - else if (v < 1.e21) { - char buf[100]; - double_conversion::StringBuilder builder(buf, sizeof(buf)); - double_conversion::DoubleToStringConverter::EcmaScriptConverter().ToFixed(v, fdigits, &builder); - str = QString::fromLatin1(builder.Finalize()); - // At some point, the 3rd party double-conversion code should be moved to qtcore. - // When that's done, we can use: -// str = QString::number(v, 'f', int (fdigits)); - } else + else if (v < 1.e21) + str = NumberLocale::instance()->toString(v, 'f', int(fdigits)); + else return RuntimeHelpers::stringFromNumber(ctx->engine(), v)->asReturnedValue(); return scope.engine->newString(str)->asReturnedValue(); } @@ -221,7 +233,7 @@ ReturnedValue NumberPrototype::method_toExponential(CallContext *ctx) if (scope.engine->hasException) return Encode::undefined(); - int fdigits = -1; + int fdigits = NumberLocale::instance()->defaultDoublePrecision; if (ctx->argc() && !ctx->args()[0].isUndefined()) { fdigits = ctx->args()[0].toInt32(); @@ -231,11 +243,7 @@ ReturnedValue NumberPrototype::method_toExponential(CallContext *ctx) } } - char str[100]; - double_conversion::StringBuilder builder(str, sizeof(str)); - double_conversion::DoubleToStringConverter::EcmaScriptConverter().ToExponential(d, fdigits, &builder); - QString result = QString::fromLatin1(builder.Finalize()); - + QString result = NumberLocale::instance()->toString(d, 'e', fdigits); return scope.engine->newString(result)->asReturnedValue(); } @@ -255,10 +263,6 @@ ReturnedValue NumberPrototype::method_toPrecision(CallContext *ctx) return ctx->engine()->throwRangeError(error); } - char str[100]; - double_conversion::StringBuilder builder(str, sizeof(str)); - double_conversion::DoubleToStringConverter::EcmaScriptConverter().ToPrecision(v->asDouble(), precision, &builder); - QString result = QString::fromLatin1(builder.Finalize()); - + QString result = NumberLocale::instance()->toString(v->asDouble(), 'g', precision); return scope.engine->newString(result)->asReturnedValue(); } diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h index cc5033531e..bd6fe3febb 100644 --- a/src/qml/jsruntime/qv4numberobject_p.h +++ b/src/qml/jsruntime/qv4numberobject_p.h @@ -60,6 +60,15 @@ struct NumberCtor : FunctionObject { } +class NumberLocale : public QLocale +{ +public: + static const NumberLocale *instance(); + const int defaultDoublePrecision; +protected: + NumberLocale(); +}; + struct NumberCtor: FunctionObject { V4_OBJECT2(NumberCtor, FunctionObject) diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 2cb8991055..594df67f44 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -1452,7 +1452,8 @@ static QV4::ReturnedValue CallOverloaded(const QQmlObjectOrGadget &object, const const QQmlPropertyData *candidate = &data; while (candidate) { error += QLatin1String("\n ") + - QString::fromUtf8(object.metaObject()->method(candidate->coreIndex).methodSignature().constData()); + QString::fromUtf8(object.metaObject()->method(candidate->coreIndex) + .methodSignature()); candidate = RelatedMethod(object, candidate, dummy, propertyCache); } diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index a988313f5f..2d0eac079f 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -43,6 +43,7 @@ #include "qv4dateobject_p.h" #include "qv4lookup_p.h" #include "qv4function_p.h" +#include "qv4numberobject_p.h" #include "private/qlocale_tools_p.h" #include "qv4scopedvalue_p.h" #include <private/qqmlcontextwrapper_p.h> @@ -60,8 +61,6 @@ #include <wtf/MathExtras.h> -#include "../../3rdparty/double-conversion/double-conversion.h" - #ifdef QV4_COUNT_RUNTIME_FUNCTIONS # include <QtCore/QBuffer> # include <QtCore/QDebug> @@ -226,10 +225,8 @@ void RuntimeHelpers::numberToString(QString *result, double num, int radix) } if (radix == 10) { - char str[100]; - double_conversion::StringBuilder builder(str, sizeof(str)); - double_conversion::DoubleToStringConverter::EcmaScriptConverter().ToShortest(num, &builder); - *result = QString::fromLatin1(builder.Finalize()); + const NumberLocale *locale = NumberLocale::instance(); + *result = locale->toString(num, 'g', locale->defaultDoublePrecision); return; } diff --git a/src/qml/jsruntime/qv4serialize_p.h b/src/qml/jsruntime/qv4serialize_p.h index d5d48edee7..e364477a19 100644 --- a/src/qml/jsruntime/qv4serialize_p.h +++ b/src/qml/jsruntime/qv4serialize_p.h @@ -50,8 +50,6 @@ QT_BEGIN_NAMESPACE -class QV8Engine; - namespace QV4 { class Serialize { diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index 757ec6c6bf..8433582215 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -264,7 +264,7 @@ ReturnedValue StringPrototype::method_charCodeAt(CallContext *context) if (pos >= 0 && pos < str.length()) return Encode(str.at(pos).unicode()); - return Encode(qSNaN()); + return Encode(qQNaN()); } ReturnedValue StringPrototype::method_concat(CallContext *context) diff --git a/src/qml/parser/qqmljsengine_p.cpp b/src/qml/parser/qqmljsengine_p.cpp index 1c0a70a372..7cc9096e59 100644 --- a/src/qml/parser/qqmljsengine_p.cpp +++ b/src/qml/parser/qqmljsengine_p.cpp @@ -56,7 +56,7 @@ static inline int toDigit(char c) double integerFromString(const char *buf, int size, int radix) { if (size == 0) - return qSNaN(); + return qQNaN(); double sign = 1.0; int i = 0; @@ -95,7 +95,7 @@ double integerFromString(const char *buf, int size, int radix) if (!qstrcmp(buf, "Infinity")) result = qInf(); else - result = qSNaN(); + result = qQNaN(); } else { result = 0; double multiplier = 1; diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp index b2bf1939b0..4ab35e69e3 100644 --- a/src/qml/qml/qqmlapplicationengine.cpp +++ b/src/qml/qml/qqmlapplicationengine.cpp @@ -197,6 +197,7 @@ QQmlApplicationEngine::QQmlApplicationEngine(QObject *parent) { Q_D(QQmlApplicationEngine); d->init(); + QJSEnginePrivate::addToDebugServer(this); } /*! @@ -208,6 +209,7 @@ QQmlApplicationEngine::QQmlApplicationEngine(const QUrl &url, QObject *parent) { Q_D(QQmlApplicationEngine); d->init(); + QJSEnginePrivate::addToDebugServer(this); load(url); } @@ -224,6 +226,7 @@ QQmlApplicationEngine::QQmlApplicationEngine(const QString &filePath, QObject *p { Q_D(QQmlApplicationEngine); d->init(); + QJSEnginePrivate::addToDebugServer(this); load(QUrl::fromLocalFile(filePath)); } @@ -233,6 +236,7 @@ QQmlApplicationEngine::QQmlApplicationEngine(const QString &filePath, QObject *p QQmlApplicationEngine::~QQmlApplicationEngine() { Q_D(QQmlApplicationEngine); + QJSEnginePrivate::removeFromDebugServer(this); d->cleanUp();//Instantiated root objects must be deleted before the engine } diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index 477a517e32..decffaf2fa 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -250,7 +250,7 @@ QQmlBoundSignal::QQmlBoundSignal(QObject *target, int signal, QObject *owner, QQmlEngine *engine) : QQmlNotifierEndpoint(QQmlNotifierEndpoint::QQmlBoundSignal), m_prevSignal(0), m_nextSignal(0), - m_expression(0) + m_enabled(true), m_expression(0) { addToObject(owner); @@ -313,18 +313,33 @@ void QQmlBoundSignal::takeExpression(QQmlBoundSignalExpression *e) m_expression->setNotifyOnValueChanged(false); } +/*! + This property holds whether the item will emit signals. + + The QQmlBoundSignal callback will only emit a signal if this property is set to true. + + By default, this property is true. + */ +void QQmlBoundSignal::setEnabled(bool enabled) +{ + if (m_enabled == enabled) + return; + + m_enabled = enabled; +} + void QQmlBoundSignal_callback(QQmlNotifierEndpoint *e, void **a) { QQmlBoundSignal *s = static_cast<QQmlBoundSignal*>(e); - if (!s->m_expression) + if (!s->m_expression || !s->m_enabled) return; QV4DebugService *service = QQmlDebugConnector::service<QV4DebugService>(); if (service) - service->signalEmitted(QString::fromLatin1(QMetaObjectPrivate::signal( - s->m_expression->target()->metaObject(), - s->signalIndex()).methodSignature())); + service->signalEmitted(QString::fromUtf8(QMetaObjectPrivate::signal( + s->m_expression->target()->metaObject(), + s->signalIndex()).methodSignature())); QQmlEngine *engine; if (s->m_expression && (engine = s->m_expression->engine())) { diff --git a/src/qml/qml/qqmlboundsignal_p.h b/src/qml/qml/qqmlboundsignal_p.h index 3742317484..ef8fdd4a1a 100644 --- a/src/qml/qml/qqmlboundsignal_p.h +++ b/src/qml/qml/qqmlboundsignal_p.h @@ -108,6 +108,8 @@ public: QQmlBoundSignalExpression *expression() const; void takeExpression(QQmlBoundSignalExpression *); + void setEnabled(bool enabled); + private: friend void QQmlBoundSignal_callback(QQmlNotifierEndpoint *, void **); friend class QQmlPropertyPrivate; @@ -119,6 +121,8 @@ private: QQmlBoundSignal **m_prevSignal; QQmlBoundSignal *m_nextSignal; + bool m_enabled; + QQmlBoundSignalExpressionPointer m_expression; }; diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h index 15ec88dd52..0ed09d9f49 100644 --- a/src/qml/qml/qqmlcomponent_p.h +++ b/src/qml/qml/qqmlcomponent_p.h @@ -63,8 +63,6 @@ QT_BEGIN_NAMESPACE -class QV8Engine; - class QQmlComponent; class QQmlEngine; class QQmlCompiledData; diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index e8422474d3..b3636d1fa6 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -176,6 +176,7 @@ void QQmlEnginePrivate::registerBaseTypes(const char *uri, int versionMajor, int qmlRegisterType<QQmlComponent>(uri,versionMajor,versionMinor,"Component"); qmlRegisterType<QObject>(uri,versionMajor,versionMinor,"QtObject"); qmlRegisterType<QQmlBind>(uri, versionMajor, versionMinor,"Binding"); + qmlRegisterType<QQmlConnections,1>(uri, versionMajor, (versionMinor < 3 ? 3 : versionMinor), "Connections"); //Only available in >=2.3 qmlRegisterType<QQmlConnections>(uri, versionMajor, versionMinor,"Connections"); qmlRegisterType<QQmlTimer>(uri, versionMajor, versionMinor,"Timer"); qmlRegisterType<QQmlInstantiator>(uri, versionMajor, (versionMinor < 1 ? 1 : versionMinor), "Instantiator"); //Only available in >=2.1 @@ -867,11 +868,6 @@ void QQmlEnginePrivate::init() v8engine()->setEngine(q); rootContext = new QQmlContext(q,true); - - if (QCoreApplication::instance()->thread() == q->thread() && QQmlDebugConnector::instance()) { - QQmlDebugConnector::instance()->open(); - QQmlDebugConnector::instance()->addEngine(q); - } } QQuickWorkerScriptEngine *QQmlEnginePrivate::getWorkerScriptEngine() @@ -923,6 +919,7 @@ QQmlEngine::QQmlEngine(QObject *parent) { Q_D(QQmlEngine); d->init(); + QJSEnginePrivate::addToDebugServer(this); } /*! @@ -947,9 +944,7 @@ QQmlEngine::QQmlEngine(QQmlEnginePrivate &dd, QObject *parent) QQmlEngine::~QQmlEngine() { Q_D(QQmlEngine); - QQmlDebugConnector *server = QQmlDebugConnector::instance(); - if (server) - server->removeEngine(this); + QJSEnginePrivate::removeFromDebugServer(this); d->typeLoader.invalidate(); diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h index 23cfc24e7a..3b17bd94de 100644 --- a/src/qml/qml/qqmlglobal_p.h +++ b/src/qml/qml/qqmlglobal_p.h @@ -227,8 +227,6 @@ inline void QQml_setParent_noEvent(QObject *object, QObject *parent) static_cast<QQmlGraphics_DerivedObject *>(object)->setParent_noEvent(parent); } - -class QV8Engine; class Q_QML_PRIVATE_EXPORT QQmlValueTypeProvider { public: diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index d538199520..fcd05bfb1b 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -1007,13 +1007,21 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath, } #else - Q_UNUSED(qmldirFilePath); - Q_UNUSED(uri); Q_UNUSED(vmaj); Q_UNUSED(vmin); Q_UNUSED(database); Q_UNUSED(qmldir); - Q_UNUSED(errors); + + if (errors) { + QQmlError error; + error.setDescription( + QQmlImportDatabase::tr( + "plugin cannot be loaded for module \"%1\": library loading is disabled") + .arg(uri)); + error.setUrl(QUrl::fromLocalFile(qmldirFilePath)); + errors->prepend(error); + } + return false; #endif // QT_NO_LIBRARY return true; @@ -1562,8 +1570,7 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e) : engine(e) { filePluginPath << QLatin1String("."); - - // Search order is applicationDirPath(), $QML2_IMPORT_PATH, QLibraryInfo::Qml2ImportsPath + // Search order is applicationDirPath(), qrc:/qt-project.org/imports, $QML2_IMPORT_PATH, QLibraryInfo::Qml2ImportsPath QString installImportsPath = QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath); addImportPath(installImportsPath); @@ -1581,6 +1588,7 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e) addImportPath(paths.at(ii)); } + addImportPath(QStringLiteral("qrc:/qt-project.org/imports")); addImportPath(QCoreApplication::applicationDirPath()); } diff --git a/src/qml/qml/qqmllistwrapper_p.h b/src/qml/qml/qqmllistwrapper_p.h index 6df3d83b2e..ae81a1fe0f 100644 --- a/src/qml/qml/qqmllistwrapper_p.h +++ b/src/qml/qml/qqmllistwrapper_p.h @@ -55,8 +55,6 @@ QT_BEGIN_NAMESPACE -class QV8Engine; - namespace QV4 { namespace Heap { diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 21e6d5f6de..cb4bbbab77 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -897,9 +897,10 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con QMetaMethod signalMethod = _qobject->metaObject()->method(property->coreIndex); if (!QMetaObject::checkConnectArgs(signalMethod, method)) { - recordError(binding->valueLocation, tr("Cannot connect mismatched signal/slot %1 %vs. %2") - .arg(QString::fromLatin1(method.methodSignature().constData())) - .arg(QString::fromLatin1(signalMethod.methodSignature().constData()))); + recordError(binding->valueLocation, + tr("Cannot connect mismatched signal/slot %1 %vs. %2") + .arg(QString::fromUtf8(method.methodSignature())) + .arg(QString::fromUtf8(signalMethod.methodSignature()))); return false; } diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 1b78ada698..bcfcf391f6 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -50,7 +50,6 @@ #include "qqmlvaluetypeproxybinding_p.h" #include <private/qjsvalue_p.h> #include <private/qv4functionobject_p.h> -#include <private/qv4runtime_p.h> #include <QStringList> #include <private/qmetaobject_p.h> @@ -1353,12 +1352,7 @@ bool QQmlPropertyPrivate::write(QObject *object, if (!ok) { v = value; - if (variantType == QVariant::Double && propertyType == QVariant::String) { - QString number; - QV4::RuntimeHelpers::numberToString(&number, v.toDouble()); - v = number; - ok = true; - } else if (v.convert(propertyType)) { + if (v.convert(propertyType)) { ok = true; } else if (v.isValid() && value.isNull()) { // For historical reasons converting a null QVariant to another type will do the trick diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h index 610709ef7f..6f9b1dca56 100644 --- a/src/qml/qml/qqmlpropertycache_p.h +++ b/src/qml/qml/qqmlpropertycache_p.h @@ -58,7 +58,6 @@ QT_BEGIN_NAMESPACE -class QV8Engine; class QMetaProperty; class QQmlEngine; class QJSEngine; diff --git a/src/qml/qml/qqmlstringconverters.cpp b/src/qml/qml/qqmlstringconverters.cpp index eb0afda927..6a5c0736cf 100644 --- a/src/qml/qml/qqmlstringconverters.cpp +++ b/src/qml/qml/qqmlstringconverters.cpp @@ -137,8 +137,8 @@ QPointF QQmlStringConverters::pointFFromString(const QString &s, bool *ok) bool xGood, yGood; int index = s.indexOf(QLatin1Char(',')); - qreal xCoord = s.left(index).toDouble(&xGood); - qreal yCoord = s.mid(index+1).toDouble(&yGood); + qreal xCoord = s.leftRef(index).toDouble(&xGood); + qreal yCoord = s.midRef(index+1).toDouble(&yGood); if (!xGood || !yGood) { if (ok) *ok = false; @@ -161,8 +161,8 @@ QSizeF QQmlStringConverters::sizeFFromString(const QString &s, bool *ok) bool wGood, hGood; int index = s.indexOf(QLatin1Char('x')); - qreal width = s.left(index).toDouble(&wGood); - qreal height = s.mid(index+1).toDouble(&hGood); + qreal width = s.leftRef(index).toDouble(&wGood); + qreal height = s.midRef(index+1).toDouble(&hGood); if (!wGood || !hGood) { if (ok) *ok = false; @@ -185,12 +185,12 @@ QRectF QQmlStringConverters::rectFFromString(const QString &s, bool *ok) bool xGood, yGood, wGood, hGood; int index = s.indexOf(QLatin1Char(',')); - qreal x = s.left(index).toDouble(&xGood); + qreal x = s.leftRef(index).toDouble(&xGood); int index2 = s.indexOf(QLatin1Char(','), index+1); - qreal y = s.mid(index+1, index2-index-1).toDouble(&yGood); + qreal y = s.midRef(index+1, index2-index-1).toDouble(&yGood); index = s.indexOf(QLatin1Char('x'), index2+1); - qreal width = s.mid(index2+1, index-index2-1).toDouble(&wGood); - qreal height = s.mid(index+1).toDouble(&hGood); + qreal width = s.midRef(index2+1, index-index2-1).toDouble(&wGood); + qreal height = s.midRef(index+1).toDouble(&hGood); if (!xGood || !yGood || !wGood || !hGood) { if (ok) *ok = false; diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 1e671542be..98c4341e06 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -2553,6 +2553,7 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent if (!m_program) { if (shared) m_loaded = true; + ctxt->destroy(); return QV4::Encode::undefined(); } diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h index e67b457c59..6f2077b64c 100644 --- a/src/qml/qml/qqmltypewrapper_p.h +++ b/src/qml/qml/qqmltypewrapper_p.h @@ -53,7 +53,6 @@ QT_BEGIN_NAMESPACE -class QV8Engine; class QQmlTypeNameCache; namespace QV4 { diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h index 156b4c85d8..b08b6e344a 100644 --- a/src/qml/qml/qqmlvaluetypewrapper_p.h +++ b/src/qml/qml/qqmlvaluetypewrapper_p.h @@ -53,7 +53,6 @@ QT_BEGIN_NAMESPACE -class QV8Engine; class QQmlValueType; namespace QV4 { diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 37dbfec2a3..00ecf813ce 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -837,8 +837,10 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * // are not rewritten correctly but this bug is deemed out-of-scope to fix for // performance reasons; see QTBUG-24064) and thus compilation will have failed. QQmlError e; - e.setDescription(QString(QLatin1String("Exception occurred during compilation of function: %1")). - arg(QLatin1String(QMetaObject::method(_id).methodSignature().constData()))); + e.setDescription(QString::fromLatin1("Exception occurred during compilation of " + "function: %1") + .arg(QString::fromUtf8(QMetaObject::method(_id) + .methodSignature()))); ep->warning(e); return -1; // The dynamic method with that id is not available. } diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index 043113bc31..ea1f18ab8e 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -1983,8 +1983,6 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_get_response(CallContext *ctx) } else { return QV4::Encode(scope.engine->newString(QString())); } - - return Encode::undefined(); } diff --git a/src/qml/qml/qqmlxmlhttprequest_p.h b/src/qml/qml/qqmlxmlhttprequest_p.h index 69847f14c1..e72374ed54 100644 --- a/src/qml/qml/qqmlxmlhttprequest_p.h +++ b/src/qml/qml/qqmlxmlhttprequest_p.h @@ -53,8 +53,6 @@ QT_BEGIN_NAMESPACE -class QV8Engine; - void *qt_add_qmlxmlhttprequest(QV4::ExecutionEngine *engine); void qt_rem_qmlxmlhttprequest(QV4::ExecutionEngine *engine, void *); diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index f4e980eefb..e859224aea 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -904,7 +904,7 @@ ReturnedValue QtObject::method_btoa(CallContext *ctx) /*! \qmlmethod string Qt::atob(data) -ASCII to binary - this function returns a base64 decoding of \c data. +ASCII to binary - this function decodes the base64 encoded \a data string and returns it. */ ReturnedValue QtObject::method_atob(CallContext *ctx) { @@ -1468,9 +1468,6 @@ QV4::ReturnedValue ConsoleObject::method_profile(CallContext *ctx) { QV4::ExecutionEngine *v4 = ctx->d()->engine; - if (!v4->qmlEngine()) - return QV4::Encode::undefined(); // Not yet implemented for JavaScript. - QV4::StackFrame frame = v4->currentStackFrame(); const QByteArray baSource = frame.source.toUtf8(); const QByteArray baFunction = frame.function.toUtf8(); @@ -1479,7 +1476,7 @@ QV4::ReturnedValue ConsoleObject::method_profile(CallContext *ctx) if (!service) { logger.warning("Cannot start profiling because debug service is disabled. Start with -qmljsdebugger=port:XXXXX."); } else { - service->startProfiling(v4->qmlEngine()); + service->startProfiling(v4->jsEngine()); logger.debug("Profiling started."); } @@ -1490,9 +1487,6 @@ QV4::ReturnedValue ConsoleObject::method_profileEnd(CallContext *ctx) { QV4::ExecutionEngine *v4 = ctx->d()->engine; - if (!v4->qmlEngine()) - return QV4::Encode::undefined(); // Not yet implemented for JavaScript. - QV4::StackFrame frame = v4->currentStackFrame(); const QByteArray baSource = frame.source.toUtf8(); const QByteArray baFunction = frame.function.toUtf8(); @@ -1502,7 +1496,7 @@ QV4::ReturnedValue ConsoleObject::method_profileEnd(CallContext *ctx) if (!service) { logger.warning("Ignoring console.profileEnd(): the debug service is disabled."); } else { - service->stopProfiling(v4->qmlEngine()); + service->stopProfiling(v4->jsEngine()); logger.debug("Profiling ended."); } diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h index d373fb6ee6..3eb3b5037f 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h +++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h @@ -52,7 +52,6 @@ QT_BEGIN_NAMESPACE class QQmlEngine; -class QV8Engine; namespace QV4 { diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index 552470c88c..a2ccc5f3b0 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -113,7 +113,6 @@ namespace QV4 { // The QQmlV8Function - and consequently the arguments and return value - only remains // valid during the call. If the return value isn't set within myMethod(), the will return // undefined. -class QV8Engine; class QQmlV4Function { diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp index 6a93410ecb..5f69bf5f94 100644 --- a/src/qml/types/qqmlconnections.cpp +++ b/src/qml/types/qqmlconnections.cpp @@ -51,11 +51,12 @@ QT_BEGIN_NAMESPACE class QQmlConnectionsPrivate : public QObjectPrivate { public: - QQmlConnectionsPrivate() : target(0), targetSet(false), ignoreUnknownSignals(false), componentcomplete(true) {} + QQmlConnectionsPrivate() : target(0), enabled(true), targetSet(false), ignoreUnknownSignals(false), componentcomplete(true) {} QList<QQmlBoundSignal*> boundsignals; QObject *target; + bool enabled; bool targetSet; bool ignoreUnknownSignals; bool componentcomplete; @@ -177,6 +178,34 @@ void QQmlConnections::setTarget(QObject *obj) } /*! + \qmlproperty bool QtQml::Connections::enabled + \since 5.7 + + This property holds whether the item accepts change events. + + By default, this property is \c true. +*/ +bool QQmlConnections::isEnabled() const +{ + Q_D(const QQmlConnections); + return d->enabled; +} + +void QQmlConnections::setEnabled(bool enabled) +{ + Q_D(QQmlConnections); + if (d->enabled == enabled) + return; + + d->enabled = enabled; + + foreach (QQmlBoundSignal *s, d->boundsignals) + s->setEnabled(d->enabled); + + emit enabledChanged(); +} + +/*! \qmlproperty bool QtQml::Connections::ignoreUnknownSignals Normally, a connection to a non-existent signal produces runtime errors. diff --git a/src/qml/types/qqmlconnections_p.h b/src/qml/types/qqmlconnections_p.h index 234c5061a7..d330b772cc 100644 --- a/src/qml/types/qqmlconnections_p.h +++ b/src/qml/types/qqmlconnections_p.h @@ -63,6 +63,7 @@ class Q_AUTOTEST_EXPORT QQmlConnections : public QObject, public QQmlParserStatu Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(QObject *target READ target WRITE setTarget NOTIFY targetChanged) + Q_REVISION(1) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) Q_PROPERTY(bool ignoreUnknownSignals READ ignoreUnknownSignals WRITE setIgnoreUnknownSignals) public: @@ -72,11 +73,15 @@ public: QObject *target() const; void setTarget(QObject *); + bool isEnabled() const; + void setEnabled(bool enabled); + bool ignoreUnknownSignals() const; void setIgnoreUnknownSignals(bool ignore); Q_SIGNALS: void targetChanged(); + Q_REVISION(1) void enabledChanged(); private: void connectSignals(); diff --git a/src/qml/types/qqmllistmodelworkeragent.cpp b/src/qml/types/qqmllistmodelworkeragent.cpp index 76aab248bc..bcf9cd94f7 100644 --- a/src/qml/types/qqmllistmodelworkeragent.cpp +++ b/src/qml/types/qqmllistmodelworkeragent.cpp @@ -161,9 +161,7 @@ void QQmlListModelWorkerAgent::move(int from, int to, int count) void QQmlListModelWorkerAgent::sync() { - Sync *s = new Sync; - s->data = data; - s->list = m_copy; + Sync *s = new Sync(data, m_copy); data.changes.clear(); mutex.lock(); diff --git a/src/qml/types/qqmllistmodelworkeragent_p.h b/src/qml/types/qqmllistmodelworkeragent_p.h index be5217eaa4..76603e4a8e 100644 --- a/src/qml/types/qqmllistmodelworkeragent_p.h +++ b/src/qml/types/qqmllistmodelworkeragent_p.h @@ -129,7 +129,11 @@ private: Data data; struct Sync : public QEvent { - Sync() : QEvent(QEvent::User) {} + Sync(const Data &d, QQmlListModel *l) + : QEvent(QEvent::User) + , data(d) + , list(l) + {} Data data; QQmlListModel *list; }; |