diff options
author | Aurindam Jana <aurindam.jana@digia.com> | 2013-09-10 16:57:45 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-19 21:40:49 +0200 |
commit | 353a068c7716a34eb90d1441893f4c4a5b28f9de (patch) | |
tree | 1c7cbaa262b10ae5dc14d9e8ab3f7a4732217bb2 /src | |
parent | 0b901ddda7936bb535125beaccc5fb9ee12617cb (diff) |
QmlDebugging: Replace QV8DebugService with QV4DebugService
Change-Id: Ic8c99e3984d9ef6d122f7d8834df97eeb1f1fda3
Reviewed-by: Kai Koehne <kai.koehne@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/debugger/debugger.pri | 2 | ||||
-rw-r--r-- | src/qml/debugger/qv4debugservice.cpp | 47 | ||||
-rw-r--r-- | src/qml/debugger/qv4debugservice_p.h | 2 | ||||
-rw-r--r-- | src/qml/debugger/qv8debugservice.cpp | 303 | ||||
-rw-r--r-- | src/qml/debugger/qv8debugservice_p.h | 107 | ||||
-rw-r--r-- | src/qml/qml/qqmlboundsignal.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 6 |
7 files changed, 52 insertions, 419 deletions
diff --git a/src/qml/debugger/debugger.pri b/src/qml/debugger/debugger.pri index 09749b73da..c10f43c8c9 100644 --- a/src/qml/debugger/debugger.pri +++ b/src/qml/debugger/debugger.pri @@ -3,7 +3,6 @@ SOURCES += \ $$PWD/qqmlprofilerservice.cpp \ $$PWD/qqmldebugserver.cpp \ $$PWD/qqmlinspectorservice.cpp \ - $$PWD/qv8debugservice.cpp \ $$PWD/qv8profilerservice.cpp \ $$PWD/qqmlenginedebugservice.cpp \ $$PWD/qdebugmessageservice.cpp \ @@ -18,7 +17,6 @@ HEADERS += \ $$PWD/qqmldebugstatesdelegate_p.h \ $$PWD/qqmlinspectorservice_p.h \ $$PWD/qqmlinspectorinterface_p.h \ - $$PWD/qv8debugservice_p.h \ $$PWD/qv8profilerservice_p.h \ $$PWD/qqmlenginedebugservice_p.h \ $$PWD/qqmldebug.h \ diff --git a/src/qml/debugger/qv4debugservice.cpp b/src/qml/debugger/qv4debugservice.cpp index 9415cc4d31..10aefbfd13 100644 --- a/src/qml/debugger/qv4debugservice.cpp +++ b/src/qml/debugger/qv4debugservice.cpp @@ -47,7 +47,8 @@ #include <private/qv8engine_p.h> -const char *V4_DEBUGGER_KEY_CONNECT = "connect"; +const char *V4_CONNECT = "connect"; +const char *V4_BREAK_ON_SIGNAL = "breakonsignal"; QT_BEGIN_NAMESPACE @@ -64,9 +65,20 @@ class QV4DebugServicePrivate : public QQmlDebugServicePrivate Q_DECLARE_PUBLIC(QV4DebugService) public: + static QByteArray packMessage(const QString &type, const QString &message = QString()) + { + QByteArray reply; + QQmlDebugStream rs(&reply, QIODevice::WriteOnly); + QByteArray cmd("V4DEBUG"); + rs << cmd << type.toUtf8() << message.toUtf8(); + return reply; + } + QMutex initializeMutex; QWaitCondition initializeCondition; QV4DebuggerAgent debuggerAgent; + + QStringList breakOnSignals; }; QV4DebugService::QV4DebugService(QObject *parent) @@ -122,6 +134,25 @@ void QV4DebugService::removeEngine(const QV4::ExecutionEngine *engine) d->debuggerAgent.removeDebugger(engine->debugger); } +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) { + if (signal == signalName) { + // TODO: pause debugger + break; + } + } +} + void QV4DebugService::stateChanged(QQmlDebugService::State newState) { Q_D(QV4DebugService); @@ -148,9 +179,21 @@ void QV4DebugService::messageReceived(const QByteArray &message) QByteArray data; ds >> command >> data; - if (command == V4_DEBUGGER_KEY_CONNECT) { + if (command == V4_CONNECT) { // wake up constructor in blocking mode d->initializeCondition.wakeAll(); + } else if (command == V4_BREAK_ON_SIGNAL) { + QQmlDebugStream rs(data); + QByteArray signal; + bool enabled; + rs >> signal >> enabled; + //Normalize to lower case. + QString signalName(QString::fromUtf8(signal).toLower()); + if (enabled) + d->breakOnSignals.append(signalName); + else + d->breakOnSignals.removeOne(signalName); + sendMessage(QV4DebugServicePrivate::packMessage(QLatin1String(V4_BREAK_ON_SIGNAL))); } } } diff --git a/src/qml/debugger/qv4debugservice_p.h b/src/qml/debugger/qv4debugservice_p.h index 14164b1237..c355a514e6 100644 --- a/src/qml/debugger/qv4debugservice_p.h +++ b/src/qml/debugger/qv4debugservice_p.h @@ -75,6 +75,8 @@ public: void addEngine(const QV4::ExecutionEngine *engine); void removeEngine(const QV4::ExecutionEngine *engine); + void signalEmitted(const QString &signal); + protected: void stateChanged(State newState); void messageReceived(const QByteArray &); diff --git a/src/qml/debugger/qv8debugservice.cpp b/src/qml/debugger/qv8debugservice.cpp deleted file mode 100644 index 2195dad089..0000000000 --- a/src/qml/debugger/qv8debugservice.cpp +++ /dev/null @@ -1,303 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv8debugservice_p.h" -#include "qqmldebugservice_p_p.h" -#include <private/qv8engine_p.h> - -#include <QtCore/QHash> -#include <QtCore/QFileInfo> -#include <QtCore/QMutex> -#include <QtCore/QWaitCondition> - -//V8 DEBUG SERVICE PROTOCOL -// <HEADER><COMMAND><DATA> -// <HEADER> : "V8DEBUG" -// <COMMAND> : ["connect", "disconnect", "interrupt", -// "v8request", "v8message", "breakonsignal", -// "breakaftercompile"] -// <DATA> : connect, disconnect, interrupt: empty -// v8request, v8message: <JSONrequest_string> -// breakonsignal: <signalname_string><enabled_bool> -// breakaftercompile: <enabled_bool> - -const char *V8_DEBUGGER_KEY_VERSION = "version"; -const char *V8_DEBUGGER_KEY_CONNECT = "connect"; -const char *V8_DEBUGGER_KEY_INTERRUPT = "interrupt"; -const char *V8_DEBUGGER_KEY_DISCONNECT = "disconnect"; -const char *V8_DEBUGGER_KEY_REQUEST = "v8request"; -const char *V8_DEBUGGER_KEY_V8MESSAGE = "v8message"; -const char *V8_DEBUGGER_KEY_BREAK_ON_SIGNAL = "breakonsignal"; - -QT_BEGIN_NAMESPACE - -struct SignalHandlerData -{ - QString functionName; - bool enabled; -}; - -Q_GLOBAL_STATIC(QV8DebugService, v8ServiceInstance) - -// DebugMessageHandler will call back already when the QV8DebugService constructor is -// running, we therefore need a plain pointer. -static QV8DebugService *v8ServiceInstancePtr = 0; - -void DebugMessageDispatchHandler() -{ - QMetaObject::invokeMethod(v8ServiceInstancePtr, "processDebugMessages", Qt::QueuedConnection); -} - -/* ### FIXME: v4 -void DebugMessageHandler(const v8::Debug::Message& message) -{ - v8::DebugEvent event = message.GetEvent(); - - if (message.IsEvent()) { - if (event == v8::AfterCompile || event == v8::BeforeCompile) - return; - } else if (event != v8::Break && event != v8::Exception && - event != v8::AfterCompile && event != v8::BeforeCompile) { - return; - } - - v8ServiceInstancePtr->debugMessageHandler(QJSConverter::toString(message.GetJSON())); -} -*/ - -class QV8DebugServicePrivate : public QQmlDebugServicePrivate -{ -public: - QV8DebugServicePrivate() - : engine(0) - { - } - - void initializeDebuggerThread(); - - static QByteArray packMessage(const QString &type, const QString &message = QString()); - - QMutex initializeMutex; - QWaitCondition initializeCondition; - QStringList breakOnSignals; - const QV8Engine *engine; -}; - -QV8DebugService::QV8DebugService(QObject *parent) - : QQmlDebugService(*(new QV8DebugServicePrivate()), - QStringLiteral("V8Debugger"), 2, parent) -{ - Q_D(QV8DebugService); - v8ServiceInstancePtr = this; - // don't execute stateChanged, messageReceived in parallel - QMutexLocker lock(&d->initializeMutex); - - if (registerService() == Enabled) { - init(); - if (blockingMode()) - d->initializeCondition.wait(&d->initializeMutex); - } -} - -QV8DebugService::~QV8DebugService() -{ -} - -QV8DebugService *QV8DebugService::instance() -{ - return v8ServiceInstance(); -} - -void QV8DebugService::addEngine(const QV8Engine *engine) -{ - // just make sure that the service is properly registered - v8ServiceInstance()->setEngine(engine); -} - -void QV8DebugService::removeEngine(const QV8Engine *engine) -{ - if (v8ServiceInstance()->d_func()->engine == engine) - v8ServiceInstance()->setEngine(0); -} - -void QV8DebugService::setEngine(const QV8Engine *engine) -{ - Q_D(QV8DebugService); - - d->engine = engine; -} - -void QV8DebugService::debugMessageHandler(const QString &message) -{ - sendMessage(QV8DebugServicePrivate::packMessage(QLatin1String(V8_DEBUGGER_KEY_V8MESSAGE), message)); -} - -void QV8DebugService::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(QV8DebugService); - - //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) { - if (signal == signalName) { - scheduledDebugBreak(true); - break; - } - } -} - -// executed in the gui thread -void QV8DebugService::init() -{ -#if 0 // ### FIXME: v4 - Q_D(QV8DebugService); - if (!d->debugIsolate) - d->debugIsolate = v8::Isolate::GetCurrent(); - v8::Debug::SetMessageHandler2(DebugMessageHandler); - v8::Debug::SetDebugMessageDispatchHandler(DebugMessageDispatchHandler); - QV4Compiler::enableV4(false); -#endif -} - -// executed in the gui thread -void QV8DebugService::scheduledDebugBreak(bool schedule) -{ -// ### FIXME: v4 -// if (schedule) -// v8::Debug::DebugBreak(); -// else -// v8::Debug::CancelDebugBreak(); -} - -// executed in the debugger thread -void QV8DebugService::stateChanged(QQmlDebugService::State newState) -{ - Q_D(QV8DebugService); - QMutexLocker lock(&d->initializeMutex); - - if (newState == Enabled) { - // execute in GUI thread, bock to make sure messageReceived isn't called - // before it finished. - QMetaObject::invokeMethod(this, "init", Qt::BlockingQueuedConnection); - } else { - // wake up constructor in blocking mode - // (we might got disabled before first message arrived) - d->initializeCondition.wakeAll(); - } -} - -// executed in the debugger thread -void QV8DebugService::messageReceived(const QByteArray &message) -{ - Q_D(QV8DebugService); - QMutexLocker lock(&d->initializeMutex); - - QQmlDebugStream ds(message); - QByteArray header; - ds >> header; - - if (header == "V8DEBUG") { - QByteArray command; - QByteArray data; - ds >> command >> data; - - if (command == V8_DEBUGGER_KEY_CONNECT) { - sendMessage(QV8DebugServicePrivate::packMessage(QLatin1String(V8_DEBUGGER_KEY_CONNECT))); - // wake up constructor in blocking mode - d->initializeCondition.wakeAll(); - } else if (command == V8_DEBUGGER_KEY_INTERRUPT) { - // break has to be executed in gui thread - QMetaObject::invokeMethod(this, "scheduledDebugBreak", Qt::QueuedConnection, Q_ARG(bool, true)); - sendMessage(QV8DebugServicePrivate::packMessage(QLatin1String(V8_DEBUGGER_KEY_INTERRUPT))); - - } else if (command == V8_DEBUGGER_KEY_DISCONNECT) { - // cancel break has to be executed in gui thread - QMetaObject::invokeMethod(this, "scheduledDebugBreak", Qt::QueuedConnection, Q_ARG(bool, false)); - sendDebugMessage(QString::fromUtf8(data)); - - } else if (command == V8_DEBUGGER_KEY_REQUEST) { - sendDebugMessage(QString::fromUtf8(data)); - - } else if (command == V8_DEBUGGER_KEY_BREAK_ON_SIGNAL) { - QQmlDebugStream rs(data); - QByteArray signal; - bool enabled; - rs >> signal >> enabled; - //Normalize to lower case. - QString signalName(QString::fromUtf8(signal).toLower()); - if (enabled) - d->breakOnSignals.append(signalName); - else - d->breakOnSignals.removeOne(signalName); - sendMessage(QV8DebugServicePrivate::packMessage(QLatin1String(V8_DEBUGGER_KEY_BREAK_ON_SIGNAL))); - } - } -} - -void QV8DebugService::sendDebugMessage(const QString &message) -{ -#if 0 // ### FIXME: v4 - Q_D(QV8DebugService); - v8::Debug::SendCommand(message.utf16(), message.size(), 0, d->debugIsolate); -#endif -} - -void QV8DebugService::processDebugMessages() -{ - Q_D(QV8DebugService); -// ### FIXME: v4 v8::Debug::ProcessDebugMessages(); -} - -QByteArray QV8DebugServicePrivate::packMessage(const QString &type, const QString &message) -{ - QByteArray reply; - QQmlDebugStream rs(&reply, QIODevice::WriteOnly); - QByteArray cmd("V8DEBUG"); - rs << cmd << type.toUtf8() << message.toUtf8(); - return reply; -} - -QT_END_NAMESPACE diff --git a/src/qml/debugger/qv8debugservice_p.h b/src/qml/debugger/qv8debugservice_p.h deleted file mode 100644 index 7acb2909ad..0000000000 --- a/src/qml/debugger/qv8debugservice_p.h +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/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 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV8DEBUGSERVICE_P_H -#define QV8DEBUGSERVICE_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" -#ifdef Q_OS_WINCE -# ifdef DebugBreak -# undef DebugBreak -# endif -#endif -#include <private/qv8debug_p.h> - -QT_BEGIN_NAMESPACE - - -class QV8Engine; -class QV8DebugServicePrivate; - -class QV8DebugService : public QQmlDebugService -{ - Q_OBJECT -public: - QV8DebugService(QObject *parent = 0); - ~QV8DebugService(); - - static QV8DebugService *instance(); - static void addEngine(const QV8Engine *engine); - static void removeEngine(const QV8Engine *engine); - - void debugMessageHandler(const QString &message); - - void signalEmitted(const QString &signal); - -public Q_SLOTS: - void processDebugMessages(); - -private Q_SLOTS: - void scheduledDebugBreak(bool schedule); - void sendDebugMessage(const QString &message); - void init(); - -protected: - void stateChanged(State newState); - void messageReceived(const QByteArray &); - -private: - void setEngine(const QV8Engine *engine); - -private: - Q_DISABLE_COPY(QV8DebugService) - Q_DECLARE_PRIVATE(QV8DebugService) -}; - -QT_END_NAMESPACE - -#endif // QV8DEBUGSERVICE_P_H diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index deb93b990d..3242ab9831 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -51,7 +51,7 @@ #include "qqmlcontext.h" #include "qqmlglobal_p.h" #include <private/qqmlprofilerservice_p.h> -#include <private/qv8debugservice_p.h> +#include <private/qv4debugservice_p.h> #include "qqmlinfo.h" #include <private/qv4value_p.h> @@ -330,7 +330,7 @@ void QQmlBoundSignal_callback(QQmlNotifierEndpoint *e, void **a) return; if (QQmlDebugService::isDebuggingEnabled()) - QV8DebugService::instance()->signalEmitted(QString::fromLatin1(QMetaObjectPrivate::signal(s->m_expression->target()->metaObject(), s->m_index).methodSignature())); + QV4DebugService::instance()->signalEmitted(QString::fromLatin1(QMetaObjectPrivate::signal(s->m_expression->target()->metaObject(), s->m_index).methodSignature())); QQmlHandlingSignalProfiler prof(s->m_expression); diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 81e20e269c..274952cb12 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -63,7 +63,7 @@ #include "qqmltypenamecache_p.h" #include "qqmlnotifier_p.h" #include <private/qqmlprofilerservice_p.h> -#include <private/qv8debugservice_p.h> +#include <private/qv4debugservice_p.h> #include <private/qdebugmessageservice_p.h> #include "qqmlincubator.h" #include "qqmlabstracturlinterceptor.h" @@ -794,7 +794,7 @@ void QQmlEnginePrivate::init() QQmlEngineDebugService::isDebuggingEnabled()) { isDebugging = true; QQmlEngineDebugService::instance()->addEngine(q); - QV8DebugService::addEngine(v8engine()); + QV4DebugService::addEngine(q); QV8ProfilerService::initialize(); QQmlProfilerService::initialize(); QDebugMessageService::instance(); @@ -883,7 +883,7 @@ QQmlEngine::~QQmlEngine() Q_D(QQmlEngine); if (d->isDebugging) { QQmlEngineDebugService::instance()->remEngine(this); - QV8DebugService::removeEngine(handle()); + QV4DebugService::removeEngine(this); } // Emit onDestruction signals for the root context before |