diff options
Diffstat (limited to 'src/declarative/debugger/qv8debugservice.cpp')
-rw-r--r-- | src/declarative/debugger/qv8debugservice.cpp | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/src/declarative/debugger/qv8debugservice.cpp b/src/declarative/debugger/qv8debugservice.cpp new file mode 100644 index 0000000000..0358d082d3 --- /dev/null +++ b/src/declarative/debugger/qv8debugservice.cpp @@ -0,0 +1,209 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qv8debugservice_p.h" +#include "qdeclarativedebugservice_p_p.h" +#include "qv8debug_p.h" +#include "qv8engine_p.h" +#include "qdeclarativeengine_p.h" + +#include <QtCore/QEventLoop> +#include <QtCore/QHash> +#include <QtCore/QFileInfo> + +QT_BEGIN_NAMESPACE + +Q_GLOBAL_STATIC(QV8DebugService, v8ServiceInstance) + +void DebugMessageHandler(const v8::Debug::Message& message) +{ + v8::DebugEvent event = message.GetEvent(); + if (event != v8::Break && event != v8::Exception && event != v8::AfterCompile) { + return; + } + + QByteArray response(QV8Engine::toStringStatic(message.GetJSON()).toUtf8()); + + QV8DebugService *service = QV8DebugService::instance(); + service->debugMessageHandler(response); + + if (event == v8::Break && !message.WillStartRunning()) { + service->executionStopped(); + } else if (event == v8::AfterCompile) { + service->appendSourcePath(response); + } //TODO::v8::Exception +} + +class QV8DebugServicePrivate : public QDeclarativeDebugServicePrivate +{ +public: + QJSEngine engine; + QList<QDeclarativeEngine *> engines; + QEventLoop loop; + QHash<QString,QString> sourcePath; +}; + +QV8DebugService::QV8DebugService(QObject *parent) + : QDeclarativeDebugService(*(new QV8DebugServicePrivate()),QLatin1String("V8Debugger"), parent) +{ + v8::Debug::SetMessageHandler2(DebugMessageHandler); +} + +QV8DebugService::~QV8DebugService() +{ +} + +QV8DebugService *QV8DebugService::instance() +{ + return v8ServiceInstance(); +} + +void QV8DebugService::addEngine(QDeclarativeEngine *engine) +{ + Q_D(QV8DebugService); + Q_ASSERT(engine); + Q_ASSERT(!d->engines.contains(engine)); + + d->engines.append(engine); +} + +void QV8DebugService::removeEngine(QDeclarativeEngine *engine) +{ + Q_D(QV8DebugService); + Q_ASSERT(engine); + Q_ASSERT(d->engines.contains(engine)); + + d->engines.removeAll(engine); +} + +void QV8DebugService::debugMessageHandler(QByteArray message) +{ + sendMessage(packMessage(message)); +} + +void QV8DebugService::executionStopped() +{ + Q_D(QV8DebugService); + + d->loop.exec(QEventLoop::ExcludeUserInputEvents); +} + +void QV8DebugService::appendSourcePath(QByteArray message) +{ + Q_D(QV8DebugService); + + QVariantMap msgMap; + { + QString msg(message); + QJSValue parser = d->engine.evaluate("JSON.parse"); + QJSValue out = parser.call(QJSValue(),QJSValueList() << QJSValue(msg)); + msgMap = out.toVariant().toMap(); + } + + QString sourcePath(msgMap.value("body").toMap().value("script").toMap().value("name").toString()); + QString fileName(QFileInfo(sourcePath).fileName()); + + d->sourcePath.insert(fileName,sourcePath); +} + +void QV8DebugService::messageReceived(const QByteArray &message) +{ + Q_D(QV8DebugService); + + QDataStream ds(message); + QByteArray command; + ds >> command; + + if (command == "V8DEBUG") { + QByteArray request; + ds >> request; + + QVariantMap reqMap; + { + QString req(request); + QJSValue parser = d->engine.evaluate("JSON.parse"); + QJSValue out = parser.call(QJSValue(),QJSValueList() << QJSValue(req)); + reqMap = out.toVariant().toMap(); + } + + QString debugCommand(reqMap.value("command").toString()); + + if (debugCommand == QString("interrupt")) { + v8::Debug::DebugBreak(); + + } else { + if (debugCommand == QString("setbreakpoint")){ + QVariantMap arguments = reqMap.value("arguments").toMap(); + QString type(arguments.value("type").toString()); + if (type == QString("script")) { + QString fileName(arguments.value("target").toString()); + QString filePath = d->sourcePath.value(fileName); + request.replace(fileName.toUtf8(),filePath.toUtf8()); + } + } + sendDebugMessage(request); + } + } + + QDeclarativeDebugService::messageReceived(message); +} + +void QV8DebugService::sendDebugMessage(const QByteArray &msg) +{ + Q_D(QV8DebugService); + + QString message(msg); + if (d->loop.isRunning()) { + d->loop.exit(); + } + v8::Debug::SendCommand(message.utf16(), message.size()); +} + +QByteArray QV8DebugService::packMessage(QByteArray &message) +{ + QByteArray reply; + QDataStream rs(&reply, QIODevice::WriteOnly); + QByteArray cmd = "V8DEBUG"; + rs << cmd << message; + return reply; +} + +QT_END_NAMESPACE |