aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorKent Hansen <kent.hansen@nokia.com>2012-03-23 14:31:47 +0100
committerKent Hansen <kent.hansen@nokia.com>2012-03-23 14:31:47 +0100
commit0655209fdad022bd0f6eb20ce85522cb56506bf0 (patch)
treecdba0c1590655f5cb75a68cedff74f8a683db3a2 /src/qml
parentc3babc03c99c6ca5fa210486e133eb456a405bab (diff)
parent3d8f103c2641f35e7681485102a1b59886db8934 (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')
-rw-r--r--src/qml/debugger/debugger.pri2
-rw-r--r--src/qml/debugger/qpacketprotocol.cpp550
-rw-r--r--src/qml/debugger/qpacketprotocol_p.h137
-rw-r--r--src/qml/debugger/qqmldebugserver.cpp35
-rw-r--r--src/qml/debugger/qqmldebugserverconnection_p.h2
-rw-r--r--src/qml/debugger/qqmlenginedebugservice.cpp86
-rw-r--r--src/qml/debugger/qqmlenginedebugservice_p.h6
-rw-r--r--src/qml/debugger/qqmlprofilerservice_p.h59
-rw-r--r--src/qml/debugger/qv8debugservice.cpp2
-rw-r--r--src/qml/debugger/qv8profilerservice.cpp21
-rw-r--r--src/qml/qml/ftw/qhashedstring_p.h4
-rw-r--r--src/qml/qml/ftw/qqmlpool.cpp4
-rw-r--r--src/qml/qml/qqmlaccessors_p.h4
-rw-r--r--src/qml/qml/qqmlbinding.cpp2
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp13
-rw-r--r--src/qml/qml/qqmlcompiler.cpp18
-rw-r--r--src/qml/qml/qqmlcomponent.cpp10
-rw-r--r--src/qml/qml/qqmlcontext_p.h2
-rw-r--r--src/qml/qml/qqmldirparser.cpp14
-rw-r--r--src/qml/qml/qqmldirparser_p.h3
-rw-r--r--src/qml/qml/qqmlextensionplugin.cpp2
-rw-r--r--src/qml/qml/qqmlimport.cpp28
-rw-r--r--src/qml/qml/qqmlimport_p.h2
-rw-r--r--src/qml/qml/qqmlincubator.cpp3
-rw-r--r--src/qml/qml/qqmlmetatype.cpp4
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp25
-rw-r--r--src/qml/qml/qqmlstringconverters.cpp3
-rw-r--r--src/qml/qml/qqmltypeloader.cpp41
-rw-r--r--src/qml/qml/qqmltypeloader_p.h1
-rw-r--r--src/qml/qml/qqmlvme.cpp2
-rw-r--r--src/qml/qml/qqmlwatcher.cpp5
-rw-r--r--src/qml/qml/qqmlwatcher_p.h2
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp2
-rw-r--r--src/qml/qml/v4/qv4bindings.cpp19
-rw-r--r--src/qml/qml/v4/qv4compiler.cpp10
-rw-r--r--src/qml/qml/v4/qv4instruction.cpp6
-rw-r--r--src/qml/qml/v4/qv4instruction_p.h2
-rw-r--r--src/qml/qml/v4/qv4irbuilder.cpp4
-rw-r--r--src/qml/qml/v8/qjsconverter_impl_p.h4
-rw-r--r--src/qml/qml/v8/qjsvalue.cpp2
-rw-r--r--src/qml/qml/v8/qjsvalue_impl_p.h2
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp45
-rw-r--r--src/qml/qml/v8/qv8engine.cpp7
43 files changed, 336 insertions, 859 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);
}
diff --git a/src/qml/qml/ftw/qhashedstring_p.h b/src/qml/qml/ftw/qhashedstring_p.h
index f575285ff6..f058f21e98 100644
--- a/src/qml/qml/ftw/qhashedstring_p.h
+++ b/src/qml/qml/ftw/qhashedstring_p.h
@@ -59,6 +59,10 @@
#include <private/qflagpointer_p.h>
+#if defined(Q_OS_QNX)
+#include <stdlib.h>
+#endif
+
QT_BEGIN_NAMESPACE
// Enable this to debug hash linking assumptions.
diff --git a/src/qml/qml/ftw/qqmlpool.cpp b/src/qml/qml/ftw/qqmlpool.cpp
index 6fd11d4b1e..64df87ada5 100644
--- a/src/qml/qml/ftw/qqmlpool.cpp
+++ b/src/qml/qml/ftw/qqmlpool.cpp
@@ -41,6 +41,10 @@
#include "qqmlpool_p.h"
+#ifdef Q_OS_QNX
+#include <malloc.h>
+#endif
+
// #define POOL_DEBUG
QT_BEGIN_NAMESPACE
diff --git a/src/qml/qml/qqmlaccessors_p.h b/src/qml/qml/qqmlaccessors_p.h
index a603bede9f..8e67a58511 100644
--- a/src/qml/qml/qqmlaccessors_p.h
+++ b/src/qml/qml/qqmlaccessors_p.h
@@ -47,6 +47,10 @@
#include <QtCore/qhash.h>
#include <QtCore/QReadWriteLock>
+#ifdef Q_OS_QNX
+#include <stdint.h>
+#endif
+
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index f43822ed0e..c4f48ef63d 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -193,8 +193,6 @@ void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags)
if (!updatingFlag()) {
QQmlBindingProfiler prof(m_url, m_lineNumber, m_columnNumber);
- if (prof.enabled)
- prof.addDetail(expression());
setUpdatingFlag(true);
QQmlAbstractExpression::DeleteWatcher watcher(this);
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index aa130d9493..f7d0c00a5c 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -174,13 +174,7 @@ int QQmlBoundSignal::qt_metacall(QMetaObject::Call c, int id, void **a)
if (QQmlDebugService::isDebuggingEnabled())
QV8DebugService::instance()->signalEmitted(QString::fromAscii(m_signal.methodSignature().constData()));
- QQmlHandlingSignalProfiler prof;
- if (prof.enabled) {
- prof.setSignalInfo(QString::fromLatin1(m_signal.methodSignature().constData()),
- m_expression->expression());
- prof.setLocation(m_expression->sourceFile(), m_expression->lineNumber(),
- m_expression->columnNumber());
- }
+ QQmlHandlingSignalProfiler prof(m_signal, m_expression);
m_isEvaluating = true;
if (!m_paramsValid) {
@@ -233,7 +227,10 @@ QQmlBoundSignalParameters::QQmlBoundSignalParameters(const QMetaMethod &method,
prop.setWritable(false);
} else {
QByteArray propType = type;
- if (t >= int(QVariant::UserType) || t == QMetaType::UnknownType || t == QMetaType::Void) {
+ if ((QMetaType::typeFlags(t) & QMetaType::IsEnumeration) == QMetaType::IsEnumeration) {
+ t = QVariant::Int;
+ propType = "int";
+ } else if (t == QMetaType::UnknownType) {
QByteArray scope;
QByteArray name;
int scopeIdx = propType.lastIndexOf("::");
diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp
index c3b8152ce1..dec9911481 100644
--- a/src/qml/qml/qqmlcompiler.cpp
+++ b/src/qml/qml/qqmlcompiler.cpp
@@ -2217,7 +2217,7 @@ bool QQmlCompiler::buildValueTypeProperty(QObject *type,
//optimization for <Type>.<EnumValue> enum assignments
bool isEnumAssignment = false;
- if (prop->core.isEnum())
+ if (prop->core.isEnum() || prop->core.propType == QMetaType::Int)
COMPILE_CHECK(testQualifiedEnumAssignment(prop, obj, value, &isEnumAssignment));
if (isEnumAssignment) {
@@ -2485,7 +2485,7 @@ bool QQmlCompiler::buildPropertyLiteralAssignment(QQmlScript::Property *prop,
if (v->value.isScript()) {
//optimization for <Type>.<EnumValue> enum assignments
- if (prop->core.isEnum()) {
+ if (prop->core.isEnum() || prop->core.propType == QMetaType::Int) {
bool isEnumAssignment = false;
COMPILE_CHECK(testQualifiedEnumAssignment(prop, obj, v, &isEnumAssignment));
if (isEnumAssignment) {
@@ -2515,8 +2515,9 @@ bool QQmlCompiler::testQualifiedEnumAssignment(QQmlScript::Property *prop,
QQmlScript::Value *v,
bool *isAssignment)
{
+ bool isIntProp = (prop->core.propType == QMetaType::Int) && !prop->core.isEnum();
*isAssignment = false;
- if (!prop->core.isEnum())
+ if (!prop->core.isEnum() && !isIntProp)
return true;
QMetaProperty mprop = obj->metaObject()->property(prop->index);
@@ -2528,6 +2529,17 @@ bool QQmlCompiler::testQualifiedEnumAssignment(QQmlScript::Property *prop,
if (!string.at(0).isUpper())
return true;
+ if (isIntProp) {
+ // Allow enum assignment to ints.
+ int enumval = evaluateEnum(string.toUtf8());
+ if (enumval != -1) {
+ v->type = Value::Literal;
+ v->value = QQmlScript::Variant((double)enumval);
+ *isAssignment = true;
+ }
+ return true;
+ }
+
QStringList parts = string.split(QLatin1Char('.'));
if (parts.count() != 2)
return true;
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 6cd5cf6cec..416178e3e1 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -829,7 +829,10 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context)
if (rv) {
QQmlData *ddata = QQmlData::get(rv);
Q_ASSERT(ddata);
+ //top level objects should never get JS ownership.
+ //if JS ownership is needed this needs to be explicitly undone (like in component.createObject())
ddata->indestructible = true;
+ ddata->explicitIndestructibleSet = true;
}
if (enginePriv->isDebugging && rv) {
@@ -1120,7 +1123,8 @@ void QQmlComponent::createObject(QQmlV8Function *args)
d->completeCreate();
Q_ASSERT(QQmlData::get(rv));
- QQmlData::get(rv)->setImplicitDestructible();
+ QQmlData::get(rv)->explicitIndestructibleSet = false;
+ QQmlData::get(rv)->indestructible = false;
if (!rv)
args->returnValue(v8::Null());
@@ -1255,10 +1259,6 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(v8::Handle<v8::
v8::Handle<v8::Value> args[] = { object, valuemap };
v8::Handle<v8::Function>::Cast(function)->Call(v8engine->global(), 2, args);
}
-
- QQmlData *ddata = QQmlData::get(toCreate);
- Q_ASSERT(ddata);
- ddata->setImplicitDestructible();
}
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index d10543bde5..97bc04b91d 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -146,7 +146,7 @@ public:
quint32 isJSContext:1;
quint32 isPragmaLibraryContext:1;
quint32 unresolvedNames:1; // True if expressions in this context failed to resolve a toplevel name
- quint32 dummy:28;
+ quint32 dummy:27;
QQmlContext *publicContext;
// VME data that is constructing this context if any
diff --git a/src/qml/qml/qqmldirparser.cpp b/src/qml/qml/qqmldirparser.cpp
index 7b99214f04..df5f7f8ee9 100644
--- a/src/qml/qml/qqmldirparser.cpp
+++ b/src/qml/qml/qqmldirparser.cpp
@@ -295,4 +295,18 @@ QList<QQmlDirParser::TypeInfo> QQmlDirParser::typeInfos() const
}
#endif
+QDebug &operator<< (QDebug &debug, const QQmlDirParser::Component &component)
+{
+ return debug << qPrintable(QString("{%1 %2.%3}").arg(component.typeName)
+ .arg(component.majorVersion)
+ .arg(component.minorVersion));
+}
+
+QDebug &operator<< (QDebug &debug, const QQmlDirParser::Script &script)
+{
+ return debug << qPrintable(QString("{%1 %2.%3}").arg(script.nameSpace)
+ .arg(script.majorVersion)
+ .arg(script.minorVersion));
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmldirparser_p.h b/src/qml/qml/qqmldirparser_p.h
index 8c681309ac..f46e1781da 100644
--- a/src/qml/qml/qqmldirparser_p.h
+++ b/src/qml/qml/qqmldirparser_p.h
@@ -55,6 +55,7 @@
#include <QtCore/QUrl>
#include <QtCore/QHash>
+#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE
@@ -160,6 +161,8 @@ private:
typedef QList<QQmlDirParser::Component> QQmlDirComponents;
typedef QList<QQmlDirParser::Script> QQmlDirScripts;
+QDebug &operator<< (QDebug &, const QQmlDirParser::Component &);
+QDebug &operator<< (QDebug &, const QQmlDirParser::Script &);
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp
index b69fa5da7a..86d9f9588d 100644
--- a/src/qml/qml/qqmlextensionplugin.cpp
+++ b/src/qml/qml/qqmlextensionplugin.cpp
@@ -97,7 +97,7 @@ QT_BEGIN_NAMESPACE
\code
TEMPLATE = lib
CONFIG += qt plugin
- QT += declarative
+ QT += qml
DESTDIR = com/nokia/TimeExample
TARGET = qmlqtimeexampleplugin
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 0c1fb3bd93..1224efdaac 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -117,7 +117,7 @@ public:
QList<QQmlError> *errors);
QString resolvedUri(const QString &dir_arg, QQmlImportDatabase *database);
- bool add(const QQmlDirComponents &qmldircomponentsnetwork,
+ QString add(const QQmlDirComponents &qmldircomponentsnetwork,
const QString& uri_arg, const QString& prefix,
int vmaj, int vmin, QQmlScript::Import::Type importType,
QQmlImportDatabase *database, QList<QQmlError> *errors);
@@ -493,7 +493,7 @@ QString QQmlImportsPrivate::resolvedUri(const QString &dir_arg, QQmlImportDataba
return stableRelativePath;
}
-bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork,
+QString QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork,
const QString& uri_arg, const QString& prefix, int vmaj, int vmin,
QQmlScript::Import::Type importType,
QQmlImportDatabase *database, QList<QQmlError> *errors)
@@ -540,7 +540,7 @@ bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork,
url = QUrl::fromLocalFile(fi.absolutePath()).toString();
uri = resolvedUri(dir, database);
if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, &qmldirscripts, errors))
- return false;
+ return QString();
break;
}
}
@@ -564,7 +564,7 @@ bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork,
url = QUrl::fromLocalFile(fi.absolutePath()).toString();
uri = resolvedUri(dir, database);
if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, &qmldirscripts, errors))
- return false;
+ return QString();
break;
}
}
@@ -586,7 +586,7 @@ bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork,
url = QUrl::fromLocalFile(absolutePath).toString();
uri = resolvedUri(dir, database);
if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, &qmldirscripts, errors))
- return false;
+ return QString();
break;
}
}
@@ -604,7 +604,7 @@ bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork,
error.setDescription(QQmlImportDatabase::tr("module \"%1\" is not installed").arg(uri_arg));
errors->prepend(error);
}
- return false;
+ return QString();
}
} else {
if (importType == QQmlScript::Import::File && qmldircomponents.isEmpty()) {
@@ -619,14 +619,14 @@ bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork,
error.setUrl(QUrl(importUrl));
errors->prepend(error);
}
- return false; // local import dirs must exist
+ return QString(); // local import dirs must exist
}
uri = resolvedUri(dir, database);
if (uri.endsWith(Slash))
uri.chop(1);
if (!typeLoader->absoluteFilePath(localFileOrQrc).isEmpty()) {
if (!importExtension(localFileOrQrc,uri,database,&qmldircomponents,&qmldirscripts,errors))
- return false;
+ return QString();
}
} else {
if (prefix.isEmpty()) {
@@ -642,7 +642,7 @@ bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork,
error.setUrl(QUrl(importUrl));
errors->prepend(error);
}
- return false;
+ return QString();
}
}
}
@@ -669,7 +669,7 @@ bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork,
error.setDescription(QQmlImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin));
errors->prepend(error);
}
- return false;
+ return QString();
}
}
@@ -686,7 +686,7 @@ bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork,
QQmlError error;
error.setDescription(QQmlImportDatabase::tr("\"%1\" is ambiguous. Found in %2 and in %3").arg(uri).arg(url).arg(it->url));
errors->prepend(error);
- return false;
+ return QString();
}
}
@@ -716,7 +716,7 @@ bool QQmlImportsPrivate::add(const QQmlDirComponents &qmldircomponentsnetwork,
s->imports.prepend(data);
- return true;
+ return data.url;
}
bool QQmlImportsPrivate::find(const QString& type, int *vmajor, int *vminor, QQmlType** type_return,
@@ -874,9 +874,11 @@ QQmlImportDatabase::~QQmlImportDatabase()
The \a prefix may be empty, in which case the import location is considered for
unqualified types.
+ Returns the resolved URL of the import on success.
+
The base URL must already have been set with Import::setBaseUrl().
*/
-bool QQmlImports::addImport(QQmlImportDatabase *importDb,
+QString QQmlImports::addImport(QQmlImportDatabase *importDb,
const QString& uri, const QString& prefix, int vmaj, int vmin,
QQmlScript::Import::Type importType,
const QQmlDirComponents &qmldircomponentsnetwork,
diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h
index ff19510525..422f2429a0 100644
--- a/src/qml/qml/qqmlimport_p.h
+++ b/src/qml/qml/qqmlimport_p.h
@@ -93,7 +93,7 @@ public:
QQmlType** type_return, QString* url_return,
int *version_major, int *version_minor) const;
- bool addImport(QQmlImportDatabase *,
+ QString addImport(QQmlImportDatabase *,
const QString& uri, const QString& prefix, int vmaj, int vmin,
QQmlScript::Import::Type importType,
const QQmlDirComponents &qmldircomponentsnetwork,
diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp
index aa9777d89e..fad2ae2f28 100644
--- a/src/qml/qml/qqmlincubator.cpp
+++ b/src/qml/qml/qqmlincubator.cpp
@@ -293,8 +293,9 @@ void QQmlIncubatorPrivate::incubate(QQmlVME::Interrupt &i)
if (result) {
QQmlData *ddata = QQmlData::get(result);
Q_ASSERT(ddata);
+ //see QQmlComponent::beginCreate for explanation of indestructible
ddata->indestructible = true;
-
+ ddata->explicitIndestructibleSet = true;
q->setInitialState(result);
}
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 5b80f57d01..4af08c28bf 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -512,7 +512,7 @@ QObject *QQmlType::create() const
d->m_newFunc(rv);
if (rv && !d->m_metaObjects.isEmpty())
- (void *)new QQmlProxyMetaObject(rv, &d->m_metaObjects);
+ (void)new QQmlProxyMetaObject(rv, &d->m_metaObjects);
return rv;
}
@@ -525,7 +525,7 @@ void QQmlType::create(QObject **out, void **memory, size_t additionalMemory) con
d->m_newFunc(rv);
if (rv && !d->m_metaObjects.isEmpty())
- (void *)new QQmlProxyMetaObject(rv, &d->m_metaObjects);
+ (void)new QQmlProxyMetaObject(rv, &d->m_metaObjects);
*out = rv;
*memory = ((char *)rv) + d->m_allocationSize;
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index afab665ea4..4a1eb79213 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -674,7 +674,13 @@ QStringList QQmlPropertyCache::propertyNames() const
return keys;
}
-static int EnumType(const QMetaObject *meta, const QByteArray &str)
+struct StaticQtMetaObject : public QObject
+{
+ static const QMetaObject *get()
+ { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; }
+};
+
+static int EnumType(const QMetaObject *metaobj, const QByteArray &str)
{
QByteArray scope;
QByteArray name;
@@ -685,6 +691,11 @@ static int EnumType(const QMetaObject *meta, const QByteArray &str)
} else {
name = str;
}
+ const QMetaObject *meta;
+ if (scope == "Qt")
+ meta = StaticQtMetaObject::get();
+ else
+ meta = metaobj;
for (int i = meta->enumeratorCount() - 1; i >= 0; --i) {
QMetaEnum m = meta->enumerator(i);
if ((m.name() == name) && (scope.isEmpty() || (m.scope() == scope)))
@@ -727,12 +738,14 @@ int *QQmlPropertyCache::methodParameterTypes(QObject *object, int index,
for (int ii = 0; ii < argc; ++ii) {
int type = m.parameterType(ii);
- if (type == QVariant::Invalid) {
+ if ((QMetaType::typeFlags(type) & QMetaType::IsEnumeration) == QMetaType::IsEnumeration)
+ type = QVariant::Int;
+ else if (type == QMetaType::UnknownType) {
if (argTypeNames.isEmpty())
argTypeNames = m.parameterTypes();
type = EnumType(object->metaObject(), argTypeNames.at(ii));
}
- if (type == QVariant::Invalid) {
+ if (type == QMetaType::UnknownType) {
if (unknownTypeError) *unknownTypeError = argTypeNames.at(ii);
free(args);
return 0;
@@ -754,12 +767,14 @@ int *QQmlPropertyCache::methodParameterTypes(QObject *object, int index,
for (int ii = 0; ii < argc; ++ii) {
int type = m.parameterType(ii);
- if (type == QVariant::Invalid) {
+ if ((QMetaType::typeFlags(type) & QMetaType::IsEnumeration) == QMetaType::IsEnumeration)
+ type = QVariant::Int;
+ else if (type == QMetaType::UnknownType) {
if (argTypeNames.isEmpty())
argTypeNames = m.parameterTypes();
type = EnumType(object->metaObject(), argTypeNames.at(ii));
}
- if (type == QVariant::Invalid) {
+ if (type == QMetaType::UnknownType) {
if (unknownTypeError) *unknownTypeError = argTypeNames.at(ii);
return 0;
}
diff --git a/src/qml/qml/qqmlstringconverters.cpp b/src/qml/qml/qqmlstringconverters.cpp
index 473097fab0..04b63ea7cd 100644
--- a/src/qml/qml/qqmlstringconverters.cpp
+++ b/src/qml/qml/qqmlstringconverters.cpp
@@ -128,6 +128,9 @@ QDateTime QQmlStringConverters::dateTimeFromString(const QString &s, bool *ok)
{
QDateTime d = QDateTime::fromString(s, Qt::ISODate);
if (ok) *ok = d.isValid();
+ // V8 never parses a date string as local time. For consistency do the same here.
+ if (d.timeSpec() == Qt::LocalTime)
+ d.setTimeSpec(Qt::UTC);
return d;
}
#endif // QT_NO_DATESTRING
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 781915e23e..abe2c0bfa4 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -1558,7 +1558,6 @@ void QQmlTypeData::dataReceived(const QByteArray &data)
ref.qualifier = import.qualifier;
ref.script = blob;
m_scripts << ref;
-
}
}
@@ -1657,8 +1656,8 @@ void QQmlTypeData::resolveTypes()
import.extractVersion(&vmaj, &vmin);
QList<QQmlError> errors;
- if (!m_imports.addImport(importDatabase, import.uri, import.qualifier,
- vmaj, vmin, import.type, qmldircomponentsnetwork, &errors)) {
+ if (m_imports.addImport(importDatabase, import.uri, import.qualifier, vmaj, vmin,
+ import.type, qmldircomponentsnetwork, &errors).isNull()) {
QQmlError error;
if (errors.size()) {
error = errors.takeFirst();
@@ -1859,8 +1858,9 @@ void QQmlScriptBlob::dataReceived(const QByteArray &data)
import.extractVersion(&vmaj, &vmin);
QList<QQmlError> errors;
- if (!m_imports.addImport(importDatabase, import.uri, import.qualifier, vmaj, vmin,
- import.type, QQmlDirComponents(), &errors)) {
+ QString importUrl = m_imports.addImport(importDatabase, import.uri, import.qualifier, vmaj, vmin,
+ import.type, QQmlDirComponents(), &errors);
+ if (importUrl.isNull()) {
QQmlError error = errors.takeFirst();
// description should be set by addImport().
error.setUrl(m_imports.baseUrl());
@@ -1871,6 +1871,22 @@ void QQmlScriptBlob::dataReceived(const QByteArray &data)
setError(errors);
return;
}
+
+ // Does this library contain any scripts?
+ QUrl libraryUrl(importUrl);
+ const QQmlDirParser *dirParser = typeLoader()->qmlDirParser(libraryUrl.path() + QLatin1String("qmldir"));
+ foreach (const QQmlDirParser::Script &script, dirParser->scripts()) {
+ QUrl scriptUrl = libraryUrl.resolved(QUrl(script.fileName));
+ QQmlScriptBlob *blob = typeLoader()->getScript(scriptUrl);
+ addDependency(blob);
+
+ ScriptReference ref;
+ ref.location = import.location.start;
+ ref.qualifier = script.nameSpace;
+ ref.nameSpace = import.qualifier;
+ ref.script = blob;
+ m_scripts << ref;
+ }
}
}
}
@@ -1902,11 +1918,20 @@ void QQmlScriptBlob::done()
m_scriptData->urlString = finalUrlString();
m_scriptData->importCache = new QQmlTypeNameCache();
- for (int ii = 0; !isError() && ii < m_scripts.count(); ++ii) {
- const ScriptReference &script = m_scripts.at(ii);
+ QSet<QString> ns;
+
+ for (int scriptIndex = 0; !isError() && scriptIndex < m_scripts.count(); ++scriptIndex) {
+ const ScriptReference &script = m_scripts.at(scriptIndex);
m_scriptData->scripts.append(script.script);
- m_scriptData->importCache->add(script.qualifier, ii);
+
+ if (!script.nameSpace.isNull()) {
+ if (!ns.contains(script.nameSpace)) {
+ ns.insert(script.nameSpace);
+ m_scriptData->importCache->add(script.nameSpace);
+ }
+ }
+ m_scriptData->importCache->add(script.qualifier, scriptIndex, script.nameSpace);
}
m_imports.populateCache(m_scriptData->importCache, engine);
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index c8c2756bd5..319b2e7a10 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -390,6 +390,7 @@ public:
QQmlScript::Location location;
QString qualifier;
+ QString nameSpace;
QQmlScriptBlob *script;
};
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index 6309335e59..352684ed5e 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -829,7 +829,7 @@ QObject *QQmlVME::run(QList<QQmlError> *errors,
bindValues.push(binding);
binding->m_mePtr = &bindValues.top();
- Q_ASSERT(binding->propertyIndex() == property);
+ Q_ASSERT(binding->propertyIndex() == (property & 0xFF00FFFF));
Q_ASSERT(binding->object() == target);
binding->addToObject();
diff --git a/src/qml/qml/qqmlwatcher.cpp b/src/qml/qml/qqmlwatcher.cpp
index 500185762f..4eaa3d2c2a 100644
--- a/src/qml/qml/qqmlwatcher.cpp
+++ b/src/qml/qml/qqmlwatcher.cpp
@@ -166,13 +166,14 @@ bool QQmlWatcher::addWatch(int id, quint32 objectId, const QString &expr)
return false;
}
-void QQmlWatcher::removeWatch(int id)
+bool QQmlWatcher::removeWatch(int id)
{
if (!m_proxies.contains(id))
- return;
+ return false;
QList<QPointer<QQmlWatchProxy> > proxies = m_proxies.take(id);
qDeleteAll(proxies);
+ return true;
}
void QQmlWatcher::addPropertyWatch(int id, QObject *object, quint32 debugId, const QMetaProperty &property)
diff --git a/src/qml/qml/qqmlwatcher_p.h b/src/qml/qml/qqmlwatcher_p.h
index 70dc9d468c..3ca2c83777 100644
--- a/src/qml/qml/qqmlwatcher_p.h
+++ b/src/qml/qml/qqmlwatcher_p.h
@@ -77,7 +77,7 @@ public:
bool addWatch(int id, quint32 objectId, const QByteArray &property);
bool addWatch(int id, quint32 objectId, const QString &expr);
- void removeWatch(int id);
+ bool removeWatch(int id);
Q_SIGNALS:
void propertyChanged(int id, int objectId, const QMetaProperty &property, const QVariant &value);
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index df1712976c..56743eb915 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -1384,7 +1384,7 @@ void QQmlXMLHttpRequest::readEncoding()
if (header.first == "content-type") {
int separatorIdx = header.second.indexOf(';');
if (separatorIdx == -1) {
- m_mime == header.second;
+ m_mime = header.second;
} else {
m_mime = header.second.mid(0, separatorIdx);
int charsetIdx = header.second.indexOf("charset=");
diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp
index 38a3acafa2..0cd6ffd082 100644
--- a/src/qml/qml/v4/qv4bindings.cpp
+++ b/src/qml/qml/v4/qv4bindings.cpp
@@ -1153,6 +1153,25 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
QML_V4_END_INSTR(ConvertColorToString, unaryop)
+ QML_V4_BEGIN_INSTR(ConvertObjectToBool, unaryop)
+ {
+ const Register &src = registers[instr->unaryop.src];
+ Register &output = registers[instr->unaryop.output];
+ // ### NaN
+ if (src.isUndefined())
+ output.setUndefined();
+ else
+ output.setbool(src.getQObject() != 0);
+ }
+ QML_V4_END_INSTR(ConvertObjectToBool, unaryop)
+
+ QML_V4_BEGIN_INSTR(ConvertNullToObject, unaryop)
+ {
+ Register &output = registers[instr->unaryop.output];
+ output.setQObject(0);
+ }
+ QML_V4_END_INSTR(ConvertNullToObject, unaryop)
+
QML_V4_BEGIN_INSTR(ResolveUrl, unaryop)
{
const Register &src = registers[instr->unaryop.src];
diff --git a/src/qml/qml/v4/qv4compiler.cpp b/src/qml/qml/v4/qv4compiler.cpp
index 09b0f3861b..c9495e8987 100644
--- a/src/qml/qml/v4/qv4compiler.cpp
+++ b/src/qml/qml/v4/qv4compiler.cpp
@@ -54,7 +54,6 @@ QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(bindingsDump, QML_BINDINGS_DUMP)
DEFINE_BOOL_CONFIG_OPTION(qmlDisableOptimizer, QML_DISABLE_OPTIMIZER)
-DEFINE_BOOL_CONFIG_OPTION(qmlExperimental, QML_EXPERIMENTAL)
DEFINE_BOOL_CONFIG_OPTION(qmlVerboseCompiler, QML_VERBOSE_COMPILER)
DEFINE_BOOL_CONFIG_OPTION(qmlBindingsTestEnv, QML_BINDINGS_TEST)
@@ -958,6 +957,7 @@ void QV4CompilerPrivate::visitMove(IR::Move *s)
case IR::StringType: opcode = V4Instr::ConvertStringToBool; break;
case IR::UrlType: opcode = V4Instr::ConvertUrlToBool; break;
case IR::ColorType: opcode = V4Instr::ConvertColorToBool; break;
+ case IR::ObjectType: opcode = V4Instr::ConvertObjectToBool; break;
default: break;
} // switch
} else if (targetTy == IR::IntType) {
@@ -1010,6 +1010,11 @@ void QV4CompilerPrivate::visitMove(IR::Move *s)
case IR::StringType: opcode = V4Instr::ConvertStringToColor; break;
default: break;
} // switch
+ } else if (targetTy == IR::ObjectType) {
+ switch (sourceTy) {
+ case IR::NullType: opcode = V4Instr::ConvertNullToObject; break;
+ default: break;
+ } // switch
}
if (opcode != V4Instr::Noop) {
V4Instr conv;
@@ -1354,9 +1359,6 @@ int QV4Compiler::compile(const Expression &expression, QQmlEnginePrivate *engine
{
if (!expression.expression.asAST()) return false;
- if (!qmlExperimental() && expression.property->isValueTypeSubProperty)
- return -1;
-
if (qmlDisableOptimizer() || !qmlEnableV4)
return -1;
diff --git a/src/qml/qml/v4/qv4instruction.cpp b/src/qml/qml/v4/qv4instruction.cpp
index 1ed8bd245e..cb6ff40589 100644
--- a/src/qml/qml/v4/qv4instruction.cpp
+++ b/src/qml/qml/v4/qv4instruction.cpp
@@ -189,6 +189,12 @@ void Bytecode::dump(const V4Instr *i, int address) const
case V4Instr::ConvertColorToString:
INSTR_DUMP << "\t" << "ConvertColorToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertObjectToBool:
+ INSTR_DUMP << "\t" << "ConvertObjectToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
+ case V4Instr::ConvertNullToObject:
+ INSTR_DUMP << "\t" << "ConvertNullToObject" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ResolveUrl:
INSTR_DUMP << "\t" << "ResolveUrl" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
diff --git a/src/qml/qml/v4/qv4instruction_p.h b/src/qml/qml/v4/qv4instruction_p.h
index d6c790e46f..239cb362cc 100644
--- a/src/qml/qml/v4/qv4instruction_p.h
+++ b/src/qml/qml/v4/qv4instruction_p.h
@@ -98,6 +98,8 @@ QT_BEGIN_NAMESPACE
F(ConvertUrlToString, unaryop) \
F(ConvertColorToBool, unaryop) \
F(ConvertColorToString, unaryop) \
+ F(ConvertObjectToBool, unaryop) \
+ F(ConvertNullToObject, unaryop) \
F(ResolveUrl, unaryop) \
F(MathSinReal, unaryop) \
F(MathCosReal, unaryop) \
diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp
index 481b23eb4a..ea4d1afbbc 100644
--- a/src/qml/qml/v4/qv4irbuilder.cpp
+++ b/src/qml/qml/v4/qv4irbuilder.cpp
@@ -428,7 +428,7 @@ bool QV4IRBuilder::visit(AST::IdentifierExpression *ast)
if (r.isValid()) {
if (r.type) {
_expr.code = _block->ATTACH_TYPE(name, r.type, IR::Name::ScopeStorage, line, column);
- } else if (r.importNamespace) {
+ } /*else if (r.importNamespace) {
QQmlMetaType::ModuleApiInstance *moduleApi = m_expression->importCache->moduleApi(r.importNamespace);
if (moduleApi) {
if (moduleApi->qobjectCallback) {
@@ -439,7 +439,7 @@ bool QV4IRBuilder::visit(AST::IdentifierExpression *ast)
if (moduleApi->qobjectApi)
_expr.code = _block->MODULE_OBJECT(name, moduleApi->qobjectApi->metaObject(), IR::Name::MemberStorage, line, column);
}
- }
+ }*/ //### we can't create the actual QObject here, as we may be running in a thread (can be reenabled once QTBUG-24894 is handled)
// We don't support anything else
} else {
bool found = false;
diff --git a/src/qml/qml/v8/qjsconverter_impl_p.h b/src/qml/qml/v8/qjsconverter_impl_p.h
index 10b8ab5fae..c2775df7f5 100644
--- a/src/qml/qml/v8/qjsconverter_impl_p.h
+++ b/src/qml/qml/v8/qjsconverter_impl_p.h
@@ -44,6 +44,10 @@
#ifndef QJSCONVERTER_IMPL_P_H
#define QJSCONVERTER_IMPL_P_H
+#ifdef Q_OS_QNX
+#include <malloc.h>
+#endif
+
QT_BEGIN_NAMESPACE
extern char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **digits_str);
diff --git a/src/qml/qml/v8/qjsvalue.cpp b/src/qml/qml/v8/qjsvalue.cpp
index 4471e68a61..6ecb97d2e5 100644
--- a/src/qml/qml/v8/qjsvalue.cpp
+++ b/src/qml/qml/v8/qjsvalue.cpp
@@ -428,7 +428,7 @@ quint32 QJSValue::toUInt() const
\table
\header \li Input Type \li Result
\row \li Undefined \li An invalid QVariant.
- \row \li Null \li An invalid QVariant.
+ \row \li Null \li A QVariant containing a null pointer (QMetaType::VoidStar).
\row \li Boolean \li A QVariant containing the value of the boolean.
\row \li Number \li A QVariant containing the value of the number.
\row \li String \li A QVariant containing the value of the string.
diff --git a/src/qml/qml/v8/qjsvalue_impl_p.h b/src/qml/qml/v8/qjsvalue_impl_p.h
index fbddcfa5ba..8d22204843 100644
--- a/src/qml/qml/v8/qjsvalue_impl_p.h
+++ b/src/qml/qml/v8/qjsvalue_impl_p.h
@@ -281,7 +281,7 @@ QVariant QJSValuePrivate::toVariant() const
case CNumber:
return QVariant(u.m_number);
case CNull:
- return QVariant();
+ return QVariant(QMetaType::VoidStar, 0);
case CUndefined:
return QVariant();
case JSValue:
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 0cd5d0ad6c..9c570d756b 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -1061,7 +1061,9 @@ v8::Handle<v8::Value> createQmlObject(const v8::Arguments &args)
QObject *obj = component.beginCreate(effectiveContext);
if (obj) {
- QQmlData::get(obj, true)->setImplicitDestructible();
+ QQmlData::get(obj, true)->explicitIndestructibleSet = false;
+ QQmlData::get(obj)->indestructible = false;
+
obj->setParent(parentArg);
@@ -1084,7 +1086,7 @@ v8::Handle<v8::Value> createQmlObject(const v8::Arguments &args)
}
/*!
-\qmlmethod object Qt::createComponent(url, mode)
+\qmlmethod object Qt::createComponent(url, mode, parent)
Returns a \l Component object created using the QML file at the specified \a url,
or \c null if an empty string was given.
@@ -1099,6 +1101,9 @@ will be \c Component.Loading while it is loading. The status will change to
\c Component.Ready if the component loads successfully, or \c Component.Error
if loading fails.
+If the optional \a parent parameter is given, it should refer to the object
+that will become the parent for the created \l Component object.
+
Call \l {Component::createObject()}{Component.createObject()} on the returned
component to create an object instance of the component.
@@ -1114,7 +1119,8 @@ use \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}.
v8::Handle<v8::Value> createComponent(const v8::Arguments &args)
{
const char *invalidArgs = "Qt.createComponent(): Invalid arguments";
- if (args.Length() < 1 || args.Length() > 2)
+ const char *invalidParent = "Qt.createComponent(): Invalid parent object";
+ if (args.Length() < 1 || args.Length() > 3)
V8THROW_ERROR(invalidArgs);
QV8Engine *v8engine = V8ENGINE();
@@ -1131,21 +1137,46 @@ v8::Handle<v8::Value> createComponent(const v8::Arguments &args)
return v8::Null();
QQmlComponent::CompilationMode compileMode = QQmlComponent::PreferSynchronous;
- if (args.Length() == 2) {
+
+ // Default to engine parent; this will be removed in the near future (QTBUG-24841)
+ QObject *parentArg = engine;
+
+ unsigned consumedCount = 1;
+ if (args.Length() > 1) {
+ const v8::Local<v8::Value> &lastArg = args[args.Length()-1];
+
+ // The second argument could be the mode enum
if (args[1]->IsInt32()) {
int mode = args[1]->Int32Value();
if (mode != int(QQmlComponent::PreferSynchronous) && mode != int(QQmlComponent::Asynchronous))
V8THROW_ERROR(invalidArgs);
compileMode = QQmlComponent::CompilationMode(mode);
+ consumedCount += 1;
} else {
- V8THROW_ERROR(invalidArgs);
+ // The second argument could be the parent only if there are exactly two args
+ if ((args.Length() != 2) || !(lastArg->IsObject() || lastArg->IsNull()))
+ V8THROW_ERROR(invalidArgs);
+ }
+
+ if (consumedCount < args.Length()) {
+ if (lastArg->IsObject()) {
+ parentArg = v8engine->toQObject(lastArg);
+ if (!parentArg)
+ V8THROW_ERROR(invalidParent);
+ } else if (lastArg->IsNull()) {
+ parentArg = 0;
+ } else {
+ V8THROW_ERROR(invalidParent);
+ }
}
}
QUrl url = context->resolvedUrl(QUrl(arg));
- QQmlComponent *c = new QQmlComponent(engine, url, compileMode, engine);
+ QQmlComponent *c = new QQmlComponent(engine, url, compileMode, parentArg);
QQmlComponentPrivate::get(c)->creationContext = effectiveContext;
- QQmlData::get(c, true)->setImplicitDestructible();
+ QQmlData::get(c, true)->explicitIndestructibleSet = false;
+ QQmlData::get(c)->indestructible = false;
+
return v8engine->newQObject(c);
}
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index f0df025541..678f9aa3ee 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -1368,7 +1368,8 @@ v8::Handle<v8::Value> QV8Engine::variantToJS(const QVariant &value)
}
// Converts a JS value to a QVariant.
-// Null, Undefined -> QVariant() (invalid)
+// Undefined -> QVariant() (invalid)
+// Null -> QVariant((void*)0)
// Boolean -> QVariant(bool)
// Number -> QVariant(double)
// String -> QVariant(QString)
@@ -1379,8 +1380,10 @@ v8::Handle<v8::Value> QV8Engine::variantToJS(const QVariant &value)
QVariant QV8Engine::variantFromJS(v8::Handle<v8::Value> value)
{
Q_ASSERT(!value.IsEmpty());
- if (value->IsNull() || value->IsUndefined())
+ if (value->IsUndefined())
return QVariant();
+ if (value->IsNull())
+ return QVariant(QMetaType::VoidStar, 0);
if (value->IsBoolean())
return value->ToBoolean()->Value();
if (value->IsInt32())