aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/debugger/debugger.pri2
-rw-r--r--src/qml/debugger/qdebugmessageservice.cpp45
-rw-r--r--src/qml/debugger/qdebugmessageservice_p.h6
-rw-r--r--src/qml/debugger/qqmlconfigurabledebugservice.cpp39
-rw-r--r--src/qml/debugger/qqmlconfigurabledebugservice_p.h16
-rw-r--r--src/qml/debugger/qqmlconfigurabledebugservice_p_p.h71
-rw-r--r--src/qml/debugger/qqmldebugserver.cpp1
-rw-r--r--src/qml/debugger/qqmldebugservice.cpp32
-rw-r--r--src/qml/debugger/qqmldebugservice_p.h3
-rw-r--r--src/qml/debugger/qqmldebugservice_p_p.h70
-rw-r--r--src/qml/debugger/qqmlprofilerservice.cpp22
-rw-r--r--src/qml/debugger/qv4debugservice.cpp501
-rw-r--r--src/qml/debugger/qv4debugservice_p.h63
13 files changed, 343 insertions, 528 deletions
diff --git a/src/qml/debugger/debugger.pri b/src/qml/debugger/debugger.pri
index cbb1646ff6..b3e3b3fc90 100644
--- a/src/qml/debugger/debugger.pri
+++ b/src/qml/debugger/debugger.pri
@@ -20,7 +20,6 @@ HEADERS += \
$$PWD/qqmldebugconnector_p.h \
$$PWD/qqmldebugpluginmanager_p.h \
$$PWD/qqmldebugservice_p.h \
- $$PWD/qqmldebugservice_p_p.h \
$$PWD/qqmlprofilerservice_p.h \
$$PWD/qqmldebugserver_p.h \
$$PWD/qqmldebugserverconnection_p.h \
@@ -32,7 +31,6 @@ HEADERS += \
$$PWD/qdebugmessageservice_p.h \
$$PWD/qv4debugservice_p.h \
$$PWD/qqmlconfigurabledebugservice_p.h \
- $$PWD/qqmlconfigurabledebugservice_p_p.h \
$$PWD/qqmlenginecontrolservice_p.h \
$$PWD/qqmlprofilerdefinitions_p.h \
$$PWD/qqmlabstractprofileradapter_p.h \
diff --git a/src/qml/debugger/qdebugmessageservice.cpp b/src/qml/debugger/qdebugmessageservice.cpp
index 88ef9eb96c..3e5cec54b1 100644
--- a/src/qml/debugger/qdebugmessageservice.cpp
+++ b/src/qml/debugger/qdebugmessageservice.cpp
@@ -32,10 +32,8 @@
****************************************************************************/
#include "qdebugmessageservice_p.h"
-#include "qqmldebugservice_p_p.h"
#include <QDataStream>
-#include <QMutex>
QT_BEGIN_NAMESPACE
@@ -47,29 +45,15 @@ void DebugMessageHandler(QtMsgType type, const QMessageLogContext &ctxt,
QDebugMessageService::instance()->sendDebugMessage(type, ctxt, buf);
}
-class QDebugMessageServicePrivate : public QQmlDebugServicePrivate
-{
-public:
- QDebugMessageServicePrivate() : QQmlDebugServicePrivate(QStringLiteral("DebugMessages"), 2),
- oldMsgHandler(0), prevState(QQmlDebugService::NotConnected)
- {
- }
-
- QtMessageHandler oldMsgHandler;
- QQmlDebugService::State prevState;
- QMutex initMutex;
-};
-
QDebugMessageService::QDebugMessageService(QObject *parent) :
- QQmlDebugService(*(new QDebugMessageServicePrivate), parent)
+ QQmlDebugService(QStringLiteral("DebugMessages"), 2, parent), oldMsgHandler(0),
+ prevState(QQmlDebugService::NotConnected)
{
- Q_D(QDebugMessageService);
-
// don't execute stateChanged() in parallel
- QMutexLocker lock(&d->initMutex);
+ QMutexLocker lock(&initMutex);
if (state() == Enabled) {
- d->oldMsgHandler = qInstallMessageHandler(DebugMessageHandler);
- d->prevState = Enabled;
+ oldMsgHandler = qInstallMessageHandler(DebugMessageHandler);
+ prevState = Enabled;
}
}
@@ -82,8 +66,6 @@ void QDebugMessageService::sendDebugMessage(QtMsgType type,
const QMessageLogContext &ctxt,
const QString &buf)
{
- Q_D(QDebugMessageService);
-
//We do not want to alter the message handling mechanism
//We just eavesdrop and forward the messages to a port
//only if a client is connected to it.
@@ -94,26 +76,25 @@ void QDebugMessageService::sendDebugMessage(QtMsgType type,
ws << ctxt.line << QString::fromLatin1(ctxt.function).toUtf8();
emit messageToClient(name(), message);
- if (d->oldMsgHandler)
- (*d->oldMsgHandler)(type, ctxt, buf);
+ if (oldMsgHandler)
+ (*oldMsgHandler)(type, ctxt, buf);
}
void QDebugMessageService::stateChanged(State state)
{
- Q_D(QDebugMessageService);
- QMutexLocker lock(&d->initMutex);
+ QMutexLocker lock(&initMutex);
- if (state != Enabled && d->prevState == Enabled) {
- QtMessageHandler handler = qInstallMessageHandler(d->oldMsgHandler);
+ if (state != Enabled && prevState == Enabled) {
+ QtMessageHandler handler = qInstallMessageHandler(oldMsgHandler);
// has our handler been overwritten in between?
if (handler != DebugMessageHandler)
qInstallMessageHandler(handler);
- } else if (state == Enabled && d->prevState != Enabled) {
- d->oldMsgHandler = qInstallMessageHandler(DebugMessageHandler);
+ } else if (state == Enabled && prevState != Enabled) {
+ oldMsgHandler = qInstallMessageHandler(DebugMessageHandler);
}
- d->prevState = state;
+ prevState = state;
}
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qdebugmessageservice_p.h b/src/qml/debugger/qdebugmessageservice_p.h
index 694cd0e64c..55e92d437f 100644
--- a/src/qml/debugger/qdebugmessageservice_p.h
+++ b/src/qml/debugger/qdebugmessageservice_p.h
@@ -48,6 +48,7 @@
#include "qqmldebugservice_p.h"
#include <QtCore/qlogging.h>
+#include <QtCore/qmutex.h>
QT_BEGIN_NAMESPACE
@@ -68,8 +69,9 @@ protected:
void stateChanged(State);
private:
- Q_DISABLE_COPY(QDebugMessageService)
- Q_DECLARE_PRIVATE(QDebugMessageService)
+ QtMessageHandler oldMsgHandler;
+ QQmlDebugService::State prevState;
+ QMutex initMutex;
};
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qqmlconfigurabledebugservice.cpp b/src/qml/debugger/qqmlconfigurabledebugservice.cpp
index 9382cea42e..679fa04abe 100644
--- a/src/qml/debugger/qqmlconfigurabledebugservice.cpp
+++ b/src/qml/debugger/qqmlconfigurabledebugservice.cpp
@@ -32,48 +32,32 @@
****************************************************************************/
#include "qqmlconfigurabledebugservice_p.h"
-#include "qqmlconfigurabledebugservice_p_p.h"
#include "qqmldebugconnector_p.h"
QT_BEGIN_NAMESPACE
QQmlConfigurableDebugService::QQmlConfigurableDebugService(const QString &name, float version,
QObject *parent) :
- QQmlDebugService((*new QQmlConfigurableDebugServicePrivate(name, version)), parent)
+ QQmlDebugService(name, version, parent), m_configMutex(QMutex::Recursive)
{
init();
}
-QQmlConfigurableDebugService::QQmlConfigurableDebugService(QQmlDebugServicePrivate &dd,
- QObject *parent) :
- QQmlDebugService(dd, parent)
-{
- init();
-}
-
-QMutex *QQmlConfigurableDebugService::configMutex()
-{
- Q_D(QQmlConfigurableDebugService);
- return &d->configMutex;
-}
-
void QQmlConfigurableDebugService::init()
{
- Q_D(QQmlConfigurableDebugService);
- QMutexLocker lock(&d->configMutex);
+ QMutexLocker lock(&m_configMutex);
// If we're not enabled or not blocking, don't wait for configuration
- d->waitingForConfiguration = (state() == Enabled &&
- QQmlDebugConnector::instance()->blockingMode());
+ m_waitingForConfiguration = (state() == Enabled &&
+ QQmlDebugConnector::instance()->blockingMode());
}
void QQmlConfigurableDebugService::stopWaiting()
{
- Q_D(QQmlConfigurableDebugService);
- QMutexLocker lock(&d->configMutex);
- d->waitingForConfiguration = false;
- foreach (QQmlEngine *engine, d->waitingEngines)
+ QMutexLocker lock(&m_configMutex);
+ m_waitingForConfiguration = false;
+ foreach (QQmlEngine *engine, m_waitingEngines)
emit attachedToEngine(engine);
- d->waitingEngines.clear();
+ m_waitingEngines.clear();
}
void QQmlConfigurableDebugService::stateChanged(QQmlDebugService::State newState)
@@ -86,10 +70,9 @@ void QQmlConfigurableDebugService::stateChanged(QQmlDebugService::State newState
void QQmlConfigurableDebugService::engineAboutToBeAdded(QQmlEngine *engine)
{
- Q_D(QQmlConfigurableDebugService);
- QMutexLocker lock(&d->configMutex);
- if (d->waitingForConfiguration)
- d->waitingEngines.append(engine);
+ QMutexLocker lock(&m_configMutex);
+ if (m_waitingForConfiguration)
+ m_waitingEngines.append(engine);
else
emit attachedToEngine(engine);
}
diff --git a/src/qml/debugger/qqmlconfigurabledebugservice_p.h b/src/qml/debugger/qqmlconfigurabledebugservice_p.h
index c7afcb94dd..28f0f4dfe2 100644
--- a/src/qml/debugger/qqmlconfigurabledebugservice_p.h
+++ b/src/qml/debugger/qqmlconfigurabledebugservice_p.h
@@ -47,31 +47,25 @@
//
#include "qqmldebugservice_p.h"
+#include <QtCore/qmutex.h>
QT_BEGIN_NAMESPACE
-class QMutex;
-class QQmlConfigurableDebugServicePrivate;
class QQmlConfigurableDebugService : public QQmlDebugService
{
Q_OBJECT
-public:
- QQmlConfigurableDebugService(const QString &name, float version, QObject *parent = 0);
-
protected:
- QQmlConfigurableDebugService(QQmlDebugServicePrivate &dd, QObject *parent = 0);
+ QQmlConfigurableDebugService(const QString &name, float version, QObject *parent = 0);
- QMutex *configMutex();
void stopWaiting();
void init();
void stateChanged(State);
void engineAboutToBeAdded(QQmlEngine *);
- virtual ~QQmlConfigurableDebugService() {}
-private:
- Q_DISABLE_COPY(QQmlConfigurableDebugService)
- Q_DECLARE_PRIVATE(QQmlConfigurableDebugService)
+ QMutex m_configMutex;
+ QList<QQmlEngine *> m_waitingEngines;
+ bool m_waitingForConfiguration;
};
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qqmlconfigurabledebugservice_p_p.h b/src/qml/debugger/qqmlconfigurabledebugservice_p_p.h
deleted file mode 100644
index fcdefe3954..0000000000
--- a/src/qml/debugger/qqmlconfigurabledebugservice_p_p.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLCONFIGURABLEDEBUGSERVICE_P_H
-#define QQMLCONFIGURABLEDEBUGSERVICE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qqmldebugservice_p.h"
-#include "qqmldebugservice_p_p.h"
-
-#include <QMutex>
-
-QT_BEGIN_NAMESPACE
-
-class QQmlEngine;
-
-class QQmlConfigurableDebugServicePrivate : public QQmlDebugServicePrivate
-{
- Q_DECLARE_PUBLIC(QQmlConfigurableDebugService)
-public:
- QQmlConfigurableDebugServicePrivate(const QString &name, float version) :
- QQmlDebugServicePrivate(name, version), configMutex(QMutex::Recursive) {}
-
- QMutex configMutex;
- QList<QQmlEngine *> waitingEngines;
- bool waitingForConfiguration;
-};
-
-QT_END_NAMESPACE
-
-#endif // QQMLCONFIGURABLEDEBUGSERVICE_P_H
diff --git a/src/qml/debugger/qqmldebugserver.cpp b/src/qml/debugger/qqmldebugserver.cpp
index a2cb8fd5a1..711550efce 100644
--- a/src/qml/debugger/qqmldebugserver.cpp
+++ b/src/qml/debugger/qqmldebugserver.cpp
@@ -34,7 +34,6 @@
#include "qqmldebugserver_p.h"
#include "qqmldebugserverconnection_p.h"
#include "qqmldebugservice_p.h"
-#include "qqmldebugservice_p_p.h"
#include <private/qqmlengine_p.h>
#include <private/qqmlglobal_p.h>
diff --git a/src/qml/debugger/qqmldebugservice.cpp b/src/qml/debugger/qqmldebugservice.cpp
index edebf7a8cb..3a69799da8 100644
--- a/src/qml/debugger/qqmldebugservice.cpp
+++ b/src/qml/debugger/qqmldebugservice.cpp
@@ -32,7 +32,6 @@
****************************************************************************/
#include "qqmldebugservice_p.h"
-#include "qqmldebugservice_p_p.h"
#include "qqmldebugconnector_p.h"
#include <private/qqmldata_p.h>
#include <private/qqmlcontext_p.h>
@@ -43,6 +42,19 @@
QT_BEGIN_NAMESPACE
+class QQmlDebugServer;
+
+class QQmlDebugServicePrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QQmlDebugService)
+public:
+ QQmlDebugServicePrivate(const QString &name, float version);
+
+ const QString name;
+ const float version;
+ QQmlDebugService::State state;
+};
+
QQmlDebugServicePrivate::QQmlDebugServicePrivate(const QString &name, float version) :
name(name), version(version), state(QQmlDebugService::NotConnected)
{
@@ -51,33 +63,17 @@ QQmlDebugServicePrivate::QQmlDebugServicePrivate(const QString &name, float vers
QQmlDebugService::QQmlDebugService(const QString &name, float version, QObject *parent)
: QObject(*(new QQmlDebugServicePrivate(name, version)), parent)
{
- registerService();
-}
-
-QQmlDebugService::QQmlDebugService(QQmlDebugServicePrivate &dd, QObject *parent)
- : QObject(dd, parent)
-{
- registerService();
-}
-
-/**
- Registers the service. This should be called in the constructor of the inherited class. From
- then on the service might get asynchronous calls to messageReceived().
- */
-QQmlDebugService::State QQmlDebugService::registerService()
-{
Q_D(QQmlDebugService);
QQmlDebugConnector *server = QQmlDebugConnector::instance();
if (!server)
- return NotConnected;
+ return;
if (server->service(d->name)) {
qWarning() << "QQmlDebugService: Conflicting plugin name" << d->name;
} else {
server->addService(this);
}
- return state();
}
QQmlDebugService::~QQmlDebugService()
diff --git a/src/qml/debugger/qqmldebugservice_p.h b/src/qml/debugger/qqmldebugservice_p.h
index 311ce3e355..3d692133cc 100644
--- a/src/qml/debugger/qqmldebugservice_p.h
+++ b/src/qml/debugger/qqmldebugservice_p.h
@@ -87,9 +87,6 @@ public:
protected:
explicit QQmlDebugService(const QString &, float version, QObject *parent = 0);
- QQmlDebugService(QQmlDebugServicePrivate &dd, QObject *parent = 0);
-
- State registerService();
signals:
void attachedToEngine(QQmlEngine *);
diff --git a/src/qml/debugger/qqmldebugservice_p_p.h b/src/qml/debugger/qqmldebugservice_p_p.h
deleted file mode 100644
index e1e93e5e0c..0000000000
--- a/src/qml/debugger/qqmldebugservice_p_p.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLDEBUGSERVICE_P_H
-#define QQMLDEBUGSERVICE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qqmldebugservice_p.h"
-#include <QtCore/qglobal.h>
-#include <private/qobject_p.h>
-
-QT_BEGIN_NAMESPACE
-
-
-class QQmlDebugServer;
-
-class QQmlDebugServicePrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QQmlDebugService)
-public:
- QQmlDebugServicePrivate(const QString &name, float version);
-
- const QString name;
- const float version;
- QQmlDebugService::State state;
-};
-
-QT_END_NAMESPACE
-
-#endif // QQMLDEBUGSERVICE_P_H
diff --git a/src/qml/debugger/qqmlprofilerservice.cpp b/src/qml/debugger/qqmlprofilerservice.cpp
index 62eae0ddd8..dfd9a0cd3b 100644
--- a/src/qml/debugger/qqmlprofilerservice.cpp
+++ b/src/qml/debugger/qqmlprofilerservice.cpp
@@ -63,7 +63,7 @@ QQmlProfilerService::~QQmlProfilerService()
void QQmlProfilerService::dataReady(QQmlAbstractProfilerAdapter *profiler)
{
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
bool dataComplete = true;
for (QMultiMap<qint64, QQmlAbstractProfilerAdapter *>::iterator i(m_startTimes.begin()); i != m_startTimes.end();) {
if (i.value() == profiler) {
@@ -104,7 +104,7 @@ void QQmlProfilerService::engineAboutToBeAdded(QQmlEngine *engine)
Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO,
"QML profilers have to be added from the engine thread");
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
QQmlProfilerAdapter *qmlAdapter = new QQmlProfilerAdapter(this, QQmlEnginePrivate::get(engine));
QV4ProfilerAdapter *v4Adapter = new QV4ProfilerAdapter(this, QV8Engine::getV4(engine->handle()));
addEngineProfiler(qmlAdapter, engine);
@@ -118,7 +118,7 @@ void QQmlProfilerService::engineAdded(QQmlEngine *engine)
Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO,
"QML profilers have to be added from the engine thread");
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
foreach (QQmlAbstractProfilerAdapter *profiler, m_engineProfilers.values(engine))
profiler->stopWaiting();
}
@@ -128,7 +128,7 @@ void QQmlProfilerService::engineAboutToBeRemoved(QQmlEngine *engine)
Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO,
"QML profilers have to be removed from the engine thread");
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
bool isRunning = false;
foreach (QQmlAbstractProfilerAdapter *profiler, m_engineProfilers.values(engine)) {
if (profiler->isRunning())
@@ -148,7 +148,7 @@ void QQmlProfilerService::engineRemoved(QQmlEngine *engine)
Q_ASSERT_X(QThread::currentThread() == engine->thread(), Q_FUNC_INFO,
"QML profilers have to be removed from the engine thread");
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
foreach (QQmlAbstractProfilerAdapter *profiler, m_engineProfilers.values(engine)) {
removeProfilerFromStartTimes(profiler);
delete profiler;
@@ -165,7 +165,7 @@ void QQmlProfilerService::addEngineProfiler(QQmlAbstractProfilerAdapter *profile
void QQmlProfilerService::addGlobalProfiler(QQmlAbstractProfilerAdapter *profiler)
{
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
profiler->synchronize(m_timer);
m_globalProfilers.append(profiler);
// Global profiler, not connected to a specific engine.
@@ -181,7 +181,7 @@ void QQmlProfilerService::addGlobalProfiler(QQmlAbstractProfilerAdapter *profile
void QQmlProfilerService::removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler)
{
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
removeProfilerFromStartTimes(profiler);
m_globalProfilers.removeOne(profiler);
delete profiler;
@@ -208,7 +208,7 @@ void QQmlProfilerService::removeProfilerFromStartTimes(const QQmlAbstractProfile
*/
void QQmlProfilerService::startProfiling(QQmlEngine *engine, quint64 features)
{
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
QByteArray message;
QQmlDebugStream d(&message, QIODevice::WriteOnly);
@@ -257,7 +257,7 @@ void QQmlProfilerService::startProfiling(QQmlEngine *engine, quint64 features)
*/
void QQmlProfilerService::stopProfiling(QQmlEngine *engine)
{
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
QList<QQmlAbstractProfilerAdapter *> stopping;
QList<QQmlAbstractProfilerAdapter *> reporting;
@@ -339,7 +339,7 @@ void QQmlProfilerService::sendMessages()
void QQmlProfilerService::stateAboutToBeChanged(QQmlDebugService::State newState)
{
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
if (state() == newState)
return;
@@ -353,7 +353,7 @@ void QQmlProfilerService::stateAboutToBeChanged(QQmlDebugService::State newState
void QQmlProfilerService::messageReceived(const QByteArray &message)
{
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
QByteArray rwData = message;
QQmlDebugStream stream(&rwData, QIODevice::ReadOnly);
diff --git a/src/qml/debugger/qv4debugservice.cpp b/src/qml/debugger/qv4debugservice.cpp
index 81d4c7b70a..19c06bffeb 100644
--- a/src/qml/debugger/qv4debugservice.cpp
+++ b/src/qml/debugger/qv4debugservice.cpp
@@ -32,9 +32,7 @@
****************************************************************************/
#include "qv4debugservice_p.h"
-#include "qqmlconfigurabledebugservice_p_p.h"
#include "qqmlengine.h"
-#include "qv4debugging_p.h"
#include "qv4engine_p.h"
#include "qv4function_p.h"
#include "qqmldebugconnector_p.h"
@@ -44,7 +42,6 @@
#include <QtCore/QJsonArray>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
-#include <QtCore/QJsonValue>
const char *const V4_CONNECT = "connect";
const char *const V4_DISCONNECT = "disconnect";
@@ -63,41 +60,6 @@ QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QV4DebugService, v4ServiceInstance)
-class QV4DebugServicePrivate;
-
-class QV4DebuggerAgent : public QV4::Debugging::DebuggerAgent
-{
-public:
- QV4DebuggerAgent(QV4DebugServicePrivate *debugServicePrivate)
- : debugServicePrivate(debugServicePrivate)
- {}
-
- QV4::Debugging::Debugger *firstDebugger() const
- {
- // Currently only 1 single engine is supported, so:
- if (m_debuggers.isEmpty())
- return 0;
- else
- return m_debuggers.first();
- }
-
- bool isRunning() const
- {
- // Currently only 1 single engine is supported, so:
- if (QV4::Debugging::Debugger *debugger = firstDebugger())
- return debugger->state() == QV4::Debugging::Debugger::Running;
- else
- return false;
- }
-
-public slots:
- virtual void debuggerPaused(QV4::Debugging::Debugger *debugger, QV4::Debugging::PauseReason reason);
- virtual void sourcesCollected(QV4::Debugging::Debugger *debugger, QStringList sources, int requestSequenceNr);
-
-private:
- QV4DebugServicePrivate *debugServicePrivate;
-};
-
class V8CommandHandler;
class UnknownV8CommandHandler;
@@ -343,164 +305,8 @@ private:
QHash<QV4::Object *, int> objectRefs;
};
-class QV4DebugServicePrivate : public QQmlConfigurableDebugServicePrivate
-{
- Q_DECLARE_PUBLIC(QV4DebugService)
-
-public:
- QV4DebugServicePrivate();
- ~QV4DebugServicePrivate() { qDeleteAll(handlers); }
-
- static QByteArray packMessage(const QByteArray &command, const QByteArray &message = QByteArray())
- {
- QByteArray reply;
- QQmlDebugStream rs(&reply, QIODevice::WriteOnly);
- static const QByteArray cmd("V8DEBUG");
- rs << cmd << command << message;
- return reply;
- }
-
- void send(QJsonObject v8Payload)
- {
- v8Payload[QLatin1String("seq")] = sequence++;
- QJsonDocument doc;
- doc.setObject(v8Payload);
-#ifdef NO_PROTOCOL_TRACING
- QByteArray responseData = doc.toJson(QJsonDocument::Compact);
-#else
- QByteArray responseData = doc.toJson(QJsonDocument::Indented);
-#endif
-
- TRACE_PROTOCOL(qDebug() << "sending response for:" << responseData.constData() << endl);
-
- emit q_func()->messageToClient(name, packMessage("v8message", responseData));
- }
-
- void processCommand(const QByteArray &command, const QByteArray &data);
-
- QV4DebuggerAgent debuggerAgent;
-
- QStringList breakOnSignals;
- QMap<int, QV4::Debugging::Debugger *> debuggerMap;
- static int debuggerIndex;
- static int sequence;
- const int version;
-
- V8CommandHandler *v8CommandHandler(const QString &command) const;
-
- void clearHandles(QV4::ExecutionEngine *engine)
- {
- theCollector.reset(new VariableCollector(engine));
- }
-
- QJsonObject buildFrame(const QV4::StackFrame &stackFrame, int frameNr,
- QV4::Debugging::Debugger *debugger)
- {
- QJsonObject frame;
- frame[QLatin1String("index")] = frameNr;
- frame[QLatin1String("debuggerFrame")] = false;
- frame[QLatin1String("func")] = theCollector->addFunctionRef(stackFrame.function);
- frame[QLatin1String("script")] = theCollector->addScriptRef(stackFrame.source);
- frame[QLatin1String("line")] = stackFrame.line - 1;
- if (stackFrame.column >= 0)
- frame[QLatin1String("column")] = stackFrame.column;
-
- QJsonArray properties;
- theCollector->setDestination(&properties);
- if (debugger->collectThisInContext(theCollector.data(), frameNr)) {
- QJsonObject obj;
- obj[QLatin1String("properties")] = properties;
- frame[QLatin1String("receiver")] = theCollector->addObjectRef(obj, false);
- }
-
- QJsonArray scopes;
- // Only type and index are used by Qt Creator, so we keep it easy:
- QVector<QV4::Heap::ExecutionContext::ContextType> scopeTypes = debugger->getScopeTypes(frameNr);
- for (int i = 0, ei = scopeTypes.count(); i != ei; ++i) {
- int type = encodeScopeType(scopeTypes[i]);
- if (type == -1)
- continue;
-
- QJsonObject scope;
- scope[QLatin1String("index")] = i;
- scope[QLatin1String("type")] = type;
- scopes.push_back(scope);
- }
- frame[QLatin1String("scopes")] = scopes;
-
- return frame;
- }
-
- int encodeScopeType(QV4::Heap::ExecutionContext::ContextType scopeType)
- {
- switch (scopeType) {
- case QV4::Heap::ExecutionContext::Type_GlobalContext:
- return 0;
- break;
- case QV4::Heap::ExecutionContext::Type_CatchContext:
- return 4;
- break;
- case QV4::Heap::ExecutionContext::Type_WithContext:
- return 2;
- break;
- case QV4::Heap::ExecutionContext::Type_SimpleCallContext:
- case QV4::Heap::ExecutionContext::Type_CallContext:
- return 1;
- break;
- case QV4::Heap::ExecutionContext::Type_QmlContext:
- default:
- return -1;
- }
- }
-
- QJsonObject buildScope(int frameNr, int scopeNr, QV4::Debugging::Debugger *debugger)
- {
- QJsonObject scope;
-
- QJsonArray properties;
- theCollector->collectScope(&properties, debugger, frameNr, scopeNr);
-
- QJsonObject anonymous;
- anonymous[QLatin1String("properties")] = properties;
-
- QVector<QV4::Heap::ExecutionContext::ContextType> scopeTypes = debugger->getScopeTypes(frameNr);
- scope[QLatin1String("type")] = encodeScopeType(scopeTypes[scopeNr]);
- scope[QLatin1String("index")] = scopeNr;
- scope[QLatin1String("frameIndex")] = frameNr;
- scope[QLatin1String("object")] = theCollector->addObjectRef(anonymous, true);
-
- return scope;
- }
-
- QJsonValue lookup(int refId) const { return theCollector->lookup(refId); }
-
- QJsonArray buildRefs()
- {
- return theCollector->retrieveRefsToInclude();
- }
-
- VariableCollector *collector() const
- {
- return theCollector.data();
- }
-
- void selectFrame(int frameNr)
- { theSelectedFrame = frameNr; }
-
- int selectedFrame() const
- { return theSelectedFrame; }
-
-private:
- QScopedPointer<VariableCollector> theCollector;
- int theSelectedFrame;
-
- void addHandler(V8CommandHandler* handler);
- QHash<QString, V8CommandHandler*> handlers;
- QScopedPointer<UnknownV8CommandHandler> unknownV8CommandHandler;
-};
-
-int QV4DebugServicePrivate::debuggerIndex = 0;
-int QV4DebugServicePrivate::sequence = 0;
+int QV4DebugService::debuggerIndex = 0;
+int QV4DebugService::sequence = 0;
class V8CommandHandler
{
@@ -514,22 +320,20 @@ public:
QString command() const { return cmd; }
- void handle(const QJsonObject &request, QQmlDebugService *s, QV4DebugServicePrivate *p)
+ void handle(const QJsonObject &request, QV4DebugService *s)
{
TRACE_PROTOCOL(qDebug() << "handling command" << command() << "...");
req = request;
seq = req.value(QStringLiteral("seq"));
debugService = s;
- debugServicePrivate = p;
handleRequest();
if (!response.isEmpty()) {
response[QLatin1String("type")] = QStringLiteral("response");
- debugServicePrivate->send(response);
+ debugService->send(response);
}
- debugServicePrivate = 0;
debugService = 0;
seq = QJsonValue();
req = QJsonObject();
@@ -549,12 +353,12 @@ protected:
void addRunning()
{
- response.insert(QStringLiteral("running"), debugServicePrivate->debuggerAgent.isRunning());
+ response.insert(QStringLiteral("running"), debugService->debuggerAgent.isRunning());
}
void addRefs()
{
- response.insert(QStringLiteral("refs"), debugServicePrivate->buildRefs());
+ response.insert(QStringLiteral("refs"), debugService->buildRefs());
}
void createErrorResponse(const QString &msg)
@@ -574,8 +378,7 @@ protected:
QString cmd;
QJsonObject req;
QJsonValue seq;
- QQmlDebugService *debugService;
- QV4DebugServicePrivate *debugServicePrivate;
+ QV4DebugService *debugService;
QJsonObject response;
};
@@ -646,7 +449,7 @@ public:
QString condition = args.value(QStringLiteral("condition")).toString();
// set the break point:
- int id = debugServicePrivate->debuggerAgent.addBreakPoint(fileName, line + 1, enabled, condition);
+ int id = debugService->debuggerAgent.addBreakPoint(fileName, line + 1, enabled, condition);
// response:
addCommand();
@@ -682,7 +485,7 @@ public:
}
// remove the break point:
- debugServicePrivate->debuggerAgent.removeBreakPoint(id);
+ debugService->debuggerAgent.removeBreakPoint(id);
// response:
addCommand();
@@ -710,12 +513,12 @@ public:
int toFrame = arguments.value(QStringLiteral("toFrame")).toInt(fromFrame + 10);
// no idea what the bottom property is for, so we'll ignore it.
- QV4::Debugging::Debugger *debugger = debugServicePrivate->debuggerAgent.firstDebugger();
+ QV4::Debugging::Debugger *debugger = debugService->debuggerAgent.firstDebugger();
QJsonArray frameArray;
QVector<QV4::StackFrame> frames = debugger->stackTrace(toFrame);
for (int i = fromFrame; i < toFrame && i < frames.size(); ++i)
- frameArray.push_back(debugServicePrivate->buildFrame(frames[i], i, debugger));
+ frameArray.push_back(debugService->buildFrame(frames[i], i, debugger));
// response:
addCommand();
@@ -744,17 +547,18 @@ public:
{
// decypher the payload:
QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
- const int frameNr = arguments.value(QStringLiteral("number")).toInt(debugServicePrivate->selectedFrame());
+ const int frameNr = arguments.value(QStringLiteral("number")).toInt(
+ debugService->selectedFrame());
- QV4::Debugging::Debugger *debugger = debugServicePrivate->debuggerAgent.firstDebugger();
+ QV4::Debugging::Debugger *debugger = debugService->debuggerAgent.firstDebugger();
QVector<QV4::StackFrame> frames = debugger->stackTrace(frameNr + 1);
if (frameNr < 0 || frameNr >= frames.size()) {
createErrorResponse(QStringLiteral("frame command has invalid frame number"));
return;
}
- debugServicePrivate->selectFrame(frameNr);
- QJsonObject frame = debugServicePrivate->buildFrame(frames[frameNr], frameNr, debugger);
+ debugService->selectFrame(frameNr);
+ QJsonObject frame = debugService->buildFrame(frames[frameNr], frameNr, debugger);
// response:
addCommand();
@@ -775,10 +579,11 @@ public:
{
// decypher the payload:
QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
- const int frameNr = arguments.value(QStringLiteral("frameNumber")).toInt(debugServicePrivate->selectedFrame());
+ const int frameNr = arguments.value(QStringLiteral("frameNumber")).toInt(
+ debugService->selectedFrame());
const int scopeNr = arguments.value(QStringLiteral("number")).toInt(0);
- QV4::Debugging::Debugger *debugger = debugServicePrivate->debuggerAgent.firstDebugger();
+ QV4::Debugging::Debugger *debugger = debugService->debuggerAgent.firstDebugger();
QVector<QV4::StackFrame> frames = debugger->stackTrace(frameNr + 1);
if (frameNr < 0 || frameNr >= frames.size()) {
createErrorResponse(QStringLiteral("scope command has invalid frame number"));
@@ -789,7 +594,7 @@ public:
return;
}
- QJsonObject scope = debugServicePrivate->buildScope(frameNr, scopeNr, debugger);
+ QJsonObject scope = debugService->buildScope(frameNr, scopeNr, debugger);
// response:
addCommand();
@@ -814,7 +619,7 @@ public:
QJsonObject body;
foreach (const QJsonValue &handle, handles)
- body[QString::number(handle.toInt())] = debugServicePrivate->lookup(handle.toInt());
+ body[QString::number(handle.toInt())] = debugService->lookup(handle.toInt());
// response:
addCommand();
@@ -836,7 +641,7 @@ public:
// decypher the payload:
QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
- QV4::Debugging::Debugger *debugger = debugServicePrivate->debuggerAgent.firstDebugger();
+ QV4::Debugging::Debugger *debugger = debugService->debuggerAgent.firstDebugger();
if (arguments.empty()) {
debugger->resume(QV4::Debugging::Debugger::FullThrottle);
@@ -874,8 +679,8 @@ public:
virtual void handleRequest()
{
- debugServicePrivate->debuggerAgent.removeAllBreakPoints();
- debugServicePrivate->debuggerAgent.resumeAll();
+ debugService->debuggerAgent.removeAllBreakPoints();
+ debugService->debuggerAgent.resumeAll();
// response:
addCommand();
@@ -892,7 +697,7 @@ public:
virtual void handleRequest()
{
- bool wasEnabled = debugServicePrivate->debuggerAgent.breakOnThrow();
+ bool wasEnabled = debugService->debuggerAgent.breakOnThrow();
//decypher the payload:
QJsonObject arguments = req.value(QStringLiteral("arguments")).toObject();
@@ -910,11 +715,11 @@ public:
}
// do it:
- debugServicePrivate->debuggerAgent.setBreakOnThrow(enabled);
+ debugService->debuggerAgent.setBreakOnThrow(enabled);
QJsonObject body;
body[QLatin1String("type")] = type;
- body[QLatin1String("enabled")] = debugServicePrivate->debuggerAgent.breakOnThrow();
+ body[QLatin1String("enabled")] = debugService->debuggerAgent.breakOnThrow();
// response:
addBody(body);
@@ -944,7 +749,7 @@ public:
}
// do it:
- debugServicePrivate->debuggerAgent.firstDebugger()->gatherSources(requestSequenceNr());
+ debugService->debuggerAgent.firstDebugger()->gatherSources(requestSequenceNr());
// response will be send by
}
@@ -990,10 +795,10 @@ public:
QString expression = arguments.value(QStringLiteral("expression")).toString();
const int frame = arguments.value(QStringLiteral("frame")).toInt(0);
- QV4::Debugging::Debugger *debugger = debugServicePrivate->debuggerAgent.firstDebugger();
+ QV4::Debugging::Debugger *debugger = debugService->debuggerAgent.firstDebugger();
Q_ASSERT(debugger->state() == QV4::Debugging::Debugger::Paused);
- VariableCollector *collector = debugServicePrivate->collector();
+ VariableCollector *collector = debugService->collector();
QJsonArray dest;
collector->setDestination(&dest);
debugger->evaluateExpression(frame, expression, collector);
@@ -1012,8 +817,22 @@ public:
};
} // anonymous namespace
-QV4DebugServicePrivate::QV4DebugServicePrivate() :
- QQmlConfigurableDebugServicePrivate(QStringLiteral("V8Debugger"), 1), debuggerAgent(this),
+void QV4DebugService::addHandler(V8CommandHandler* handler)
+{
+ handlers[handler->command()] = handler;
+}
+
+V8CommandHandler *QV4DebugService::v8CommandHandler(const QString &command) const
+{
+ V8CommandHandler *handler = handlers.value(command, 0);
+ if (handler)
+ return handler;
+ else
+ return unknownV8CommandHandler.data();
+}
+
+QV4DebugService::QV4DebugService(QObject *parent) :
+ QQmlConfigurableDebugService(QStringLiteral("V8Debugger"), 1, parent), debuggerAgent(this),
version(1), theSelectedFrame(0), unknownV8CommandHandler(new UnknownV8CommandHandler)
{
addHandler(new V8VersionRequest);
@@ -1030,26 +849,9 @@ QV4DebugServicePrivate::QV4DebugServicePrivate() :
addHandler(new V8EvaluateRequest);
}
-void QV4DebugServicePrivate::addHandler(V8CommandHandler* handler)
-{
- handlers[handler->command()] = handler;
-}
-
-V8CommandHandler *QV4DebugServicePrivate::v8CommandHandler(const QString &command) const
-{
- V8CommandHandler *handler = handlers.value(command, 0);
- if (handler)
- return handler;
- else
- return unknownV8CommandHandler.data();
-}
-
-QV4DebugService::QV4DebugService(QObject *parent)
- : QQmlConfigurableDebugService(*(new QV4DebugServicePrivate()), parent)
-{}
-
QV4DebugService::~QV4DebugService()
{
+ qDeleteAll(handlers);
}
QV4DebugService *QV4DebugService::instance()
@@ -1059,17 +861,16 @@ QV4DebugService *QV4DebugService::instance()
void QV4DebugService::engineAboutToBeAdded(QQmlEngine *engine)
{
- Q_D(QV4DebugService);
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
if (engine) {
QV4::ExecutionEngine *ee = QV8Engine::getV4(engine->handle());
if (QQmlDebugConnector *server = QQmlDebugConnector::instance()) {
if (ee) {
ee->enableDebugger();
QV4::Debugging::Debugger *debugger = ee->debugger;
- d->debuggerMap.insert(d->debuggerIndex++, debugger);
- d->debuggerAgent.addDebugger(debugger);
- d->debuggerAgent.moveToThread(server->thread());
+ debuggerMap.insert(debuggerIndex++, debugger);
+ debuggerAgent.addDebugger(debugger);
+ debuggerAgent.moveToThread(server->thread());
moveToThread(server->thread());
}
}
@@ -1079,21 +880,20 @@ void QV4DebugService::engineAboutToBeAdded(QQmlEngine *engine)
void QV4DebugService::engineAboutToBeRemoved(QQmlEngine *engine)
{
- Q_D(QV4DebugService);
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
if (engine){
const QV4::ExecutionEngine *ee = QV8Engine::getV4(engine->handle());
if (ee) {
QV4::Debugging::Debugger *debugger = ee->debugger;
typedef QMap<int, QV4::Debugging::Debugger *>::const_iterator DebuggerMapIterator;
- const DebuggerMapIterator end = d->debuggerMap.constEnd();
- for (DebuggerMapIterator i = d->debuggerMap.constBegin(); i != end; ++i) {
+ const DebuggerMapIterator end = debuggerMap.constEnd();
+ for (DebuggerMapIterator i = debuggerMap.constBegin(); i != end; ++i) {
if (i.value() == debugger) {
- d->debuggerMap.remove(i.key());
+ debuggerMap.remove(i.key());
break;
}
}
- d->debuggerAgent.removeDebugger(debugger);
+ debuggerAgent.removeDebugger(debugger);
}
}
QQmlConfigurableDebugService::engineAboutToBeRemoved(engine);
@@ -1104,13 +904,12 @@ void QV4DebugService::signalEmitted(const QString &signal)
//This function is only called by QQmlBoundSignal
//only if there is a slot connected to the signal. Hence, there
//is no need for additional check.
- Q_D(QV4DebugService);
//Parse just the name and remove the class info
//Normalize to Lower case.
QString signalName = signal.left(signal.indexOf(QLatin1Char('('))).toLower();
- foreach (const QString &signal, d->breakOnSignals) {
+ foreach (const QString &signal, breakOnSignals) {
if (signal == signalName) {
// TODO: pause debugger
break;
@@ -1120,8 +919,7 @@ void QV4DebugService::signalEmitted(const QString &signal)
void QV4DebugService::messageReceived(const QByteArray &message)
{
- Q_D(QV4DebugService);
- QMutexLocker lock(configMutex());
+ QMutexLocker lock(&m_configMutex);
QQmlDebugStream ms(message);
QByteArray header;
@@ -1136,10 +934,10 @@ void QV4DebugService::messageReceived(const QByteArray &message)
TRACE_PROTOCOL(qDebug() << "... type:" << type);
if (type == V4_CONNECT) {
- emit messageToClient(name(), d->packMessage(type));
+ emit messageToClient(name(), packMessage(type));
stopWaiting();
} else if (type == V4_PAUSE) {
- d->debuggerAgent.pauseAll();
+ debuggerAgent.pauseAll();
sendSomethingToSomebody(type);
} else if (type == V4_BREAK_ON_SIGNAL) {
QByteArray signal;
@@ -1148,9 +946,9 @@ void QV4DebugService::messageReceived(const QByteArray &message)
//Normalize to lower case.
QString signalName(QString::fromUtf8(signal).toLower());
if (enabled)
- d->breakOnSignals.append(signalName);
+ breakOnSignals.append(signalName);
else
- d->breakOnSignals.removeOne(signalName);
+ breakOnSignals.removeOne(signalName);
} else if (type == "v8request") {
handleV8Request(payload);
} else if (type == V4_DISCONNECT) {
@@ -1164,20 +962,40 @@ void QV4DebugService::messageReceived(const QByteArray &message)
void QV4DebugService::sendSomethingToSomebody(const char *type, int magicNumber)
{
- Q_D(QV4DebugService);
-
QByteArray response;
QQmlDebugStream rs(&response, QIODevice::WriteOnly);
rs << QByteArray(type)
- << QByteArray::number(d->version) << QByteArray::number(magicNumber);
- emit messageToClient(name(), d->packMessage(type, response));
+ << QByteArray::number(version) << QByteArray::number(magicNumber);
+ emit messageToClient(name(), packMessage(type, response));
+}
+
+QV4DebuggerAgent::QV4DebuggerAgent(QV4DebugService *debugService)
+ : debugService(debugService)
+{}
+
+QV4::Debugging::Debugger *QV4DebuggerAgent::firstDebugger() const
+{
+ // Currently only 1 single engine is supported, so:
+ if (m_debuggers.isEmpty())
+ return 0;
+ else
+ return m_debuggers.first();
+}
+
+bool QV4DebuggerAgent::isRunning() const
+{
+ // Currently only 1 single engine is supported, so:
+ if (QV4::Debugging::Debugger *debugger = firstDebugger())
+ return debugger->state() == QV4::Debugging::Debugger::Running;
+ else
+ return false;
}
void QV4DebuggerAgent::debuggerPaused(QV4::Debugging::Debugger *debugger, QV4::Debugging::PauseReason reason)
{
Q_UNUSED(reason);
- debugServicePrivate->clearHandles(debugger->engine());
+ debugService->clearHandles(debugger->engine());
QJsonObject event, body, script;
event.insert(QStringLiteral("type"), QStringLiteral("event"));
@@ -1212,7 +1030,7 @@ void QV4DebuggerAgent::debuggerPaused(QV4::Debugging::Debugger *debugger, QV4::D
body.insert(QStringLiteral("script"), script);
if (!body.isEmpty())
event.insert(QStringLiteral("body"), body);
- debugServicePrivate->send(event);
+ debugService->send(event);
}
void QV4DebuggerAgent::sourcesCollected(QV4::Debugging::Debugger *debugger, QStringList sources, int requestSequenceNr)
@@ -1232,13 +1050,11 @@ void QV4DebuggerAgent::sourcesCollected(QV4::Debugging::Debugger *debugger, QStr
response[QLatin1String("command")] = QStringLiteral("scripts");
response[QLatin1String("request_seq")] = requestSequenceNr;
response[QLatin1String("type")] = QStringLiteral("response");
- debugServicePrivate->send(response);
+ debugService->send(response);
}
void QV4DebugService::handleV8Request(const QByteArray &payload)
{
- Q_D(QV4DebugService);
-
TRACE_PROTOCOL(qDebug() << "v8request, payload:" << payload.constData());
QJsonDocument request = QJsonDocument::fromJson(payload);
@@ -1246,10 +1062,145 @@ void QV4DebugService::handleV8Request(const QByteArray &payload)
QJsonValue type = o.value(QStringLiteral("type"));
if (type.toString() == QStringLiteral("request")) {
QJsonValue command = o.value(QStringLiteral("command"));
- V8CommandHandler *h = d->v8CommandHandler(command.toString());
+ V8CommandHandler *h = v8CommandHandler(command.toString());
if (h)
- h->handle(o, this, d);
+ h->handle(o, this);
+ }
+}
+
+QByteArray QV4DebugService::packMessage(const QByteArray &command, const QByteArray &message)
+{
+ QByteArray reply;
+ QQmlDebugStream rs(&reply, QIODevice::WriteOnly);
+ static const QByteArray cmd("V8DEBUG");
+ rs << cmd << command << message;
+ return reply;
+}
+
+void QV4DebugService::send(QJsonObject v8Payload)
+{
+ v8Payload[QLatin1String("seq")] = sequence++;
+ QJsonDocument doc;
+ doc.setObject(v8Payload);
+#ifdef NO_PROTOCOL_TRACING
+ QByteArray responseData = doc.toJson(QJsonDocument::Compact);
+#else
+ QByteArray responseData = doc.toJson(QJsonDocument::Indented);
+#endif
+
+ TRACE_PROTOCOL(qDebug() << "sending response for:" << responseData.constData() << endl);
+
+ emit messageToClient(name(), packMessage("v8message", responseData));
+}
+
+void QV4DebugService::clearHandles(QV4::ExecutionEngine *engine)
+{
+ theCollector.reset(new VariableCollector(engine));
+}
+
+QJsonObject QV4DebugService::buildFrame(const QV4::StackFrame &stackFrame, int frameNr,
+ QV4::Debugging::Debugger *debugger)
+{
+ QJsonObject frame;
+ frame[QLatin1String("index")] = frameNr;
+ frame[QLatin1String("debuggerFrame")] = false;
+ frame[QLatin1String("func")] = theCollector->addFunctionRef(stackFrame.function);
+ frame[QLatin1String("script")] = theCollector->addScriptRef(stackFrame.source);
+ frame[QLatin1String("line")] = stackFrame.line - 1;
+ if (stackFrame.column >= 0)
+ frame[QLatin1String("column")] = stackFrame.column;
+
+ QJsonArray properties;
+ theCollector->setDestination(&properties);
+ if (debugger->collectThisInContext(theCollector.data(), frameNr)) {
+ QJsonObject obj;
+ obj[QLatin1String("properties")] = properties;
+ frame[QLatin1String("receiver")] = theCollector->addObjectRef(obj, false);
}
+
+ QJsonArray scopes;
+ // Only type and index are used by Qt Creator, so we keep it easy:
+ QVector<QV4::Heap::ExecutionContext::ContextType> scopeTypes = debugger->getScopeTypes(frameNr);
+ for (int i = 0, ei = scopeTypes.count(); i != ei; ++i) {
+ int type = encodeScopeType(scopeTypes[i]);
+ if (type == -1)
+ continue;
+
+ QJsonObject scope;
+ scope[QLatin1String("index")] = i;
+ scope[QLatin1String("type")] = type;
+ scopes.push_back(scope);
+ }
+ frame[QLatin1String("scopes")] = scopes;
+
+ return frame;
+}
+
+int QV4DebugService::encodeScopeType(QV4::Heap::ExecutionContext::ContextType scopeType)
+{
+ switch (scopeType) {
+ case QV4::Heap::ExecutionContext::Type_GlobalContext:
+ return 0;
+ break;
+ case QV4::Heap::ExecutionContext::Type_CatchContext:
+ return 4;
+ break;
+ case QV4::Heap::ExecutionContext::Type_WithContext:
+ return 2;
+ break;
+ case QV4::Heap::ExecutionContext::Type_SimpleCallContext:
+ case QV4::Heap::ExecutionContext::Type_CallContext:
+ return 1;
+ break;
+ case QV4::Heap::ExecutionContext::Type_QmlContext:
+ default:
+ return -1;
+ }
+}
+
+QJsonObject QV4DebugService::buildScope(int frameNr, int scopeNr,
+ QV4::Debugging::Debugger *debugger)
+{
+ QJsonObject scope;
+
+ QJsonArray properties;
+ theCollector->collectScope(&properties, debugger, frameNr, scopeNr);
+
+ QJsonObject anonymous;
+ anonymous[QLatin1String("properties")] = properties;
+
+ QVector<QV4::Heap::ExecutionContext::ContextType> scopeTypes = debugger->getScopeTypes(frameNr);
+ scope[QLatin1String("type")] = encodeScopeType(scopeTypes[scopeNr]);
+ scope[QLatin1String("index")] = scopeNr;
+ scope[QLatin1String("frameIndex")] = frameNr;
+ scope[QLatin1String("object")] = theCollector->addObjectRef(anonymous, true);
+
+ return scope;
+}
+
+QJsonValue QV4DebugService::lookup(int refId) const
+{
+ return theCollector->lookup(refId);
+}
+
+QJsonArray QV4DebugService::buildRefs()
+{
+ return theCollector->retrieveRefsToInclude();
+}
+
+VariableCollector *QV4DebugService::collector() const
+{
+ return theCollector.data();
+}
+
+void QV4DebugService::selectFrame(int frameNr)
+{
+ theSelectedFrame = frameNr;
+}
+
+int QV4DebugService::selectedFrame() const
+{
+ return theSelectedFrame;
}
QT_END_NAMESPACE
diff --git a/src/qml/debugger/qv4debugservice_p.h b/src/qml/debugger/qv4debugservice_p.h
index f7b38b11b6..b824b47b23 100644
--- a/src/qml/debugger/qv4debugservice_p.h
+++ b/src/qml/debugger/qv4debugservice_p.h
@@ -46,12 +46,38 @@
//
#include "qqmlconfigurabledebugservice_p.h"
+#include <private/qv4debugging_p.h>
+
+#include <QtCore/QJsonValue>
QT_BEGIN_NAMESPACE
namespace QV4 { struct ExecutionEngine; }
+
class QQmlEngine;
-class QV4DebugServicePrivate;
+class VariableCollector;
+class V8CommandHandler;
+class UnknownV8CommandHandler;
+class QV4DebugService;
+
+class QV4DebuggerAgent : public QV4::Debugging::DebuggerAgent
+{
+ Q_OBJECT
+public:
+ QV4DebuggerAgent(QV4DebugService *debugService);
+ QV4::Debugging::Debugger *firstDebugger() const;
+ bool isRunning() const;
+
+public slots:
+ virtual void debuggerPaused(QV4::Debugging::Debugger *debugger,
+ QV4::Debugging::PauseReason reason);
+ virtual void sourcesCollected(QV4::Debugging::Debugger *debugger, QStringList sources,
+ int requestSequenceNr);
+
+private:
+ QV4DebugService *debugService;
+};
+
class QV4DebugService : public QQmlConfigurableDebugService
{
@@ -65,6 +91,21 @@ public:
void engineAboutToBeRemoved(QQmlEngine *engine);
void signalEmitted(const QString &signal);
+ void send(QJsonObject v8Payload);
+
+ QJsonObject buildScope(int frameNr, int scopeNr, QV4::Debugging::Debugger *debugger);
+ QJsonArray buildRefs();
+ QJsonValue lookup(int refId) const;
+
+ QJsonObject buildFrame(const QV4::StackFrame &stackFrame, int frameNr,
+ QV4::Debugging::Debugger *debugger);
+ int selectedFrame() const;
+ void selectFrame(int frameNr);
+
+ void clearHandles(QV4::ExecutionEngine *engine);
+
+ VariableCollector *collector() const;
+ QV4DebuggerAgent debuggerAgent;
protected:
void messageReceived(const QByteArray &);
@@ -72,10 +113,24 @@ protected:
private:
void handleV8Request(const QByteArray &payload);
+ static QByteArray packMessage(const QByteArray &command,
+ const QByteArray &message = QByteArray());
+ void processCommand(const QByteArray &command, const QByteArray &data);
+ V8CommandHandler *v8CommandHandler(const QString &command) const;
+ int encodeScopeType(QV4::Heap::ExecutionContext::ContextType scopeType);
-private:
- Q_DISABLE_COPY(QV4DebugService)
- Q_DECLARE_PRIVATE(QV4DebugService)
+ QStringList breakOnSignals;
+ QMap<int, QV4::Debugging::Debugger *> debuggerMap;
+ static int debuggerIndex;
+ static int sequence;
+ const int version;
+
+ QScopedPointer<VariableCollector> theCollector;
+ int theSelectedFrame;
+
+ void addHandler(V8CommandHandler* handler);
+ QHash<QString, V8CommandHandler*> handlers;
+ QScopedPointer<UnknownV8CommandHandler> unknownV8CommandHandler;
};
QT_END_NAMESPACE