diff options
author | Kent Hansen <kent.hansen@nokia.com> | 2012-03-23 14:31:47 +0100 |
---|---|---|
committer | Kent Hansen <kent.hansen@nokia.com> | 2012-03-23 14:31:47 +0100 |
commit | 0655209fdad022bd0f6eb20ce85522cb56506bf0 (patch) | |
tree | cdba0c1590655f5cb75a68cedff74f8a683db3a2 /src/qml/debugger | |
parent | c3babc03c99c6ca5fa210486e133eb456a405bab (diff) | |
parent | 3d8f103c2641f35e7681485102a1b59886db8934 (diff) |
Merge master into api_changes
Conflicts:
src/qml/qml/qqmlboundsignal.cpp
src/qml/qml/qqmlpropertycache.cpp
Change-Id: I5193a193fa301c0b518291645bf626a5fa07118f
Diffstat (limited to 'src/qml/debugger')
-rw-r--r-- | src/qml/debugger/debugger.pri | 2 | ||||
-rw-r--r-- | src/qml/debugger/qpacketprotocol.cpp | 550 | ||||
-rw-r--r-- | src/qml/debugger/qpacketprotocol_p.h | 137 | ||||
-rw-r--r-- | src/qml/debugger/qqmldebugserver.cpp | 35 | ||||
-rw-r--r-- | src/qml/debugger/qqmldebugserverconnection_p.h | 2 | ||||
-rw-r--r-- | src/qml/debugger/qqmlenginedebugservice.cpp | 86 | ||||
-rw-r--r-- | src/qml/debugger/qqmlenginedebugservice_p.h | 6 | ||||
-rw-r--r-- | src/qml/debugger/qqmlprofilerservice_p.h | 59 | ||||
-rw-r--r-- | src/qml/debugger/qv8debugservice.cpp | 2 | ||||
-rw-r--r-- | src/qml/debugger/qv8profilerservice.cpp | 21 |
10 files changed, 113 insertions, 787 deletions
diff --git a/src/qml/debugger/debugger.pri b/src/qml/debugger/debugger.pri index f5abd2c196..f16e225cfd 100644 --- a/src/qml/debugger/debugger.pri +++ b/src/qml/debugger/debugger.pri @@ -1,5 +1,4 @@ SOURCES += \ - $$PWD/qpacketprotocol.cpp \ $$PWD/qqmldebugservice.cpp \ $$PWD/qqmlprofilerservice.cpp \ $$PWD/qqmldebugserver.cpp \ @@ -10,7 +9,6 @@ SOURCES += \ $$PWD/qdebugmessageservice.cpp HEADERS += \ - $$PWD/qpacketprotocol_p.h \ $$PWD/qqmldebugservice_p.h \ $$PWD/qqmldebugservice_p_p.h \ $$PWD/qqmlprofilerservice_p.h \ diff --git a/src/qml/debugger/qpacketprotocol.cpp b/src/qml/debugger/qpacketprotocol.cpp deleted file mode 100644 index 978054a238..0000000000 --- a/src/qml/debugger/qpacketprotocol.cpp +++ /dev/null @@ -1,550 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQml 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 "qpacketprotocol_p.h" - -#include <QtCore/QBuffer> -#include <QtCore/QElapsedTimer> - -QT_BEGIN_NAMESPACE - -static const unsigned int MAX_PACKET_SIZE = 0x7FFFFFFF; - -/*! - \class QPacketProtocol - \internal - - \brief The QPacketProtocol class encapsulates communicating discrete packets - across fragmented IO channels, such as TCP sockets. - - QPacketProtocol makes it simple to send arbitrary sized data "packets" across - fragmented transports such as TCP and UDP. - - As transmission boundaries are not respected, sending packets over protocols - like TCP frequently involves "stitching" them back together at the receiver. - QPacketProtocol makes this easier by performing this task for you. Packet - data sent using QPacketProtocol is prepended with a 4-byte size header - allowing the receiving QPacketProtocol to buffer the packet internally until - it has all been received. QPacketProtocol does not perform any sanity - checking on the size or on the data, so this class should only be used in - prototyping or trusted situations where DOS attacks are unlikely. - - QPacketProtocol does not perform any communications itself. Instead it can - operate on any QIODevice that supports the QIODevice::readyRead() signal. A - logical "packet" is encapsulated by the companion QPacket class. The - following example shows two ways to send data using QPacketProtocol. The - transmitted data is equivalent in both. - - \code - QTcpSocket socket; - // ... connect socket ... - - QPacketProtocol protocol(&socket); - - // Send packet the quick way - protocol.send() << "Hello world" << 123; - - // Send packet the longer way - QPacket packet; - packet << "Hello world" << 123; - protocol.send(packet); - \endcode - - Likewise, the following shows how to read data from QPacketProtocol, assuming - that the QPacketProtocol::readyRead() signal has been emitted. - - \code - // ... QPacketProtocol::readyRead() is emitted ... - - int a; - QByteArray b; - - // Receive packet the quick way - protocol.read() >> a >> b; - - // Receive packet the longer way - QPacket packet = protocol.read(); - p >> a >> b; - \endcode - - \ingroup io - \sa QPacket -*/ - -class QPacketProtocolPrivate : public QObject -{ - Q_OBJECT -public: - QPacketProtocolPrivate(QPacketProtocol *parent, QIODevice *_dev) - : QObject(parent), inProgressSize(-1), maxPacketSize(MAX_PACKET_SIZE), - waitingForPacket(false), dev(_dev) - { - Q_ASSERT(4 == sizeof(qint32)); - - QObject::connect(this, SIGNAL(readyRead()), - parent, SIGNAL(readyRead())); - QObject::connect(this, SIGNAL(packetWritten()), - parent, SIGNAL(packetWritten())); - QObject::connect(this, SIGNAL(invalidPacket()), - parent, SIGNAL(invalidPacket())); - QObject::connect(dev, SIGNAL(readyRead()), - this, SLOT(readyToRead())); - QObject::connect(dev, SIGNAL(aboutToClose()), - this, SLOT(aboutToClose())); - QObject::connect(dev, SIGNAL(bytesWritten(qint64)), - this, SLOT(bytesWritten(qint64))); - } - -Q_SIGNALS: - void readyRead(); - void packetWritten(); - void invalidPacket(); - -public Q_SLOTS: - void aboutToClose() - { - inProgress.clear(); - sendingPackets.clear(); - inProgressSize = -1; - } - - void bytesWritten(qint64 bytes) - { - Q_ASSERT(!sendingPackets.isEmpty()); - - while (bytes) { - if (sendingPackets.at(0) > bytes) { - sendingPackets[0] -= bytes; - bytes = 0; - } else { - bytes -= sendingPackets.at(0); - sendingPackets.removeFirst(); - emit packetWritten(); - } - } - } - - void readyToRead() - { - while (true) { - // Need to get trailing data - if (-1 == inProgressSize) { - // We need a size header of sizeof(qint32) - if (sizeof(qint32) > (uint)dev->bytesAvailable()) - return; - - // Read size header - int read = dev->read((char *)&inProgressSize, sizeof(qint32)); - Q_ASSERT(read == sizeof(qint32)); - Q_UNUSED(read); - - // Check sizing constraints - if (inProgressSize > maxPacketSize) { - QObject::disconnect(dev, SIGNAL(readyRead()), - this, SLOT(readyToRead())); - QObject::disconnect(dev, SIGNAL(aboutToClose()), - this, SLOT(aboutToClose())); - QObject::disconnect(dev, SIGNAL(bytesWritten(qint64)), - this, SLOT(bytesWritten(qint64))); - dev = 0; - emit invalidPacket(); - return; - } - - inProgressSize -= sizeof(qint32); - } else { - inProgress.append(dev->read(inProgressSize - inProgress.size())); - - if (inProgressSize == inProgress.size()) { - // Packet has arrived! - packets.append(inProgress); - inProgressSize = -1; - inProgress.clear(); - - waitingForPacket = false; - emit readyRead(); - } else - return; - } - } - } - -public: - QList<qint64> sendingPackets; - QList<QByteArray> packets; - QByteArray inProgress; - qint32 inProgressSize; - qint32 maxPacketSize; - bool waitingForPacket; - QIODevice *dev; -}; - -/*! - Construct a QPacketProtocol instance that works on \a dev with the - specified \a parent. - */ -QPacketProtocol::QPacketProtocol(QIODevice *dev, QObject *parent) - : QObject(parent), d(new QPacketProtocolPrivate(this, dev)) -{ - Q_ASSERT(dev); -} - -/*! - Destroys the QPacketProtocol instance. - */ -QPacketProtocol::~QPacketProtocol() -{ -} - -/*! - Returns the maximum packet size allowed. By default this is - 2,147,483,647 bytes. - - If a packet claiming to be larger than the maximum packet size is received, - the QPacketProtocol::invalidPacket() signal is emitted. - - \sa QPacketProtocol::setMaximumPacketSize() - */ -qint32 QPacketProtocol::maximumPacketSize() const -{ - return d->maxPacketSize; -} - -/*! - Sets the maximum allowable packet size to \a max. - - \sa QPacketProtocol::maximumPacketSize() - */ -qint32 QPacketProtocol::setMaximumPacketSize(qint32 max) -{ - if (max > (signed)sizeof(qint32)) - d->maxPacketSize = max; - return d->maxPacketSize; -} - -/*! - Returns a streamable object that is transmitted on destruction. For example - - \code - protocol.send() << "Hello world" << 123; - \endcode - - will send a packet containing "Hello world" and 123. To construct more - complex packets, explicitly construct a QPacket instance. - */ -QPacketAutoSend QPacketProtocol::send() -{ - return QPacketAutoSend(this); -} - -/*! - \fn void QPacketProtocol::send(const QPacket & packet) - - Transmit the \a packet. - */ -void QPacketProtocol::send(const QPacket & p) -{ - if (p.b.isEmpty()) - return; // We don't send empty packets - - qint64 sendSize = p.b.size() + sizeof(qint32); - - d->sendingPackets.append(sendSize); - qint32 sendSize32 = sendSize; - qint64 writeBytes = d->dev->write((char *)&sendSize32, sizeof(qint32)); - Q_ASSERT(writeBytes == sizeof(qint32)); - writeBytes = d->dev->write(p.b); - Q_ASSERT(writeBytes == p.b.size()); -} - -/*! - Returns the number of received packets yet to be read. - */ -qint64 QPacketProtocol::packetsAvailable() const -{ - return d->packets.count(); -} - -/*! - Discard any unread packets. - */ -void QPacketProtocol::clear() -{ - d->packets.clear(); -} - -/*! - Return the next unread packet, or an invalid QPacket instance if no packets - are available. This method does NOT block. - */ -QPacket QPacketProtocol::read() -{ - if (0 == d->packets.count()) - return QPacket(); - - QPacket rv(d->packets.at(0)); - d->packets.removeFirst(); - return rv; -} - -/* - Returns the difference between msecs and elapsed. If msecs is -1, - however, -1 is returned. -*/ -static int qt_timeout_value(int msecs, int elapsed) -{ - if (msecs == -1) - return -1; - - int timeout = msecs - elapsed; - return timeout < 0 ? 0 : timeout; -} - -/*! - This function locks until a new packet is available for reading and the - \l{QIODevice::}{readyRead()} signal has been emitted. The function - will timeout after \a msecs milliseconds; the default timeout is - 30000 milliseconds. - - The function returns true if the readyRead() signal is emitted and - there is new data available for reading; otherwise it returns false - (if an error occurred or the operation timed out). - */ - -bool QPacketProtocol::waitForReadyRead(int msecs) -{ - if (!d->packets.isEmpty()) - return true; - - QElapsedTimer stopWatch; - stopWatch.start(); - - d->waitingForPacket = true; - do { - if (!d->dev->waitForReadyRead(msecs)) - return false; - if (!d->waitingForPacket) - return true; - msecs = qt_timeout_value(msecs, stopWatch.elapsed()); - } while (true); -} - -/*! - Return the QIODevice passed to the QPacketProtocol constructor. -*/ -QIODevice *QPacketProtocol::device() -{ - return d->dev; -} - -/*! - \fn void QPacketProtocol::readyRead() - - Emitted whenever a new packet is received. Applications may use - QPacketProtocol::read() to retrieve this packet. - */ - -/*! - \fn void QPacketProtocol::invalidPacket() - - A packet larger than the maximum allowable packet size was received. The - packet will be discarded and, as it indicates corruption in the protocol, no - further packets will be received. - */ - -/*! - \fn void QPacketProtocol::packetWritten() - - Emitted each time a packet is completing written to the device. This signal - may be used for communications flow control. - */ - -/*! - \class QPacket - \internal - - \brief The QPacket class encapsulates an unfragmentable packet of data to be - transmitted by QPacketProtocol. - - The QPacket class works together with QPacketProtocol to make it simple to - send arbitrary sized data "packets" across fragmented transports such as TCP - and UDP. - - QPacket provides a QDataStream interface to an unfragmentable packet. - Applications should construct a QPacket, propagate it with data and then - transmit it over a QPacketProtocol instance. For example: - \code - QPacketProtocol protocol(...); - - QPacket myPacket; - myPacket << "Hello world!" << 123; - protocol.send(myPacket); - \endcode - - As long as both ends of the connection are using the QPacketProtocol class, - the data within this packet will be delivered unfragmented at the other end, - ready for extraction. - - \code - QByteArray greeting; - int count; - - QPacket myPacket = protocol.read(); - - myPacket >> greeting >> count; - \endcode - - Only packets returned from QPacketProtocol::read() may be read from. QPacket - instances constructed by directly by applications are for transmission only - and are considered "write only". Attempting to read data from them will - result in undefined behavior. - - \ingroup io - \sa QPacketProtocol - */ - -/*! - Constructs an empty write-only packet. - */ -QPacket::QPacket() - : QDataStream(), buf(0) -{ - buf = new QBuffer(&b); - buf->open(QIODevice::WriteOnly); - setDevice(buf); - setVersion(QDataStream::Qt_4_7); -} - -/*! - Destroys the QPacket instance. - */ -QPacket::~QPacket() -{ - if (buf) { - delete buf; - buf = 0; - } -} - -/*! - Creates a copy of \a other. The initial stream positions are shared, but the - two packets are otherwise independent. - */ -QPacket::QPacket(const QPacket & other) - : QDataStream(), b(other.b), buf(0) -{ - buf = new QBuffer(&b); - buf->open(other.buf->openMode()); - setDevice(buf); -} - -/*! - \internal - */ -QPacket::QPacket(const QByteArray & ba) - : QDataStream(), b(ba), buf(0) -{ - buf = new QBuffer(&b); - buf->open(QIODevice::ReadOnly); - setDevice(buf); -} - -/*! - Returns true if this packet is empty - that is, contains no data. - */ -bool QPacket::isEmpty() const -{ - return b.isEmpty(); -} - -/*! - Returns raw packet data. - */ -QByteArray QPacket::data() const -{ - return b; -} - -/*! - Clears data in the packet. This is useful for reusing one writable packet. - For example - \code - QPacketProtocol protocol(...); - - QPacket packet; - - packet << "Hello world!" << 123; - protocol.send(packet); - - packet.clear(); - packet << "Goodbyte world!" << 789; - protocol.send(packet); - \endcode - */ -void QPacket::clear() -{ - QBuffer::OpenMode oldMode = buf->openMode(); - buf->close(); - b.clear(); - buf->setBuffer(&b); // reset QBuffer internals with new size of b. - buf->open(oldMode); -} - -/*! - \class QPacketAutoSend - \internal - - \internal - */ -QPacketAutoSend::QPacketAutoSend(QPacketProtocol *_p) - : QPacket(), p(_p) -{ -} - -QPacketAutoSend::~QPacketAutoSend() -{ - if (!b.isEmpty()) - p->send(*this); -} - -QT_END_NAMESPACE - -#include <qpacketprotocol.moc> diff --git a/src/qml/debugger/qpacketprotocol_p.h b/src/qml/debugger/qpacketprotocol_p.h deleted file mode 100644 index c6123d2836..0000000000 --- a/src/qml/debugger/qpacketprotocol_p.h +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtQml 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$ -** -****************************************************************************/ - -#ifndef QPACKETPROTOCOL_H -#define QPACKETPROTOCOL_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 <QtCore/qobject.h> -#include <QtCore/qdatastream.h> - -#include <private/qtqmlglobal_p.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - - -class QIODevice; -class QBuffer; -class QPacket; -class QPacketAutoSend; -class QPacketProtocolPrivate; - -class Q_QML_PRIVATE_EXPORT QPacketProtocol : public QObject -{ - Q_OBJECT -public: - explicit QPacketProtocol(QIODevice *dev, QObject *parent = 0); - virtual ~QPacketProtocol(); - - qint32 maximumPacketSize() const; - qint32 setMaximumPacketSize(qint32); - - QPacketAutoSend send(); - void send(const QPacket &); - - qint64 packetsAvailable() const; - QPacket read(); - - bool waitForReadyRead(int msecs = 3000); - - void clear(); - - QIODevice *device(); - -Q_SIGNALS: - void readyRead(); - void invalidPacket(); - void packetWritten(); - -private: - QPacketProtocolPrivate *d; -}; - - -class Q_QML_PRIVATE_EXPORT QPacket : public QDataStream -{ -public: - QPacket(); - QPacket(const QPacket &); - virtual ~QPacket(); - - void clear(); - bool isEmpty() const; - QByteArray data() const; - -protected: - friend class QPacketProtocol; - QPacket(const QByteArray &ba); - QByteArray b; - QBuffer *buf; -}; - -class Q_QML_PRIVATE_EXPORT QPacketAutoSend : public QPacket -{ -public: - virtual ~QPacketAutoSend(); - -private: - friend class QPacketProtocol; - QPacketAutoSend(QPacketProtocol *); - QPacketProtocol *p; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/qml/debugger/qqmldebugserver.cpp b/src/qml/debugger/qqmldebugserver.cpp index ec3f9dafc2..dcf93b400e 100644 --- a/src/qml/debugger/qqmldebugserver.cpp +++ b/src/qml/debugger/qqmldebugserver.cpp @@ -117,9 +117,10 @@ public: m_pluginName = pluginName; } - void setPort(int port, bool block) { + void setPort(int port, bool block, QString &hostAddress) { m_port = port; m_block = block; + m_hostAddress = hostAddress; } void run(); @@ -128,6 +129,7 @@ private: QString m_pluginName; int m_port; bool m_block; + QString m_hostAddress; }; QQmlDebugServerPrivate::QQmlDebugServerPrivate() : @@ -214,7 +216,7 @@ void QQmlDebugServerThread::run() = server->d_func()->loadConnectionPlugin(m_pluginName); if (connection) { connection->setServer(QQmlDebugServer::instance()); - connection->setPort(m_port, m_block); + connection->setPort(m_port, m_block, m_hostAddress); } else { QCoreApplicationPrivate *appD = static_cast<QCoreApplicationPrivate*>(QObjectPrivate::get(qApp)); qWarning() << QString(QLatin1String("QML Debugger: Ignoring \"-qmljsdebugger=%1\". " @@ -258,8 +260,9 @@ QQmlDebugServer *QQmlDebugServer::instance() int port = 0; bool block = false; bool ok = false; + QString hostAddress; - // format: qmljsdebugger=port:3768[,block] OR qmljsdebugger=ost[,block] + // format: qmljsdebugger=port:3768[,host:<ip address>][,block] OR qmljsdebugger=ost[,block] if (!appD->qmljsDebugArgumentsString().isEmpty()) { if (!QQmlEnginePrivate::qml_debugging_enabled) { qWarning() << QString(QLatin1String( @@ -270,24 +273,30 @@ QQmlDebugServer *QQmlDebugServer::instance() } QString pluginName; - if (appD->qmljsDebugArgumentsString().indexOf(QLatin1String("port:")) == 0) { - int separatorIndex = appD->qmljsDebugArgumentsString().indexOf(QLatin1Char(',')); - port = appD->qmljsDebugArgumentsString().mid(5, separatorIndex - 5).toInt(&ok); - pluginName = QStringLiteral("qmldbg_tcp"); - } else if (appD->qmljsDebugArgumentsString().contains(QLatin1String("ost"))) { - pluginName = QStringLiteral("qmldbg_ost"); - ok = true; + QStringList lstjsDebugArguments = appD->qmljsDebugArgumentsString() + .split(QLatin1Char(',')); + foreach (const QString &strArgument, lstjsDebugArguments) { + if (strArgument.startsWith(QLatin1String("port:"))) { + port = strArgument.mid(5).toInt(&ok); + pluginName = QLatin1String("qmldbg_tcp"); + } else if (strArgument.startsWith(QLatin1String("host:"))) { + hostAddress = strArgument.mid(5); + } else if (strArgument == QLatin1String("block")) { + block = true; + } else { + qWarning() << QString::fromLatin1("QML Debugger: Invalid argument '%1' " + "detected. Ignoring the same.") + .arg(strArgument); + } } - block = appD->qmljsDebugArgumentsString().contains(QLatin1String("block")); - if (ok) { qQmlDebugServer = new QQmlDebugServer(); QQmlDebugServerThread *thread = new QQmlDebugServerThread; qQmlDebugServer->d_func()->thread = thread; qQmlDebugServer->moveToThread(thread); thread->setPluginName(pluginName); - thread->setPort(port, block); + thread->setPort(port, block, hostAddress); thread->start(); if (block) { diff --git a/src/qml/debugger/qqmldebugserverconnection_p.h b/src/qml/debugger/qqmldebugserverconnection_p.h index ab9e7bd73f..920e82ed47 100644 --- a/src/qml/debugger/qqmldebugserverconnection_p.h +++ b/src/qml/debugger/qqmldebugserverconnection_p.h @@ -69,7 +69,7 @@ public: virtual ~QQmlDebugServerConnection() {} virtual void setServer(QQmlDebugServer *server) = 0; - virtual void setPort(int port, bool bock) = 0; + virtual void setPort(int port, bool bock, const QString &hostaddress) = 0; virtual bool isConnected() const = 0; virtual void send(const QList<QByteArray> &messages) = 0; virtual void disconnect() = 0; diff --git a/src/qml/debugger/qqmlenginedebugservice.cpp b/src/qml/debugger/qqmlenginedebugservice.cpp index 67bec3577b..7f0bf7ca33 100644 --- a/src/qml/debugger/qqmlenginedebugservice.cpp +++ b/src/qml/debugger/qqmlenginedebugservice.cpp @@ -67,7 +67,7 @@ QQmlEngineDebugService *QQmlEngineDebugService::instance() } QQmlEngineDebugService::QQmlEngineDebugService(QObject *parent) - : QQmlDebugService(QStringLiteral("QDeclarativeEngine"), 1, parent), + : QQmlDebugService(QStringLiteral("QmlDebugger"), 1, parent), m_watch(new QQmlWatcher(this)), m_statesDelegate(0) { @@ -394,12 +394,10 @@ void QQmlEngineDebugService::processMessage(const QByteArray &message) QDataStream ds(message); QByteArray type; - ds >> type; + int queryId; + ds >> type >> queryId; if (type == "LIST_ENGINES") { - int queryId; - ds >> queryId; - QByteArray reply; QDataStream rs(&reply, QIODevice::WriteOnly); rs << QByteArray("LIST_ENGINES_R"); @@ -416,9 +414,8 @@ void QQmlEngineDebugService::processMessage(const QByteArray &message) sendMessage(reply); } else if (type == "LIST_OBJECTS") { - int queryId; int engineId = -1; - ds >> queryId >> engineId; + ds >> engineId; QQmlEngine *engine = qobject_cast<QQmlEngine *>(QQmlDebugService::objectForId(engineId)); @@ -443,12 +440,11 @@ void QQmlEngineDebugService::processMessage(const QByteArray &message) sendMessage(reply); } else if (type == "FETCH_OBJECT") { - int queryId; int objectId; bool recurse; bool dumpProperties = true; - ds >> queryId >> objectId >> recurse >> dumpProperties; + ds >> objectId >> recurse >> dumpProperties; QObject *object = QQmlDebugService::objectForId(objectId); @@ -464,10 +460,9 @@ void QQmlEngineDebugService::processMessage(const QByteArray &message) sendMessage(reply); } else if (type == "WATCH_OBJECT") { - int queryId; int objectId; - ds >> queryId >> objectId; + ds >> objectId; bool ok = m_watch->addWatch(queryId, objectId); QByteArray reply; @@ -476,11 +471,10 @@ void QQmlEngineDebugService::processMessage(const QByteArray &message) sendMessage(reply); } else if (type == "WATCH_PROPERTY") { - int queryId; int objectId; QByteArray property; - ds >> queryId >> objectId >> property; + ds >> objectId >> property; bool ok = m_watch->addWatch(queryId, objectId, property); QByteArray reply; @@ -489,11 +483,10 @@ void QQmlEngineDebugService::processMessage(const QByteArray &message) sendMessage(reply); } else if (type == "WATCH_EXPR_OBJECT") { - int queryId; int debugId; QString expr; - ds >> queryId >> debugId >> expr; + ds >> debugId >> expr; bool ok = m_watch->addWatch(queryId, debugId, expr); QByteArray reply; @@ -501,16 +494,17 @@ void QQmlEngineDebugService::processMessage(const QByteArray &message) rs << QByteArray("WATCH_EXPR_OBJECT_R") << queryId << ok; sendMessage(reply); } else if (type == "NO_WATCH") { - int queryId; + bool ok = m_watch->removeWatch(queryId); - ds >> queryId; - m_watch->removeWatch(queryId); + QByteArray reply; + QDataStream rs(&reply, QIODevice::WriteOnly); + rs << QByteArray("NO_WATCH_R") << queryId << ok; + sendMessage(reply); } else if (type == "EVAL_EXPRESSION") { - int queryId; int objectId; QString expr; - ds >> queryId >> objectId >> expr; + ds >> objectId >> expr; QObject *object = QQmlDebugService::objectForId(objectId); QQmlContext *context = qmlContext(object); @@ -539,26 +533,43 @@ void QQmlEngineDebugService::processMessage(const QByteArray &message) bool isLiteralValue; QString filename; int line; - ds >> objectId >> propertyName >> expr >> isLiteralValue; - if (!ds.atEnd()) { // backward compatibility from 2.1, 2.2 - ds >> filename >> line; - } - setBinding(objectId, propertyName, expr, isLiteralValue, filename, line); + ds >> objectId >> propertyName >> expr >> isLiteralValue >> + filename >> line; + bool ok = setBinding(objectId, propertyName, expr, isLiteralValue, + filename, line); + + QByteArray reply; + QDataStream rs(&reply, QIODevice::WriteOnly); + rs << QByteArray("SET_BINDING_R") << queryId << ok; + + sendMessage(reply); } else if (type == "RESET_BINDING") { int objectId; QString propertyName; ds >> objectId >> propertyName; - resetBinding(objectId, propertyName); + bool ok = resetBinding(objectId, propertyName); + + QByteArray reply; + QDataStream rs(&reply, QIODevice::WriteOnly); + rs << QByteArray("RESET_BINDING_R") << queryId << ok; + + sendMessage(reply); } else if (type == "SET_METHOD_BODY") { int objectId; QString methodName; QString methodBody; ds >> objectId >> methodName >> methodBody; - setMethodBody(objectId, methodName, methodBody); + bool ok = setMethodBody(objectId, methodName, methodBody); + + QByteArray reply; + QDataStream rs(&reply, QIODevice::WriteOnly); + rs << QByteArray("SET_METHOD_BODY_R") << queryId << ok; + + sendMessage(reply); } } -void QQmlEngineDebugService::setBinding(int objectId, +bool QQmlEngineDebugService::setBinding(int objectId, const QString &propertyName, const QVariant &expression, bool isLiteralValue, @@ -566,6 +577,7 @@ void QQmlEngineDebugService::setBinding(int objectId, int line, int column) { + bool ok = true; QObject *object = objectForId(objectId); QQmlContext *context = qmlContext(object); @@ -594,22 +606,23 @@ void QQmlEngineDebugService::setBinding(int objectId, oldBinding->destroy(); binding->update(); } else { + ok = false; qWarning() << "QQmlEngineDebugService::setBinding: unable to set property" << propertyName << "on object" << object; } } } else { // not a valid property - bool ok = false; if (m_statesDelegate) ok = m_statesDelegate->setBindingForInvalidProperty(object, propertyName, expression, isLiteralValue); if (!ok) qWarning() << "QQmlEngineDebugService::setBinding: unable to set property" << propertyName << "on object" << object; } } + return ok; } -void QQmlEngineDebugService::resetBinding(int objectId, const QString &propertyName) +bool QQmlEngineDebugService::resetBinding(int objectId, const QString &propertyName) { QObject *object = objectForId(objectId); QQmlContext *context = qmlContext(object); @@ -651,24 +664,25 @@ void QQmlEngineDebugService::resetBinding(int objectId, const QString &propertyN m_statesDelegate->resetBindingForInvalidProperty(object, propertyName); } } + return true; } -void QQmlEngineDebugService::setMethodBody(int objectId, const QString &method, const QString &body) +bool QQmlEngineDebugService::setMethodBody(int objectId, const QString &method, const QString &body) { QObject *object = objectForId(objectId); QQmlContext *context = qmlContext(object); if (!object || !context || !context->engine()) - return; + return false; QQmlContextData *contextData = QQmlContextData::get(context); if (!contextData) - return; + return false; QQmlPropertyData dummy; QQmlPropertyData *prop = QQmlPropertyCache::property(context->engine(), object, method, dummy); if (!prop || !prop->isVMEFunction()) - return; + return false; QMetaMethod metaMethod = object->metaObject()->method(prop->coreIndex); QList<QByteArray> paramNames = metaMethod.parameterNames(); @@ -690,6 +704,7 @@ void QQmlEngineDebugService::setMethodBody(int objectId, const QString &method, int lineNumber = vmeMetaObject->vmeMethodLineNumber(prop->coreIndex); vmeMetaObject->setVmeMethod(prop->coreIndex, QQmlExpressionPrivate::evalFunction(contextData, object, jsfunction, contextData->url.toString(), lineNumber)); + return true; } void QQmlEngineDebugService::propertyChanged(int id, int objectId, const QMetaProperty &property, const QVariant &value) @@ -729,7 +744,8 @@ void QQmlEngineDebugService::objectCreated(QQmlEngine *engine, QObject *object) QByteArray reply; QDataStream rs(&reply, QIODevice::WriteOnly); - rs << QByteArray("OBJECT_CREATED") << engineId << objectId; + //unique queryId -1 + rs << QByteArray("OBJECT_CREATED") << -1 << engineId << objectId; sendMessage(reply); } diff --git a/src/qml/debugger/qqmlenginedebugservice_p.h b/src/qml/debugger/qqmlenginedebugservice_p.h index f41063d7a3..19a5776e27 100644 --- a/src/qml/debugger/qqmlenginedebugservice_p.h +++ b/src/qml/debugger/qqmlenginedebugservice_p.h @@ -119,9 +119,9 @@ private: QQmlObjectData objectData(QObject *); QQmlObjectProperty propertyData(QObject *, int); QVariant valueContents(const QVariant &defaultValue) const; - void setBinding(int objectId, const QString &propertyName, const QVariant &expression, bool isLiteralValue, QString filename = QString(), int line = -1, int column = 0); - void resetBinding(int objectId, const QString &propertyName); - void setMethodBody(int objectId, const QString &method, const QString &body); + bool setBinding(int objectId, const QString &propertyName, const QVariant &expression, bool isLiteralValue, QString filename = QString(), int line = -1, int column = 0); + bool resetBinding(int objectId, const QString &propertyName); + bool setMethodBody(int objectId, const QString &method, const QString &body); QList<QQmlEngine *> m_engines; QQmlWatcher *m_watch; diff --git a/src/qml/debugger/qqmlprofilerservice_p.h b/src/qml/debugger/qqmlprofilerservice_p.h index 7a708456ba..2b4cafb615 100644 --- a/src/qml/debugger/qqmlprofilerservice_p.h +++ b/src/qml/debugger/qqmlprofilerservice_p.h @@ -54,12 +54,15 @@ // #include <private/qqmldebugservice_p.h> -#include <QtQml/qtqmlglobal.h> +#include "qqmlexpression.h" + #include <QtCore/qelapsedtimer.h> +#include <QtCore/qmetaobject.h> #include <QtCore/qmutex.h> #include <QtCore/qvector.h> #include <QtCore/qstringbuilder.h> + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -194,47 +197,30 @@ struct QQmlBindingProfiler { QQmlProfilerService::instance->endRange(QQmlProfilerService::Binding); } - void addDetail(const QString &details) - { - if (enabled) - QQmlProfilerService::instance->rangeData(QQmlProfilerService::Binding, - details); - } -\ bool enabled; }; struct QQmlHandlingSignalProfiler { - QQmlHandlingSignalProfiler() + QQmlHandlingSignalProfiler(const QMetaMethod &signal, QQmlExpression *expression) { enabled = QQmlProfilerService::instance ? QQmlProfilerService::instance->profilingEnabled() : false; if (enabled) { - QQmlProfilerService::instance->startRange( - QQmlProfilerService::HandlingSignal); + QQmlProfilerService *service = QQmlProfilerService::instance; + service->startRange(QQmlProfilerService::HandlingSignal); + service->rangeData(QQmlProfilerService::HandlingSignal, + QString::fromLatin1(signal.methodSignature()) + QLatin1String(": ") + + expression->expression()); + service->rangeLocation(QQmlProfilerService::HandlingSignal, + expression->sourceFile(), expression->lineNumber(), + expression->columnNumber()); } } - void setSignalInfo(const QString &name, const QString &expression) - { - if (enabled) - QQmlProfilerService::instance->rangeData( - QQmlProfilerService::HandlingSignal, - name % QLatin1String(": ") % expression); - } - - void setLocation(const QString &file, int line, int column) - { - if (enabled) - QQmlProfilerService::instance->rangeLocation( - QQmlProfilerService::HandlingSignal, file, line, column); - } - ~QQmlHandlingSignalProfiler() { if (enabled) - QQmlProfilerService::instance->endRange( - QQmlProfilerService::HandlingSignal); + QQmlProfilerService::instance->endRange(QQmlProfilerService::HandlingSignal); } bool enabled; @@ -243,22 +229,23 @@ struct QQmlHandlingSignalProfiler { struct QQmlObjectCreatingProfiler { QQmlObjectCreatingProfiler() { - QQmlProfilerService *instance = QQmlProfilerService::instance; - enabled = instance ? - instance->profilingEnabled() : false; - if (enabled) - instance->startRange(QQmlProfilerService::Creating); + enabled = QQmlProfilerService::instance + ? QQmlProfilerService::instance->profilingEnabled() : false; + if (enabled) { + QQmlProfilerService *service = QQmlProfilerService::instance; + service->startRange(QQmlProfilerService::Creating); + } } void setTypeName(const QString &typeName) { - if (enabled) - QQmlProfilerService::instance->rangeData( - QQmlProfilerService::Creating, typeName); + Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled."); + QQmlProfilerService::instance->rangeData(QQmlProfilerService::Creating, typeName); } void setLocation(const QUrl &url, int line, int column) { + Q_ASSERT_X(enabled, Q_FUNC_INFO, "method called although profiler is not enabled."); if (enabled) QQmlProfilerService::instance->rangeLocation( QQmlProfilerService::Creating, url, line, column); diff --git a/src/qml/debugger/qv8debugservice.cpp b/src/qml/debugger/qv8debugservice.cpp index a6aeda31d5..7d54a59ac0 100644 --- a/src/qml/debugger/qv8debugservice.cpp +++ b/src/qml/debugger/qv8debugservice.cpp @@ -42,6 +42,7 @@ #include "qv8debugservice_p.h" #include "qqmldebugservice_p_p.h" #include <private/qjsconverter_impl_p.h> +#include <private/qv4compiler_p.h> #include <private/qv8engine_p.h> #include <QtCore/QHash> @@ -192,6 +193,7 @@ void QV8DebugService::init() Q_D(QV8DebugService); v8::Debug::SetMessageHandler2(DebugMessageHandler); v8::Debug::SetDebugMessageDispatchHandler(DebugMessageDispatchHandler); + QV4Compiler::enableV4(false); d->initializeMutex.unlock(); } diff --git a/src/qml/debugger/qv8profilerservice.cpp b/src/qml/debugger/qv8profilerservice.cpp index 6208676522..c75c258785 100644 --- a/src/qml/debugger/qv8profilerservice.cpp +++ b/src/qml/debugger/qv8profilerservice.cpp @@ -52,20 +52,19 @@ Q_GLOBAL_STATIC(QV8ProfilerService, v8ProfilerInstance) class DebugServiceOutputStream : public v8::OutputStream { - QQmlDebugService &_service; public: - DebugServiceOutputStream(QQmlDebugService &service) - : v8::OutputStream(), - _service(service) {} + DebugServiceOutputStream() + : v8::OutputStream() {} void EndOfStream() {} WriteResult WriteAsciiChunk(char *rawData, int size) { QByteArray data; QDataStream ds(&data, QIODevice::WriteOnly); ds << QV8ProfilerService::V8SnapshotChunk << QByteArray(rawData, size); - _service.sendMessage(data); + messages.append(data); return kContinue; } + QList<QByteArray> messages; }; // convert to a QByteArray that can be sent to the debug client @@ -267,16 +266,18 @@ void QV8ProfilerServicePrivate::takeSnapshot(v8::HeapSnapshot::Type snapshotType v8::HandleScope scope; v8::Local<v8::String> title = v8::String::New(""); - DebugServiceOutputStream outputStream(*q); + DebugServiceOutputStream outputStream; const v8::HeapSnapshot *snapshot = v8::HeapProfiler::TakeSnapshot(title, snapshotType); snapshot->Serialize(&outputStream, v8::HeapSnapshot::kJSON); + QList<QByteArray> messages = outputStream.messages; //indicate completion QByteArray data; QDataStream ds(&data, QIODevice::WriteOnly); ds << (int)QV8ProfilerService::V8SnapshotComplete; + messages.append(data); - q->sendMessage(data); + q->sendMessages(messages); } void QV8ProfilerServicePrivate::sendMessages() @@ -285,16 +286,16 @@ void QV8ProfilerServicePrivate::sendMessages() QList<QByteArray> messages; for (int i = 0; i < m_data.count(); ++i) - messages << m_data.at(i).toByteArray(); - q->sendMessages(messages); + messages.append(m_data.at(i).toByteArray()); m_data.clear(); //indicate completion QByteArray data; QDataStream ds(&data, QIODevice::WriteOnly); ds << (int)QV8ProfilerService::V8Complete; + messages.append(data); - q->sendMessage(data); + q->sendMessages(messages); } |