aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsapi
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-08-08 13:02:40 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-08-08 15:35:08 +0200
commit6c51b182f3fc3abdd6330b402c4fe16d623d1b0a (patch)
treef3f997f565d74420102c6f67faaada24b30a9350 /src/qml/jsapi
parent3081b4f90f59eeaa64fe3ff59e5bfbc84a16191f (diff)
Move the JS Api into it's own folder
Change-Id: I7ef371ff929387097862121b73a7a5863b51ccf1 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/jsapi')
-rw-r--r--src/qml/jsapi/jsapi.pri12
-rw-r--r--src/qml/jsapi/qjsengine.cpp430
-rw-r--r--src/qml/jsapi/qjsengine.h138
-rw-r--r--src/qml/jsapi/qjsengine_p.h75
-rw-r--r--src/qml/jsapi/qjsvalue.cpp1047
-rw-r--r--src/qml/jsapi/qjsvalue.h149
-rw-r--r--src/qml/jsapi/qjsvalue_p.h99
-rw-r--r--src/qml/jsapi/qjsvalueiterator.cpp206
-rw-r--r--src/qml/jsapi/qjsvalueiterator.h78
-rw-r--r--src/qml/jsapi/qjsvalueiterator_p.h70
10 files changed, 2304 insertions, 0 deletions
diff --git a/src/qml/jsapi/jsapi.pri b/src/qml/jsapi/jsapi.pri
new file mode 100644
index 0000000000..f70588ec7b
--- /dev/null
+++ b/src/qml/jsapi/jsapi.pri
@@ -0,0 +1,12 @@
+SOURCES += \
+ $$PWD/qjsengine.cpp \
+ $$PWD/qjsvalue.cpp \
+ $$PWD/qjsvalueiterator.cpp \
+
+HEADERS += \
+ $$PWD/qjsengine.h \
+ $$PWD/qjsengine_p.h \
+ $$PWD/qjsvalue.h \
+ $$PWD/qjsvalue_p.h \
+ $$PWD/qjsvalueiterator.h \
+ $$PWD/qjsvalueiterator_p.h
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
new file mode 100644
index 0000000000..d3c2c75ca7
--- /dev/null
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -0,0 +1,430 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qjsengine.h"
+#include "qjsengine_p.h"
+#include "qjsvalue.h"
+#include "qjsvalue_p.h"
+#include "private/qv8engine_p.h"
+
+#include "private/qv4engine_p.h"
+#include "private/qv4mm_p.h"
+#include "private/qv4globalobject_p.h"
+#include "private/qv4script_p.h"
+#include "private/qv4exception_p.h"
+
+#include <QtCore/qdatetime.h>
+#include <QtCore/qmetaobject.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qvariant.h>
+#include <QtCore/qdatetime.h>
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qdir.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qpluginloader.h>
+#include <qthread.h>
+#include <qmutex.h>
+#include <qwaitcondition.h>
+#include <private/qqmlglobal_p.h>
+#include <qqmlengine.h>
+
+#undef Q_D
+#undef Q_Q
+#define Q_D(blah)
+#define Q_Q(blah)
+
+Q_DECLARE_METATYPE(QList<int>)
+
+/*!
+ \since 5.0
+ \class QJSEngine
+
+ \brief The QJSEngine class provides an environment for evaluating JavaScript code.
+
+ \ingroup qtjavascript
+ \inmodule QtQml
+ \mainclass
+
+ \section1 Evaluating Scripts
+
+ Use evaluate() to evaluate script code.
+
+ \snippet code/src_script_qjsengine.cpp 0
+
+ evaluate() returns a QJSValue that holds the result of the
+ evaluation. The QJSValue class provides functions for converting
+ the result to various C++ types (e.g. QJSValue::toString()
+ and QJSValue::toNumber()).
+
+ The following code snippet shows how a script function can be
+ defined and then invoked from C++ using QJSValue::call():
+
+ \snippet code/src_script_qjsengine.cpp 1
+
+ As can be seen from the above snippets, a script is provided to the
+ engine in the form of a string. One common way of loading scripts is
+ by reading the contents of a file and passing it to evaluate():
+
+ \snippet code/src_script_qjsengine.cpp 2
+
+ Here we pass the name of the file as the second argument to
+ evaluate(). This does not affect evaluation in any way; the second
+ argument is a general-purpose string that is used to identify the
+ script for debugging purposes.
+
+ \section1 Engine Configuration
+
+ The globalObject() function returns the \b {Global Object}
+ associated with the script engine. Properties of the Global Object
+ are accessible from any script code (i.e. they are global
+ variables). Typically, before evaluating "user" scripts, you will
+ want to configure a script engine by adding one or more properties
+ to the Global Object:
+
+ \snippet code/src_script_qjsengine.cpp 3
+
+ Adding custom properties to the scripting environment is one of the
+ standard means of providing a scripting API that is specific to your
+ application. Usually these custom properties are objects created by
+ the newQObject() or newObject() functions.
+
+ \section1 Script Exceptions
+
+ evaluate() can throw a script exception (e.g. due to a syntax
+ error); in that case, the return value is the value that was thrown
+ (typically an \c{Error} object). You can check whether the
+ evaluation caused an exception by calling isError() on the return
+ value. If isError() returns true, you can call toString() on the
+ error object to obtain an error message.
+
+ \snippet code/src_script_qjsengine.cpp 4
+
+ \section1 Script Object Creation
+
+ Use newObject() to create a JavaScript object; this is the
+ C++ equivalent of the script statement \c{new Object()}. You can use
+ the object-specific functionality in QJSValue to manipulate the
+ script object (e.g. QJSValue::setProperty()). Similarly, use
+ newArray() to create a JavaScript array object.
+
+ \section1 QObject Integration
+
+ Use newQObject() to wrap a QObject (or subclass)
+ pointer. newQObject() returns a proxy script object; properties,
+ children, and signals and slots of the QObject are available as
+ properties of the proxy object. No binding code is needed because it
+ is done dynamically using the Qt meta object system.
+
+ \snippet code/src_script_qjsengine.cpp 5
+
+ \sa QJSValue, {Making Applications Scriptable}
+
+*/
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+ Constructs a QJSEngine object.
+
+ The globalObject() is initialized to have properties as described in
+ \l{ECMA-262}, Section 15.1.
+*/
+QJSEngine::QJSEngine()
+ : d(new QV8Engine(this))
+{
+}
+
+/*!
+ Constructs a QJSEngine object with the given \a parent.
+
+ The globalObject() is initialized to have properties as described in
+ \l{ECMA-262}, Section 15.1.
+*/
+
+QJSEngine::QJSEngine(QObject *parent)
+ : QObject(parent)
+ , d(new QV8Engine(this))
+{
+}
+
+/*!
+ \internal
+*/
+QJSEngine::QJSEngine(QJSEnginePrivate &dd, QObject *parent)
+ : QObject(dd, parent)
+ , d(new QV8Engine(this))
+{
+}
+
+/*!
+ Destroys this QJSEngine.
+
+ Garbage is not collected from the persistent JS heap during QJSEngine
+ destruction. If you need all memory freed, call collectGarbage manually
+ right before destroying the QJSEngine.
+*/
+QJSEngine::~QJSEngine()
+{
+ delete d;
+}
+
+/*!
+ \fn QV8Engine *QJSEngine::handle() const
+ \internal
+*/
+
+/*!
+ Runs the garbage collector.
+
+ The garbage collector will attempt to reclaim memory by locating and disposing of objects that are
+ no longer reachable in the script environment.
+
+ Normally you don't need to call this function; the garbage collector will automatically be invoked
+ when the QJSEngine decides that it's wise to do so (i.e. when a certain number of new objects
+ have been created). However, you can call this function to explicitly request that garbage
+ collection should be performed as soon as possible.
+*/
+void QJSEngine::collectGarbage()
+{
+ d->m_v4Engine->memoryManager->runGC();
+}
+
+/*!
+ Evaluates \a program, using \a lineNumber as the base line number,
+ and returns the result of the evaluation.
+
+ The script code will be evaluated in the current context.
+
+ The evaluation of \a program can cause an exception in the
+ engine; in this case the return value will be the exception
+ that was thrown (typically an \c{Error} object; see
+ QJSValue::isError()).
+
+ \a lineNumber is used to specify a starting line number for \a
+ program; line number information reported by the engine that pertain
+ to this evaluation will be based on this argument. For example, if
+ \a program consists of two lines of code, and the statement on the
+ second line causes a script exception, the exception line number
+ would be \a lineNumber plus one. When no starting line number is
+ specified, line numbers will be 1-based.
+
+ \a fileName is used for error reporting. For example in error objects
+ the file name is accessible through the "fileName" property if it's
+ provided with this function.
+
+ \note If an exception was thrown and the exception value is not an
+ Error instance (i.e., QJSValue::isError() returns false), the
+ exception value will still be returned, but there is currently no
+ API for detecting that an exception did occur in this case.
+*/
+QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, int lineNumber)
+{
+ QV4::ExecutionContext *ctx = d->m_v4Engine->current;
+ try {
+ QV4::Script script(ctx, program, fileName, lineNumber);
+ script.strictMode = ctx->strictMode;
+ script.inheritContext = true;
+ script.parse();
+ QV4::Value result = script.run();
+ return new QJSValuePrivate(d->m_v4Engine, result);
+ } catch (QV4::Exception& ex) {
+ ex.accept(ctx);
+ return new QJSValuePrivate(d->m_v4Engine, ex.value());
+ }
+}
+
+/*!
+ Creates a JavaScript object of class Object.
+
+ The prototype of the created object will be the Object
+ prototype object.
+
+ \sa newArray(), QJSValue::setProperty()
+*/
+QJSValue QJSEngine::newObject()
+{
+ return new QJSValuePrivate(d->m_v4Engine->newObject());
+}
+
+/*!
+ Creates a JavaScript object of class Array with the given \a length.
+
+ \sa newObject()
+*/
+QJSValue QJSEngine::newArray(uint length)
+{
+ QV4::ArrayObject *array = d->m_v4Engine->newArrayObject();
+ if (length < 0x1000)
+ array->arrayReserve(length);
+ array->setArrayLengthUnchecked(length);
+ return new QJSValuePrivate(array);
+}
+
+/*!
+ Creates a JavaScript object that wraps the given QObject \a
+ object, using JavaScriptOwnership.
+
+ Signals and slots, properties and children of \a object are
+ available as properties of the created QJSValue.
+
+ If \a object is a null pointer, this function returns a null value.
+
+ If a default prototype has been registered for the \a object's class
+ (or its superclass, recursively), the prototype of the new script
+ object will be set to be that default prototype.
+
+ If the given \a object is deleted outside of the engine's control, any
+ attempt to access the deleted QObject's members through the JavaScript
+ wrapper object (either by script code or C++) will result in a
+ script exception.
+
+ \sa QJSValue::toQObject()
+*/
+QJSValue QJSEngine::newQObject(QObject *object)
+{
+ Q_D(QJSEngine);
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(d);
+ QQmlEngine::setObjectOwnership(object, QQmlEngine::JavaScriptOwnership);
+ return new QJSValuePrivate(v4, QV4::QObjectWrapper::wrap(v4, object));
+}
+
+/*!
+ Returns this engine's Global Object.
+
+ By default, the Global Object contains the built-in objects that are
+ part of \l{ECMA-262}, such as Math, Date and String. Additionally,
+ you can set properties of the Global Object to make your own
+ extensions available to all script code. Non-local variables in
+ script code will be created as properties of the Global Object, as
+ well as local variables in global code.
+*/
+QJSValue QJSEngine::globalObject() const
+{
+ return new QJSValuePrivate(d->m_v4Engine->globalObject);
+}
+
+/*!
+ * \internal
+ * used by QJSEngine::toScriptValue
+ */
+QJSValue QJSEngine::create(int type, const void *ptr)
+{
+ Q_D(QJSEngine);
+ return new QJSValuePrivate(d->m_v4Engine, d->metaTypeToJS(type, ptr));
+}
+
+/*!
+ \internal
+ convert \a value to \a type, store the result in \a ptr
+*/
+bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr)
+{
+ QJSValuePrivate *vp = QJSValuePrivate::get(value);
+ QV8Engine *engine = vp->engine ? vp->engine->v8Engine : 0;
+ if (engine) {
+ return engine->metaTypeFromJS(vp->getValue(engine->m_v4Engine), type, ptr);
+ } else {
+ switch (type) {
+ case QMetaType::Bool:
+ *reinterpret_cast<bool*>(ptr) = vp->value.toBoolean();
+ return true;
+ case QMetaType::Int:
+ *reinterpret_cast<int*>(ptr) = vp->value.toInt32();
+ return true;
+ case QMetaType::UInt:
+ *reinterpret_cast<uint*>(ptr) = vp->value.toUInt32();
+ return true;
+ case QMetaType::LongLong:
+ *reinterpret_cast<qlonglong*>(ptr) = vp->value.toInteger();
+ return true;
+ case QMetaType::ULongLong:
+ *reinterpret_cast<qulonglong*>(ptr) = vp->value.toInteger();
+ return true;
+ case QMetaType::Double:
+ *reinterpret_cast<double*>(ptr) = vp->value.toNumber();
+ return true;
+ case QMetaType::QString:
+ *reinterpret_cast<QString*>(ptr) = value.toString();
+ return true;
+ case QMetaType::Float:
+ *reinterpret_cast<float*>(ptr) = vp->value.toNumber();
+ return true;
+ case QMetaType::Short:
+ *reinterpret_cast<short*>(ptr) = vp->value.toInt32();
+ return true;
+ case QMetaType::UShort:
+ *reinterpret_cast<unsigned short*>(ptr) = vp->value.toUInt16();
+ return true;
+ case QMetaType::Char:
+ *reinterpret_cast<char*>(ptr) = vp->value.toInt32();
+ return true;
+ case QMetaType::UChar:
+ *reinterpret_cast<unsigned char*>(ptr) = vp->value.toUInt16();
+ return true;
+ case QMetaType::QChar:
+ *reinterpret_cast<QChar*>(ptr) = vp->value.toUInt16();
+ return true;
+ default:
+ return false;
+ }
+ }
+}
+
+/*! \fn QJSValue QJSEngine::toScriptValue(const T &value)
+
+ Creates a QJSValue with the given \a value.
+
+ \sa fromScriptValue()
+*/
+
+/*! \fn T QJSEngine::fromScriptValue(const QJSValue &value)
+
+ Returns the given \a value converted to the template type \c{T}.
+
+ \sa toScriptValue()
+*/
+
+QT_END_NAMESPACE
+
+#include "moc_qjsengine.cpp"
diff --git a/src/qml/jsapi/qjsengine.h b/src/qml/jsapi/qjsengine.h
new file mode 100644
index 0000000000..0a575f84e9
--- /dev/null
+++ b/src/qml/jsapi/qjsengine.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QJSENGINE_H
+#define QJSENGINE_H
+
+#include <QtCore/qmetatype.h>
+
+#include <QtCore/qvariant.h>
+#include <QtCore/qsharedpointer.h>
+#include <QtCore/qobject.h>
+#include <QtQml/qjsvalue.h>
+
+QT_BEGIN_NAMESPACE
+
+
+class QV8Engine;
+
+template <typename T>
+inline T qjsvalue_cast(const QJSValue &);
+
+class QJSEnginePrivate;
+class Q_QML_EXPORT QJSEngine
+ : public QObject
+{
+ Q_OBJECT
+public:
+ QJSEngine();
+ explicit QJSEngine(QObject *parent);
+ virtual ~QJSEngine();
+
+ QJSValue globalObject() const;
+
+ QJSValue evaluate(const QString &program, const QString &fileName = QString(), int lineNumber = 1);
+
+ QJSValue newObject();
+ QJSValue newArray(uint length = 0);
+
+ QJSValue newQObject(QObject *object);
+
+ template <typename T>
+ inline QJSValue toScriptValue(const T &value)
+ {
+ return create(qMetaTypeId<T>(), &value);
+ }
+ template <typename T>
+ inline T fromScriptValue(const QJSValue &value)
+ {
+ return qjsvalue_cast<T>(value);
+ }
+
+ void collectGarbage();
+
+ QV8Engine *handle() const { return d; }
+
+private:
+ QJSValue create(int type, const void *ptr);
+
+ static bool convertV2(const QJSValue &value, int type, void *ptr);
+
+ friend inline bool qjsvalue_cast_helper(const QJSValue &, int, void *);
+
+protected:
+ QJSEngine(QJSEnginePrivate &dd, QObject *parent = 0);
+
+private:
+ QV8Engine *d;
+ Q_DISABLE_COPY(QJSEngine)
+ Q_DECLARE_PRIVATE(QJSEngine)
+ friend class QV8Engine;
+};
+
+inline bool qjsvalue_cast_helper(const QJSValue &value, int type, void *ptr)
+{
+ return QJSEngine::convertV2(value, type, ptr);
+}
+
+template<typename T>
+T qjsvalue_cast(const QJSValue &value)
+{
+ T t;
+ const int id = qMetaTypeId<T>();
+
+ if (qjsvalue_cast_helper(value, id, &t))
+ return t;
+ else if (value.isVariant())
+ return qvariant_cast<T>(value.toVariant());
+
+ return T();
+}
+
+template <>
+inline QVariant qjsvalue_cast<QVariant>(const QJSValue &value)
+{
+ return value.toVariant();
+}
+
+QT_END_NAMESPACE
+
+#endif // QJSENGINE_H
diff --git a/src/qml/jsapi/qjsengine_p.h b/src/qml/jsapi/qjsengine_p.h
new file mode 100644
index 0000000000..c12e647997
--- /dev/null
+++ b/src/qml/jsapi/qjsengine_p.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QJSENGINE_P_H
+#define QJSENGINE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/private/qobject_p.h>
+#include "qjsengine.h"
+
+
+QT_BEGIN_NAMESPACE
+
+
+class QJSEnginePrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QJSEngine)
+
+public:
+ static QJSEnginePrivate* get(QJSEngine*e) { return e->d_func(); }
+
+ QJSEnginePrivate() {}
+};
+
+QT_END_NAMESPACE
+
+#endif // QJSENGINE_P_H
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
new file mode 100644
index 0000000000..ec8cc2a1b3
--- /dev/null
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -0,0 +1,1047 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qstring.h>
+#include <QtCore/qvarlengtharray.h>
+#include <QtCore/qdatetime.h>
+#include "qjsengine.h"
+#include "qjsvalue.h"
+#include "qjsvalue_p.h"
+#include "qv4value_p.h"
+#include "qv4object_p.h"
+#include "qv4functionobject_p.h"
+#include "qv4dateobject_p.h"
+#include "qv4runtime_p.h"
+#include "qv4variantobject_p.h"
+#include "qv4regexpobject_p.h"
+#include "private/qv8engine_p.h"
+#include <private/qv4mm_p.h>
+#include <private/qv4exception_p.h>
+
+QV4::Value QJSValuePrivate::getValue(QV4::ExecutionEngine *e)
+{
+ if (!this->engine)
+ this->engine = e;
+ else if (this->engine != e) {
+ qWarning("JSValue can't be reassigned to another engine.");
+ return QV4::Value::emptyValue();
+ }
+ if (value.asString() == &string) {
+ value = QV4::Value::fromString(engine->newString(string.toQString()));
+ PersistentValuePrivate **listRoot = &engine->memoryManager->m_persistentValues;
+ prev = listRoot;
+ next = *listRoot;
+ *prev = this;
+ if (next)
+ next->prev = &this->next;
+ }
+ return value;
+}
+
+/*!
+ \since 5.0
+ \class QJSValue
+
+ \brief The QJSValue class acts as a container for Qt/JavaScript data types.
+
+ \ingroup qtjavascript
+ \inmodule QtQml
+ \mainclass
+
+ QJSValue supports the types defined in the \l{ECMA-262}
+ standard: The primitive types, which are Undefined, Null, Boolean,
+ Number, and String; and the Object type. Additionally, built-in
+ support is provided for Qt/C++ types such as QVariant and QObject.
+
+ For the object-based types (including Date and RegExp), use the
+ newT() functions in QJSEngine (e.g. QJSEngine::newObject())
+ to create a QJSValue of the desired type. For the primitive types,
+ use one of the QJSValue constructor overloads.
+
+ The methods named isT() (e.g. isBool(), isUndefined()) can be
+ used to test if a value is of a certain type. The methods named
+ toT() (e.g. toBool(), toString()) can be used to convert a
+ QJSValue to another type. You can also use the generic
+ QJSValue_cast() function.
+
+ Object values have zero or more properties which are themselves
+ QJSValues. Use setProperty() to set a property of an object, and
+ call property() to retrieve the value of a property.
+
+ \snippet code/src_script_qjsvalue.cpp 0
+
+ If you want to iterate over the properties of a script object, use
+ the QJSValueIterator class.
+
+ Object values have an internal \c{prototype} property, which can be
+ accessed with prototype() and setPrototype().
+
+ Function objects (objects for which isCallable()) returns true) can
+ be invoked by calling call(). Constructor functions can be used to
+ construct new objects by calling callAsConstructor().
+
+ Use equals() or strictlyEquals() to compare a QJSValue to another.
+
+ Note that a QJSValue for which isObject() is true only carries a
+ reference to an actual object; copying the QJSValue will only
+ copy the object reference, not the object itself. If you want to
+ clone an object (i.e. copy an object's properties to another
+ object), you can do so with the help of a \c{for-in} statement in
+ script code, or QJSValueIterator in C++.
+
+ \sa QJSEngine, QJSValueIterator
+*/
+
+/*!
+ \enum QJSValue::SpecialValue
+
+ This enum is used to specify a single-valued type.
+
+ \value UndefinedValue An undefined value.
+
+ \value NullValue A null value.
+*/
+
+QT_BEGIN_NAMESPACE
+
+using namespace QV4;
+
+/*!
+ Constructs a new QJSValue with a boolean \a value.
+*/
+QJSValue::QJSValue(bool value)
+ : d(new QJSValuePrivate(0, Value::fromBoolean(value)))
+{
+}
+
+QJSValue::QJSValue(QJSValuePrivate *dd)
+ : d(dd)
+{
+}
+
+/*!
+ Constructs a new QJSValue with a number \a value.
+*/
+QJSValue::QJSValue(int value)
+ : d(new QJSValuePrivate(0, Value::fromInt32(value)))
+{
+}
+
+/*!
+ Constructs a new QJSValue with a number \a value.
+*/
+QJSValue::QJSValue(uint value)
+ : d(new QJSValuePrivate(0, Value::fromUInt32(value)))
+{
+}
+
+/*!
+ Constructs a new QJSValue with a number \a value.
+*/
+QJSValue::QJSValue(double value)
+ : d(new QJSValuePrivate(0, Value::fromDouble(value)))
+{
+}
+
+/*!
+ Constructs a new QJSValue with a string \a value.
+*/
+QJSValue::QJSValue(const QString& value)
+ : d(new QJSValuePrivate(value))
+{
+}
+
+/*!
+ Constructs a new QJSValue with a special \a value.
+*/
+QJSValue::QJSValue(SpecialValue value)
+ : d(new QJSValuePrivate(0, value == UndefinedValue ? Value::undefinedValue() : Value::nullValue()))
+{
+}
+
+/*!
+ Constructs a new QJSValue with a string \a value.
+*/
+QJSValue::QJSValue(const QLatin1String &value)
+ : d(new QJSValuePrivate(value))
+{
+}
+
+/*!
+ Constructs a new QJSValue with a string \a value.
+*/
+#ifndef QT_NO_CAST_FROM_ASCII
+QJSValue::QJSValue(const char *value)
+ : d(new QJSValuePrivate(QString::fromLatin1(value)))
+{
+}
+#endif
+
+/*!
+ Constructs a new QJSValue that is a copy of \a other.
+
+ Note that if \a other is an object (i.e., isObject() would return
+ true), then only a reference to the underlying object is copied into
+ the new script value (i.e., the object itself is not copied).
+*/
+QJSValue::QJSValue(const QJSValue& other)
+ : d(other.d)
+{
+ d->ref();
+}
+
+/*!
+ Destroys this QJSValue.
+*/
+QJSValue::~QJSValue()
+{
+ d->deref();
+}
+
+/*!
+ Returns true if this QJSValue is of the primitive type Boolean;
+ otherwise returns false.
+
+ \sa toBool()
+*/
+bool QJSValue::isBool() const
+{
+ return d->value.isBoolean();
+}
+
+/*!
+ Returns true if this QJSValue is of the primitive type Number;
+ otherwise returns false.
+
+ \sa toNumber()
+*/
+bool QJSValue::isNumber() const
+{
+ return d->value.isNumber();
+}
+
+/*!
+ Returns true if this QJSValue is of the primitive type Null;
+ otherwise returns false.
+*/
+bool QJSValue::isNull() const
+{
+ return d->value.isNull();
+}
+
+/*!
+ Returns true if this QJSValue is of the primitive type String;
+ otherwise returns false.
+
+ \sa toString()
+*/
+bool QJSValue::isString() const
+{
+ return d->value.isString();
+}
+
+/*!
+ Returns true if this QJSValue is of the primitive type Undefined;
+ otherwise returns false.
+*/
+bool QJSValue::isUndefined() const
+{
+ return d->value.isUndefined();
+}
+
+/*!
+ Returns true if this QJSValue is an object of the Error class;
+ otherwise returns false.
+*/
+bool QJSValue::isError() const
+{
+ Object *o = d->value.asObject();
+ return o && o->asErrorObject();
+}
+
+/*!
+ Returns true if this QJSValue is an object of the Array class;
+ otherwise returns false.
+
+ \sa QJSEngine::newArray()
+*/
+bool QJSValue::isArray() const
+{
+ return d->value.asArrayObject();
+}
+
+/*!
+ Returns true if this QJSValue is of the Object type; otherwise
+ returns false.
+
+ Note that function values, variant values, and QObject values are
+ objects, so this function returns true for such values.
+
+ \sa QJSEngine::newObject()
+*/
+bool QJSValue::isObject() const
+{
+ return d->value.asObject();
+}
+
+/*!
+ Returns true if this QJSValue can be called a function, otherwise
+ returns false.
+
+ \sa call()
+*/
+bool QJSValue::isCallable() const
+{
+ return d->value.asFunctionObject();
+}
+
+/*!
+ Returns true if this QJSValue is a variant value;
+ otherwise returns false.
+
+ \sa toVariant()
+*/
+bool QJSValue::isVariant() const
+{
+ Managed *m = d->value.asManaged();
+ return m ? m->as<QV4::VariantObject>() : 0;
+}
+
+/*!
+ Returns the string value of this QJSValue, as defined in
+ \l{ECMA-262} section 9.8, "ToString".
+
+ Note that if this QJSValue is an object, calling this function
+ has side effects on the script engine, since the engine will call
+ the object's toString() function (and possibly valueOf()) in an
+ attempt to convert the object to a primitive value (possibly
+ resulting in an uncaught script exception).
+
+ \sa isString()
+*/
+QString QJSValue::toString() const
+{
+ return d->value.toQString();
+}
+
+/*!
+ Returns the number value of this QJSValue, as defined in
+ \l{ECMA-262} section 9.3, "ToNumber".
+
+ Note that if this QJSValue is an object, calling this function
+ has side effects on the script engine, since the engine will call
+ the object's valueOf() function (and possibly toString()) in an
+ attempt to convert the object to a primitive value (possibly
+ resulting in an uncaught script exception).
+
+ \sa isNumber(), toInt(), toUInt()
+*/
+double QJSValue::toNumber() const
+{
+ QV4::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
+ try {
+ return d->value.toNumber();
+ } catch (Exception &e) {
+ e.accept(ctx);
+ return 0;
+ }
+}
+
+/*!
+ Returns the boolean value of this QJSValue, using the conversion
+ rules described in \l{ECMA-262} section 9.2, "ToBoolean".
+
+ Note that if this QJSValue is an object, calling this function
+ has side effects on the script engine, since the engine will call
+ the object's valueOf() function (and possibly toString()) in an
+ attempt to convert the object to a primitive value (possibly
+ resulting in an uncaught script exception).
+
+ \sa isBool()
+*/
+bool QJSValue::toBool() const
+{
+ QV4::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
+ try {
+ return d->value.toBoolean();
+ } catch (Exception &e) {
+ e.accept(ctx);
+ return false;
+ }
+}
+
+/*!
+ Returns the signed 32-bit integer value of this QJSValue, using
+ the conversion rules described in \l{ECMA-262} section 9.5, "ToInt32".
+
+ Note that if this QJSValue is an object, calling this function
+ has side effects on the script engine, since the engine will call
+ the object's valueOf() function (and possibly toString()) in an
+ attempt to convert the object to a primitive value (possibly
+ resulting in an uncaught script exception).
+
+ \sa toNumber(), toUInt()
+*/
+qint32 QJSValue::toInt() const
+{
+ QV4::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
+ try {
+ return d->value.toInt32();
+ } catch (Exception &e) {
+ e.accept(ctx);
+ return 0;
+ }
+}
+
+/*!
+ Returns the unsigned 32-bit integer value of this QJSValue, using
+ the conversion rules described in \l{ECMA-262} section 9.6, "ToUint32".
+
+ Note that if this QJSValue is an object, calling this function
+ has side effects on the script engine, since the engine will call
+ the object's valueOf() function (and possibly toString()) in an
+ attempt to convert the object to a primitive value (possibly
+ resulting in an uncaught script exception).
+
+ \sa toNumber(), toInt()
+*/
+quint32 QJSValue::toUInt() const
+{
+ QV4::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
+ try {
+ return d->value.toUInt32();
+ } catch (Exception &e) {
+ e.accept(ctx);
+ return 0;
+ }
+}
+
+/*!
+ Returns the QVariant value of this QJSValue, if it can be
+ converted to a QVariant; otherwise returns an invalid QVariant.
+ The conversion is performed according to the following table:
+
+ \table
+ \header \li Input Type \li Result
+ \row \li Undefined \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.
+ \row \li QVariant Object \li The result is the QVariant value of the object (no conversion).
+ \row \li QObject Object \li A QVariant containing a pointer to the QObject.
+ \row \li Date Object \li A QVariant containing the date value (toDateTime()).
+ \row \li RegExp Object \li A QVariant containing the regular expression value.
+ \row \li Array Object \li The array is converted to a QVariantList. Each element is converted to a QVariant, recursively; cyclic references are not followed.
+ \row \li Object \li The object is converted to a QVariantMap. Each property is converted to a QVariant, recursively; cyclic references are not followed.
+ \endtable
+
+ \sa isVariant()
+*/
+QVariant QJSValue::toVariant() const
+{
+ return QV4::VariantObject::toVariant(d->value);
+}
+
+/*!
+ Calls this QJSValue as a function, passing \a args as arguments
+ to the function, and using the globalObject() as the "this"-object.
+ Returns the value returned from the function.
+
+ If this QJSValue is not callable, call() does nothing and
+ returns an undefined QJSValue.
+
+ Calling call() can cause an exception to occur in the script engine;
+ in that case, call() returns the value that was thrown (typically an
+ \c{Error} object). You can call isError() on the return value to
+ determine whether an exception occurred.
+
+ \sa isCallable(), callWithInstance(), callAsConstructor()
+*/
+QJSValue QJSValue::call(const QJSValueList &args)
+{
+ FunctionObject *f = d->value.asFunctionObject();
+ if (!f)
+ return QJSValue();
+
+ ExecutionEngine *engine = d->engine;
+ assert(engine);
+
+ QVarLengthArray<Value, 9> arguments(args.length());
+ for (int i = 0; i < args.size(); ++i) {
+ if (!args.at(i).d->checkEngine(engine)) {
+ qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
+ return QJSValue();
+ }
+ arguments[i] = args.at(i).d->getValue(engine);
+ }
+
+ Value result;
+ QV4::ExecutionContext *ctx = engine->current;
+ try {
+ result = f->call(Value::fromObject(engine->globalObject), arguments.data(), arguments.size());
+ } catch (Exception &e) {
+ e.accept(ctx);
+ result = e.value();
+ }
+
+ return new QJSValuePrivate(engine, result);
+}
+
+/*!
+ Calls this QJSValue as a function, using \a instance as
+ the `this' object in the function call, and passing \a args
+ as arguments to the function. Returns the value returned from
+ the function.
+
+ If this QJSValue is not a function, call() does nothing
+ and returns an undefined QJSValue.
+
+ Note that if \a instance is not an object, the global object
+ (see \l{QJSEngine::globalObject()}) will be used as the
+ `this' object.
+
+ Calling call() can cause an exception to occur in the script engine;
+ in that case, call() returns the value that was thrown (typically an
+ \c{Error} object). You can call isError() on the return value to
+ determine whether an exception occurred.
+
+ \sa call()
+*/
+QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList &args)
+{
+ FunctionObject *f = d->value.asFunctionObject();
+ if (!f)
+ return QJSValue();
+
+ ExecutionEngine *engine = d->engine;
+ assert(engine);
+
+ if (!instance.d->checkEngine(engine)) {
+ qWarning("QJSValue::call() failed: cannot call function with thisObject created in a different engine");
+ return QJSValue();
+ }
+
+ QVarLengthArray<Value, 9> arguments(args.length());
+ for (int i = 0; i < args.size(); ++i) {
+ if (!args.at(i).d->checkEngine(engine)) {
+ qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
+ return QJSValue();
+ }
+ arguments[i] = args.at(i).d->getValue(engine);
+ }
+
+ Value result;
+ QV4::ExecutionContext *ctx = engine->current;
+ try {
+ result = f->call(instance.d->getValue(engine), arguments.data(), arguments.size());
+ } catch (Exception &e) {
+ e.accept(ctx);
+ result = e.value();
+ }
+
+ return new QJSValuePrivate(engine, result);
+}
+
+/*!
+ Creates a new \c{Object} and calls this QJSValue as a
+ constructor, using the created object as the `this' object and
+ passing \a args as arguments. If the return value from the
+ constructor call is an object, then that object is returned;
+ otherwise the default constructed object is returned.
+
+ If this QJSValue is not a function, callAsConstructor() does
+ nothing and returns an undefined QJSValue.
+
+ Calling this function can cause an exception to occur in the
+ script engine; in that case, the value that was thrown
+ (typically an \c{Error} object) is returned. You can call
+ isError() on the return value to determine whether an
+ exception occurred.
+
+ \sa call(), QJSEngine::newObject()
+*/
+QJSValue QJSValue::callAsConstructor(const QJSValueList &args)
+{
+ FunctionObject *f = d->value.asFunctionObject();
+ if (!f)
+ return QJSValue();
+
+ ExecutionEngine *engine = d->engine;
+ assert(engine);
+
+ QVarLengthArray<Value, 9> arguments(args.length());
+ for (int i = 0; i < args.size(); ++i) {
+ if (!args.at(i).d->checkEngine(engine)) {
+ qWarning("QJSValue::callAsConstructor() failed: cannot construct function with argument created in a different engine");
+ return QJSValue();
+ }
+ arguments[i] = args.at(i).d->getValue(engine);
+ }
+
+ Value result;
+ QV4::ExecutionContext *ctx = engine->current;
+ try {
+ result = f->construct(arguments.data(), arguments.size());
+ } catch (Exception &e) {
+ e.accept(ctx);
+ result = e.value();
+ }
+
+ return new QJSValuePrivate(engine, result);
+}
+
+#ifdef QT_DEPRECATED
+
+/*!
+ \obsolete
+
+ Returns the QJSEngine that created this QJSValue,
+ or 0 if this QJSValue is invalid or the value is not
+ associated with a particular engine.
+*/
+QJSEngine* QJSValue::engine() const
+{
+ QV4::ExecutionEngine *engine = d->engine;
+ if (engine)
+ return engine->v8Engine->publicEngine();
+ return 0;
+}
+
+#endif // QT_DEPRECATED
+
+/*!
+ If this QJSValue is an object, returns the internal prototype
+ (\c{__proto__} property) of this object; otherwise returns an
+ undefined QJSValue.
+
+ \sa setPrototype(), isObject()
+*/
+QJSValue QJSValue::prototype() const
+{
+ Object *o = d->value.asObject();
+ if (!o)
+ return QJSValue();
+ if (!o->prototype)
+ return QJSValue(NullValue);
+ return new QJSValuePrivate(o->internalClass->engine, Value::fromObject(o->prototype));
+}
+
+/*!
+ If this QJSValue is an object, sets the internal prototype
+ (\c{__proto__} property) of this object to be \a prototype;
+ if the QJSValue is null, it sets the prototype to null;
+ otherwise does nothing.
+
+ The internal prototype should not be confused with the public
+ property with name "prototype"; the public prototype is usually
+ only set on functions that act as constructors.
+
+ \sa prototype(), isObject()
+*/
+void QJSValue::setPrototype(const QJSValue& prototype)
+{
+ Object *o = d->value.asObject();
+ if (!o)
+ return;
+ if (prototype.d->value.isNull()) {
+ o->prototype = 0;
+ return;
+ }
+
+ Object *p = prototype.d->value.asObject();
+ if (!p)
+ return;
+ if (o->engine() != p->engine()) {
+ qWarning("QJSValue::setPrototype() failed: cannot set a prototype created in a different engine");
+ return;
+ }
+ Object *pp = p;
+ while (pp) {
+ if (pp == o) {
+ qWarning("QJSValue::setPrototype() failed: cyclic prototype value");
+ return;
+ }
+ pp = pp->prototype;
+ }
+ o->prototype = p;
+}
+
+/*!
+ Assigns the \a other value to this QJSValue.
+
+ Note that if \a other is an object (isObject() returns true),
+ only a reference to the underlying object will be assigned;
+ the object itself will not be copied.
+*/
+QJSValue& QJSValue::operator=(const QJSValue& other)
+{
+ if (d == other.d)
+ return *this;
+ d->deref();
+ d = other.d;
+ d->ref();
+}
+
+/*!
+ Returns true if this QJSValue is equal to \a other, otherwise
+ returns false. The comparison follows the behavior described in
+ \l{ECMA-262} section 11.9.3, "The Abstract Equality Comparison
+ Algorithm".
+
+ This function can return true even if the type of this QJSValue
+ is different from the type of the \a other value; i.e. the
+ comparison is not strict. For example, comparing the number 9 to
+ the string "9" returns true; comparing an undefined value to a null
+ value returns true; comparing a \c{Number} object whose primitive
+ value is 6 to a \c{String} object whose primitive value is "6"
+ returns true; and comparing the number 1 to the boolean value
+ \c{true} returns true. If you want to perform a comparison
+ without such implicit value conversion, use strictlyEquals().
+
+ Note that if this QJSValue or the \a other value are objects,
+ calling this function has side effects on the script engine, since
+ the engine will call the object's valueOf() function (and possibly
+ toString()) in an attempt to convert the object to a primitive value
+ (possibly resulting in an uncaught script exception).
+
+ \sa strictlyEquals()
+*/
+bool QJSValue::equals(const QJSValue& other) const
+{
+ return __qmljs_cmp_eq(d->value, other.d->value);
+}
+
+/*!
+ Returns true if this QJSValue is equal to \a other using strict
+ comparison (no conversion), otherwise returns false. The comparison
+ follows the behavior described in \l{ECMA-262} section 11.9.6, "The
+ Strict Equality Comparison Algorithm".
+
+ If the type of this QJSValue is different from the type of the
+ \a other value, this function returns false. If the types are equal,
+ the result depends on the type, as shown in the following table:
+
+ \table
+ \header \li Type \li Result
+ \row \li Undefined \li true
+ \row \li Null \li true
+ \row \li Boolean \li true if both values are true, false otherwise
+ \row \li Number \li false if either value is NaN (Not-a-Number); true if values are equal, false otherwise
+ \row \li String \li true if both values are exactly the same sequence of characters, false otherwise
+ \row \li Object \li true if both values refer to the same object, false otherwise
+ \endtable
+
+ \sa equals()
+*/
+bool QJSValue::strictlyEquals(const QJSValue& other) const
+{
+ return __qmljs_strict_equal(d->value, other.d->value);
+}
+
+/*!
+ Returns the value of this QJSValue's property with the given \a name.
+ If no such property exists, an undefined QJSValue is returned.
+
+ If the property is implemented using a getter function (i.e. has the
+ PropertyGetter flag set), calling property() has side-effects on the
+ script engine, since the getter function will be called (possibly
+ resulting in an uncaught script exception). If an exception
+ occurred, property() returns the value that was thrown (typically
+ an \c{Error} object).
+
+ \sa setProperty(), hasProperty(), QJSValueIterator
+*/
+QJSValue QJSValue::property(const QString& name) const
+{
+ Object *o = d->value.asObject();
+ if (!o)
+ return QJSValue();
+
+ ExecutionEngine *engine = d->engine;
+ String *s = engine->newString(name);
+ uint idx = s->asArrayIndex();
+ if (idx < UINT_MAX)
+ return property(idx);
+
+ s->makeIdentifier();
+ QV4::ExecutionContext *ctx = engine->current;
+ try {
+ QV4::Value v = o->get(s);
+ return new QJSValuePrivate(engine, v);
+ } catch (QV4::Exception &e) {
+ e.accept(ctx);
+ return new QJSValuePrivate(engine, e.value());
+ }
+}
+
+/*!
+ \overload
+
+ Returns the property at the given \a arrayIndex.
+
+ This function is provided for convenience and performance when
+ working with array objects.
+
+ If this QJSValue is not an Array object, this function behaves
+ as if property() was called with the string representation of \a
+ arrayIndex.
+*/
+QJSValue QJSValue::property(quint32 arrayIndex) const
+{
+ Object *o = d->value.asObject();
+ if (!o)
+ return QJSValue();
+
+ ExecutionEngine *engine = d->engine;
+ QV4::ExecutionContext *ctx = engine->current;
+ try {
+ QV4::Value v = arrayIndex == UINT_MAX ? o->get(engine->id_uintMax) : o->getIndexed(arrayIndex);
+ return new QJSValuePrivate(engine, v);
+ } catch (QV4::Exception &e) {
+ e.accept(ctx);
+ return new QJSValuePrivate(engine, e.value());
+ }
+}
+
+/*!
+ Sets the value of this QJSValue's property with the given \a name to
+ the given \a value.
+
+ If this QJSValue is not an object, this function does nothing.
+
+ If this QJSValue does not already have a property with name \a name,
+ a new property is created.
+
+ \sa property(), deleteProperty()
+*/
+void QJSValue::setProperty(const QString& name, const QJSValue& value)
+{
+ Object *o = d->value.asObject();
+ if (!o)
+ return;
+
+ if (!value.d->checkEngine(o->engine())) {
+ qWarning("QJSValue::setProperty(%s) failed: cannot set value created in a different engine", name.toUtf8().constData());
+ return;
+ }
+
+ ExecutionEngine *engine = d->engine;
+ String *s = engine->newString(name);
+ uint idx = s->asArrayIndex();
+ if (idx < UINT_MAX) {
+ setProperty(idx, value);
+ return;
+ }
+
+ QV4::ExecutionContext *ctx = engine->current;
+ s->makeIdentifier();
+ try {
+ o->put(s, value.d->getValue(engine));
+ } catch (QV4::Exception &e) {
+ e.accept(ctx);
+ }
+}
+
+/*!
+ \overload
+
+ Sets the property at the given \a arrayIndex to the given \a value.
+
+ This function is provided for convenience and performance when
+ working with array objects.
+
+ If this QJSValue is not an Array object, this function behaves
+ as if setProperty() was called with the string representation of \a
+ arrayIndex.
+*/
+void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value)
+{
+ Object *o = d->value.asObject();
+ if (!o)
+ return;
+
+ ExecutionEngine *engine = d->engine;
+ QV4::ExecutionContext *ctx = engine->current;
+ try {
+ if (arrayIndex != UINT_MAX)
+ o->putIndexed(arrayIndex, value.d->getValue(engine));
+ else
+ o->put(engine->id_uintMax, value.d->getValue(engine));
+ } catch (QV4::Exception &e) {
+ e.accept(ctx);
+ }
+}
+
+/*!
+ Attempts to delete this object's property of the given \a name.
+ Returns true if the property was deleted, otherwise returns false.
+
+ The behavior of this function is consistent with the JavaScript
+ delete operator. In particular:
+
+ \list
+ \li Non-configurable properties cannot be deleted.
+ \li This function will return true even if this object doesn't
+ have a property of the given \a name (i.e., non-existent
+ properties are "trivially deletable").
+ \li If this object doesn't have an own property of the given
+ \a name, but an object in the prototype() chain does, the
+ prototype object's property is not deleted, and this function
+ returns true.
+ \endlist
+
+ \sa setProperty(), hasOwnProperty()
+*/
+bool QJSValue::deleteProperty(const QString &name)
+{
+ Object *o = d->value.asObject();
+ if (!o)
+ return false;
+
+ ExecutionEngine *engine = d->engine;
+ String *s = engine->newString(name);
+ return o->deleteProperty(s);
+}
+
+/*!
+ Returns true if this object has a property of the given \a name,
+ otherwise returns false.
+
+ \sa property(), hasOwnProperty()
+*/
+bool QJSValue::hasProperty(const QString &name) const
+{
+ Object *o = d->value.asObject();
+ if (!o)
+ return false;
+
+ ExecutionEngine *engine = d->engine;
+ String *s = engine->newIdentifier(name);
+ return o->__hasProperty__(s);
+}
+
+/*!
+ Returns true if this object has an own (not prototype-inherited)
+ property of the given \a name, otherwise returns false.
+
+ \sa property(), hasProperty()
+*/
+bool QJSValue::hasOwnProperty(const QString &name) const
+{
+ Object *o = d->value.asObject();
+ if (!o)
+ return false;
+
+ ExecutionEngine *engine = d->engine;
+ String *s = engine->newIdentifier(name);
+ return o->__getOwnProperty__(s);
+}
+
+/*!
+ * If this QJSValue is a QObject, returns the QObject pointer
+ * that the QJSValue represents; otherwise, returns 0.
+ *
+ * If the QObject that this QJSValue wraps has been deleted,
+ * this function returns 0 (i.e. it is possible for toQObject()
+ * to return 0 even when isQObject() returns true).
+ *
+ * \sa isQObject()
+ */
+QObject *QJSValue::toQObject() const
+{
+ QV4::QObjectWrapper *o = d->value.as<QV4::QObjectWrapper>();
+ if (!o)
+ return 0;
+
+ return o->object();
+}
+
+/*!
+ Returns a QDateTime representation of this value, in local time.
+ If this QJSValue is not a date, or the value of the date is NaN
+ (Not-a-Number), an invalid QDateTime is returned.
+
+ \sa isDate()
+*/
+QDateTime QJSValue::toDateTime() const
+{
+ QV4::DateObject *date = d->value.asDateObject();
+ if (!date)
+ return QDateTime();
+ return date->toQDateTime();
+}
+
+/*!
+ Returns true if this QJSValue is an object of the Date class;
+ otherwise returns false.
+
+ \sa QJSEngine::newDate()
+*/
+bool QJSValue::isDate() const
+{
+ return d->value.asDateObject();
+}
+
+/*!
+ Returns true if this QJSValue is an object of the RegExp class;
+ otherwise returns false.
+*/
+bool QJSValue::isRegExp() const
+{
+ return d->value.as<RegExpObject>();
+}
+
+/*!
+ Returns true if this QJSValue is a QObject; otherwise returns
+ false.
+
+ Note: This function returns true even if the QObject that this
+ QJSValue wraps has been deleted.
+
+ \sa toQObject(), QJSEngine::newQObject()
+*/
+bool QJSValue::isQObject() const
+{
+ return d->value.as<QV4::QObjectWrapper>() != 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/qml/jsapi/qjsvalue.h b/src/qml/jsapi/qjsvalue.h
new file mode 100644
index 0000000000..cf02ad819e
--- /dev/null
+++ b/src/qml/jsapi/qjsvalue.h
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QJSVALUE_H
+#define QJSVALUE_H
+
+#include <QtQml/qtqmlglobal.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qmetatype.h>
+
+QT_BEGIN_NAMESPACE
+
+
+class QJSValue;
+class QJSEngine;
+class QVariant;
+class QObject;
+struct QMetaObject;
+class QDateTime;
+
+typedef QList<QJSValue> QJSValueList;
+class QJSValuePrivate;
+
+class Q_QML_EXPORT QJSValue
+{
+public:
+ enum SpecialValue {
+ NullValue,
+ UndefinedValue
+ };
+
+public:
+ QJSValue(SpecialValue value = UndefinedValue);
+ ~QJSValue();
+ QJSValue(const QJSValue &other);
+
+ QJSValue(bool value);
+ QJSValue(int value);
+ QJSValue(uint value);
+ QJSValue(double value);
+ QJSValue(const QString &value);
+ QJSValue(const QLatin1String &value);
+#ifndef QT_NO_CAST_FROM_ASCII
+ QT_ASCII_CAST_WARN QJSValue(const char *str);
+#endif
+
+ QJSValue &operator=(const QJSValue &other);
+
+ bool isBool() const;
+ bool isNumber() const;
+ bool isNull() const;
+ bool isString() const;
+ bool isUndefined() const;
+ bool isVariant() const;
+ bool isQObject() const;
+ bool isObject() const;
+ bool isDate() const;
+ bool isRegExp() const;
+ bool isArray() const;
+ bool isError() const;
+
+ QString toString() const;
+ double toNumber() const;
+ qint32 toInt() const;
+ quint32 toUInt() const;
+ bool toBool() const;
+ QVariant toVariant() const;
+ QObject *toQObject() const;
+ QDateTime toDateTime() const;
+
+ bool equals(const QJSValue &other) const;
+ bool strictlyEquals(const QJSValue &other) const;
+
+ QJSValue prototype() const;
+ void setPrototype(const QJSValue &prototype);
+
+ QJSValue property(const QString &name) const;
+ void setProperty(const QString &name, const QJSValue &value);
+
+ bool hasProperty(const QString &name) const;
+ bool hasOwnProperty(const QString &name) const;
+
+ QJSValue property(quint32 arrayIndex) const;
+ void setProperty(quint32 arrayIndex, const QJSValue &value);
+
+ bool deleteProperty(const QString &name);
+
+ bool isCallable() const;
+ QJSValue call(const QJSValueList &args = QJSValueList());
+ QJSValue callWithInstance(const QJSValue &instance, const QJSValueList &args = QJSValueList());
+ QJSValue callAsConstructor(const QJSValueList &args = QJSValueList());
+
+#ifdef QT_DEPRECATED
+ QT_DEPRECATED QJSEngine *engine() const;
+#endif
+
+ QJSValue(QJSValuePrivate *dd);
+private:
+ friend class QJSValuePrivate;
+ // force compile error, prevent QJSValue(bool) to be called
+ QJSValue(void *) Q_DECL_EQ_DELETE;
+
+ QJSValuePrivate *d;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QJSValue)
+
+#endif
diff --git a/src/qml/jsapi/qjsvalue_p.h b/src/qml/jsapi/qjsvalue_p.h
new file mode 100644
index 0000000000..ef94dea555
--- /dev/null
+++ b/src/qml/jsapi/qjsvalue_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// 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.
+//
+
+#ifndef QJSVALUE_P_H
+#define QJSVALUE_P_H
+
+#include <qjsvalue.h>
+#include <private/qv4value_p.h>
+#include <private/qv4string_p.h>
+#include <private/qv4engine_p.h>
+#include <private/qv4object_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \internal
+ \class QJSValuePrivate
+*/
+class QJSValuePrivate : public QV4::PersistentValuePrivate
+{
+public:
+ QJSValuePrivate(QV4::ExecutionEngine *engine, const QV4::Value &v)
+ : PersistentValuePrivate(v, engine)
+ {
+ if (value.isEmpty())
+ value = QV4::Value::undefinedValue();
+ }
+ QJSValuePrivate(QV4::Object *o)
+ : PersistentValuePrivate(QV4::Value::fromObject(o))
+ { }
+ QJSValuePrivate(QV4::String *s)
+ : PersistentValuePrivate(QV4::Value::fromString(s))
+ { }
+ QJSValuePrivate(const QString &s)
+ : PersistentValuePrivate(QV4::Value::undefinedValue())
+ , string(0, s)
+ {
+ value = QV4::Value::fromString(&string);
+ }
+
+ QV4::Value getValue(QV4::ExecutionEngine *e);
+
+ static QJSValuePrivate *get(const QJSValue &v) { return v.d; }
+
+ QV4::String string;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/jsapi/qjsvalueiterator.cpp b/src/qml/jsapi/qjsvalueiterator.cpp
new file mode 100644
index 0000000000..aa1ecd6e54
--- /dev/null
+++ b/src/qml/jsapi/qjsvalueiterator.cpp
@@ -0,0 +1,206 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qjsvalueiterator.h"
+#include "qjsvalueiterator_p.h"
+#include "qjsvalue_p.h"
+#include "private/qv4string_p.h"
+#include "private/qv4object_p.h"
+#include "private/qv4exception_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QJSValueIteratorPrivate::QJSValueIteratorPrivate(const QJSValue &v)
+ : value(v)
+ , iterator(QJSValuePrivate::get(v)->value.asObject(), QV4::ObjectIterator::NoFlags)
+ , currentName(0)
+ , currentIndex(UINT_MAX)
+ , nextName(0)
+ , nextIndex(UINT_MAX)
+{
+}
+
+
+/*!
+ \class QJSValueIterator
+
+ \brief The QJSValueIterator class provides a Java-style iterator for QJSValue.
+
+ \ingroup qtjavascript
+ \inmodule QtQml
+
+
+ The QJSValueIterator constructor takes a QJSValue as
+ argument. After construction, the iterator is located at the very
+ beginning of the sequence of properties. Here's how to iterate over
+ all the properties of a QJSValue:
+
+ \snippet code/src_script_qjsvalueiterator.cpp 0
+
+ The next() advances the iterator. The name() and value()
+ functions return the name and value of the last item that was
+ jumped over.
+
+ Note that QJSValueIterator only iterates over the QJSValue's
+ own properties; i.e. it does not follow the prototype chain. You can
+ use a loop like this to follow the prototype chain:
+
+ \snippet code/src_script_qjsvalueiterator.cpp 1
+
+ \sa QJSValue::property()
+*/
+
+/*!
+ Constructs an iterator for traversing \a object. The iterator is
+ set to be at the front of the sequence of properties (before the
+ first property).
+*/
+QJSValueIterator::QJSValueIterator(const QJSValue& object)
+ : d_ptr(new QJSValueIteratorPrivate(object))
+{
+ d_ptr->iterator.next(&d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
+}
+
+/*!
+ Destroys the iterator.
+*/
+QJSValueIterator::~QJSValueIterator()
+{
+}
+
+/*!
+ Returns true if there is at least one item ahead of the iterator
+ (i.e. the iterator is \e not at the back of the property sequence);
+ otherwise returns false.
+
+ \sa next()
+*/
+bool QJSValueIterator::hasNext() const
+{
+ if (!QJSValuePrivate::get(d_ptr->value)->value.isObject())
+ return false;
+ return d_ptr->nextName != 0 || d_ptr->nextIndex != UINT_MAX;
+}
+
+/*!
+ Advances the iterator by one position.
+ Returns true if there is at least one item ahead of the iterator
+ (i.e. the iterator is \e not at the back of the property sequence);
+ otherwise returns false.
+
+ Calling this function on an iterator located at the back of the
+ container leads to undefined results.
+
+ \sa hasNext(), name()
+*/
+bool QJSValueIterator::next()
+{
+ if (!QJSValuePrivate::get(d_ptr->value)->value.isObject())
+ return false;
+ d_ptr->currentName = d_ptr->nextName;
+ d_ptr->currentIndex = d_ptr->nextIndex;
+ d_ptr->currentAttributes = d_ptr->nextAttributes;
+
+ d_ptr->iterator.next(&d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
+ return d_ptr->nextName != 0 || d_ptr->nextIndex != UINT_MAX;
+}
+
+/*!
+ Returns the name of the last property that was jumped over using
+ next().
+
+ \sa value()
+*/
+QString QJSValueIterator::name() const
+{
+ if (!QJSValuePrivate::get(d_ptr->value)->value.isObject())
+ return false;
+ if (d_ptr->currentName)
+ return d_ptr->currentName->toQString();
+ if (d_ptr->currentIndex < UINT_MAX)
+ return QString::number(d_ptr->currentIndex);
+ return QString();
+}
+
+
+/*!
+ Returns the value of the last property that was jumped over using
+ next().
+
+ \sa name()
+*/
+QJSValue QJSValueIterator::value() const
+{
+ if (!QJSValuePrivate::get(d_ptr->value)->value.isObject())
+ return QJSValue();
+
+ QV4::Object *o = d_ptr->iterator.object;
+ QV4::ExecutionEngine *engine = o->internalClass->engine;
+ QV4::ExecutionContext *ctx = engine->current;
+ try {
+ QV4::Value v;
+ if (d_ptr->currentName)
+ v = o->get(d_ptr->currentName);
+ else if (d_ptr->currentIndex != UINT_MAX)
+ v = o->getIndexed(d_ptr->currentIndex);
+ else
+ return QJSValue();
+ return new QJSValuePrivate(engine, v);
+ } catch (QV4::Exception &e) {
+ e.accept(ctx);
+ return QJSValue();
+ }
+}
+
+
+/*!
+ Makes the iterator operate on \a object. The iterator is set to be
+ at the front of the sequence of properties (before the first
+ property).
+*/
+QJSValueIterator& QJSValueIterator::operator=(QJSValue& object)
+{
+ d_ptr->iterator = QV4::ObjectIterator(QJSValuePrivate::get(object)->value.asObject(), QV4::ObjectIterator::NoFlags);
+ d_ptr->iterator.next(&d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
+ return *this;
+}
+
+QT_END_NAMESPACE
diff --git a/src/qml/jsapi/qjsvalueiterator.h b/src/qml/jsapi/qjsvalueiterator.h
new file mode 100644
index 0000000000..e204558e90
--- /dev/null
+++ b/src/qml/jsapi/qjsvalueiterator.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSCRIPTVALUEITERATOR_H
+#define QSCRIPTVALUEITERATOR_H
+
+#include <QtQml/qjsvalue.h>
+#include <QtQml/qtqmlglobal.h>
+#include <QtCore/qscopedpointer.h>
+
+QT_BEGIN_NAMESPACE
+
+
+class QString;
+
+class QJSValueIteratorPrivate;
+class Q_QML_EXPORT QJSValueIterator
+{
+public:
+ QJSValueIterator(const QJSValue &value);
+ ~QJSValueIterator();
+
+ bool hasNext() const;
+ bool next();
+
+ QString name() const;
+
+ QJSValue value() const;
+ QJSValueIterator& operator=(QJSValue &value);
+
+private:
+ QScopedPointer<QJSValueIteratorPrivate> d_ptr;
+
+ Q_DECLARE_PRIVATE(QJSValueIterator)
+ Q_DISABLE_COPY(QJSValueIterator)
+};
+
+QT_END_NAMESPACE
+
+#endif // QSCRIPTVALUEITERATOR_H
diff --git a/src/qml/jsapi/qjsvalueiterator_p.h b/src/qml/jsapi/qjsvalueiterator_p.h
new file mode 100644
index 0000000000..7687f896a1
--- /dev/null
+++ b/src/qml/jsapi/qjsvalueiterator_p.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QJSVALUEITERATOR_P_H
+#define QJSVALUEITERATOR_P_H
+
+#include "qjsvalue.h"
+#include "private/qv4objectiterator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QV8Engine;
+
+class QJSValueIteratorPrivate
+{
+public:
+ QJSValueIteratorPrivate(const QJSValue &v);
+
+ QJSValue value;
+ QV4::ObjectIterator iterator;
+ QV4::PropertyAttributes currentAttributes;
+ QV4::String *currentName;
+ uint currentIndex;
+ QV4::PropertyAttributes nextAttributes;
+ QV4::String *nextName;
+ uint nextIndex;
+};
+
+
+QT_END_NAMESPACE
+
+#endif // QJSVALUEITERATOR_P_H