aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/v8
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/v8')
-rw-r--r--src/qml/qml/v8/qjsconverter_impl_p.h273
-rw-r--r--src/qml/qml/v8/qjsconverter_p.h111
-rw-r--r--src/qml/qml/v8/qjsengine.cpp119
-rw-r--r--src/qml/qml/v8/qjsvalue.cpp492
-rw-r--r--src/qml/qml/v8/qjsvalue.h17
-rw-r--r--src/qml/qml/v8/qjsvalue_impl_p.h950
-rw-r--r--src/qml/qml/v8/qjsvalue_p.h174
-rw-r--r--src/qml/qml/v8/qjsvalueiterator.cpp79
-rw-r--r--src/qml/qml/v8/qjsvalueiterator.h2
-rw-r--r--src/qml/qml/v8/qjsvalueiterator_impl_p.h143
-rw-r--r--src/qml/qml/v8/qjsvalueiterator_p.h42
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp1642
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions_p.h137
-rw-r--r--src/qml/qml/v8/qscript_impl_p.h61
-rw-r--r--src/qml/qml/v8/qscriptisolate_p.h89
-rw-r--r--src/qml/qml/v8/qscriptoriginalglobalobject_p.h177
-rw-r--r--src/qml/qml/v8/qscriptshareddata_p.h169
-rw-r--r--src/qml/qml/v8/qscripttools_p.h86
-rw-r--r--src/qml/qml/v8/qv4domerrors.cpp72
-rw-r--r--src/qml/qml/v8/qv4domerrors_p.h (renamed from src/qml/qml/v8/qv8domerrors_p.h)19
-rw-r--r--src/qml/qml/v8/qv4sqlerrors.cpp (renamed from src/qml/qml/v8/qv8stringwrapper.cpp)44
-rw-r--r--src/qml/qml/v8/qv4sqlerrors_p.h (renamed from src/qml/qml/v8/qv8sqlerrors_p.h)7
-rw-r--r--src/qml/qml/v8/qv8_p.h42
-rw-r--r--src/qml/qml/v8/qv8bindings.cpp334
-rw-r--r--src/qml/qml/v8/qv8bindings_p.h161
-rw-r--r--src/qml/qml/v8/qv8contextwrapper.cpp430
-rw-r--r--src/qml/qml/v8/qv8contextwrapper_p.h116
-rw-r--r--src/qml/qml/v8/qv8debug_p.h2
-rw-r--r--src/qml/qml/v8/qv8domerrors.cpp73
-rw-r--r--src/qml/qml/v8/qv8engine.cpp1250
-rw-r--r--src/qml/qml/v8/qv8engine_impl_p.h172
-rw-r--r--src/qml/qml/v8/qv8engine_p.h503
-rw-r--r--src/qml/qml/v8/qv8include.cpp245
-rw-r--r--src/qml/qml/v8/qv8include_p.h113
-rw-r--r--src/qml/qml/v8/qv8jsonwrapper.cpp181
-rw-r--r--src/qml/qml/v8/qv8jsonwrapper_p.h100
-rw-r--r--src/qml/qml/v8/qv8listwrapper.cpp194
-rw-r--r--src/qml/qml/v8/qv8listwrapper_p.h97
-rw-r--r--src/qml/qml/v8/qv8objectresource_p.h84
-rw-r--r--src/qml/qml/v8/qv8profiler_p.h2
-rw-r--r--src/qml/qml/v8/qv8qobjectwrapper.cpp2283
-rw-r--r--src/qml/qml/v8/qv8qobjectwrapper_p.h186
-rw-r--r--src/qml/qml/v8/qv8sequencewrapper.cpp323
-rw-r--r--src/qml/qml/v8/qv8sequencewrapper_p.h114
-rw-r--r--src/qml/qml/v8/qv8sequencewrapper_p_p.h512
-rw-r--r--src/qml/qml/v8/qv8sqlerrors.cpp64
-rw-r--r--src/qml/qml/v8/qv8stringwrapper_p.h78
-rw-r--r--src/qml/qml/v8/qv8typewrapper.cpp307
-rw-r--r--src/qml/qml/v8/qv8typewrapper_p.h94
-rw-r--r--src/qml/qml/v8/qv8valuetypewrapper.cpp452
-rw-r--r--src/qml/qml/v8/qv8valuetypewrapper_p.h108
-rw-r--r--src/qml/qml/v8/qv8variantresource_p.h81
-rw-r--r--src/qml/qml/v8/qv8variantwrapper.cpp279
-rw-r--r--src/qml/qml/v8/qv8variantwrapper_p.h110
-rw-r--r--src/qml/qml/v8/qv8worker.cpp392
-rw-r--r--src/qml/qml/v8/qv8worker_p.h75
-rw-r--r--src/qml/qml/v8/script.pri11
-rw-r--r--src/qml/qml/v8/v8.pri40
58 files changed, 2005 insertions, 12508 deletions
diff --git a/src/qml/qml/v8/qjsconverter_impl_p.h b/src/qml/qml/v8/qjsconverter_impl_p.h
deleted file mode 100644
index 4b17d5ed31..0000000000
--- a/src/qml/qml/v8/qjsconverter_impl_p.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qjsconverter_p.h"
-#include <stdlib.h>
-
-#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);
-Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax);
-
-
-quint32 QJSConverter::toArrayIndex(const QString& string)
-{
- // FIXME this function should be exported by JSC C API.
- bool ok;
- quint32 idx = string.toUInt(&ok);
- if (!ok || toString(idx) != string)
- idx = 0xffffffff;
-
- return idx;
-}
-
-QString QJSConverter::toString(v8::Handle<v8::String> jsString)
-{
- if (jsString.IsEmpty())
- return QString();
- QString qstr;
- qstr.resize(jsString->Length());
- jsString->Write(reinterpret_cast<uint16_t*>(qstr.data()));
- return qstr;
-}
-
-v8::Local<v8::String> QJSConverter::toString(const QString& string)
-{
- return v8::String::New(reinterpret_cast<const uint16_t*>(string.data()), string.size());
-}
-
-QString QJSConverter::toString(double value)
-{
- // FIXME this should be easier. The ideal fix is to create
- // a new function in V8 API which could cover the functionality.
-
- if (qIsNaN(value))
- return QString::fromLatin1("NaN");
- if (qIsInf(value))
- return QString::fromLatin1(value < 0 ? "-Infinity" : "Infinity");
- if (!value)
- return QString::fromLatin1("0");
-
- QVarLengthArray<char, 25> buf;
- int decpt;
- int sign;
- char* result = 0;
- char* endresult;
- (void)qdtoa(value, 0, 0, &decpt, &sign, &endresult, &result);
-
- if (!result)
- return QString();
-
- int resultLen = endresult - result;
- if (decpt <= 0 && decpt > -6) {
- buf.resize(-decpt + 2 + sign);
- memset(buf.data(), '0', -decpt + 2 + sign);
- if (sign) // fix the sign.
- buf[0] = '-';
- buf[sign + 1] = '.';
- buf.append(result, resultLen);
- } else {
- if (sign)
- buf.append('-');
- int length = buf.size() - sign + resultLen;
- if (decpt <= 21 && decpt > 0) {
- if (length <= decpt) {
- const char* zeros = "0000000000000000000000000";
- buf.append(result, resultLen);
- buf.append(zeros, decpt - length);
- } else {
- buf.append(result, decpt);
- buf.append('.');
- buf.append(result + decpt, resultLen - decpt);
- }
- } else if (result[0] >= '0' && result[0] <= '9') {
- if (length > 1) {
- buf.append(result, 1);
- buf.append('.');
- buf.append(result + 1, resultLen - 1);
- } else
- buf.append(result, resultLen);
- buf.append('e');
- buf.append(decpt >= 0 ? '+' : '-');
- int e = qAbs(decpt - 1);
- if (e >= 100)
- buf.append('0' + e / 100);
- if (e >= 10)
- buf.append('0' + (e % 100) / 10);
- buf.append('0' + e % 10);
- }
- }
- free(result);
- buf.append(0);
- return QString::fromLatin1(buf.constData());
-}
-
-// return a mask of v8::PropertyAttribute that may also contains QScriptValue::PropertyGetter or QScriptValue::PropertySetter
-uint QJSConverter::toPropertyAttributes(const QFlags<QJSValuePrivate::PropertyFlag>& flags)
-{
- uint attr = 0;
- if (flags.testFlag(QJSValuePrivate::ReadOnly))
- attr |= v8::ReadOnly;
- if (flags.testFlag(QJSValuePrivate::Undeletable))
- attr |= v8::DontDelete;
- if (flags.testFlag(QJSValuePrivate::SkipInEnumeration))
- attr |= v8::DontEnum;
- // if (flags.testFlag(QScriptValue::PropertyGetter))
- // attr |= QScriptValue::PropertyGetter;
- // if (flags.testFlag(QScriptValue::PropertySetter))
- // attr |= QScriptValue::PropertySetter;
- return attr;
-}
-
-// Converts a JS RegExp to a QRegExp.
-// The conversion is not 100% exact since ECMA regexp and QRegExp
-// have different semantics/flags, but we try to do our best.
-QRegExp QJSConverter::toRegExp(v8::Handle<v8::RegExp> jsRegExp)
-{
- QString pattern = QJSConverter::toString(jsRegExp->GetSource());
- Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive;
- if (jsRegExp->GetFlags() & v8::RegExp::kIgnoreCase)
- caseSensitivity = Qt::CaseInsensitive;
- return QRegExp(pattern, caseSensitivity, QRegExp::RegExp2);
-}
-
-// Converts a QRegExp to a JS RegExp.
-// The conversion is not 100% exact since ECMA regexp and QRegExp
-// have different semantics/flags, but we try to do our best.
-v8::Local<v8::RegExp> QJSConverter::toRegExp(const QRegExp &re)
-{
- // Convert the pattern to a ECMAScript pattern.
- QString pattern = qt_regexp_toCanonical(re.pattern(), re.patternSyntax());
- if (re.isMinimal()) {
- QString ecmaPattern;
- int len = pattern.length();
- ecmaPattern.reserve(len);
- int i = 0;
- const QChar *wc = pattern.unicode();
- bool inBracket = false;
- while (i < len) {
- QChar c = wc[i++];
- ecmaPattern += c;
- switch (c.unicode()) {
- case '?':
- case '+':
- case '*':
- case '}':
- if (!inBracket)
- ecmaPattern += QLatin1Char('?');
- break;
- case '\\':
- if (i < len)
- ecmaPattern += wc[i++];
- break;
- case '[':
- inBracket = true;
- break;
- case ']':
- inBracket = false;
- break;
- default:
- break;
- }
- }
- pattern = ecmaPattern;
- }
-
- int flags = v8::RegExp::kNone;
- if (re.caseSensitivity() == Qt::CaseInsensitive)
- flags |= v8::RegExp::kIgnoreCase;
-
- return v8::RegExp::New(QJSConverter::toString(pattern), static_cast<v8::RegExp::Flags>(flags));
-}
-
-// Converts a QStringList to JS.
-// The result is a new Array object with length equal to the length
-// of the QStringList, and the elements being the QStringList's
-// elements converted to JS Strings.
-v8::Local<v8::Array> QJSConverter::toStringList(const QStringList &lst)
-{
- v8::Local<v8::Array> result = v8::Array::New(lst.size());
- for (int i = 0; i < lst.size(); ++i)
- result->Set(i, toString(lst.at(i)));
- return result;
-}
-
-// Converts a JS Array object to a QStringList.
-// The result is a QStringList with length equal to the length
-// of the JS Array, and elements being the JS Array's elements
-// converted to QStrings.
-QStringList QJSConverter::toStringList(v8::Handle<v8::Array> jsArray)
-{
- QStringList result;
- uint32_t length = jsArray->Length();
- for (uint32_t i = 0; i < length; ++i)
- result.append(toString(jsArray->Get(i)->ToString()));
- return result;
-}
-
-
-// Converts a JS Date to a QDateTime.
-QDateTime QJSConverter::toDateTime(v8::Handle<v8::Date> jsDate)
-{
- return QDateTime::fromMSecsSinceEpoch(jsDate->NumberValue());
-}
-
-// Converts a QDateTime to a JS Date.
-v8::Local<v8::Value> QJSConverter::toDateTime(const QDateTime &dt)
-{
- double date;
- if (!dt.isValid())
- date = qSNaN();
- else
- date = dt.toMSecsSinceEpoch();
- return v8::Date::New(date);
-}
-
-QT_END_NAMESPACE
-
-#endif // QJSCONVERTER_IMPL_P_H
diff --git a/src/qml/qml/v8/qjsconverter_p.h b/src/qml/qml/v8/qjsconverter_p.h
deleted file mode 100644
index 5f6633f580..0000000000
--- a/src/qml/qml/v8/qjsconverter_p.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QJSCONVERTER_P_H
-#define QJSCONVERTER_P_H
-
-#include "qjsvalue_p.h"
-#include <QtCore/qglobal.h>
-#include <QtCore/qnumeric.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qregexp.h>
-#include <QtCore/qdatetime.h>
-
-#include <private/qv8_p.h>
-
-QT_BEGIN_NAMESPACE
-
-/*
- \internal
- \class QJSConverter
- QJSValue and QJSEngine helper class. This class's responsibility is to convert values
- between JS values and Qt/C++ values.
-
- This is a nice way to inline these functions in both QJSValue and QJSEngine.
-*/
-class QJSConverter {
-public:
- static inline quint32 toArrayIndex(const QString& string);
-
- static inline QString toString(v8::Handle<v8::String> jsString);
- static inline v8::Local<v8::String> toString(const QString& string);
- static inline QString toString(double value);
-
- enum {
- PropertyAttributeMask = v8::ReadOnly | v8::DontDelete | v8::DontEnum,
- };
- // return a mask of v8::PropertyAttribute that may also contains QScriptValue::PropertyGetter or QScriptValue::PropertySetter
- static inline uint toPropertyAttributes(const QFlags<QJSValuePrivate::PropertyFlag>& flags);
-
- // Converts a JS RegExp to a QRegExp.
- // The conversion is not 100% exact since ECMA regexp and QRegExp
- // have different semantics/flags, but we try to do our best.
- static inline QRegExp toRegExp(v8::Handle<v8::RegExp> jsRegExp);
-
- // Converts a QRegExp to a JS RegExp.
- // The conversion is not 100% exact since ECMA regexp and QRegExp
- // have different semantics/flags, but we try to do our best.
- static inline v8::Local<v8::RegExp> toRegExp(const QRegExp &re);
-
- // Converts a QStringList to JS.
- // The result is a new Array object with length equal to the length
- // of the QStringList, and the elements being the QStringList's
- // elements converted to JS Strings.
- static inline v8::Local<v8::Array> toStringList(const QStringList &lst);
-
- // Converts a JS Array object to a QStringList.
- // The result is a QStringList with length equal to the length
- // of the JS Array, and elements being the JS Array's elements
- // converted to QStrings.
- static inline QStringList toStringList(v8::Handle<v8::Array> jsArray);
-
- // Converts a JS Date to a QDateTime.
- static inline QDateTime toDateTime(v8::Handle<v8::Date> jsDate);
-
- // Converts a QDateTime to a JS Date.
- static inline v8::Local<v8::Value> toDateTime(const QDateTime &dt);
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/qml/qml/v8/qjsengine.cpp b/src/qml/qml/v8/qjsengine.cpp
index dbd0851fec..13281875e6 100644
--- a/src/qml/qml/v8/qjsengine.cpp
+++ b/src/qml/qml/v8/qjsengine.cpp
@@ -43,10 +43,13 @@
#include "qjsengine_p.h"
#include "qjsvalue.h"
#include "qjsvalue_p.h"
-#include "qscriptisolate_p.h"
-#include "qscript_impl_p.h"
#include "qv8engine_p.h"
+#include "private/qv4engine_p.h"
+#include "private/qv4mm_p.h"
+#include "private/qv4globalobject_p.h"
+#include "private/qv4script_p.h"
+
#include <QtCore/qdatetime.h>
#include <QtCore/qmetaobject.h>
#include <QtCore/qstringlist.h>
@@ -62,13 +65,13 @@
#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(QObjectList)
Q_DECLARE_METATYPE(QList<int>)
/*!
@@ -223,9 +226,7 @@ QJSEngine::~QJSEngine()
*/
void QJSEngine::collectGarbage()
{
- Q_D(QJSEngine);
- QScriptIsolate api(d);
- d->collectGarbage();
+ d->m_v4Engine->memoryManager->runGC();
}
/*!
@@ -258,10 +259,18 @@ void QJSEngine::collectGarbage()
*/
QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, int lineNumber)
{
- Q_D(QJSEngine);
- QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
- v8::HandleScope handleScope;
- return QJSValuePrivate::get(d->evaluate(program, fileName, qmlSourceCoordinate(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());
+ }
}
/*!
@@ -274,10 +283,7 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in
*/
QJSValue QJSEngine::newObject()
{
- Q_D(QJSEngine);
- QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
- v8::HandleScope handleScope;
- return QJSValuePrivate::get(new QJSValuePrivate(d, v8::Object::New()));
+ return new QJSValuePrivate(d->m_v4Engine->newObject());
}
/*!
@@ -287,10 +293,11 @@ QJSValue QJSEngine::newObject()
*/
QJSValue QJSEngine::newArray(uint length)
{
- Q_D(QJSEngine);
- QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
- v8::HandleScope handleScope;
- return QJSValuePrivate::get(d->newArray(length));
+ QV4::ArrayObject *array = d->m_v4Engine->newArrayObject();
+ if (length < 0x1000)
+ array->arrayReserve(length);
+ array->setArrayLengthUnchecked(length);
+ return new QJSValuePrivate(array);
}
/*!
@@ -316,9 +323,9 @@ QJSValue QJSEngine::newArray(uint length)
QJSValue QJSEngine::newQObject(QObject *object)
{
Q_D(QJSEngine);
- QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
- v8::HandleScope handleScope;
- return d->scriptValueFromInternal(d->newQObject(object, QV8Engine::JavaScriptOwnership));
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(d);
+ QQmlEngine::setObjectOwnership(object, QQmlEngine::JavaScriptOwnership);
+ return new QJSValuePrivate(v4, QV4::QObjectWrapper::wrap(v4, object));
}
/*!
@@ -333,10 +340,7 @@ QJSValue QJSEngine::newQObject(QObject *object)
*/
QJSValue QJSEngine::globalObject() const
{
- Q_D(const QJSEngine);
- QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
- v8::HandleScope handleScope;
- return d->scriptValueFromInternal(d->global());
+ return new QJSValuePrivate(d->m_v4Engine->globalObject);
}
/*!
@@ -346,9 +350,7 @@ QJSValue QJSEngine::globalObject() const
QJSValue QJSEngine::create(int type, const void *ptr)
{
Q_D(QJSEngine);
- QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
- v8::HandleScope handleScope;
- return d->scriptValueFromInternal(d->metaTypeToJS(type, ptr));
+ return new QJSValuePrivate(d->m_v4Engine, d->metaTypeToJS(type, ptr));
}
/*!
@@ -358,51 +360,49 @@ QJSValue QJSEngine::create(int type, const void *ptr)
bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr)
{
QJSValuePrivate *vp = QJSValuePrivate::get(value);
- QV8Engine *engine = vp->engine();
+ QV8Engine *engine = vp->engine ? vp->engine->v8Engine : 0;
if (engine) {
- QScriptIsolate api(engine, QScriptIsolate::NotNullEngine);
- v8::HandleScope handleScope;
- return engine->metaTypeFromJS(*vp, type, ptr);
+ return engine->metaTypeFromJS(vp->getValue(engine->m_v4Engine), type, ptr);
} else {
switch (type) {
case QMetaType::Bool:
- *reinterpret_cast<bool*>(ptr) = vp->toBool();
+ *reinterpret_cast<bool*>(ptr) = vp->value.toBoolean();
return true;
case QMetaType::Int:
- *reinterpret_cast<int*>(ptr) = vp->toInt32();
+ *reinterpret_cast<int*>(ptr) = vp->value.toInt32();
return true;
case QMetaType::UInt:
- *reinterpret_cast<uint*>(ptr) = vp->toUInt32();
+ *reinterpret_cast<uint*>(ptr) = vp->value.toUInt32();
return true;
case QMetaType::LongLong:
- *reinterpret_cast<qlonglong*>(ptr) = vp->toInteger();
+ *reinterpret_cast<qlonglong*>(ptr) = vp->value.toInteger();
return true;
case QMetaType::ULongLong:
- *reinterpret_cast<qulonglong*>(ptr) = vp->toInteger();
+ *reinterpret_cast<qulonglong*>(ptr) = vp->value.toInteger();
return true;
case QMetaType::Double:
- *reinterpret_cast<double*>(ptr) = vp->toNumber();
+ *reinterpret_cast<double*>(ptr) = vp->value.toNumber();
return true;
case QMetaType::QString:
- *reinterpret_cast<QString*>(ptr) = vp->toString();
+ *reinterpret_cast<QString*>(ptr) = value.toString();
return true;
case QMetaType::Float:
- *reinterpret_cast<float*>(ptr) = vp->toNumber();
+ *reinterpret_cast<float*>(ptr) = vp->value.toNumber();
return true;
case QMetaType::Short:
- *reinterpret_cast<short*>(ptr) = vp->toInt32();
+ *reinterpret_cast<short*>(ptr) = vp->value.toInt32();
return true;
case QMetaType::UShort:
- *reinterpret_cast<unsigned short*>(ptr) = vp->toUInt16();
+ *reinterpret_cast<unsigned short*>(ptr) = vp->value.toUInt16();
return true;
case QMetaType::Char:
- *reinterpret_cast<char*>(ptr) = vp->toInt32();
+ *reinterpret_cast<char*>(ptr) = vp->value.toInt32();
return true;
case QMetaType::UChar:
- *reinterpret_cast<unsigned char*>(ptr) = vp->toUInt16();
+ *reinterpret_cast<unsigned char*>(ptr) = vp->value.toUInt16();
return true;
case QMetaType::QChar:
- *reinterpret_cast<QChar*>(ptr) = vp->toUInt16();
+ *reinterpret_cast<QChar*>(ptr) = vp->value.toUInt16();
return true;
default:
return false;
@@ -424,35 +424,6 @@ bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr)
\sa toScriptValue()
*/
-/*!
- \internal
-
- Returns this engine's internal V8 context.
-
- The context enables direct use of the V8 API.
- The caller is responsible for ensuring that a handle scope is in place,
- and for entering/exiting the context.
- Example:
-
- \code
- QJSEngine eng;
- ...
- v8::HandleScope handleScope;
- v8::Local<v8::Context> context = qt_QJSEngineV8Context(&eng);
- v8::Context::Scope contextScope(context);
-
- // Do stuff (e.g., call v8::Script::Compile()) ...
- \endcode
-
- \sa qt_QJSValueV8Value()
-*/
-Q_QML_EXPORT v8::Local<v8::Context> qt_QJSEngineV8Context(QJSEngine *engine)
-{
- Q_ASSERT(engine != 0);
- QV8Engine *d = engine->handle();
- return v8::Local<v8::Context>::New(d->context());
-}
-
QT_END_NAMESPACE
#include "moc_qjsengine.cpp"
diff --git a/src/qml/qml/v8/qjsvalue.cpp b/src/qml/qml/v8/qjsvalue.cpp
index 87be773218..ffbc469a76 100644
--- a/src/qml/qml/v8/qjsvalue.cpp
+++ b/src/qml/qml/v8/qjsvalue.cpp
@@ -39,14 +39,41 @@
**
****************************************************************************/
-#include "qscriptisolate_p.h"
+#include <QtCore/qstring.h>
+#include <QtCore/qvarlengtharray.h>
+#include <QtCore/qdatetime.h>
#include "qjsengine.h"
-#include "qv8engine_p.h"
#include "qjsvalue.h"
#include "qjsvalue_p.h"
-#include "qscript_impl_p.h"
-#include "qscriptshareddata_p.h"
-#include <QtCore/qstring.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 "qv8engine_p.h"
+#include <private/qv4mm_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
@@ -114,11 +141,18 @@
QT_BEGIN_NAMESPACE
+using namespace QV4;
+
/*!
Constructs a new QJSValue with a boolean \a value.
*/
QJSValue::QJSValue(bool value)
- : d_ptr(new QJSValuePrivate(value))
+ : d(new QJSValuePrivate(0, Value::fromBoolean(value)))
+{
+}
+
+QJSValue::QJSValue(QJSValuePrivate *dd)
+ : d(dd)
{
}
@@ -126,7 +160,7 @@ QJSValue::QJSValue(bool value)
Constructs a new QJSValue with a number \a value.
*/
QJSValue::QJSValue(int value)
- : d_ptr(new QJSValuePrivate(value))
+ : d(new QJSValuePrivate(0, Value::fromInt32(value)))
{
}
@@ -134,7 +168,7 @@ QJSValue::QJSValue(int value)
Constructs a new QJSValue with a number \a value.
*/
QJSValue::QJSValue(uint value)
- : d_ptr(new QJSValuePrivate(value))
+ : d(new QJSValuePrivate(0, Value::fromUInt32(value)))
{
}
@@ -142,7 +176,7 @@ QJSValue::QJSValue(uint value)
Constructs a new QJSValue with a number \a value.
*/
QJSValue::QJSValue(double value)
- : d_ptr(new QJSValuePrivate(value))
+ : d(new QJSValuePrivate(0, Value::fromDouble(value)))
{
}
@@ -150,7 +184,7 @@ QJSValue::QJSValue(double value)
Constructs a new QJSValue with a string \a value.
*/
QJSValue::QJSValue(const QString& value)
- : d_ptr(new QJSValuePrivate(value))
+ : d(new QJSValuePrivate(value))
{
}
@@ -158,7 +192,7 @@ QJSValue::QJSValue(const QString& value)
Constructs a new QJSValue with a special \a value.
*/
QJSValue::QJSValue(SpecialValue value)
- : d_ptr(new QJSValuePrivate(value))
+ : d(new QJSValuePrivate(0, value == UndefinedValue ? Value::undefinedValue() : Value::nullValue()))
{
}
@@ -166,7 +200,7 @@ QJSValue::QJSValue(SpecialValue value)
Constructs a new QJSValue with a string \a value.
*/
QJSValue::QJSValue(const QLatin1String &value)
- : d_ptr(new QJSValuePrivate(value))
+ : d(new QJSValuePrivate(value))
{
}
@@ -175,30 +209,12 @@ QJSValue::QJSValue(const QLatin1String &value)
*/
#ifndef QT_NO_CAST_FROM_ASCII
QJSValue::QJSValue(const char *value)
- : d_ptr(new QJSValuePrivate(QString::fromLatin1(value)))
+ : d(new QJSValuePrivate(QString::fromLatin1(value)))
{
}
#endif
/*!
- Constructs a new QJSValue from private
- \internal
-*/
-QJSValue::QJSValue(QJSValuePrivate* d)
- : d_ptr(d)
-{
-}
-
-/*!
- Constructs a new QJSValue from private
- \internal
-*/
-QJSValue::QJSValue(QScriptPassPointer<QJSValuePrivate> d)
- : d_ptr(d.give())
-{
-}
-
-/*!
Constructs a new QJSValue that is a copy of \a other.
Note that if \a other is an object (i.e., isObject() would return
@@ -206,8 +222,9 @@ QJSValue::QJSValue(QScriptPassPointer<QJSValuePrivate> d)
the new script value (i.e., the object itself is not copied).
*/
QJSValue::QJSValue(const QJSValue& other)
- : d_ptr(other.d_ptr)
+ : d(other.d)
{
+ d->ref();
}
/*!
@@ -215,6 +232,7 @@ QJSValue::QJSValue(const QJSValue& other)
*/
QJSValue::~QJSValue()
{
+ d->deref();
}
/*!
@@ -225,9 +243,7 @@ QJSValue::~QJSValue()
*/
bool QJSValue::isBool() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->isBool();
+ return d->value.isBoolean();
}
/*!
@@ -238,9 +254,7 @@ bool QJSValue::isBool() const
*/
bool QJSValue::isNumber() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->isNumber();
+ return d->value.isNumber();
}
/*!
@@ -249,9 +263,7 @@ bool QJSValue::isNumber() const
*/
bool QJSValue::isNull() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->isNull();
+ return d->value.isNull();
}
/*!
@@ -262,9 +274,7 @@ bool QJSValue::isNull() const
*/
bool QJSValue::isString() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->isString();
+ return d->value.isString();
}
/*!
@@ -273,9 +283,7 @@ bool QJSValue::isString() const
*/
bool QJSValue::isUndefined() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->isUndefined();
+ return d->value.isUndefined();
}
/*!
@@ -284,9 +292,8 @@ bool QJSValue::isUndefined() const
*/
bool QJSValue::isError() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->isError();
+ Object *o = d->value.asObject();
+ return o && o->asErrorObject();
}
/*!
@@ -297,10 +304,8 @@ bool QJSValue::isError() const
*/
bool QJSValue::isArray() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->isArray();
- }
+ return d->value.asArrayObject();
+}
/*!
Returns true if this QJSValue is of the Object type; otherwise
@@ -313,9 +318,7 @@ bool QJSValue::isArray() const
*/
bool QJSValue::isObject() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->isObject();
+ return d->value.asObject();
}
/*!
@@ -326,9 +329,7 @@ bool QJSValue::isObject() const
*/
bool QJSValue::isCallable() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->isCallable();
+ return d->value.asFunctionObject();
}
/*!
@@ -339,9 +340,8 @@ bool QJSValue::isCallable() const
*/
bool QJSValue::isVariant() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->isVariant();
+ Managed *m = d->value.asManaged();
+ return m ? m->as<QV4::VariantObject>() : 0;
}
/*!
@@ -358,9 +358,7 @@ bool QJSValue::isVariant() const
*/
QString QJSValue::toString() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->toString();
+ return d->value.toQString();
}
/*!
@@ -377,9 +375,13 @@ QString QJSValue::toString() const
*/
double QJSValue::toNumber() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->toNumber();
+ QV4::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
+ try {
+ return d->value.toNumber();
+ } catch (Exception &e) {
+ e.accept(ctx);
+ return 0;
+ }
}
/*!
@@ -396,9 +398,13 @@ double QJSValue::toNumber() const
*/
bool QJSValue::toBool() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->toBool();
+ QV4::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
+ try {
+ return d->value.toBoolean();
+ } catch (Exception &e) {
+ e.accept(ctx);
+ return false;
+ }
}
/*!
@@ -415,9 +421,13 @@ bool QJSValue::toBool() const
*/
qint32 QJSValue::toInt() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->toInt32();
+ QV4::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
+ try {
+ return d->value.toInt32();
+ } catch (Exception &e) {
+ e.accept(ctx);
+ return 0;
+ }
}
/*!
@@ -434,9 +444,13 @@ qint32 QJSValue::toInt() const
*/
quint32 QJSValue::toUInt() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->toUInt32();
+ QV4::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
+ try {
+ return d->value.toUInt32();
+ } catch (Exception &e) {
+ e.accept(ctx);
+ return 0;
+ }
}
/*!
@@ -463,9 +477,7 @@ quint32 QJSValue::toUInt() const
*/
QVariant QJSValue::toVariant() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->toVariant();
+ return QV4::VariantObject::toVariant(d->value);
}
/*!
@@ -485,9 +497,32 @@ QVariant QJSValue::toVariant() const
*/
QJSValue QJSValue::call(const QJSValueList &args)
{
- Q_D(QJSValue);
- QScriptIsolate api(d->engine());
- return d->call(/*thisObject=*/0, 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);
}
/*!
@@ -512,9 +547,37 @@ QJSValue QJSValue::call(const QJSValueList &args)
*/
QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList &args)
{
- Q_D(QJSValue);
- QScriptIsolate api(d->engine());
- return d->call(QJSValuePrivate::get(instance), 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);
}
/*!
@@ -537,9 +600,32 @@ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList
*/
QJSValue QJSValue::callAsConstructor(const QJSValueList &args)
{
- Q_D(QJSValue);
- QScriptIsolate api(d->engine());
- return QJSValuePrivate::get(d->callAsConstructor(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
@@ -553,12 +639,9 @@ QJSValue QJSValue::callAsConstructor(const QJSValueList &args)
*/
QJSEngine* QJSValue::engine() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- QV8Engine* engine = d->engine();
+ QV4::ExecutionEngine *engine = d->engine;
if (engine)
- return QV8Engine::get(engine);
- return 0;
+ return engine->v8Engine->publicEngine();
}
#endif // QT_DEPRECATED
@@ -572,14 +655,18 @@ QJSEngine* QJSValue::engine() const
*/
QJSValue QJSValue::prototype() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return QJSValuePrivate::get(d->prototype());
+ 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
@@ -590,9 +677,30 @@ QJSValue QJSValue::prototype() const
*/
void QJSValue::setPrototype(const QJSValue& prototype)
{
- Q_D(QJSValue);
- QScriptIsolate api(d->engine());
- d->setPrototype(QJSValuePrivate::get(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;
}
/*!
@@ -604,8 +712,11 @@ void QJSValue::setPrototype(const QJSValue& prototype)
*/
QJSValue& QJSValue::operator=(const QJSValue& other)
{
- d_ptr = other.d_ptr;
- return *this;
+ if (d == other.d)
+ return *this;
+ d->deref();
+ d = other.d;
+ d->ref();
}
/*!
@@ -634,10 +745,7 @@ QJSValue& QJSValue::operator=(const QJSValue& other)
*/
bool QJSValue::equals(const QJSValue& other) const
{
- Q_D(const QJSValue);
- QJSValuePrivate* otherValue = QJSValuePrivate::get(other);
- QScriptIsolate api(d->engine() ? d->engine() : otherValue->engine());
- return d_ptr->equals(otherValue);
+ return __qmljs_equal(d->value, other.d->value);
}
/*!
@@ -664,10 +772,7 @@ bool QJSValue::equals(const QJSValue& other) const
*/
bool QJSValue::strictlyEquals(const QJSValue& other) const
{
- Q_D(const QJSValue);
- QJSValuePrivate* o = QJSValuePrivate::get(other);
- QScriptIsolate api(d->engine() ? d->engine() : o->engine());
- return d_ptr->strictlyEquals(o);
+ return __qmljs_strict_equal(d->value, other.d->value);
}
/*!
@@ -685,9 +790,25 @@ bool QJSValue::strictlyEquals(const QJSValue& other) const
*/
QJSValue QJSValue::property(const QString& name) const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return QJSValuePrivate::get(d->property(name));
+ 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());
+ }
}
/*!
@@ -704,9 +825,19 @@ QJSValue QJSValue::property(const QString& name) const
*/
QJSValue QJSValue::property(quint32 arrayIndex) const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return QJSValuePrivate::get(d->property(arrayIndex));
+ 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());
+ }
}
/*!
@@ -722,9 +853,30 @@ QJSValue QJSValue::property(quint32 arrayIndex) const
*/
void QJSValue::setProperty(const QString& name, const QJSValue& value)
{
- Q_D(QJSValue);
- QScriptIsolate api(d->engine());
- d->setProperty(name, QJSValuePrivate::get(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);
+ }
}
/*!
@@ -741,9 +893,20 @@ void QJSValue::setProperty(const QString& name, const QJSValue& value)
*/
void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value)
{
- Q_D(QJSValue);
- QScriptIsolate api(d->engine());
- d->setProperty(arrayIndex, QJSValuePrivate::get(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);
+ }
}
/*!
@@ -768,9 +931,13 @@ void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value)
*/
bool QJSValue::deleteProperty(const QString &name)
{
- Q_D(QJSValue);
- QScriptIsolate api(d->engine());
- return d->deleteProperty(name);
+ Object *o = d->value.asObject();
+ if (!o)
+ return false;
+
+ ExecutionEngine *engine = d->engine;
+ String *s = engine->newString(name);
+ return o->deleteProperty(s);
}
/*!
@@ -781,9 +948,13 @@ bool QJSValue::deleteProperty(const QString &name)
*/
bool QJSValue::hasProperty(const QString &name) const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->hasProperty(name);
+ Object *o = d->value.asObject();
+ if (!o)
+ return false;
+
+ ExecutionEngine *engine = d->engine;
+ String *s = engine->newIdentifier(name);
+ return o->__hasProperty__(s);
}
/*!
@@ -794,9 +965,13 @@ bool QJSValue::hasProperty(const QString &name) const
*/
bool QJSValue::hasOwnProperty(const QString &name) const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->hasOwnProperty(name);
+ Object *o = d->value.asObject();
+ if (!o)
+ return false;
+
+ ExecutionEngine *engine = d->engine;
+ String *s = engine->newIdentifier(name);
+ return o->__getOwnProperty__(s);
}
/*!
@@ -811,9 +986,11 @@ bool QJSValue::hasOwnProperty(const QString &name) const
*/
QObject *QJSValue::toQObject() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->toQObject();
+ QV4::QObjectWrapper *o = d->value.as<QV4::QObjectWrapper>();
+ if (!o)
+ return 0;
+
+ return o->object();
}
/*!
@@ -825,9 +1002,10 @@ QObject *QJSValue::toQObject() const
*/
QDateTime QJSValue::toDateTime() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->toDataTime();
+ QV4::DateObject *date = d->value.asDateObject();
+ if (!date)
+ return QDateTime();
+ return date->toQDateTime();
}
/*!
@@ -838,9 +1016,7 @@ QDateTime QJSValue::toDateTime() const
*/
bool QJSValue::isDate() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->isDate();
+ return d->value.asDateObject();
}
/*!
@@ -849,9 +1025,7 @@ bool QJSValue::isDate() const
*/
bool QJSValue::isRegExp() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->isRegExp();
+ return d->value.as<RegExpObject>();
}
/*!
@@ -865,35 +1039,7 @@ bool QJSValue::isRegExp() const
*/
bool QJSValue::isQObject() const
{
- Q_D(const QJSValue);
- QScriptIsolate api(d->engine());
- return d->isQObject();
-}
-
-/*!
- \internal
-
- Returns this value's internal V8 value, or an empty handle if
- the QJSValue isn't bound to a QJSEngine.
-
- The V8 value enables direct use of the V8 API.
- The caller is responsible for ensuring that a handle scope is in place.
- Example:
-
- \code
- QJSValue value = ...;
- v8::HandleScope handleScope;
- v8::Local<v8::Value> v8value = qt_QJSValueV8Value(value);
-
- // Do something with the V8 value (e.g., call v8::Value::IsInt32()) ...
- \endcode
-
- \sa qt_QJSEngineV8Context()
-*/
-Q_QML_EXPORT v8::Local<v8::Value> qt_QJSValueV8Value(const QJSValue &value)
-{
- QJSValuePrivate *d = QJSValuePrivate::get(value);
- return v8::Local<v8::Value>::New(d->handle());
+ return d->value.as<QV4::QObjectWrapper>() != 0;
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qjsvalue.h b/src/qml/qml/v8/qjsvalue.h
index efd52ce880..cf02ad819e 100644
--- a/src/qml/qml/v8/qjsvalue.h
+++ b/src/qml/qml/v8/qjsvalue.h
@@ -45,8 +45,7 @@
#include <QtQml/qtqmlglobal.h>
#include <QtCore/qstring.h>
#include <QtCore/qlist.h>
-#include <QtCore/qsharedpointer.h>
-#include <QtCore/qshareddata.h>
+#include <QtCore/qmetatype.h>
QT_BEGIN_NAMESPACE
@@ -59,10 +58,7 @@ struct QMetaObject;
class QDateTime;
typedef QList<QJSValue> QJSValueList;
-
class QJSValuePrivate;
-struct QScriptValuePrivatePointerDeleter;
-template <class T> class QScriptPassPointer;
class Q_QML_EXPORT QJSValue
{
@@ -137,18 +133,13 @@ public:
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;
- QJSValue(QJSValuePrivate*);
- QJSValue(QScriptPassPointer<QJSValuePrivate>);
-
-private:
- QExplicitlySharedDataPointer<QJSValuePrivate> d_ptr;
-
- Q_DECLARE_PRIVATE(QJSValue)
+ QJSValuePrivate *d;
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qjsvalue_impl_p.h b/src/qml/qml/v8/qjsvalue_impl_p.h
deleted file mode 100644
index 2e779c22e9..0000000000
--- a/src/qml/qml/v8/qjsvalue_impl_p.h
+++ /dev/null
@@ -1,950 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//
-// 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_IMPL_P_H
-#define QJSVALUE_IMPL_P_H
-
-#include "qjsconverter_p.h"
-#include "qjsvalue_p.h"
-#include "qv8engine_p.h"
-#include "qscriptisolate_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QJSValuePrivate* QJSValuePrivate::get(const QJSValue& q) { Q_ASSERT(q.d_ptr.data()); return q.d_ptr.data(); }
-
-QJSValue QJSValuePrivate::get(const QJSValuePrivate* d)
-{
- Q_ASSERT(d);
- return QJSValue(const_cast<QJSValuePrivate*>(d));
-}
-
-QJSValue QJSValuePrivate::get(QScriptPassPointer<QJSValuePrivate> d)
-{
- Q_ASSERT(d);
- return QJSValue(d);
-}
-
-QJSValue QJSValuePrivate::get(QJSValuePrivate* d)
-{
- Q_ASSERT(d);
- return QJSValue(d);
-}
-
-QJSValuePrivate::QJSValuePrivate(bool value)
- : m_engine(0), m_state(CBool), u(value)
-{
-}
-
-QJSValuePrivate::QJSValuePrivate(int value)
- : m_engine(0), m_state(CNumber), u(value)
-{
-}
-
-QJSValuePrivate::QJSValuePrivate(uint value)
- : m_engine(0), m_state(CNumber), u(value)
-{
-}
-
-QJSValuePrivate::QJSValuePrivate(double value)
- : m_engine(0), m_state(CNumber), u(value)
-{
-}
-
-QJSValuePrivate::QJSValuePrivate(const QString& value)
- : m_engine(0), m_state(CString), u(new QString(value))
-{
-}
-
-QJSValuePrivate::QJSValuePrivate(QJSValue::SpecialValue value)
- : m_engine(0), m_state(value == QJSValue::NullValue ? CNull : CUndefined)
-{
-}
-
-QJSValuePrivate::QJSValuePrivate(QV8Engine* engine, bool value)
- : m_engine(engine), m_state(JSValue)
-{
- Q_ASSERT(engine);
- v8::HandleScope handleScope;
- m_value = v8::Persistent<v8::Value>::New(m_engine->makeJSValue(value));
- m_engine->registerValue(this);
-}
-
-QJSValuePrivate::QJSValuePrivate(QV8Engine* engine, int value)
- : m_engine(engine), m_state(JSValue)
-{
- Q_ASSERT(engine);
- v8::HandleScope handleScope;
- m_value = v8::Persistent<v8::Value>::New(m_engine->makeJSValue(value));
- m_engine->registerValue(this);
-}
-
-QJSValuePrivate::QJSValuePrivate(QV8Engine* engine, uint value)
- : m_engine(engine), m_state(JSValue)
-{
- Q_ASSERT(engine);
- v8::HandleScope handleScope;
- m_value = v8::Persistent<v8::Value>::New(m_engine->makeJSValue(value));
- m_engine->registerValue(this);
-}
-
-QJSValuePrivate::QJSValuePrivate(QV8Engine* engine, double value)
- : m_engine(engine), m_state(JSValue)
-{
- Q_ASSERT(engine);
- v8::HandleScope handleScope;
- m_value = v8::Persistent<v8::Value>::New(m_engine->makeJSValue(value));
- m_engine->registerValue(this);
-}
-
-QJSValuePrivate::QJSValuePrivate(QV8Engine* engine, const QString& value)
- : m_engine(engine), m_state(JSValue)
-{
- Q_ASSERT(engine);
- v8::HandleScope handleScope;
- m_value = v8::Persistent<v8::Value>::New(m_engine->makeJSValue(value));
- m_engine->registerValue(this);
-}
-
-QJSValuePrivate::QJSValuePrivate(QV8Engine* engine, QJSValue::SpecialValue value)
- : m_engine(engine), m_state(JSValue)
-{
- Q_ASSERT(engine);
- v8::HandleScope handleScope;
- m_value = v8::Persistent<v8::Value>::New(m_engine->makeJSValue(value));
- m_engine->registerValue(this);
-}
-
-QJSValuePrivate::QJSValuePrivate(QV8Engine *engine, v8::Handle<v8::Value> value)
- : m_engine(engine), m_state(JSValue), m_value(v8::Persistent<v8::Value>::New(value))
-{
- Q_ASSERT(engine);
- // It shouldn't happen, v8 shows errors by returning an empty handler. This is important debug
- // information and it can't be simply ignored.
- Q_ASSERT(!value.IsEmpty());
- m_engine->registerValue(this);
-}
-
-QJSValuePrivate::~QJSValuePrivate()
-{
- if (isJSBased()) {
- m_engine->unregisterValue(this);
- QScriptIsolate api(m_engine);
- m_value.Dispose();
- } else if (isStringBased()) {
- delete u.m_string;
- }
-}
-
-bool QJSValuePrivate::toBool() const
-{
- switch (m_state) {
- case JSValue:
- {
- v8::HandleScope scope;
- return m_value->ToBoolean()->Value();
- }
- case CNumber:
- return !(qIsNaN(u.m_number) || !u.m_number);
- case CBool:
- return u.m_bool;
- case CNull:
- case CUndefined:
- return false;
- case CString:
- return u.m_string->length();
- }
-
- Q_ASSERT_X(false, "toBool()", "Not all states are included in the previous switch statement.");
- return false; // Avoid compiler warning.
-}
-
-double QJSValuePrivate::toNumber() const
-{
- switch (m_state) {
- case JSValue:
- {
- v8::HandleScope scope;
- return m_value->ToNumber()->Value();
- }
- case CNumber:
- return u.m_number;
- case CBool:
- return u.m_bool ? 1 : 0;
- case CNull:
- case CUndefined:
- return qQNaN();
- case CString:
- bool ok;
- double result = u.m_string->toDouble(&ok);
- if (ok)
- return result;
- result = u.m_string->toInt(&ok, 0); // Try other bases.
- if (ok)
- return result;
- if (*u.m_string == QLatin1String("Infinity"))
- return qInf();
- if (*u.m_string == QLatin1String("-Infinity"))
- return -qInf();
- return u.m_string->length() ? qQNaN() : 0;
- }
-
- Q_ASSERT_X(false, "toNumber()", "Not all states are included in the previous switch statement.");
- return 0; // Avoid compiler warning.
-}
-
-QString QJSValuePrivate::toString() const
-{
- switch (m_state) {
- case CBool:
- return u.m_bool ? QString::fromLatin1("true") : QString::fromLatin1("false");
- case CString:
- return *u.m_string;
- case CNumber:
- return QJSConverter::toString(u.m_number);
- case CNull:
- return QString::fromLatin1("null");
- case CUndefined:
- return QString::fromLatin1("undefined");
- case JSValue:
- Q_ASSERT(!m_value.IsEmpty());
- v8::HandleScope handleScope;
- v8::TryCatch tryCatch;
- v8::Local<v8::String> result = m_value->ToString();
- if (result.IsEmpty())
- result = tryCatch.Exception()->ToString();
- return QJSConverter::toString(result);
- }
-
- Q_ASSERT_X(false, "toString()", "Not all states are included in the previous switch statement.");
- return QString(); // Avoid compiler warning.
-}
-
-QVariant QJSValuePrivate::toVariant() const
-{
- switch (m_state) {
- case CBool:
- return QVariant(u.m_bool);
- case CString:
- return QVariant(*u.m_string);
- case CNumber:
- return QVariant(u.m_number);
- case CNull:
- return QVariant(QMetaType::VoidStar, 0);
- case CUndefined:
- return QVariant();
- case JSValue:
- break;
- }
-
- Q_ASSERT(m_state == JSValue);
- Q_ASSERT(!m_value.IsEmpty());
- Q_ASSERT(m_engine);
-
- v8::HandleScope handleScope;
- return m_engine->variantFromJS(m_value);
-}
-
-inline QDateTime QJSValuePrivate::toDataTime() const
-{
- if (!isDate())
- return QDateTime();
-
- v8::HandleScope handleScope;
- return QJSConverter::toDateTime(v8::Handle<v8::Date>::Cast(m_value));
-
-}
-
-QObject* QJSValuePrivate::toQObject() const
-{
- if (!isJSBased())
- return 0;
-
- v8::HandleScope handleScope;
- return engine()->qtObjectFromJS(m_value);
-}
-
-double QJSValuePrivate::toInteger() const
-{
- double result = toNumber();
- if (qIsNaN(result))
- return 0;
- if (qIsInf(result))
- return result;
-
- // Must use floor explicitly rather than qFloor here. On some
- // platforms qFloor will cast the value to a single precision float and use
- // floorf() which results in test failures.
- return (result > 0) ? floor(result) : -1 * floor(-result);
-}
-
-qint32 QJSValuePrivate::toInt32() const
-{
- double result = toInteger();
- // Orginaly it should look like that (result == 0 || qIsInf(result) || qIsNaN(result)), but
- // some of these operation are invoked in toInteger subcall.
- if (qIsInf(result))
- return 0;
- return result;
-}
-
-quint32 QJSValuePrivate::toUInt32() const
-{
- double result = toInteger();
- // Orginaly it should look like that (result == 0 || qIsInf(result) || qIsNaN(result)), but
- // some of these operation are invoked in toInteger subcall.
- if (qIsInf(result))
- return 0;
-
- // The explicit casts are required to avoid undefined behaviour. For example, casting
- // a negative double directly to an unsigned int on ARM NEON FPU results in the value
- // being set to zero. Casting to a signed int first ensures well defined behaviour.
- return (quint32) (qint32) result;
-}
-
-quint16 QJSValuePrivate::toUInt16() const
-{
- return toInt32();
-}
-
-inline bool QJSValuePrivate::isArray() const
-{
- return isJSBased() && m_value->IsArray();
-}
-
-inline bool QJSValuePrivate::isBool() const
-{
- return m_state == CBool || (isJSBased() && m_value->IsBoolean());
-}
-
-inline bool QJSValuePrivate::isCallable() const
-{
- if (isFunction())
- return true;
- if (isObject()) {
- // Our C++ wrappers register function handlers but not always act as callables.
- return v8::Object::Cast(*m_value)->IsCallable();
- }
- return false;
-}
-
-inline bool QJSValuePrivate::isError() const
-{
- if (!isJSBased())
- return false;
- v8::HandleScope handleScope;
- return m_value->IsError();
-}
-
-inline bool QJSValuePrivate::isFunction() const
-{
- return isJSBased() && m_value->IsFunction();
-}
-
-inline bool QJSValuePrivate::isNull() const
-{
- return m_state == CNull || (isJSBased() && m_value->IsNull());
-}
-
-inline bool QJSValuePrivate::isNumber() const
-{
- return m_state == CNumber || (isJSBased() && m_value->IsNumber());
-}
-
-inline bool QJSValuePrivate::isObject() const
-{
- return isJSBased() && m_value->IsObject();
-}
-
-inline bool QJSValuePrivate::isString() const
-{
- return m_state == CString || (isJSBased() && m_value->IsString());
-}
-
-inline bool QJSValuePrivate::isUndefined() const
-{
- return m_state == CUndefined || (isJSBased() && m_value->IsUndefined());
-}
-
-inline bool QJSValuePrivate::isVariant() const
-{
- return isJSBased() && m_engine->isVariant(m_value);
-}
-
-bool QJSValuePrivate::isDate() const
-{
- return (isJSBased() && m_value->IsDate());
-}
-
-bool QJSValuePrivate::isRegExp() const
-{
- return (isJSBased() && m_value->IsRegExp());
-}
-
-bool QJSValuePrivate::isQObject() const
-{
- return isJSBased() && engine()->isQObject(m_value);
-}
-
-inline bool QJSValuePrivate::equals(QJSValuePrivate* other)
-{
- if (!isJSBased() && !other->isJSBased()) {
- switch (m_state) {
- case CNull:
- case CUndefined:
- return other->isUndefined() || other->isNull();
- case CNumber:
- switch (other->m_state) {
- case CBool:
- case CString:
- return u.m_number == other->toNumber();
- case CNumber:
- return u.m_number == other->u.m_number;
- default:
- return false;
- }
- case CBool:
- switch (other->m_state) {
- case CBool:
- return u.m_bool == other->u.m_bool;
- case CNumber:
- return toNumber() == other->u.m_number;
- case CString:
- return toNumber() == other->toNumber();
- default:
- return false;
- }
- case CString:
- switch (other->m_state) {
- case CBool:
- return toNumber() == other->toNumber();
- case CNumber:
- return toNumber() == other->u.m_number;
- case CString:
- return *u.m_string == *other->u.m_string;
- default:
- return false;
- }
- default:
- Q_ASSERT_X(false, "QJSValue::equals", "Not all states are included in the previous switch statement.");
- }
- }
-
- v8::HandleScope handleScope;
- if (isJSBased() && !other->isJSBased()) {
- if (!other->assignEngine(engine())) {
- qWarning("QJSValue::equals: cannot compare to a value created in a different engine");
- return false;
- }
- } else if (!isJSBased() && other->isJSBased()) {
- if (!assignEngine(other->engine())) {
- qWarning("QJSValue::equals: cannot compare to a value created in a different engine");
- return false;
- }
- }
-
- Q_ASSERT(this->engine() && other->engine());
- if (this->engine() != other->engine()) {
- qWarning("QJSValue::equals: cannot compare to a value created in a different engine");
- return false;
- }
- return m_value->Equals(other->m_value);
-}
-
-inline bool QJSValuePrivate::strictlyEquals(QJSValuePrivate* other)
-{
- if (isJSBased()) {
- // We can't compare these two values without binding to the same engine.
- if (!other->isJSBased()) {
- if (other->assignEngine(engine()))
- return m_value->StrictEquals(other->m_value);
- return false;
- }
- if (other->engine() != engine()) {
- qWarning("QJSValue::strictlyEquals: cannot compare to a value created in a different engine");
- return false;
- }
- return m_value->StrictEquals(other->m_value);
- }
- if (isStringBased()) {
- if (other->isStringBased())
- return *u.m_string == *(other->u.m_string);
- if (other->isJSBased()) {
- assignEngine(other->engine());
- return m_value->StrictEquals(other->m_value);
- }
- }
- if (isNumberBased()) {
- if (other->isJSBased()) {
- assignEngine(other->engine());
- return m_value->StrictEquals(other->m_value);
- }
- if (m_state != other->m_state)
- return false;
- if (m_state == CNumber)
- return u.m_number == other->u.m_number;
- Q_ASSERT(m_state == CBool);
- return u.m_bool == other->u.m_bool;
- }
-
- return (isUndefined() && other->isUndefined())
- || (isNull() && other->isNull());
-}
-
-inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::prototype() const
-{
- if (isObject()) {
- v8::HandleScope handleScope;
- return new QJSValuePrivate(engine(), v8::Handle<v8::Object>::Cast(m_value)->GetPrototype());
- }
- return new QJSValuePrivate();
-}
-
-inline void QJSValuePrivate::setPrototype(QJSValuePrivate* prototype)
-{
- if (isObject() && (prototype->isObject() || prototype->isNull())) {
- if (engine() != prototype->engine()) {
- if (prototype->engine()) {
- qWarning("QJSValue::setPrototype() failed: cannot set a prototype created in a different engine");
- return;
- }
- prototype->assignEngine(engine());
- }
- v8::HandleScope handleScope;
- if (!v8::Handle<v8::Object>::Cast(m_value)->SetPrototype(*prototype))
- qWarning("QJSValue::setPrototype() failed: cyclic prototype value");
- }
-}
-
-inline void QJSValuePrivate::setProperty(const QString& name, QJSValuePrivate* value, uint attribs)
-{
- if (!isObject())
- return;
- v8::HandleScope handleScope;
- setProperty(QJSConverter::toString(name), value, attribs);
-}
-
-inline void QJSValuePrivate::setProperty(v8::Handle<v8::String> name, QJSValuePrivate* value, uint attribs)
-{
- if (!isObject())
- return;
-
- if (!value->isJSBased())
- value->assignEngine(engine());
-
- if (engine() != value->engine()) {
- qWarning("QJSValue::setProperty(%s) failed: "
- "cannot set value created in a different engine",
- qPrintable(QJSConverter::toString(name)));
- return;
- }
-
- v8::TryCatch tryCatch;
-// if (attribs & (QJSValue::PropertyGetter | QJSValue::PropertySetter)) {
-// engine()->originalGlobalObject()->defineGetterOrSetter(*this, name, value->m_value, attribs);
-// } else {
- v8::Object::Cast(*m_value)->Set(name, value->m_value, v8::PropertyAttribute(attribs & QJSConverter::PropertyAttributeMask));
-// }
-}
-
-inline void QJSValuePrivate::setProperty(quint32 index, QJSValuePrivate* value, uint attribs)
-{
- // FIXME this method should by integrated with other overloads to use the same code patch.
- // for now it is not possible as v8 doesn't allow to set property attributes using index based api.
-
- if (!isObject())
- return;
-
- if (attribs) {
- // FIXME we don't need to convert index to a string.
- //Object::Set(int,value) do not take attributes.
- setProperty(QString::number(index), value, attribs);
- return;
- }
-
- if (!value->isJSBased())
- value->assignEngine(engine());
-
- if (engine() != value->engine()) {
- qWarning("QJSValue::setProperty() failed: cannot set value created in a different engine");
- return;
- }
-
- v8::HandleScope handleScope;
- v8::Object::Cast(*m_value)->Set(index, value->m_value);
-}
-
-inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::property(const QString& name) const
-{
- if (!isObject())
- return new QJSValuePrivate();
- if (!name.length())
- return new QJSValuePrivate(engine());
-
- v8::HandleScope handleScope;
- return property(QJSConverter::toString(name));
-}
-
-inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::property(v8::Handle<v8::String> name) const
-{
- Q_ASSERT(!name.IsEmpty());
- if (!isObject())
- return new QJSValuePrivate();
- return property<>(name);
-}
-
-inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::property(quint32 index) const
-{
- if (!isObject())
- return new QJSValuePrivate();
- return property<>(index);
-}
-
-template<typename T>
-inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::property(T name) const
-{
- Q_ASSERT(isObject());
- v8::HandleScope handleScope;
- v8::Handle<v8::Object> self(v8::Object::Cast(*m_value));
-
- v8::TryCatch tryCatch;
- v8::Handle<v8::Value> result = self->Get(name);
- if (tryCatch.HasCaught())
- result = tryCatch.Exception();
- if (result.IsEmpty())
- return new QJSValuePrivate(engine());
- return new QJSValuePrivate(engine(), result);
-}
-
-inline bool QJSValuePrivate::deleteProperty(const QString& name)
-{
- if (!isObject())
- return false;
-
- v8::HandleScope handleScope;
- v8::Handle<v8::Object> self(v8::Handle<v8::Object>::Cast(m_value));
- return self->Delete(QJSConverter::toString(name));
-}
-
-inline bool QJSValuePrivate::hasProperty(const QString &name) const
-{
- if (!isObject())
- return false;
-
- v8::HandleScope handleScope;
- v8::Handle<v8::Object> self(v8::Handle<v8::Object>::Cast(m_value));
- return self->Has(QJSConverter::toString(name));
-}
-
-inline bool QJSValuePrivate::hasOwnProperty(const QString &name) const
-{
- if (!isObject())
- return false;
-
- v8::HandleScope handleScope;
- v8::Handle<v8::Object> self(v8::Handle<v8::Object>::Cast(m_value));
- return self->HasOwnProperty(QJSConverter::toString(name));
-}
-
-inline QJSValuePrivate::PropertyFlags QJSValuePrivate::propertyFlags(const QString& name) const
-{
- if (!isObject())
- return QJSValuePrivate::PropertyFlags(0);
-
- v8::HandleScope handleScope;
- return engine()->getPropertyFlags(v8::Handle<v8::Object>::Cast(m_value), QJSConverter::toString(name));
-}
-
-inline QJSValuePrivate::PropertyFlags QJSValuePrivate::propertyFlags(v8::Handle<v8::String> name) const
-{
- if (!isObject())
- return QJSValuePrivate::PropertyFlags(0);
-
- v8::HandleScope handleScope;
- return engine()->getPropertyFlags(v8::Handle<v8::Object>::Cast(m_value), name);
-}
-
-inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::call(QJSValuePrivate* thisObject, const QJSValueList& args)
-{
- if (!isCallable())
- return new QJSValuePrivate();
-
- v8::HandleScope handleScope;
-
- // Convert all arguments and bind to the engine.
- int argc = args.size();
- QVarLengthArray<v8::Handle<v8::Value>, 8> argv(argc);
- if (!prepareArgumentsForCall(argv.data(), args)) {
- qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
- return new QJSValuePrivate(engine());
- }
-
- return call(thisObject, argc, argv.data());
-}
-
-QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::call(QJSValuePrivate* thisObject, int argc, v8::Handle<v8::Value> *argv)
-{
- QV8Engine *e = engine();
-
- v8::Handle<v8::Object> recv;
-
- if (!thisObject || !thisObject->isObject()) {
- recv = v8::Handle<v8::Object>(v8::Object::Cast(*e->global()));
- } else {
- if (!thisObject->assignEngine(e)) {
- qWarning("QJSValue::call() failed: cannot call function with thisObject created in a different engine");
- return new QJSValuePrivate(engine());
- }
-
- recv = v8::Handle<v8::Object>(v8::Object::Cast(*thisObject->m_value));
- }
-
- if (argc < 0) {
- v8::Local<v8::Value> exeption = v8::Exception::TypeError(v8::String::New("Arguments must be an array"));
- return new QJSValuePrivate(e, exeption);
- }
-
- v8::TryCatch tryCatch;
- v8::Handle<v8::Value> result = v8::Object::Cast(*m_value)->CallAsFunction(recv, argc, argv);
-
- if (result.IsEmpty()) {
- result = tryCatch.Exception();
- // TODO: figure out why v8 doesn't always produce an exception value.
- //Q_ASSERT(!result.IsEmpty());
- if (result.IsEmpty())
- result = v8::Exception::Error(v8::String::New("missing exception value"));
- }
-
- return new QJSValuePrivate(e, result);
-}
-
-inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::callAsConstructor(int argc, v8::Handle<v8::Value> *argv)
-{
- QV8Engine *e = engine();
-
- if (argc < 0) {
- v8::Local<v8::Value> exeption = v8::Exception::TypeError(v8::String::New("Arguments must be an array"));
- return new QJSValuePrivate(e, exeption);
- }
-
- v8::TryCatch tryCatch;
- v8::Handle<v8::Value> result = v8::Object::Cast(*m_value)->CallAsConstructor(argc, argv);
-
- if (result.IsEmpty())
- result = tryCatch.Exception();
-
- return new QJSValuePrivate(e, result);
-}
-
-inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::callAsConstructor(const QJSValueList& args)
-{
- if (!isCallable())
- return new QJSValuePrivate();
-
- v8::HandleScope handleScope;
-
- // Convert all arguments and bind to the engine.
- int argc = args.size();
- QVarLengthArray<v8::Handle<v8::Value>, 8> argv(argc);
- if (!prepareArgumentsForCall(argv.data(), args)) {
- qWarning("QJSValue::callAsConstructor() failed: cannot construct function with argument created in a different engine");
- return new QJSValuePrivate(engine());
- }
-
- return callAsConstructor(argc, argv.data());
-}
-
-/*! \internal
- * Make sure this value is associated with a v8 value belonging to this engine.
- * If the value belongs to another engine, returns false.
- */
-bool QJSValuePrivate::assignEngine(QV8Engine* engine)
-{
- Q_ASSERT(engine);
- v8::HandleScope handleScope;
- switch (m_state) {
- case CBool:
- m_value = v8::Persistent<v8::Value>::New(engine->makeJSValue(u.m_bool));
- break;
- case CString:
- m_value = v8::Persistent<v8::Value>::New(engine->makeJSValue(*u.m_string));
- delete u.m_string;
- break;
- case CNumber:
- m_value = v8::Persistent<v8::Value>::New(engine->makeJSValue(u.m_number));
- break;
- case CNull:
- m_value = v8::Persistent<v8::Value>::New(engine->makeJSValue(QJSValue::NullValue));
- break;
- case CUndefined:
- m_value = v8::Persistent<v8::Value>::New(engine->makeJSValue(QJSValue::UndefinedValue));
- break;
- default:
- if (this->engine() == engine)
- return true;
- else if (!isJSBased())
- Q_ASSERT_X(!isJSBased(), "assignEngine()", "Not all states are included in the previous switch statement.");
- else
- qWarning("JSValue can't be rassigned to an another engine.");
- return false;
- }
- m_engine = engine;
- m_state = JSValue;
-
- m_engine->registerValue(this);
- return true;
-}
-
-/*!
- \internal
- Invalidates this value (makes it undefined).
-
- Does not remove the value from the engine's list of
- registered values; that's the responsibility of the caller.
-*/
-void QJSValuePrivate::invalidate()
-{
- if (isJSBased()) {
- m_value.Dispose();
- m_value.Clear();
- } else if (isStringBased()) {
- delete u.m_string;
- }
- m_engine = 0;
- m_state = CUndefined;
-}
-
-QV8Engine* QJSValuePrivate::engine() const
-{
- return m_engine;
-}
-
-inline QJSValuePrivate::operator v8::Handle<v8::Value>() const
-{
- Q_ASSERT(isJSBased());
- return m_value;
-}
-
-inline QJSValuePrivate::operator v8::Handle<v8::Object>() const
-{
- Q_ASSERT(isObject());
- return v8::Handle<v8::Object>::Cast(m_value);
-}
-
-inline v8::Handle<v8::Value> QJSValuePrivate::handle() const
-{
- return m_value;
-}
-
-/*!
- * Return a v8::Handle, assign to the engine if needed.
- */
-v8::Handle<v8::Value> QJSValuePrivate::asV8Value(QV8Engine* engine)
-{
- if (!m_engine) {
- if (!assignEngine(engine))
- return v8::Handle<v8::Value>();
- }
- Q_ASSERT(isJSBased());
- return m_value;
-}
-
-/*!
- \internal
- Returns true if QSV have an engine associated.
-*/
-bool QJSValuePrivate::isJSBased() const
-{
-#ifndef QT_NO_DEBUG
- // internals check.
- if (m_state >= JSValue)
- Q_ASSERT(!m_value.IsEmpty());
- else
- Q_ASSERT(m_value.IsEmpty());
-#endif
- return m_state >= JSValue;
-}
-
-/*!
- \internal
- Returns true if current value of QSV is placed in m_number.
-*/
-bool QJSValuePrivate::isNumberBased() const { return m_state == CNumber || m_state == CBool; }
-
-/*!
- \internal
- Returns true if current value of QSV is placed in m_string.
-*/
-bool QJSValuePrivate::isStringBased() const { return m_state == CString; }
-
-/*!
- \internal
- Converts arguments and bind them to the engine.
- \attention argv should be big enough
-*/
-inline bool QJSValuePrivate::prepareArgumentsForCall(v8::Handle<v8::Value> argv[], const QJSValueList& args) const
-{
- QJSValueList::const_iterator i = args.constBegin();
- for (int j = 0; i != args.constEnd(); j++, i++) {
- QJSValuePrivate* value = QJSValuePrivate::get(*i);
- if ((value->isJSBased() && engine() != value->engine())
- || (!value->isJSBased() && !value->assignEngine(engine())))
- // Different engines are not allowed!
- return false;
- argv[j] = *value;
- }
- return true;
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/qml/qml/v8/qjsvalue_p.h b/src/qml/qml/v8/qjsvalue_p.h
index c4c8d415d4..ef94dea555 100644
--- a/src/qml/qml/v8/qjsvalue_p.h
+++ b/src/qml/qml/v8/qjsvalue_p.h
@@ -53,161 +53,47 @@
#ifndef QJSVALUE_P_H
#define QJSVALUE_P_H
-#include <private/qv8_p.h>
-
-#include <QtCore/qbytearray.h>
-#include <QtCore/qdatetime.h>
-#include <QtCore/qmath.h>
-#include <QtCore/qvarlengtharray.h>
-#include <qdebug.h>
-
-#include <private/qintrusivelist_p.h>
-#include "qscriptshareddata_p.h"
-#include "qjsvalue.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
-class QV8Engine;
-
/*!
\internal
\class QJSValuePrivate
*/
-class QJSValuePrivate
- : public QSharedData
+class QJSValuePrivate : public QV4::PersistentValuePrivate
{
public:
- enum PropertyFlag {
- ReadOnly = 0x00000001,
- Undeletable = 0x00000002,
- SkipInEnumeration = 0x00000004
- };
- Q_DECLARE_FLAGS(PropertyFlags, PropertyFlag)
-
- inline static QJSValuePrivate* get(const QJSValue& q);
- inline static QJSValue get(const QJSValuePrivate* d);
- inline static QJSValue get(QJSValuePrivate* d);
- inline static QJSValue get(QScriptPassPointer<QJSValuePrivate> d);
- inline ~QJSValuePrivate();
-
- inline QJSValuePrivate(bool value);
- inline QJSValuePrivate(int value);
- inline QJSValuePrivate(uint value);
- inline QJSValuePrivate(double value);
- inline QJSValuePrivate(const QString& value);
- inline QJSValuePrivate(QJSValue::SpecialValue value = QJSValue::UndefinedValue);
-
- inline QJSValuePrivate(QV8Engine *engine, bool value);
- inline QJSValuePrivate(QV8Engine *engine, int value);
- inline QJSValuePrivate(QV8Engine *engine, uint value);
- inline QJSValuePrivate(QV8Engine *engine, double value);
- inline QJSValuePrivate(QV8Engine *engine, const QString& value);
- inline QJSValuePrivate(QV8Engine *engine, QJSValue::SpecialValue value = QJSValue::UndefinedValue);
- inline QJSValuePrivate(QV8Engine *engine, v8::Handle<v8::Value>);
- inline void invalidate();
-
- inline bool toBool() const;
- inline double toNumber() const;
- inline QString toString() const;
- inline double toInteger() const;
- inline qint32 toInt32() const;
- inline quint32 toUInt32() const;
- inline quint16 toUInt16() const;
- inline QDateTime toDataTime() const;
- inline QObject *toQObject() const;
- inline QVariant toVariant() const;
-
- inline bool isArray() const;
- inline bool isBool() const;
- inline bool isCallable() const;
- inline bool isError() const;
- inline bool isFunction() const;
- inline bool isNull() const;
- inline bool isNumber() const;
- inline bool isObject() const;
- inline bool isString() const;
- inline bool isUndefined() const;
- inline bool isVariant() const;
- inline bool isDate() const;
- inline bool isRegExp() const;
- inline bool isQObject() const;
-
- inline bool equals(QJSValuePrivate* other);
- inline bool strictlyEquals(QJSValuePrivate* other);
-
- inline QScriptPassPointer<QJSValuePrivate> prototype() const;
- inline void setPrototype(QJSValuePrivate* prototype);
-
- inline void setProperty(const QString &name, QJSValuePrivate *value, uint attribs = 0);
- inline void setProperty(v8::Handle<v8::String> name, QJSValuePrivate *value, uint attribs = 0);
- inline void setProperty(quint32 index, QJSValuePrivate* value, uint attribs = 0);
- inline QScriptPassPointer<QJSValuePrivate> property(const QString& name) const;
- inline QScriptPassPointer<QJSValuePrivate> property(v8::Handle<v8::String> name) const;
- inline QScriptPassPointer<QJSValuePrivate> property(quint32 index) const;
- template<typename T>
- inline QScriptPassPointer<QJSValuePrivate> property(T name) const;
- inline bool deleteProperty(const QString& name);
- inline bool hasProperty(const QString &name) const;
- inline bool hasOwnProperty(const QString &name) const;
- inline PropertyFlags propertyFlags(const QString& name) const;
- inline PropertyFlags propertyFlags(v8::Handle<v8::String> name) const;
-
- inline QScriptPassPointer<QJSValuePrivate> call(QJSValuePrivate* thisObject, const QJSValueList& args);
- inline QScriptPassPointer<QJSValuePrivate> call(QJSValuePrivate* thisObject, const QJSValue& arguments);
- inline QScriptPassPointer<QJSValuePrivate> call(QJSValuePrivate* thisObject, int argc, v8::Handle< v8::Value >* argv);
- inline QScriptPassPointer<QJSValuePrivate> callAsConstructor(int argc, v8::Handle<v8::Value> *argv);
- inline QScriptPassPointer<QJSValuePrivate> callAsConstructor(const QJSValueList& args);
- inline QScriptPassPointer<QJSValuePrivate> callAsConstructor(const QJSValue& arguments);
-
- inline bool assignEngine(QV8Engine *engine);
- inline QV8Engine *engine() const;
-
- inline operator v8::Handle<v8::Value>() const;
- inline operator v8::Handle<v8::Object>() const;
- inline v8::Handle<v8::Value> handle() const;
- inline v8::Handle<v8::Value> asV8Value(QV8Engine *engine);
-private:
- QIntrusiveListNode m_node;
- QV8Engine *m_engine;
-
- // Please, update class documentation when you change the enum.
- enum State {
- CString = 0x1000,
- CNumber,
- CBool,
- CNull,
- CUndefined,
- JSValue = 0x2000 // V8 values are equal or higher then this value.
- // JSPrimitive,
- // JSObject
- } m_state;
-
- union CValue {
- bool m_bool;
- double m_number;
- QString* m_string;
-
- CValue() : m_number(0) {}
- CValue(bool value) : m_bool(value) {}
- CValue(int number) : m_number(number) {}
- CValue(uint number) : m_number(number) {}
- CValue(double number) : m_number(number) {}
- CValue(QString* string) : m_string(string) {}
- } u;
- // v8::Persistent is not a POD, so can't be part of the union.
- v8::Persistent<v8::Value> m_value;
-
- Q_DISABLE_COPY(QJSValuePrivate)
- inline bool isJSBased() const;
- inline bool isNumberBased() const;
- inline bool isStringBased() const;
- inline bool prepareArgumentsForCall(v8::Handle<v8::Value> argv[], const QJSValueList& arguments) const;
-
- friend class QV8Engine;
+ 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;
};
-Q_DECLARE_OPERATORS_FOR_FLAGS(QJSValuePrivate::PropertyFlags)
-
QT_END_NAMESPACE
#endif
diff --git a/src/qml/qml/v8/qjsvalueiterator.cpp b/src/qml/qml/v8/qjsvalueiterator.cpp
index 67646c9eb4..a6fba112c9 100644
--- a/src/qml/qml/v8/qjsvalueiterator.cpp
+++ b/src/qml/qml/v8/qjsvalueiterator.cpp
@@ -41,14 +41,25 @@
#include "qjsvalueiterator.h"
#include "qjsvalueiterator_p.h"
-
-#include "qscriptisolate_p.h"
#include "qjsvalue_p.h"
-#include "qv8engine_p.h"
-#include "qscript_impl_p.h"
+#include "private/qv4string_p.h"
+#include "private/qv4object_p.h"
QT_BEGIN_NAMESPACE
+QJSValueIteratorPrivate::QJSValueIteratorPrivate(const QJSValue &v)
+ : value(v)
+ , iterator(QJSValuePrivate::get(v)->value.asObject(), QV4::ObjectIterator::NoFlags)
+ , currentValue(0)
+ , currentName(0)
+ , currentIndex(UINT_MAX)
+ , nextValue(0)
+ , nextName(0)
+ , nextIndex(UINT_MAX)
+{
+}
+
+
/*!
\class QJSValueIterator
@@ -84,14 +95,17 @@ QT_BEGIN_NAMESPACE
first property).
*/
QJSValueIterator::QJSValueIterator(const QJSValue& object)
- : d_ptr(new QJSValueIteratorPrivate(QJSValuePrivate::get(object)))
-{}
+ : d_ptr(new QJSValueIteratorPrivate(object))
+{
+ d_ptr->nextValue = 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
@@ -102,9 +116,9 @@ QJSValueIterator::~QJSValueIterator()
*/
bool QJSValueIterator::hasNext() const
{
- Q_D(const QJSValueIterator);
- QScriptIsolate api(d->engine());
- return d->hasNext();
+ if (!QJSValuePrivate::get(d_ptr->value)->value.isObject())
+ return false;
+ return d_ptr->nextValue != 0;
}
/*!
@@ -120,9 +134,15 @@ bool QJSValueIterator::hasNext() const
*/
bool QJSValueIterator::next()
{
- Q_D(QJSValueIterator);
- QScriptIsolate api(d->engine());
- return d->next();
+ if (!QJSValuePrivate::get(d_ptr->value)->value.isObject())
+ return false;
+ d_ptr->currentValue = d_ptr->nextValue;
+ d_ptr->currentName = d_ptr->nextName;
+ d_ptr->currentIndex = d_ptr->nextIndex;
+ d_ptr->currentAttributes = d_ptr->nextAttributes;
+
+ d_ptr->nextValue = d_ptr->iterator.next(&d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
+ return d_ptr->nextValue != 0;
}
/*!
@@ -133,9 +153,13 @@ bool QJSValueIterator::next()
*/
QString QJSValueIterator::name() const
{
- Q_D(const QJSValueIterator);
- QScriptIsolate api(d->engine());
- return d_ptr->name();
+ 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();
}
@@ -147,9 +171,21 @@ QString QJSValueIterator::name() const
*/
QJSValue QJSValueIterator::value() const
{
- Q_D(const QJSValueIterator);
- QScriptIsolate api(d->engine());
- return QJSValuePrivate::get(d->value());
+ if (!QJSValuePrivate::get(d_ptr->value)->value.isObject())
+ return QJSValue();
+ if (!d_ptr->currentValue)
+ return QJSValue();
+
+ QV4::Object *o = d_ptr->iterator.object;
+ QV4::ExecutionEngine *engine = o->internalClass->engine;
+ QV4::ExecutionContext *ctx = engine->current;
+ try {
+ QV4::Value v = o->getValue(d_ptr->currentValue, d_ptr->currentAttributes);
+ return new QJSValuePrivate(engine, v);
+ } catch (QV4::Exception &e) {
+ e.accept(ctx);
+ return QJSValue();
+ }
}
@@ -160,9 +196,8 @@ QJSValue QJSValueIterator::value() const
*/
QJSValueIterator& QJSValueIterator::operator=(QJSValue& object)
{
- Q_D(QJSValueIterator);
- QScriptIsolate api(d->engine());
- d_ptr.reset(new QJSValueIteratorPrivate(QJSValuePrivate::get(object)));
+ d_ptr->iterator = QV4::ObjectIterator(QJSValuePrivate::get(object)->value.asObject(), QV4::ObjectIterator::NoFlags);
+ d_ptr->nextValue = d_ptr->iterator.next(&d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
return *this;
}
diff --git a/src/qml/qml/v8/qjsvalueiterator.h b/src/qml/qml/v8/qjsvalueiterator.h
index b4f90a44b7..e204558e90 100644
--- a/src/qml/qml/v8/qjsvalueiterator.h
+++ b/src/qml/qml/v8/qjsvalueiterator.h
@@ -42,8 +42,8 @@
#ifndef QSCRIPTVALUEITERATOR_H
#define QSCRIPTVALUEITERATOR_H
-#include <QtQml/qtqmlglobal.h>
#include <QtQml/qjsvalue.h>
+#include <QtQml/qtqmlglobal.h>
#include <QtCore/qscopedpointer.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/qml/v8/qjsvalueiterator_impl_p.h b/src/qml/qml/v8/qjsvalueiterator_impl_p.h
deleted file mode 100644
index f7b6943f57..0000000000
--- a/src/qml/qml/v8/qjsvalueiterator_impl_p.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QJSVALUEITERATOR_IMPL_P_H
-#define QJSVALUEITERATOR_IMPL_P_H
-
-#include "qjsvalueiterator_p.h"
-#include <private/qv8engine_p.h>
-#include "qjsconverter_p.h"
-
-QT_BEGIN_NAMESPACE
-
-inline QJSValueIteratorPrivate::QJSValueIteratorPrivate(const QJSValuePrivate* value)
- : m_object(const_cast<QJSValuePrivate*>(value))
- , m_index(0)
- , m_count(0)
-{
- Q_ASSERT(value);
- QV8Engine *engine = m_object->engine();
- if (!m_object->isObject())
- m_object = 0;
- else {
- QScriptIsolate api(engine, QScriptIsolate::NotNullEngine);
- v8::HandleScope scope;
-
- v8::Handle<v8::Value> tmp = *value;
- v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(tmp);
- v8::Local<v8::Array> names;
-
- // FIXME we need newer V8!
- //names = obj->GetOwnPropertyNames();
- names = engine->getOwnPropertyNames(obj);
- m_names = v8::Persistent<v8::Array>::New(names);
- m_count = names->Length();
-
- engine->registerValueIterator(this);
- }
-}
-
-inline QJSValueIteratorPrivate::~QJSValueIteratorPrivate()
-{
- if (isValid()) {
- engine()->unregisterValueIterator(this);
- m_names.Dispose();
- }
-}
-
-inline void QJSValueIteratorPrivate::invalidate()
-{
- m_names.Dispose();
- m_object.reset();
- m_index = 0;
- m_count = 0;
-}
-
-inline bool QJSValueIteratorPrivate::hasNext() const
-{
- return isValid() ? m_index < m_count : false;
-}
-
-inline bool QJSValueIteratorPrivate::next()
-{
- if (hasNext()) {
- ++m_index;
- return true;
- }
- return false;
-}
-
-inline QString QJSValueIteratorPrivate::name() const
-{
- if (!isValid())
- return QString();
-
- v8::HandleScope handleScope;
- return QJSConverter::toString(m_names->Get(m_index - 1)->ToString());
-}
-
-inline QScriptPassPointer<QJSValuePrivate> QJSValueIteratorPrivate::value() const
-{
- if (!isValid())
- return new QJSValuePrivate();
-
- v8::HandleScope handleScope;
- return m_object->property(m_names->Get(m_index - 1)->ToString());
-}
-
-inline bool QJSValueIteratorPrivate::isValid() const
-{
- bool result = m_object ? !m_object->isUndefined() : false;
- // We know that if this object is still valid then it is an object
- // if this assumption is not correct then some other logic in this class
- // have to be changed too.
- Q_ASSERT(!result || m_object->isObject());
- return result;
-}
-
-inline QV8Engine* QJSValueIteratorPrivate::engine() const
-{
- return m_object ? m_object->engine() : 0;
-}
-
-QT_END_NAMESPACE
-
-#endif // QJSVALUEITERATOR_IMPL_P_H
diff --git a/src/qml/qml/v8/qjsvalueiterator_p.h b/src/qml/qml/v8/qjsvalueiterator_p.h
index 2d36ac3ca5..999003b41c 100644
--- a/src/qml/qml/v8/qjsvalueiterator_p.h
+++ b/src/qml/qml/v8/qjsvalueiterator_p.h
@@ -42,10 +42,8 @@
#ifndef QJSVALUEITERATOR_P_H
#define QJSVALUEITERATOR_P_H
-#include <private/qintrusivelist_p.h>
-#include "qjsvalue_p.h"
-
-#include <private/qv8_p.h>
+#include "qjsvalue.h"
+#include "private/qv4objectiterator_p.h"
QT_BEGIN_NAMESPACE
@@ -54,30 +52,18 @@ class QV8Engine;
class QJSValueIteratorPrivate
{
public:
- inline QJSValueIteratorPrivate(const QJSValuePrivate* value);
- inline ~QJSValueIteratorPrivate();
-
- inline bool hasNext() const;
- inline bool next();
-
- inline QString name() const;
-
- inline QScriptPassPointer<QJSValuePrivate> value() const;
-
- inline bool isValid() const;
- inline QV8Engine* engine() const;
-
- inline void invalidate();
-private:
- Q_DISABLE_COPY(QJSValueIteratorPrivate)
-
- QIntrusiveListNode m_node;
- QScriptSharedDataPointer<QJSValuePrivate> m_object;
- v8::Persistent<v8::Array> m_names;
- uint32_t m_index;
- uint32_t m_count;
-
- friend class QV8Engine;
+ QJSValueIteratorPrivate(const QJSValue &v);
+
+ QJSValue value;
+ QV4::ObjectIterator iterator;
+ QV4::Property *currentValue;
+ QV4::PropertyAttributes currentAttributes;
+ QV4::String *currentName;
+ uint currentIndex;
+ QV4::Property *nextValue;
+ QV4::PropertyAttributes nextAttributes;
+ QV4::String *nextName;
+ uint nextIndex;
};
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 457d0bb969..97736355d4 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -47,12 +47,21 @@
#include <private/qqmlstringconverters_p.h>
#include <private/qqmllocale_p.h>
#include <private/qv8engine_p.h>
-#include <private/qjsconverter_impl_p.h>
#include <private/qv8profilerservice_p.h>
#include <private/qqmlprofilerservice_p.h>
#include <private/qqmlglobal_p.h>
+#include <private/qqmlplatform_p.h>
+
+#include <private/qv4engine_p.h>
+#include <private/qv4functionobject_p.h>
+#include <private/qv4include_p.h>
+#include <private/qv4context_p.h>
+#include <private/qv4stringobject_p.h>
+#include <private/qv4mm_p.h>
+#include <private/qv4jsonobject_p.h>
+
#include <QtCore/qstring.h>
#include <QtCore/qdatetime.h>
#include <QtCore/qcryptographichash.h>
@@ -65,336 +74,105 @@
QT_BEGIN_NAMESPACE
-namespace QQmlBuiltinFunctions {
-
-enum ConsoleLogTypes {
- Log,
- Warn,
- Error
-};
-
-static void jsContext(v8::Handle<v8::Value> *file, int *line, v8::Handle<v8::Value> *function) {
- v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(1);
- if (stackTrace->GetFrameCount()) {
- v8::Local<v8::StackFrame> frame = stackTrace->GetFrame(0);
- *file = frame->GetScriptName();
- *line = frame->GetLineNumber();
- *function = frame->GetFunctionName();
- }
-}
-
-static QString jsStack() {
- QStringList stackFrames;
-
- //The v8 default is currently 10 stack frames.
- v8::Handle<v8::StackTrace> stackTrace =
- v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kOverview);
- int stackCount = stackTrace->GetFrameCount();
-
- for (int i = 0; i < stackCount; i++) {
- v8::Local<v8::StackFrame> frame = stackTrace->GetFrame(i);
- v8::Handle<v8::String> function(frame->GetFunctionName());
- v8::Handle<v8::String> script(frame->GetScriptName());
- int lineNumber = frame->GetLineNumber();
- int columnNumber = frame->GetColumn();
-
- QString stackFrame =
- QString::fromLatin1("%1 (%2:%3:%4)").arg(QJSConverter::toString(function),
- QJSConverter::toString(script),
- QString::number(lineNumber),
- QString::number(columnNumber));
- stackFrames.append(stackFrame);
- }
- return stackFrames.join(QLatin1String("\n"));
-}
-
-v8::Handle<v8::Value> console(ConsoleLogTypes logType, const v8::Arguments &args,
- bool printStack = false)
-{
- v8::HandleScope handleScope;
-
- QString result;
- QV8Engine *engine = V8ENGINE();
- for (int i = 0; i < args.Length(); ++i) {
- if (i != 0)
- result.append(QLatin1Char(' '));
-
- v8::Local<v8::Value> value = args[i];
-
- v8::TryCatch tryCatch;
- v8::Local<v8::String> toString = value->ToString();
- if (tryCatch.HasCaught()) {
- // toString() threw Exception
- // Is it possible for value to be anything other than Object?
- QString str;
- if (value->IsObject()) {
- str = QStringLiteral("[object Object]");
- } else {
- toString = tryCatch.Exception()->ToString();
- str = QStringLiteral("toString() threw exception: %1")
- .arg(engine->toString(toString));
- }
- result.append(str);
- continue;
- }
-
- QString tmp = engine->toString(toString);
- if (value->IsArray())
- result.append(QStringLiteral("[%1]").arg(tmp));
- else
- result.append(tmp);
- }
-
- if (printStack) {
- result.append(QLatin1String("\n"));
- result.append(jsStack());
- }
-
- v8::Handle<v8::Value> fileHandle;
- v8::Handle<v8::Value> functionHandle;
- int line;
-
- jsContext(&fileHandle, &line, &functionHandle);
-
- switch (logType) {
- case Log:
- QMessageLogger(*v8::String::AsciiValue(fileHandle), line,
- *v8::String::AsciiValue(functionHandle)).debug("%s", qPrintable(result));
- break;
- case Warn:
- QMessageLogger(*v8::String::AsciiValue(fileHandle), line,
- *v8::String::AsciiValue(functionHandle)).warning("%s", qPrintable(result));
- break;
- case Error:
- QMessageLogger(*v8::String::AsciiValue(fileHandle), line,
- *v8::String::AsciiValue(functionHandle)).critical("%s", qPrintable(result));
- break;
- default:
- break;
- }
+using namespace QV4;
- return v8::Undefined();
-}
+DEFINE_MANAGED_VTABLE(QtObject);
-v8::Handle<v8::Value> gc(const v8::Arguments &args)
+struct StaticQtMetaObject : public QObject
{
- Q_UNUSED(args);
- QV8Engine::gc();
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> consoleError(const v8::Arguments &args)
-{
- return console(Error, args);
-}
-
-v8::Handle<v8::Value> consoleLog(const v8::Arguments &args)
-{
- //console.log
- //console.debug
- //console.info
- //print
- return console(Log, args);
-}
+ static const QMetaObject *get()
+ { return &staticQtMetaObject; }
+};
-v8::Handle<v8::Value> consoleProfile(const v8::Arguments &args)
+QV4::QtObject::QtObject(ExecutionEngine *v4, QQmlEngine *qmlEngine)
+ : Object(v4)
+ , m_platform(0)
+ , m_application(0)
{
- //DeclarativeDebugTrace cannot handle nested profiling
- //although v8 can handle several profiling at once,
- //we do not allow that. Hence, we pass an empty(default) title
- Q_UNUSED(args);
- QString title;
-
-
-
- v8::Handle<v8::Value> file;
- v8::Handle<v8::Value> function;
- int line;
- jsContext(&file, &line, &function);
-
- if (QQmlProfilerService::startProfiling()) {
- QV8ProfilerService::instance()->startProfiling(title);
-
- QMessageLogger(*v8::String::AsciiValue(file), line,
- *v8::String::AsciiValue(function)).debug("Profiling started.");
- } else {
- QMessageLogger(*v8::String::AsciiValue(file), line,
- *v8::String::AsciiValue(function)).warning(
- "Profiling is already in progress. First, end current profiling session.");
+ vtbl = &static_vtbl;
+
+ // Set all the enums from the "Qt" namespace
+ const QMetaObject *qtMetaObject = StaticQtMetaObject::get();
+ for (int ii = 0; ii < qtMetaObject->enumeratorCount(); ++ii) {
+ QMetaEnum enumerator = qtMetaObject->enumerator(ii);
+ for (int jj = 0; jj < enumerator.keyCount(); ++jj) {
+ put(v4->newString(enumerator.key(jj)), QV4::Value::fromInt32(enumerator.value(jj)));
+ }
}
-
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> consoleProfileEnd(const v8::Arguments &args)
-{
- //DeclarativeDebugTrace cannot handle nested profiling
- //although v8 can handle several profiling at once,
- //we do not allow that. Hence, we pass an empty(default) title
- Q_UNUSED(args);
- QString title;
-
- v8::Handle<v8::Value> file;
- v8::Handle<v8::Value> function;
- int line;
- jsContext(&file, &line, &function);
-
- if (QQmlProfilerService::stopProfiling()) {
- QV8ProfilerService *profiler = QV8ProfilerService::instance();
- profiler->stopProfiling(title);
- QQmlProfilerService::sendProfilingData();
- profiler->sendProfilingData();
-
- QMessageLogger(*v8::String::AsciiValue(file), line,
- *v8::String::AsciiValue(function)).debug("Profiling ended.");
- } else {
- QMessageLogger(*v8::String::AsciiValue(file), line,
- *v8::String::AsciiValue(function)).warning("Profiling was not started.");
+ put(v4->newString("Asynchronous"), QV4::Value::fromInt32(0));
+ put(v4->newString("Synchronous"), QV4::Value::fromInt32(1));
+
+ defineDefaultProperty(v4, QStringLiteral("include"), QV4Include::include);
+ defineDefaultProperty(v4, QStringLiteral("isQtObject"), method_isQtObject);
+ defineDefaultProperty(v4, QStringLiteral("rgba"), method_rgba);
+ defineDefaultProperty(v4, QStringLiteral("hsla"), method_hsla);
+ defineDefaultProperty(v4, QStringLiteral("colorEqual"), method_colorEqual);
+ defineDefaultProperty(v4, QStringLiteral("rect"), method_rect);
+ defineDefaultProperty(v4, QStringLiteral("point"), method_point);
+ defineDefaultProperty(v4, QStringLiteral("size"), method_size);
+ defineDefaultProperty(v4, QStringLiteral("font"), method_font);
+
+ defineDefaultProperty(v4, QStringLiteral("vector2d"), method_vector2d);
+ defineDefaultProperty(v4, QStringLiteral("vector3d"), method_vector3d);
+ defineDefaultProperty(v4, QStringLiteral("vector4d"), method_vector4d);
+ defineDefaultProperty(v4, QStringLiteral("quaternion"), method_quaternion);
+ defineDefaultProperty(v4, QStringLiteral("matrix4x4"), method_matrix4x4);
+
+ defineDefaultProperty(v4, QStringLiteral("formatDate"), method_formatDate);
+ defineDefaultProperty(v4, QStringLiteral("formatTime"), method_formatTime);
+ defineDefaultProperty(v4, QStringLiteral("formatDateTime"), method_formatDateTime);
+
+ defineDefaultProperty(v4, QStringLiteral("openUrlExternally"), method_openUrlExternally);
+ defineDefaultProperty(v4, QStringLiteral("fontFamilies"), method_fontFamilies);
+ defineDefaultProperty(v4, QStringLiteral("md5"), method_md5);
+ defineDefaultProperty(v4, QStringLiteral("btoa"), method_btoa);
+ defineDefaultProperty(v4, QStringLiteral("atob"), method_atob);
+ defineDefaultProperty(v4, QStringLiteral("resolvedUrl"), method_resolvedUrl);
+ defineDefaultProperty(v4, QStringLiteral("locale"), method_locale);
+ defineDefaultProperty(v4, QStringLiteral("binding"), method_binding);
+
+ if (qmlEngine) {
+ defineDefaultProperty(v4, QStringLiteral("lighter"), method_lighter);
+ defineDefaultProperty(v4, QStringLiteral("darker"), method_darker);
+ defineDefaultProperty(v4, QStringLiteral("tint"), method_tint);
+ defineDefaultProperty(v4, QStringLiteral("quit"), method_quit);
+ defineDefaultProperty(v4, QStringLiteral("createQmlObject"), method_createQmlObject);
+ defineDefaultProperty(v4, QStringLiteral("createComponent"), method_createComponent);
}
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> consoleTime(const v8::Arguments &args)
-{
- if (args.Length() != 1)
- V8THROW_ERROR("console.time(): Invalid arguments");
- QString name = V8ENGINE()->toString(args[0]);
- V8ENGINE()->startTimer(name);
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> consoleTimeEnd(const v8::Arguments &args)
-{
- if (args.Length() != 1)
- V8THROW_ERROR("console.time(): Invalid arguments");
- QString name = V8ENGINE()->toString(args[0]);
- bool wasRunning;
- qint64 elapsed = V8ENGINE()->stopTimer(name, &wasRunning);
- if (wasRunning) {
- qDebug("%s: %llims", qPrintable(name), elapsed);
+ {
+ String *s = v4->newString(QStringLiteral("platform"));
+ Property *p = insertMember(s, Attr_Accessor);
+ FunctionObject* f = v4->newBuiltinFunction(v4->rootContext, s, method_get_platform);
+ p->setGetter(f);
}
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> consoleCount(const v8::Arguments &args)
-{
- // first argument: name to print. Ignore any additional arguments
- QString name;
- if (args.Length() > 0)
- name = V8ENGINE()->toString(args[0]);
-
- v8::Handle<v8::StackTrace> stackTrace =
- v8::StackTrace::CurrentStackTrace(1, v8::StackTrace::kOverview);
-
- if (stackTrace->GetFrameCount()) {
- v8::Local<v8::StackFrame> frame = stackTrace->GetFrame(0);
-
- QString scriptName = V8ENGINE()->toString(frame->GetScriptName());
- QString functionName = V8ENGINE()->toString(frame->GetFunctionName());
- int line = frame->GetLineNumber();
- int column = frame->GetColumn();
-
- int value = V8ENGINE()->consoleCountHelper(scriptName, line, column);
- QString message = name + QLatin1String(": ") + QString::number(value);
-
- QMessageLogger(qPrintable(scriptName), line,
- qPrintable(functionName)).debug("%s", qPrintable(message));
+ {
+ String *s = v4->newString(QStringLiteral("application"));
+ Property *p = insertMember(s, Attr_Accessor);
+ FunctionObject* f = v4->newBuiltinFunction(v4->rootContext, s, method_get_application);
+ p->setGetter(f);
}
-
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> consoleTrace(const v8::Arguments &args)
-{
- if (args.Length() != 0)
- V8THROW_ERROR("console.trace(): Invalid arguments");
-
- QString stack = jsStack();
-
- v8::Handle<v8::Value> file;
- v8::Handle<v8::Value> function;
- int line;
- jsContext(&file, &line, &function);
-
- QMessageLogger(*v8::String::AsciiValue(file), line, *v8::String::AsciiValue(function)).debug(
- "%s", qPrintable(stack));
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> consoleWarn(const v8::Arguments &args)
-{
- return console(Warn, args);
-}
-
-v8::Handle<v8::Value> consoleAssert(const v8::Arguments &args)
-{
- if (args.Length() == 0)
- V8THROW_ERROR("console.assert(): Missing argument");
-
- if (!args[0]->ToBoolean()->Value()) {
- QString message;
- for (int i = 1; i < args.Length(); ++i) {
- if (i != 1)
- message.append(QLatin1Char(' '));
-
- v8::Local<v8::Value> value = args[i];
- message.append(V8ENGINE()->toString(value->ToString()));
- }
-
- QString stack = jsStack();
-
- v8::Handle<v8::Value> file;
- v8::Handle<v8::Value> function;
- int line;
- jsContext(&file, &line, &function);
-
- QMessageLogger(*v8::String::AsciiValue(file), line, *v8::String::AsciiValue(function)).critical(
- "%s\n%s", qPrintable(message), qPrintable(stack));
-
+#ifndef QT_NO_IM
+ {
+ String *s = v4->newString(QStringLiteral("inputMethod"));
+ Property *p = insertMember(s, Attr_Accessor);
+ FunctionObject* f = v4->newBuiltinFunction(v4->rootContext, s, method_get_inputMethod);
+ p->setGetter(f);
}
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> consoleException(const v8::Arguments &args)
-{
- if (args.Length() == 0)
- V8THROW_ERROR("console.exception(): Missing argument");
-
- console(Error, args, true);
-
- return v8::Undefined();
+#endif
}
-v8::Handle<v8::Value> stringArg(const v8::Arguments &args)
-{
- QString value = V8ENGINE()->toString(args.This()->ToString());
- if (args.Length() != 1)
- V8THROW_ERROR("String.arg(): Invalid arguments");
-
- v8::Handle<v8::Value> arg = args[0];
- if (arg->IsUint32())
- return V8ENGINE()->toString(value.arg(arg->Uint32Value()));
- else if (arg->IsInt32())
- return V8ENGINE()->toString(value.arg(arg->Int32Value()));
- else if (arg->IsNumber())
- return V8ENGINE()->toString(value.arg(arg->NumberValue()));
- else if (arg->IsBoolean())
- return V8ENGINE()->toString(value.arg(arg->BooleanValue()));
-
- return V8ENGINE()->toString(value.arg(V8ENGINE()->toString(arg)));
-}
/*!
\qmlmethod bool Qt::isQtObject(object)
Returns true if \c object is a valid reference to a Qt or QML object, otherwise false.
*/
-v8::Handle<v8::Value> isQtObject(const v8::Arguments &args)
+Value QtObject::method_isQtObject(QV4::SimpleCallContext *ctx)
{
- if (args.Length() == 0)
- return v8::Boolean::New(false);
+ if (ctx->argumentCount == 0)
+ return QV4::Value::fromBoolean(false);
- return v8::Boolean::New(0 != V8ENGINE()->toQObject(args[0]));
+ return QV4::Value::fromBoolean(ctx->arguments[0].as<QV4::QObjectWrapper>() != 0);
}
/*!
@@ -403,16 +181,16 @@ v8::Handle<v8::Value> isQtObject(const v8::Arguments &args)
Returns a color with the specified \c red, \c green, \c blue and \c alpha components.
All components should be in the range 0-1 inclusive.
*/
-v8::Handle<v8::Value> rgba(const v8::Arguments &args)
+Value QtObject::method_rgba(QV4::SimpleCallContext *ctx)
{
- int argCount = args.Length();
+ int argCount = ctx->argumentCount;
if (argCount < 3 || argCount > 4)
- V8THROW_ERROR("Qt.rgba(): Invalid arguments");
+ V4THROW_ERROR("Qt.rgba(): Invalid arguments");
- double r = args[0]->NumberValue();
- double g = args[1]->NumberValue();
- double b = args[2]->NumberValue();
- double a = (argCount == 4) ? args[3]->NumberValue() : 1;
+ double r = ctx->arguments[0].toNumber();
+ double g = ctx->arguments[1].toNumber();
+ double b = ctx->arguments[2].toNumber();
+ double a = (argCount == 4) ? ctx->arguments[3].toNumber() : 1;
if (r < 0.0) r=0.0;
if (r > 1.0) r=1.0;
@@ -423,7 +201,7 @@ v8::Handle<v8::Value> rgba(const v8::Arguments &args)
if (a < 0.0) a=0.0;
if (a > 1.0) a=1.0;
- return V8ENGINE()->fromVariant(QQml_colorProvider()->fromRgbF(r, g, b, a));
+ return ctx->engine->v8Engine->fromVariant(QQml_colorProvider()->fromRgbF(r, g, b, a));
}
/*!
@@ -432,16 +210,16 @@ v8::Handle<v8::Value> rgba(const v8::Arguments &args)
Returns a color with the specified \c hue, \c saturation, \c lightness and \c alpha components.
All components should be in the range 0-1 inclusive.
*/
-v8::Handle<v8::Value> hsla(const v8::Arguments &args)
+Value QtObject::method_hsla(QV4::SimpleCallContext *ctx)
{
- int argCount = args.Length();
+ int argCount = ctx->argumentCount;
if (argCount < 3 || argCount > 4)
- V8THROW_ERROR("Qt.hsla(): Invalid arguments");
+ V4THROW_ERROR("Qt.hsla(): Invalid arguments");
- double h = args[0]->NumberValue();
- double s = args[1]->NumberValue();
- double l = args[2]->NumberValue();
- double a = (argCount == 4) ? args[3]->NumberValue() : 1;
+ double h = ctx->arguments[0].toNumber();
+ double s = ctx->arguments[1].toNumber();
+ double l = ctx->arguments[2].toNumber();
+ double a = (argCount == 4) ? ctx->arguments[3].toNumber() : 1;
if (h < 0.0) h=0.0;
if (h > 1.0) h=1.0;
@@ -452,7 +230,7 @@ v8::Handle<v8::Value> hsla(const v8::Arguments &args)
if (a < 0.0) a=0.0;
if (a > 1.0) a=1.0;
- return V8ENGINE()->fromVariant(QQml_colorProvider()->fromHslF(h, s, l, a));
+ return ctx->engine->v8Engine->fromVariant(QQml_colorProvider()->fromHslF(h, s, l, a));
}
/*!
@@ -463,35 +241,37 @@ may be either color values or string values. If a string value is supplied it
must be convertible to a color, as described for the \l{colorbasictypedocs}{color}
basic type.
*/
-v8::Handle<v8::Value> colorEqual(const v8::Arguments &args)
+Value QtObject::method_colorEqual(QV4::SimpleCallContext *ctx)
{
- if (args.Length() != 2)
- V8THROW_ERROR("Qt.colorEqual(): Invalid arguments");
+ if (ctx->argumentCount != 2)
+ V4THROW_ERROR("Qt.colorEqual(): Invalid arguments");
bool ok = false;
- QVariant lhs = V8ENGINE()->toVariant(args[0], -1);
+ QV8Engine *v8engine = ctx->engine->v8Engine;
+
+ QVariant lhs = v8engine->toVariant(ctx->arguments[0], -1);
if (lhs.userType() == QVariant::String) {
lhs = QQmlStringConverters::colorFromString(lhs.toString(), &ok);
if (!ok) {
- V8THROW_ERROR("Qt.colorEqual(): Invalid color name");
+ V4THROW_ERROR("Qt.colorEqual(): Invalid color name");
}
} else if (lhs.userType() != QVariant::Color) {
- V8THROW_ERROR("Qt.colorEqual(): Invalid arguments");
+ V4THROW_ERROR("Qt.colorEqual(): Invalid arguments");
}
- QVariant rhs = V8ENGINE()->toVariant(args[1], -1);
+ QVariant rhs = v8engine->toVariant(ctx->arguments[1], -1);
if (rhs.userType() == QVariant::String) {
rhs = QQmlStringConverters::colorFromString(rhs.toString(), &ok);
if (!ok) {
- V8THROW_ERROR("Qt.colorEqual(): Invalid color name");
+ V4THROW_ERROR("Qt.colorEqual(): Invalid color name");
}
} else if (rhs.userType() != QVariant::Color) {
- V8THROW_ERROR("Qt.colorEqual(): Invalid arguments");
+ V4THROW_ERROR("Qt.colorEqual(): Invalid arguments");
}
bool equal = (lhs == rhs);
- return V8ENGINE()->fromVariant(equal);
+ return QV4::Value::fromBoolean(equal);
}
/*!
@@ -501,141 +281,147 @@ Returns a \c rect with the top-left corner at \c x, \c y and the specified \c wi
The returned object has \c x, \c y, \c width and \c height attributes with the given values.
*/
-v8::Handle<v8::Value> rect(const v8::Arguments &args)
+Value QtObject::method_rect(QV4::SimpleCallContext *ctx)
{
- if (args.Length() != 4)
- V8THROW_ERROR("Qt.rect(): Invalid arguments");
+ if (ctx->argumentCount != 4)
+ V4THROW_ERROR("Qt.rect(): Invalid arguments");
- double x = args[0]->NumberValue();
- double y = args[1]->NumberValue();
- double w = args[2]->NumberValue();
- double h = args[3]->NumberValue();
+ double x = ctx->arguments[0].toNumber();
+ double y = ctx->arguments[1].toNumber();
+ double w = ctx->arguments[2].toNumber();
+ double h = ctx->arguments[3].toNumber();
- return V8ENGINE()->fromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
+ return ctx->engine->v8Engine->fromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
}
/*!
\qmlmethod point Qt::point(int x, int y)
Returns a Point with the specified \c x and \c y coordinates.
*/
-v8::Handle<v8::Value> point(const v8::Arguments &args)
+Value QtObject::method_point(QV4::SimpleCallContext *ctx)
{
- if (args.Length() != 2)
- V8THROW_ERROR("Qt.point(): Invalid arguments");
+ if (ctx->argumentCount != 2)
+ V4THROW_ERROR("Qt.point(): Invalid arguments");
- double x = args[0]->ToNumber()->Value();
- double y = args[1]->ToNumber()->Value();
+ double x = ctx->arguments[0].toNumber();
+ double y = ctx->arguments[1].toNumber();
- return V8ENGINE()->fromVariant(QVariant::fromValue(QPointF(x, y)));
+ return ctx->engine->v8Engine->fromVariant(QVariant::fromValue(QPointF(x, y)));
}
/*!
\qmlmethod Qt::size(int width, int height)
Returns a Size with the specified \c width and \c height.
*/
-v8::Handle<v8::Value> size(const v8::Arguments &args)
+Value QtObject::method_size(QV4::SimpleCallContext *ctx)
{
- if (args.Length() != 2)
- V8THROW_ERROR("Qt.size(): Invalid arguments");
+ if (ctx->argumentCount != 2)
+ V4THROW_ERROR("Qt.size(): Invalid arguments");
- double w = args[0]->ToNumber()->Value();
- double h = args[1]->ToNumber()->Value();
+ double w = ctx->arguments[0].toNumber();
+ double h = ctx->arguments[1].toNumber();
- return V8ENGINE()->fromVariant(QVariant::fromValue(QSizeF(w, h)));
+ return ctx->engine->v8Engine->fromVariant(QVariant::fromValue(QSizeF(w, h)));
}
/*!
+\qmlmethod Qt::font(object fontSpecifier)
+Returns a Font with the properties specified in the \c fontSpecifier object
+or the nearest matching font. The \c fontSpecifier object should contain
+key-value pairs where valid keys are the \l{fontbasictypedocs}{font} type's
+subproperty names, and the values are valid values for each subproperty.
+Invalid keys will be ignored.
+*/
+Value QtObject::method_font(QV4::SimpleCallContext *ctx)
+{
+ if (ctx->argumentCount != 1 || !ctx->arguments[0].isObject())
+ V4THROW_ERROR("Qt.font(): Invalid arguments");
+
+ QV8Engine *v8engine = ctx->engine->v8Engine;
+ bool ok = false;
+ QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QFont, QQmlV4Handle(ctx->arguments[0]), v8engine, &ok);
+ if (!ok)
+ V4THROW_ERROR("Qt.font(): Invalid argument: no valid font subproperties specified");
+ return v8engine->fromVariant(v);
+}
+
+
+
+/*!
\qmlmethod Qt::vector2d(real x, real y)
Returns a Vector2D with the specified \c x and \c y.
*/
-v8::Handle<v8::Value> vector2d(const v8::Arguments &args)
+Value QtObject::method_vector2d(QV4::SimpleCallContext *ctx)
{
- if (args.Length() != 2)
- V8THROW_ERROR("Qt.vector2d(): Invalid arguments");
+ if (ctx->argumentCount != 2)
+ V4THROW_ERROR("Qt.vector2d(): Invalid arguments");
float xy[3]; // qvector2d uses float internally
- xy[0] = args[0]->ToNumber()->Value();
- xy[1] = args[1]->ToNumber()->Value();
+ xy[0] = ctx->arguments[0].toNumber();
+ xy[1] = ctx->arguments[1].toNumber();
const void *params[] = { xy };
- return V8ENGINE()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params));
+ QV8Engine *v8engine = ctx->engine->v8Engine;
+ return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params));
}
/*!
\qmlmethod Qt::vector3d(real x, real y, real z)
Returns a Vector3D with the specified \c x, \c y and \c z.
*/
-v8::Handle<v8::Value> vector3d(const v8::Arguments &args)
+Value QtObject::method_vector3d(QV4::SimpleCallContext *ctx)
{
- if (args.Length() != 3)
- V8THROW_ERROR("Qt.vector3d(): Invalid arguments");
+ if (ctx->argumentCount != 3)
+ V4THROW_ERROR("Qt.vector3d(): Invalid arguments");
float xyz[3]; // qvector3d uses float internally
- xyz[0] = args[0]->ToNumber()->Value();
- xyz[1] = args[1]->ToNumber()->Value();
- xyz[2] = args[2]->ToNumber()->Value();
+ xyz[0] = ctx->arguments[0].toNumber();
+ xyz[1] = ctx->arguments[1].toNumber();
+ xyz[2] = ctx->arguments[2].toNumber();
const void *params[] = { xyz };
- return V8ENGINE()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params));
+ QV8Engine *v8engine = ctx->engine->v8Engine;
+ return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params));
}
/*!
\qmlmethod Qt::vector4d(real x, real y, real z, real w)
Returns a Vector4D with the specified \c x, \c y, \c z and \c w.
*/
-v8::Handle<v8::Value> vector4d(const v8::Arguments &args)
+Value QtObject::method_vector4d(QV4::SimpleCallContext *ctx)
{
- if (args.Length() != 4)
- V8THROW_ERROR("Qt.vector4d(): Invalid arguments");
+ if (ctx->argumentCount != 4)
+ V4THROW_ERROR("Qt.vector4d(): Invalid arguments");
float xyzw[4]; // qvector4d uses float internally
- xyzw[0] = args[0]->ToNumber()->Value();
- xyzw[1] = args[1]->ToNumber()->Value();
- xyzw[2] = args[2]->ToNumber()->Value();
- xyzw[3] = args[3]->ToNumber()->Value();
+ xyzw[0] = ctx->arguments[0].toNumber();
+ xyzw[1] = ctx->arguments[1].toNumber();
+ xyzw[2] = ctx->arguments[2].toNumber();
+ xyzw[3] = ctx->arguments[3].toNumber();
const void *params[] = { xyzw };
- return V8ENGINE()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params));
+ QV8Engine *v8engine = ctx->engine->v8Engine;
+ return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params));
}
/*!
\qmlmethod Qt::quaternion(real scalar, real x, real y, real z)
Returns a Quaternion with the specified \c scalar, \c x, \c y, and \c z.
*/
-v8::Handle<v8::Value> quaternion(const v8::Arguments &args)
+Value QtObject::method_quaternion(QV4::SimpleCallContext *ctx)
{
- if (args.Length() != 4)
- V8THROW_ERROR("Qt.quaternion(): Invalid arguments");
+ if (ctx->argumentCount != 4)
+ V4THROW_ERROR("Qt.quaternion(): Invalid arguments");
qreal sxyz[4]; // qquaternion uses qreal internally
- sxyz[0] = args[0]->ToNumber()->Value();
- sxyz[1] = args[1]->ToNumber()->Value();
- sxyz[2] = args[2]->ToNumber()->Value();
- sxyz[3] = args[3]->ToNumber()->Value();
+ sxyz[0] = ctx->arguments[0].toNumber();
+ sxyz[1] = ctx->arguments[1].toNumber();
+ sxyz[2] = ctx->arguments[2].toNumber();
+ sxyz[3] = ctx->arguments[3].toNumber();
const void *params[] = { sxyz };
- return V8ENGINE()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params));
-}
-
-/*!
-\qmlmethod Qt::font(object fontSpecifier)
-Returns a Font with the properties specified in the \c fontSpecifier object
-or the nearest matching font. The \c fontSpecifier object should contain
-key-value pairs where valid keys are the \l{fontbasictypedocs}{font} type's
-subproperty names, and the values are valid values for each subproperty.
-Invalid keys will be ignored.
-*/
-v8::Handle<v8::Value> font(const v8::Arguments &args)
-{
- if (args.Length() != 1 || !args[0]->IsObject())
- V8THROW_ERROR("Qt.font(): Invalid arguments");
-
- v8::Handle<v8::Object> obj = args[0]->ToObject();
- bool ok = false;
- QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QFont, QQmlV8Handle::fromHandle(obj), V8ENGINE(), &ok);
- if (!ok)
- V8THROW_ERROR("Qt.font(): Invalid argument: no valid font subproperties specified");
- return V8ENGINE()->fromVariant(v);
+ QV8Engine *v8engine = ctx->engine->v8Engine;
+ return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params));
}
/*!
@@ -645,40 +431,41 @@ Alternatively, the function may be called with a single argument
where that argument is a JavaScript array which contains the sixteen
matrix values.
*/
-v8::Handle<v8::Value> matrix4x4(const v8::Arguments &args)
+Value QtObject::method_matrix4x4(QV4::SimpleCallContext *ctx)
{
- if (args.Length() == 1 && args[0]->IsObject()) {
- v8::Handle<v8::Object> obj = args[0]->ToObject();
+ QV8Engine *v8engine = ctx->engine->v8Engine;
+
+ if (ctx->argumentCount == 1 && ctx->arguments[0].isObject()) {
bool ok = false;
- QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV8Handle::fromHandle(obj), V8ENGINE(), &ok);
+ QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV4Handle(ctx->arguments[0]), v8engine, &ok);
if (!ok)
- V8THROW_ERROR("Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array");
- return V8ENGINE()->fromVariant(v);
+ V4THROW_ERROR("Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array");
+ return v8engine->fromVariant(v);
}
- if (args.Length() != 16)
- V8THROW_ERROR("Qt.matrix4x4(): Invalid arguments");
+ if (ctx->argumentCount != 16)
+ V4THROW_ERROR("Qt.matrix4x4(): Invalid arguments");
qreal vals[16]; // qmatrix4x4 uses qreal internally
- vals[0] = args[0]->ToNumber()->Value();
- vals[1] = args[1]->ToNumber()->Value();
- vals[2] = args[2]->ToNumber()->Value();
- vals[3] = args[3]->ToNumber()->Value();
- vals[4] = args[4]->ToNumber()->Value();
- vals[5] = args[5]->ToNumber()->Value();
- vals[6] = args[6]->ToNumber()->Value();
- vals[7] = args[7]->ToNumber()->Value();
- vals[8] = args[8]->ToNumber()->Value();
- vals[9] = args[9]->ToNumber()->Value();
- vals[10] = args[10]->ToNumber()->Value();
- vals[11] = args[11]->ToNumber()->Value();
- vals[12] = args[12]->ToNumber()->Value();
- vals[13] = args[13]->ToNumber()->Value();
- vals[14] = args[14]->ToNumber()->Value();
- vals[15] = args[15]->ToNumber()->Value();
+ vals[0] = ctx->arguments[0].toNumber();
+ vals[1] = ctx->arguments[1].toNumber();
+ vals[2] = ctx->arguments[2].toNumber();
+ vals[3] = ctx->arguments[3].toNumber();
+ vals[4] = ctx->arguments[4].toNumber();
+ vals[5] = ctx->arguments[5].toNumber();
+ vals[6] = ctx->arguments[6].toNumber();
+ vals[7] = ctx->arguments[7].toNumber();
+ vals[8] = ctx->arguments[8].toNumber();
+ vals[9] = ctx->arguments[9].toNumber();
+ vals[10] = ctx->arguments[10].toNumber();
+ vals[11] = ctx->arguments[11].toNumber();
+ vals[12] = ctx->arguments[12].toNumber();
+ vals[13] = ctx->arguments[13].toNumber();
+ vals[14] = ctx->arguments[14].toNumber();
+ vals[15] = ctx->arguments[15].toNumber();
const void *params[] = { vals };
- return V8ENGINE()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params));
+ return v8engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params));
}
/*!
@@ -695,27 +482,28 @@ by factor and converts the color back to RGB.
If \c factor is not supplied, returns a color 50% lighter than \c baseColor (factor 1.5).
*/
-v8::Handle<v8::Value> lighter(const v8::Arguments &args)
+Value QtObject::method_lighter(QV4::SimpleCallContext *ctx)
{
- if (args.Length() != 1 && args.Length() != 2)
- V8THROW_ERROR("Qt.lighter(): Invalid arguments");
+ if (ctx->argumentCount != 1 && ctx->argumentCount != 2)
+ V4THROW_ERROR("Qt.lighter(): Invalid arguments");
- QVariant v = V8ENGINE()->toVariant(args[0], -1);
+ QV8Engine *v8engine = ctx->engine->v8Engine;
+ QVariant v = v8engine->toVariant(ctx->arguments[0], -1);
if (v.userType() == QVariant::String) {
bool ok = false;
v = QQmlStringConverters::colorFromString(v.toString(), &ok);
if (!ok) {
- return v8::Null();
+ return QV4::Value::nullValue();
}
} else if (v.userType() != QVariant::Color) {
- return v8::Null();
+ return QV4::Value::nullValue();
}
qreal factor = 1.5;
- if (args.Length() == 2)
- factor = args[1]->ToNumber()->Value();
+ if (ctx->argumentCount == 2)
+ factor = ctx->arguments[1].toNumber();
- return V8ENGINE()->fromVariant(QQml_colorProvider()->lighter(v, factor));
+ return v8engine->fromVariant(QQml_colorProvider()->lighter(v, factor));
}
/*!
@@ -733,27 +521,28 @@ by factor and converts the color back to RGB.
If \c factor is not supplied, returns a color 50% darker than \c baseColor (factor 2.0).
*/
-v8::Handle<v8::Value> darker(const v8::Arguments &args)
+Value QtObject::method_darker(QV4::SimpleCallContext *ctx)
{
- if (args.Length() != 1 && args.Length() != 2)
- V8THROW_ERROR("Qt.darker(): Invalid arguments");
+ if (ctx->argumentCount != 1 && ctx->argumentCount != 2)
+ V4THROW_ERROR("Qt.darker(): Invalid arguments");
- QVariant v = V8ENGINE()->toVariant(args[0], -1);
+ QV8Engine *v8engine = ctx->engine->v8Engine;
+ QVariant v = v8engine->toVariant(ctx->arguments[0], -1);
if (v.userType() == QVariant::String) {
bool ok = false;
v = QQmlStringConverters::colorFromString(v.toString(), &ok);
if (!ok) {
- return v8::Null();
+ return QV4::Value::nullValue();
}
} else if (v.userType() != QVariant::Color) {
- return v8::Null();
+ return QV4::Value::nullValue();
}
qreal factor = 2.0;
- if (args.Length() == 2)
- factor = args[1]->ToNumber()->Value();
+ if (ctx->argumentCount == 2)
+ factor = ctx->arguments[1].toNumber();
- return V8ENGINE()->fromVariant(QQml_colorProvider()->darker(v, factor));
+ return v8engine->fromVariant(QQml_colorProvider()->darker(v, factor));
}
/*!
@@ -780,36 +569,38 @@ v8::Handle<v8::Value> darker(const v8::Arguments &args)
Tint is most useful when a subtle change is intended to be conveyed due to some event; you can then use tinting to more effectively tune the visible color.
*/
-v8::Handle<v8::Value> tint(const v8::Arguments &args)
+Value QtObject::method_tint(QV4::SimpleCallContext *ctx)
{
- if (args.Length() != 2)
- V8THROW_ERROR("Qt.tint(): Invalid arguments");
+ if (ctx->argumentCount != 2)
+ V4THROW_ERROR("Qt.tint(): Invalid arguments");
+
+ QV8Engine *v8engine = ctx->engine->v8Engine;
// base color
- QVariant v1 = V8ENGINE()->toVariant(args[0], -1);
+ QVariant v1 = v8engine->toVariant(ctx->arguments[0], -1);
if (v1.userType() == QVariant::String) {
bool ok = false;
v1 = QQmlStringConverters::colorFromString(v1.toString(), &ok);
if (!ok) {
- return v8::Null();
+ return QV4::Value::nullValue();
}
} else if (v1.userType() != QVariant::Color) {
- return v8::Null();
+ return QV4::Value::nullValue();
}
// tint color
- QVariant v2 = V8ENGINE()->toVariant(args[1], -1);
+ QVariant v2 = v8engine->toVariant(ctx->arguments[1], -1);
if (v2.userType() == QVariant::String) {
bool ok = false;
v2 = QQmlStringConverters::colorFromString(v2.toString(), &ok);
if (!ok) {
- return v8::Null();
+ return QV4::Value::nullValue();
}
} else if (v2.userType() != QVariant::Color) {
- return v8::Null();
+ return QV4::Value::nullValue();
}
- return V8ENGINE()->fromVariant(QQml_colorProvider()->tint(v1, v2));
+ return v8engine->fromVariant(QQml_colorProvider()->tint(v1, v2));
}
/*!
@@ -828,30 +619,32 @@ If \a format is not specified, \a date is formatted using
\sa Locale
*/
-v8::Handle<v8::Value> formatDate(const v8::Arguments &args)
+Value QtObject::method_formatDate(QV4::SimpleCallContext *ctx)
{
- if (args.Length() < 1 || args.Length() > 2)
- V8THROW_ERROR("Qt.formatDate(): Invalid arguments");
+ if (ctx->argumentCount < 1 || ctx->argumentCount > 2)
+ V4THROW_ERROR("Qt.formatDate(): Invalid arguments");
+
+ QV8Engine *v8engine = ctx->engine->v8Engine;
Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
- QDate date = V8ENGINE()->toVariant(args[0], -1).toDateTime().date();
+ QDate date = v8engine->toVariant(ctx->arguments[0], -1).toDateTime().date();
QString formattedDate;
- if (args.Length() == 2) {
- if (args[1]->IsString()) {
- QString format = V8ENGINE()->toVariant(args[1], -1).toString();
+ if (ctx->argumentCount == 2) {
+ if (String *s = ctx->arguments[1].asString()) {
+ QString format = s->toQString();
formattedDate = date.toString(format);
- } else if (args[1]->IsNumber()) {
- quint32 intFormat = args[1]->ToNumber()->Value();
+ } else if (ctx->arguments[1].isNumber()) {
+ quint32 intFormat = ctx->arguments[1].asDouble();
Qt::DateFormat format = Qt::DateFormat(intFormat);
formattedDate = date.toString(format);
} else {
- V8THROW_ERROR("Qt.formatDate(): Invalid date format");
+ V4THROW_ERROR("Qt.formatDate(): Invalid date format");
}
} else {
formattedDate = date.toString(enumFormat);
}
- return V8ENGINE()->fromVariant(QVariant::fromValue(formattedDate));
+ return v8engine->fromVariant(QVariant::fromValue(formattedDate));
}
/*!
@@ -869,36 +662,38 @@ If \a format is not specified, \a time is formatted using
\sa Locale
*/
-v8::Handle<v8::Value> formatTime(const v8::Arguments &args)
+Value QtObject::method_formatTime(QV4::SimpleCallContext *ctx)
{
- if (args.Length() < 1 || args.Length() > 2)
- V8THROW_ERROR("Qt.formatTime(): Invalid arguments");
+ if (ctx->argumentCount < 1 || ctx->argumentCount > 2)
+ V4THROW_ERROR("Qt.formatTime(): Invalid arguments");
- QVariant argVariant = V8ENGINE()->toVariant(args[0], -1);
+ QV8Engine *v8engine = ctx->engine->v8Engine;
+
+ QVariant argVariant = v8engine->toVariant(ctx->arguments[0], -1);
QTime time;
- if (args[0]->IsDate() || (argVariant.type() == QVariant::String))
+ if (ctx->arguments[0].asDateObject() || (argVariant.type() == QVariant::String))
time = argVariant.toDateTime().time();
else // if (argVariant.type() == QVariant::Time), or invalid.
time = argVariant.toTime();
Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
QString formattedTime;
- if (args.Length() == 2) {
- if (args[1]->IsString()) {
- QString format = V8ENGINE()->toVariant(args[1], -1).toString();
+ if (ctx->argumentCount == 2) {
+ if (String *s = ctx->arguments[1].asString()) {
+ QString format = s->toQString();
formattedTime = time.toString(format);
- } else if (args[1]->IsNumber()) {
- quint32 intFormat = args[1]->ToNumber()->Value();
+ } else if (ctx->arguments[1].isNumber()) {
+ quint32 intFormat = ctx->arguments[1].asDouble();
Qt::DateFormat format = Qt::DateFormat(intFormat);
formattedTime = time.toString(format);
} else {
- V8THROW_ERROR("Qt.formatTime(): Invalid time format");
+ V4THROW_ERROR("Qt.formatTime(): Invalid time format");
}
} else {
formattedTime = time.toString(enumFormat);
}
- return V8ENGINE()->fromVariant(QVariant::fromValue(formattedTime));
+ return v8engine->fromVariant(QVariant::fromValue(formattedTime));
}
/*!
@@ -991,118 +786,125 @@ with the \a format values below to produce the following results:
\sa Locale
*/
-v8::Handle<v8::Value> formatDateTime(const v8::Arguments &args)
+Value QtObject::method_formatDateTime(QV4::SimpleCallContext *ctx)
{
- if (args.Length() < 1 || args.Length() > 2)
- V8THROW_ERROR("Qt.formatDateTime(): Invalid arguments");
+ if (ctx->argumentCount < 1 || ctx->argumentCount > 2)
+ V4THROW_ERROR("Qt.formatDateTime(): Invalid arguments");
+
+ QV8Engine *v8engine = ctx->engine->v8Engine;
Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
- QDateTime dt = V8ENGINE()->toVariant(args[0], -1).toDateTime();
+ QDateTime dt = v8engine->toVariant(ctx->arguments[0], -1).toDateTime();
QString formattedDt;
- if (args.Length() == 2) {
- if (args[1]->IsString()) {
- QString format = V8ENGINE()->toVariant(args[1], -1).toString();
+ if (ctx->argumentCount == 2) {
+ if (String *s = ctx->arguments[1].asString()) {
+ QString format = s->toQString();
formattedDt = dt.toString(format);
- } else if (args[1]->IsNumber()) {
- quint32 intFormat = args[1]->ToNumber()->Value();
+ } else if (ctx->arguments[1].isNumber()) {
+ quint32 intFormat = ctx->arguments[1].asDouble();
Qt::DateFormat format = Qt::DateFormat(intFormat);
formattedDt = dt.toString(format);
} else {
- V8THROW_ERROR("Qt.formatDateTime(): Invalid datetime format");
+ V4THROW_ERROR("Qt.formatDateTime(): Invalid datetime format");
}
} else {
formattedDt = dt.toString(enumFormat);
}
- return V8ENGINE()->fromVariant(QVariant::fromValue(formattedDt));
+ return v8engine->fromVariant(QVariant::fromValue(formattedDt));
}
/*!
\qmlmethod bool Qt::openUrlExternally(url target)
Attempts to open the specified \c target url in an external application, based on the user's desktop preferences. Returns true if it succeeds, and false otherwise.
*/
-v8::Handle<v8::Value> openUrlExternally(const v8::Arguments &args)
+Value QtObject::method_openUrlExternally(QV4::SimpleCallContext *ctx)
{
- if (args.Length() != 1)
- return V8ENGINE()->fromVariant(false);
+ if (ctx->argumentCount != 1)
+ return QV4::Value::fromBoolean(false);
- QUrl url(V8ENGINE()->toVariant(resolvedUrl(args), -1).toUrl());
- return V8ENGINE()->fromVariant(QQml_guiProvider()->openUrlExternally(url));
+ QV8Engine *v8engine = ctx->engine->v8Engine;
+
+ QUrl url(method_resolvedUrl(ctx).toQString());
+ return v8engine->fromVariant(QQml_guiProvider()->openUrlExternally(url));
}
/*!
\qmlmethod url Qt::resolvedUrl(url url)
Returns \a url resolved relative to the URL of the caller.
*/
-v8::Handle<v8::Value> resolvedUrl(const v8::Arguments &args)
+Value QtObject::method_resolvedUrl(QV4::SimpleCallContext *ctx)
{
- QUrl url = V8ENGINE()->toVariant(args[0], -1).toUrl();
- QQmlEngine *e = V8ENGINE()->engine();
+ QV8Engine *v8engine = ctx->engine->v8Engine;
+
+ QUrl url = v8engine->toVariant(ctx->arguments[0], -1).toUrl();
+ QQmlEngine *e = v8engine->engine();
QQmlEnginePrivate *p = 0;
if (e) p = QQmlEnginePrivate::get(e);
if (p) {
- QQmlContextData *ctxt = V8ENGINE()->callingContext();
+ QQmlContextData *ctxt = v8engine->callingContext();
if (ctxt)
- return V8ENGINE()->toString(ctxt->resolvedUrl(url).toString());
+ return Value::fromString(ctx, ctxt->resolvedUrl(url).toString());
else
- return V8ENGINE()->toString(url.toString());
+ return Value::fromString(ctx, url.toString());
}
- return V8ENGINE()->toString(e->baseUrl().resolved(url).toString());
+ return Value::fromString(ctx, e->baseUrl().resolved(url).toString());
}
/*!
\qmlmethod list<string> Qt::fontFamilies()
Returns a list of the font families available to the application.
*/
-v8::Handle<v8::Value> fontFamilies(const v8::Arguments &args)
+Value QtObject::method_fontFamilies(SimpleCallContext *ctx)
{
- if (args.Length() != 0)
- V8THROW_ERROR("Qt.fontFamilies(): Invalid arguments");
+ if (ctx->argumentCount != 0)
+ V4THROW_ERROR("Qt.fontFamilies(): Invalid arguments");
- return V8ENGINE()->fromVariant(QVariant(QQml_guiProvider()->fontFamilies()));
+ QV8Engine *v8engine = ctx->engine->v8Engine;
+ return v8engine->fromVariant(QVariant(QQml_guiProvider()->fontFamilies()));
}
/*!
\qmlmethod string Qt::md5(data)
Returns a hex string of the md5 hash of \c data.
*/
-v8::Handle<v8::Value> md5(const v8::Arguments &args)
+Value QtObject::method_md5(SimpleCallContext *ctx)
{
- if (args.Length() != 1)
- V8THROW_ERROR("Qt.md5(): Invalid arguments");
+ if (ctx->argumentCount != 1)
+ V4THROW_ERROR("Qt.md5(): Invalid arguments");
- QByteArray data = V8ENGINE()->toString(args[0]->ToString()).toUtf8();
+ QByteArray data = ctx->arguments[0].toQString().toUtf8();
QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5);
- return V8ENGINE()->toString(QLatin1String(result.toHex()));
+ return Value::fromString(ctx, QLatin1String(result.toHex()));
}
/*!
\qmlmethod string Qt::btoa(data)
Binary to ASCII - this function returns a base64 encoding of \c data.
*/
-v8::Handle<v8::Value> btoa(const v8::Arguments &args)
+Value QtObject::method_btoa(SimpleCallContext *ctx)
{
- if (args.Length() != 1)
- V8THROW_ERROR("Qt.btoa(): Invalid arguments");
+ if (ctx->argumentCount != 1)
+ V4THROW_ERROR("Qt.btoa(): Invalid arguments");
- QByteArray data = V8ENGINE()->toString(args[0]->ToString()).toUtf8();
+ QByteArray data = ctx->arguments[0].toQString().toUtf8();
- return V8ENGINE()->toString(QLatin1String(data.toBase64()));
+ return Value::fromString(ctx, QLatin1String(data.toBase64()));
}
/*!
\qmlmethod string Qt::atob(data)
ASCII to binary - this function returns a base64 decoding of \c data.
*/
-v8::Handle<v8::Value> atob(const v8::Arguments &args)
+Value QtObject::method_atob(SimpleCallContext *ctx)
{
- if (args.Length() != 1)
- V8THROW_ERROR("Qt.atob(): Invalid arguments");
+ if (ctx->argumentCount != 1)
+ V4THROW_ERROR("Qt.atob(): Invalid arguments");
- QByteArray data = V8ENGINE()->toString(args[0]->ToString()).toUtf8();
+ QByteArray data = ctx->arguments[0].toQString().toLatin1();
- return V8ENGINE()->toString(QLatin1String(QByteArray::fromBase64(data)));
+ return Value::fromString(ctx, QString::fromUtf8(QByteArray::fromBase64(data)));
}
/*!
@@ -1112,10 +914,12 @@ Within the \l {Prototyping with qmlscene}, this causes the launcher application
to quit a C++ application when this method is called, connect the
QQmlEngine::quit() signal to the QCoreApplication::quit() slot.
*/
-v8::Handle<v8::Value> quit(const v8::Arguments &args)
+Value QtObject::method_quit(SimpleCallContext *ctx)
{
- QQmlEnginePrivate::get(V8ENGINE()->engine())->sendQuit();
- return v8::Undefined();
+ QV8Engine *v8engine = ctx->engine->v8Engine;
+
+ QQmlEnginePrivate::get(v8engine->engine())->sendQuit();
+ return QV4::Value::undefinedValue();
}
/*!
@@ -1142,35 +946,35 @@ If this is the case, consider using \l{QtQml2::Qt::createComponent()}{Qt.createC
See \l {Dynamic QML Object Creation from JavaScript} for more information on using this function.
*/
-v8::Handle<v8::Value> createQmlObject(const v8::Arguments &args)
+Value QtObject::method_createQmlObject(SimpleCallContext *ctx)
{
- if (args.Length() < 2 || args.Length() > 3)
- V8THROW_ERROR("Qt.createQmlObject(): Invalid arguments");
+ if (ctx->argumentCount < 2 || ctx->argumentCount > 3)
+ V4THROW_ERROR("Qt.createQmlObject(): Invalid arguments");
struct Error {
- static v8::Local<v8::Value> create(QV8Engine *engine, const QList<QQmlError> &errors) {
+ static Value create(QV8Engine *engine, const QList<QQmlError> &errors) {
QString errorstr = QLatin1String("Qt.createQmlObject(): failed to create object: ");
- v8::Local<v8::Array> qmlerrors = v8::Array::New(errors.count());
+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+ QV4::ArrayObject *qmlerrors = v4->newArrayObject();
for (int ii = 0; ii < errors.count(); ++ii) {
const QQmlError &error = errors.at(ii);
errorstr += QLatin1String("\n ") + error.toString();
- v8::Local<v8::Object> qmlerror = v8::Object::New();
- qmlerror->Set(v8::String::New("lineNumber"), v8::Integer::New(error.line()));
- qmlerror->Set(v8::String::New("columnNumber"), v8::Integer::New(error.column()));
- qmlerror->Set(v8::String::New("fileName"), engine->toString(error.url().toString()));
- qmlerror->Set(v8::String::New("message"), engine->toString(error.description()));
- qmlerrors->Set(ii, qmlerror);
+ QV4::Object *qmlerror = v4->newObject();
+ qmlerror->put(v4->newString("lineNumber"), QV4::Value::fromInt32(error.line()));
+ qmlerror->put(v4->newString("columnNumber"), QV4::Value::fromInt32(error.column()));
+ qmlerror->put(v4->newString("fileName"), engine->toString(error.url().toString()));
+ qmlerror->put(v4->newString("message"), engine->toString(error.description()));
+ qmlerrors->putIndexed(ii, QV4::Value::fromObject(qmlerror));
}
- v8::Local<v8::Value> error = v8::Exception::Error(engine->toString(errorstr));
- v8::Local<v8::Object> errorObject = error->ToObject();
- errorObject->Set(v8::String::New("qmlErrors"), qmlerrors);
- return error;
+ QV4::Object *errorObject = v4->newErrorObject(engine->toString(errorstr));
+ errorObject->put(v4->newString("qmlErrors"), Value::fromObject(qmlerrors));
+ return Value::fromObject(errorObject);
}
};
- QV8Engine *v8engine = V8ENGINE();
+ QV8Engine *v8engine = ctx->engine->v8Engine;
QQmlEngine *engine = v8engine->engine();
QQmlContextData *context = v8engine->callingContext();
@@ -1181,33 +985,35 @@ v8::Handle<v8::Value> createQmlObject(const v8::Arguments &args)
effectiveContext = context->asQQmlContext();
Q_ASSERT(context && effectiveContext);
- QString qml = v8engine->toString(args[0]->ToString());
+ QString qml = ctx->arguments[0].toQString();
if (qml.isEmpty())
- return v8::Null();
+ return QV4::Value::nullValue();
QUrl url;
- if (args.Length() > 2)
- url = QUrl(v8engine->toString(args[2]->ToString()));
+ if (ctx->argumentCount > 2)
+ url = QUrl(ctx->arguments[2].toQString());
else
url = QUrl(QLatin1String("inline"));
if (url.isValid() && url.isRelative())
url = context->resolvedUrl(url);
- QObject *parentArg = v8engine->toQObject(args[1]);
+ QObject *parentArg = 0;
+ if (QV4::QObjectWrapper *qobjectWrapper = ctx->arguments[1].as<QV4::QObjectWrapper>())
+ parentArg = qobjectWrapper->object();
if (!parentArg)
- V8THROW_ERROR("Qt.createQmlObject(): Missing parent object");
+ V4THROW_ERROR("Qt.createQmlObject(): Missing parent object");
QQmlComponent component(engine);
component.setData(qml.toUtf8(), url);
if (component.isError()) {
- v8::ThrowException(Error::create(v8engine, component.errors()));
- return v8::Undefined();
+ ctx->throwError(Error::create(v8engine, component.errors()));
+ return QV4::Value::undefinedValue();
}
if (!component.isReady())
- V8THROW_ERROR("Qt.createQmlObject(): Component is not ready");
+ V4THROW_ERROR("Qt.createQmlObject(): Component is not ready");
QObject *obj = component.beginCreate(effectiveContext);
if (obj) {
@@ -1226,13 +1032,13 @@ v8::Handle<v8::Value> createQmlObject(const v8::Arguments &args)
component.completeCreate();
if (component.isError()) {
- v8::ThrowException(Error::create(v8engine, component.errors()));
- return v8::Undefined();
+ ctx->throwError(Error::create(v8engine, component.errors()));
+ return QV4::Value::undefinedValue();
}
Q_ASSERT(obj);
- return v8engine->newQObject(obj);
+ return QV4::QObjectWrapper::wrap(ctx->engine, obj);
}
/*!
@@ -1266,14 +1072,14 @@ See \l {Dynamic QML Object Creation from JavaScript} for more information on usi
To create a QML object from an arbitrary string of QML (instead of a file),
use \l{QtQml2::Qt::createQmlObject()}{Qt.createQmlObject()}.
*/
-v8::Handle<v8::Value> createComponent(const v8::Arguments &args)
+Value QtObject::method_createComponent(SimpleCallContext *ctx)
{
- const char *invalidArgs = "Qt.createComponent(): Invalid arguments";
- const char *invalidParent = "Qt.createComponent(): Invalid parent object";
- if (args.Length() < 1 || args.Length() > 3)
- V8THROW_ERROR(invalidArgs);
+ const QString invalidArgs = QStringLiteral("Qt.createComponent(): Invalid arguments");
+ const QString invalidParent = QStringLiteral("Qt.createComponent(): Invalid parent object");
+ if (ctx->argumentCount < 1 || ctx->argumentCount > 3)
+ ctx->throwError(invalidArgs);
- QV8Engine *v8engine = V8ENGINE();
+ QV8Engine *v8engine = ctx->engine->v8Engine;
QQmlEngine *engine = v8engine->engine();
QQmlContextData *context = v8engine->callingContext();
@@ -1282,39 +1088,40 @@ v8::Handle<v8::Value> createComponent(const v8::Arguments &args)
effectiveContext = 0;
Q_ASSERT(context);
- QString arg = v8engine->toString(args[0]->ToString());
+ QString arg = ctx->arguments[0].toQString();
if (arg.isEmpty())
- return v8::Null();
+ return QV4::Value::nullValue();
QQmlComponent::CompilationMode compileMode = QQmlComponent::PreferSynchronous;
QObject *parentArg = 0;
int consumedCount = 1;
- if (args.Length() > 1) {
- const v8::Local<v8::Value> &lastArg = args[args.Length()-1];
+ if (ctx->argumentCount > 1) {
+ Value lastArg = ctx->arguments[ctx->argumentCount-1];
// The second argument could be the mode enum
- if (args[1]->IsInt32()) {
- int mode = args[1]->Int32Value();
+ if (ctx->arguments[1].isInteger()) {
+ int mode = ctx->arguments[1].integerValue();
if (mode != int(QQmlComponent::PreferSynchronous) && mode != int(QQmlComponent::Asynchronous))
- V8THROW_ERROR(invalidArgs);
+ ctx->throwError(invalidArgs);
compileMode = QQmlComponent::CompilationMode(mode);
consumedCount += 1;
} else {
// 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 ((ctx->argumentCount != 2) || !(lastArg.isObject() || lastArg.isNull()))
+ ctx->throwError(invalidArgs);
}
- if (consumedCount < args.Length()) {
- if (lastArg->IsObject()) {
- parentArg = v8engine->toQObject(lastArg);
+ if (consumedCount < ctx->argumentCount) {
+ if (lastArg.isObject()) {
+ if (QV4::QObjectWrapper *qobjectWrapper = lastArg.as<QV4::QObjectWrapper>())
+ parentArg = qobjectWrapper->object();
if (!parentArg)
- V8THROW_ERROR(invalidParent);
- } else if (lastArg->IsNull()) {
+ ctx->throwError(invalidParent);
+ } else if (lastArg.isNull()) {
parentArg = 0;
} else {
- V8THROW_ERROR(invalidParent);
+ ctx->throwError(invalidParent);
}
}
}
@@ -1325,9 +1132,471 @@ v8::Handle<v8::Value> createComponent(const v8::Arguments &args)
QQmlData::get(c, true)->explicitIndestructibleSet = false;
QQmlData::get(c)->indestructible = false;
- return v8engine->newQObject(c);
+ return QV4::QObjectWrapper::wrap(ctx->engine, c);
+}
+
+/*!
+ \qmlmethod Qt::locale(name)
+
+ Returns a JS object representing the locale with the specified
+ name, which has the format "language[_territory][.codeset][@modifier]"
+ or "C", where:
+
+ \list
+ \li language is a lowercase, two-letter, ISO 639 language code,
+ \li territory is an uppercase, two-letter, ISO 3166 country code,
+ \li and codeset and modifier are ignored.
+ \endlist
+
+ If the string violates the locale format, or language is not a
+ valid ISO 369 code, the "C" locale is used instead. If country
+ is not present, or is not a valid ISO 3166 code, the most
+ appropriate country is chosen for the specified language.
+
+ \sa QtQuick2::Locale
+*/
+Value QtObject::method_locale(SimpleCallContext *ctx)
+{
+ QString code;
+ if (ctx->argumentCount > 1)
+ V4THROW_ERROR("locale() requires 0 or 1 argument");
+ if (ctx->argumentCount == 1 && !ctx->arguments[0].isString())
+ V4THROW_TYPE("locale(): argument (locale code) must be a string");
+
+ QV8Engine *v8engine = ctx->engine->v8Engine;
+ if (ctx->argumentCount == 1)
+ code = ctx->arguments[0].toQString();
+
+ return QQmlLocale::locale(v8engine, code);
+}
+
+namespace {
+
+struct BindingFunction : public QV4::FunctionObject
+{
+ Q_MANAGED
+ BindingFunction(FunctionObject *originalFunction)
+ : QV4::FunctionObject(originalFunction->scope, originalFunction->name)
+ , originalFunction(originalFunction)
+ {
+ vtbl = &static_vtbl;
+ bindingKeyFlag = true;
+ }
+
+ static Value call(Managed *that, const Value &thisObject, Value *argv, int argc)
+ {
+ BindingFunction *This = static_cast<BindingFunction*>(that);
+ return This->originalFunction->call(thisObject, argv, argc);
+ }
+
+ static void markObjects(Managed *that)
+ {
+ BindingFunction *This = static_cast<BindingFunction*>(that);
+ This->originalFunction->mark();
+ QV4::FunctionObject::markObjects(that);
+ }
+
+ QV4::FunctionObject *originalFunction;
+};
+
+DEFINE_MANAGED_VTABLE(BindingFunction);
+
}
+/*!
+ \qmlmethod Qt::binding(function)
+
+ Returns a JS object representing a binding expression which may be
+ assigned to any property in imperative code to cause a binding
+ assignment.
+
+ There are two main use-cases for the function: firstly, in imperative
+ JavaScript code to cause a binding assignment:
+
+ \snippet qml/qtBinding.1.qml 0
+
+ and secondly, when defining initial property values of dynamically
+ constructed objects (via Component.createObject() or
+ Loader.setSource()) as being bound to the result of an expression.
+
+ For example, assuming the existence of a DynamicText component:
+ \snippet qml/DynamicText.qml 0
+
+ the output from:
+ \snippet qml/qtBinding.2.qml 0
+
+ and from:
+ \snippet qml/qtBinding.3.qml 0
+
+ should both be:
+ \code
+ Root text extra text
+ Modified root text extra text
+ Dynamic text extra text
+ Modified dynamic text extra text
+ \endcode
+
+ This function cannot be used in property binding declarations
+ (see the documentation on \l{qml-javascript-assignment}{binding
+ declarations and binding assignments}) except when the result is
+ stored in an array bound to a var property.
+
+ \snippet qml/qtBinding.4.qml 0
+
+ \note In \l {Qt Quick 1}, all function assignment was treated as
+ binding assignment, so the Qt.binding() function is new in
+ \l {Qt Quick}{Qt Quick 2}.
+
+ \since QtQuick 2.0
+*/
+Value QtObject::method_binding(SimpleCallContext *ctx)
+{
+ if (ctx->argumentCount != 1)
+ V4THROW_ERROR("binding() requires 1 argument");
+ QV4::FunctionObject *f = ctx->arguments[0].asFunctionObject();
+ if (!f)
+ V4THROW_TYPE("binding(): argument (binding expression) must be a function");
+
+ return QV4::Value::fromObject(new (ctx->engine->memoryManager) BindingFunction(f));
+}
+
+
+Value QtObject::method_get_platform(SimpleCallContext *ctx)
+{
+ // ### inefficient. Should be just a value based getter
+ Object *o = ctx->thisObject.asObject();
+ if (!o)
+ ctx->throwTypeError();
+ QtObject *qt = o->as<QtObject>();
+ if (!qt)
+ ctx->throwTypeError();
+
+ if (!qt->m_platform)
+ // Only allocate a platform object once
+ qt->m_platform = new QQmlPlatform(ctx->engine->v8Engine->publicEngine());
+
+ return QV4::QObjectWrapper::wrap(ctx->engine, qt->m_platform);
+}
+
+Value QtObject::method_get_application(SimpleCallContext *ctx)
+{
+ // ### inefficient. Should be just a value based getter
+ Object *o = ctx->thisObject.asObject();
+ if (!o)
+ ctx->throwTypeError();
+ QtObject *qt = o->as<QtObject>();
+ if (!qt)
+ ctx->throwTypeError();
+
+ if (!qt->m_application)
+ // Only allocate an application object once
+ qt->m_application = QQml_guiProvider()->application(ctx->engine->v8Engine->publicEngine());
+
+ return QV4::QObjectWrapper::wrap(ctx->engine, qt->m_application);
+}
+
+#ifndef QT_NO_IM
+Value QtObject::method_get_inputMethod(SimpleCallContext *ctx)
+{
+ QObject *o = QQml_guiProvider()->inputMethod();
+ QQmlEngine::setObjectOwnership(o, QQmlEngine::CppOwnership);
+ return QV4::QObjectWrapper::wrap(ctx->engine, o);
+}
+#endif
+
+
+QV4::ConsoleObject::ConsoleObject(ExecutionEngine *v4)
+ : Object(v4)
+{
+ defineDefaultProperty(v4, QStringLiteral("debug"), method_log);
+ defineDefaultProperty(v4, QStringLiteral("log"), method_log);
+ defineDefaultProperty(v4, QStringLiteral("info"), method_log);
+ defineDefaultProperty(v4, QStringLiteral("warn"), method_warn);
+ defineDefaultProperty(v4, QStringLiteral("error"), method_error);
+ defineDefaultProperty(v4, QStringLiteral("assert"), method_assert);
+
+ defineDefaultProperty(v4, QStringLiteral("count"), method_count);
+ defineDefaultProperty(v4, QStringLiteral("profile"), method_profile);
+ defineDefaultProperty(v4, QStringLiteral("profileEnd"), method_profileEnd);
+ defineDefaultProperty(v4, QStringLiteral("time"), method_time);
+ defineDefaultProperty(v4, QStringLiteral("timeEnd"), method_timeEnd);
+ defineDefaultProperty(v4, QStringLiteral("trace"), method_trace);
+ defineDefaultProperty(v4, QStringLiteral("exception"), method_exception);
+}
+
+
+enum ConsoleLogTypes {
+ Log,
+ Warn,
+ Error
+};
+
+static QString jsStack(QV4::ExecutionEngine *engine) {
+ QString stack;
+
+ QVector<QV4::ExecutionEngine::StackFrame> stackTrace = engine->stackTrace(10);
+
+ for (int i = 0; i < stackTrace.count(); i++) {
+ const QV4::ExecutionEngine::StackFrame &frame = stackTrace.at(i);
+
+ QString stackFrame;
+ if (frame.column >= 0)
+ stackFrame = QString::fromLatin1("%1 (%2:%3:%4)").arg(frame.function,
+ frame.source,
+ QString::number(frame.line),
+ QString::number(frame.column));
+ else
+ stackFrame = QString::fromLatin1("%1 (%2:%3)").arg(frame.function,
+ frame.source,
+ QString::number(frame.line));
+
+ if (i)
+ stack += QChar('\n');
+ stack += stackFrame;
+ }
+ return stack;
+}
+
+static QV4::Value writeToConsole(ConsoleLogTypes logType, SimpleCallContext *ctx,
+ bool printStack = false)
+{
+ QString result;
+ QV4::ExecutionEngine *v4 = ctx->engine;
+
+ for (int i = 0; i < ctx->argumentCount; ++i) {
+ if (i != 0)
+ result.append(QLatin1Char(' '));
+
+ QV4::Value value = ctx->arguments[i];
+ if (value.asArrayObject())
+ result.append(QStringLiteral("[") + value.toQString() + QStringLiteral("]"));
+ else
+ result.append(value.toQString());
+ }
+
+ if (printStack) {
+ result.append(QLatin1String("\n"));
+ result.append(jsStack(v4));
+ }
+
+ QV4::ExecutionEngine::StackFrame frame = v4->currentStackFrame();
+ QMessageLogger logger(frame.source.toUtf8().constData(), frame.line, frame.function.toUtf8().constData());
+ switch (logType) {
+ case Log:
+ logger.debug("%s", qPrintable(result));
+ break;
+ case Warn:
+ logger.warning("%s", qPrintable(result));
+ break;
+ case Error:
+ logger.critical("%s", qPrintable(result));
+ break;
+ default:
+ break;
+ }
+
+ return QV4::Value::undefinedValue();
+}
+
+QV4::Value ConsoleObject::method_error(SimpleCallContext *ctx)
+{
+ return writeToConsole(Error, ctx);
+}
+
+QV4::Value ConsoleObject::method_log(SimpleCallContext *ctx)
+{
+ //console.log
+ //console.debug
+ //console.info
+ //print
+ return writeToConsole(Log, ctx);
+}
+
+QV4::Value ConsoleObject::method_profile(SimpleCallContext *ctx)
+{
+ //DeclarativeDebugTrace cannot handle nested profiling
+ //although v8 can handle several profiling at once,
+ //we do not allow that. Hence, we pass an empty(default) title
+ QString title;
+ QV4::ExecutionEngine *v4 = ctx->engine;
+
+ QV4::ExecutionEngine::StackFrame frame = v4->currentStackFrame();
+ QMessageLogger logger(frame.source.toUtf8().constData(), frame.line, frame.function.toUtf8().constData());
+ if (QQmlProfilerService::startProfiling()) {
+ QV8ProfilerService::instance()->startProfiling(title);
+
+ logger.debug("Profiling started.");
+ } else {
+ logger.warning("Profiling is already in progress. First, end current profiling session.");
+ }
+
+ return QV4::Value::undefinedValue();
+}
+
+QV4::Value ConsoleObject::method_profileEnd(SimpleCallContext *ctx)
+{
+ //DeclarativeDebugTrace cannot handle nested profiling
+ //although v8 can handle several profiling at once,
+ //we do not allow that. Hence, we pass an empty(default) title
+ QString title;
+
+ QV4::ExecutionEngine *v4 = ctx->engine;
+
+ QV4::ExecutionEngine::StackFrame frame = v4->currentStackFrame();
+ QMessageLogger logger(frame.source.toUtf8().constData(), frame.line, frame.function.toUtf8().constData());
+
+ if (QQmlProfilerService::stopProfiling()) {
+ QV8ProfilerService *profiler = QV8ProfilerService::instance();
+ profiler->stopProfiling(title);
+ QQmlProfilerService::sendProfilingData();
+ profiler->sendProfilingData();
+
+ logger.debug("Profiling ended.");
+ } else {
+ logger.warning("Profiling was not started.");
+ }
+
+ return QV4::Value::undefinedValue();
+}
+
+QV4::Value ConsoleObject::method_time(SimpleCallContext *ctx)
+{
+ if (ctx->argumentCount != 1)
+ V4THROW_ERROR("console.time(): Invalid arguments");
+
+ QV8Engine *v8engine = ctx->engine->v8Engine;
+
+ QString name = ctx->arguments[0].toQString();
+ v8engine->startTimer(name);
+ return QV4::Value::undefinedValue();
+}
+
+QV4::Value ConsoleObject::method_timeEnd(SimpleCallContext *ctx)
+{
+ if (ctx->argumentCount != 1)
+ V4THROW_ERROR("console.time(): Invalid arguments");
+
+ QV8Engine *v8engine = ctx->engine->v8Engine;
+
+ QString name = ctx->arguments[0].toQString();
+ bool wasRunning;
+ qint64 elapsed = v8engine->stopTimer(name, &wasRunning);
+ if (wasRunning) {
+ qDebug("%s: %llims", qPrintable(name), elapsed);
+ }
+ return QV4::Value::undefinedValue();
+}
+
+QV4::Value ConsoleObject::method_count(SimpleCallContext *ctx)
+{
+ // first argument: name to print. Ignore any additional arguments
+ QString name;
+ if (ctx->argumentCount > 0)
+ name = ctx->arguments[0].toQString();
+
+ QV4::ExecutionEngine *v4 = ctx->engine;
+ QV8Engine *v8engine = ctx->engine->v8Engine;
+
+ QV4::ExecutionEngine::StackFrame frame = v4->currentStackFrame();
+
+ QString scriptName = frame.source;
+
+ int value = v8engine->consoleCountHelper(scriptName, frame.line, frame.column);
+ QString message = name + QLatin1String(": ") + QString::number(value);
+
+ QMessageLogger(qPrintable(scriptName), frame.line,
+ qPrintable(frame.function)).debug("%s", qPrintable(message));
+
+ return QV4::Value::undefinedValue();
+}
+
+QV4::Value ConsoleObject::method_trace(SimpleCallContext *ctx)
+{
+ if (ctx->argumentCount != 0)
+ V4THROW_ERROR("console.trace(): Invalid arguments");
+
+ QV4::ExecutionEngine *v4 = ctx->engine;
+
+ QString stack = jsStack(v4);
+
+ QV4::ExecutionEngine::StackFrame frame = v4->currentStackFrame();
+ QMessageLogger logger(frame.source.toUtf8().constData(), frame.line, frame.function.toUtf8().constData());
+
+ logger.debug("%s", qPrintable(stack));
+ return QV4::Value::undefinedValue();
+}
+
+QV4::Value ConsoleObject::method_warn(SimpleCallContext *ctx)
+{
+ return writeToConsole(Warn, ctx);
+}
+
+QV4::Value ConsoleObject::method_assert(SimpleCallContext *ctx)
+{
+ if (ctx->argumentCount == 0)
+ V4THROW_ERROR("console.assert(): Missing argument");
+
+ QV4::ExecutionEngine *v4 = ctx->engine;
+
+ if (!ctx->arguments[0].toBoolean()) {
+ QString message;
+ for (int i = 1; i < ctx->argumentCount; ++i) {
+ if (i != 1)
+ message.append(QLatin1Char(' '));
+
+ message.append(ctx->arguments[i].toQString());
+ }
+
+ QString stack = jsStack(v4);
+
+ QV4::ExecutionEngine::StackFrame frame = v4->currentStackFrame();
+ QMessageLogger logger(frame.source.toUtf8().constData(), frame.line, frame.function.toUtf8().constData());
+ logger.critical("%s\n%s", qPrintable(message), qPrintable(stack));
+
+ }
+ return QV4::Value::undefinedValue();
+}
+
+QV4::Value ConsoleObject::method_exception(SimpleCallContext *ctx)
+{
+ if (ctx->argumentCount == 0)
+ V4THROW_ERROR("console.exception(): Missing argument");
+
+ writeToConsole(Error, ctx, true);
+
+ return QV4::Value::undefinedValue();
+}
+
+
+
+void QV4::GlobalExtensions::init(QQmlEngine *qmlEngine, Object *globalObject)
+{
+ QV4::ExecutionEngine *v4 = globalObject->engine();
+
+#ifndef QT_NO_TRANSLATION
+ globalObject->defineDefaultProperty(v4, QStringLiteral("qsTranslate"), method_qsTranslate);
+ globalObject->defineDefaultProperty(v4, QStringLiteral("QT_TRANSLATE_NOOP"), method_qsTranslateNoOp);
+ globalObject->defineDefaultProperty(v4, QStringLiteral("qsTr"), method_qsTr);
+ globalObject->defineDefaultProperty(v4, QStringLiteral("QT_TR_NOOP"), method_qsTrNoOp);
+ globalObject->defineDefaultProperty(v4, QStringLiteral("qsTrId"), method_qsTrId);
+ globalObject->defineDefaultProperty(v4, QStringLiteral("QT_TRID_NOOP"), method_qsTrIdNoOp);
+#endif
+
+ globalObject->defineDefaultProperty(v4, QStringLiteral("print"), ConsoleObject::method_log);
+ globalObject->defineDefaultProperty(v4, QStringLiteral("gc"), method_gc);
+
+ Value console = QV4::Value::fromObject(new (v4->memoryManager) QV4::ConsoleObject(v4));
+ globalObject->defineDefaultProperty(v4, QStringLiteral("console"), console);
+
+ Value qt = QV4::Value::fromObject(new (v4->memoryManager) QV4::QtObject(v4, qmlEngine));
+ globalObject->defineDefaultProperty(v4, QStringLiteral("Qt"), qt);
+
+ // string prototype extension
+ QV4::Object *stringProto = v4->stringPrototype;
+ stringProto->defineDefaultProperty(v4, QStringLiteral("arg"), string_arg);
+}
+
+
#ifndef QT_NO_TRANSLATION
/*!
\qmlmethod string Qt::qsTranslate(string context, string sourceText, string disambiguation, int n)
@@ -1346,39 +1615,38 @@ v8::Handle<v8::Value> createComponent(const v8::Arguments &args)
\sa {Internationalization and Localization with Qt Quick}
*/
-v8::Handle<v8::Value> qsTranslate(const v8::Arguments &args)
+Value GlobalExtensions::method_qsTranslate(SimpleCallContext *ctx)
{
- if (args.Length() < 2)
- V8THROW_ERROR("qsTranslate() requires at least two arguments");
- if (!args[0]->IsString())
- V8THROW_ERROR("qsTranslate(): first argument (context) must be a string");
- if (!args[1]->IsString())
- V8THROW_ERROR("qsTranslate(): second argument (sourceText) must be a string");
- if ((args.Length() > 2) && !args[2]->IsString())
- V8THROW_ERROR("qsTranslate(): third argument (disambiguation) must be a string");
-
- QV8Engine *v8engine = V8ENGINE();
- QString context = v8engine->toString(args[0]);
- QString text = v8engine->toString(args[1]);
+ if (ctx->argumentCount < 2)
+ V4THROW_ERROR("qsTranslate() requires at least two arguments");
+ if (!ctx->arguments[0].isString())
+ V4THROW_ERROR("qsTranslate(): first argument (context) must be a string");
+ if (!ctx->arguments[1].isString())
+ V4THROW_ERROR("qsTranslate(): second argument (sourceText) must be a string");
+ if ((ctx->argumentCount > 2) && !ctx->arguments[2].isString())
+ V4THROW_ERROR("qsTranslate(): third argument (disambiguation) must be a string");
+
+ QString context = ctx->arguments[0].toQString();
+ QString text = ctx->arguments[1].toQString();
QString comment;
- if (args.Length() > 2) comment = v8engine->toString(args[2]);
+ if (ctx->argumentCount > 2) comment = ctx->arguments[2].toQString();
int i = 3;
- if (args.Length() > i && args[i]->IsString()) {
+ if (ctx->argumentCount > i && ctx->arguments[i].isString()) {
qWarning("qsTranslate(): specifying the encoding as fourth argument is deprecated");
++i;
}
int n = -1;
- if (args.Length() > i)
- n = args[i]->Int32Value();
+ if (ctx->argumentCount > i)
+ n = ctx->arguments[i].toInt32();
QString result = QCoreApplication::translate(context.toUtf8().constData(),
text.toUtf8().constData(),
comment.toUtf8().constData(),
n);
- return v8engine->toString(result);
+ return Value::fromString(ctx, result);
}
/*!
@@ -1403,11 +1671,11 @@ v8::Handle<v8::Value> qsTranslate(const v8::Arguments &args)
\sa {Internationalization and Localization with Qt Quick}
*/
-v8::Handle<v8::Value> qsTranslateNoOp(const v8::Arguments &args)
+Value GlobalExtensions::method_qsTranslateNoOp(SimpleCallContext *ctx)
{
- if (args.Length() < 2)
- return v8::Undefined();
- return args[1];
+ if (ctx->argumentCount < 2)
+ return QV4::Value::undefinedValue();
+ return ctx->arguments[1];
}
/*!
@@ -1427,36 +1695,36 @@ v8::Handle<v8::Value> qsTranslateNoOp(const v8::Arguments &args)
\sa {Internationalization and Localization with Qt Quick}
*/
-v8::Handle<v8::Value> qsTr(const v8::Arguments &args)
+Value GlobalExtensions::method_qsTr(SimpleCallContext *ctx)
{
- if (args.Length() < 1)
- V8THROW_ERROR("qsTr() requires at least one argument");
- if (!args[0]->IsString())
- V8THROW_ERROR("qsTr(): first argument (sourceText) must be a string");
- if ((args.Length() > 1) && !args[1]->IsString())
- V8THROW_ERROR("qsTr(): second argument (disambiguation) must be a string");
- if ((args.Length() > 2) && !args[2]->IsNumber())
- V8THROW_ERROR("qsTr(): third argument (n) must be a number");
-
- QV8Engine *v8engine = V8ENGINE();
+ if (ctx->argumentCount < 1)
+ V4THROW_ERROR("qsTr() requires at least one argument");
+ if (!ctx->arguments[0].isString())
+ V4THROW_ERROR("qsTr(): first argument (sourceText) must be a string");
+ if ((ctx->argumentCount > 1) && !ctx->arguments[1].isString())
+ V4THROW_ERROR("qsTr(): second argument (disambiguation) must be a string");
+ if ((ctx->argumentCount > 2) && !ctx->arguments[2].isNumber())
+ V4THROW_ERROR("qsTr(): third argument (n) must be a number");
+
+ QV8Engine *v8engine = ctx->engine->v8Engine;
QQmlContextData *ctxt = v8engine->callingContext();
QString path = ctxt->url.toString();
int lastSlash = path.lastIndexOf(QLatin1Char('/'));
QString context = (lastSlash > -1) ? path.mid(lastSlash + 1, path.length()-lastSlash-5) : QString();
- QString text = v8engine->toString(args[0]);
+ QString text = ctx->arguments[0].toQString();
QString comment;
- if (args.Length() > 1)
- comment = v8engine->toString(args[1]);
+ if (ctx->argumentCount > 1)
+ comment = ctx->arguments[1].toQString();
int n = -1;
- if (args.Length() > 2)
- n = args[2]->Int32Value();
+ if (ctx->argumentCount > 2)
+ n = ctx->arguments[2].toInt32();
QString result = QCoreApplication::translate(context.toUtf8().constData(), text.toUtf8().constData(),
comment.toUtf8().constData(), n);
- return v8engine->toString(result);
+ return Value::fromString(ctx, result);
}
/*!
@@ -1481,11 +1749,11 @@ v8::Handle<v8::Value> qsTr(const v8::Arguments &args)
\sa {Internationalization and Localization with Qt Quick}
*/
-v8::Handle<v8::Value> qsTrNoOp(const v8::Arguments &args)
+Value GlobalExtensions::method_qsTrNoOp(SimpleCallContext *ctx)
{
- if (args.Length() < 1)
- return v8::Undefined();
- return args[0];
+ if (ctx->argumentCount < 1)
+ return QV4::Value::undefinedValue();
+ return ctx->arguments[0];
}
/*!
@@ -1518,21 +1786,20 @@ v8::Handle<v8::Value> qsTrNoOp(const v8::Arguments &args)
\sa QT_TRID_NOOP, {Internationalization and Localization with Qt Quick}
*/
-v8::Handle<v8::Value> qsTrId(const v8::Arguments &args)
+Value GlobalExtensions::method_qsTrId(SimpleCallContext *ctx)
{
- if (args.Length() < 1)
- V8THROW_ERROR("qsTrId() requires at least one argument");
- if (!args[0]->IsString())
- V8THROW_TYPE("qsTrId(): first argument (id) must be a string");
- if (args.Length() > 1 && !args[1]->IsNumber())
- V8THROW_TYPE("qsTrId(): second argument (n) must be a number");
+ if (ctx->argumentCount < 1)
+ V4THROW_ERROR("qsTrId() requires at least one argument");
+ if (!ctx->arguments[0].isString())
+ V4THROW_TYPE("qsTrId(): first argument (id) must be a string");
+ if (ctx->argumentCount > 1 && !ctx->arguments[1].isNumber())
+ V4THROW_TYPE("qsTrId(): second argument (n) must be a number");
int n = -1;
- if (args.Length() > 1)
- n = args[1]->Int32Value();
+ if (ctx->argumentCount > 1)
+ n = ctx->arguments[1].toInt32();
- QV8Engine *v8engine = V8ENGINE();
- return v8engine->toString(qtTrId(v8engine->toString(args[0]).toUtf8().constData(), n));
+ return Value::fromString(ctx, qtTrId(ctx->arguments[0].toQString().toUtf8().constData(), n));
}
/*!
@@ -1551,108 +1818,41 @@ v8::Handle<v8::Value> qsTrId(const v8::Arguments &args)
\sa qsTrId(), {Internationalization and Localization with Qt Quick}
*/
-v8::Handle<v8::Value> qsTrIdNoOp(const v8::Arguments &args)
+Value GlobalExtensions::method_qsTrIdNoOp(SimpleCallContext *ctx)
{
- if (args.Length() < 1)
- return v8::Undefined();
- return args[0];
+ if (ctx->argumentCount < 1)
+ return QV4::Value::undefinedValue();
+ return ctx->arguments[0];
}
#endif // QT_NO_TRANSLATION
-/*!
- \qmlmethod Qt::locale(name)
- Returns a JS object representing the locale with the specified
- name, which has the format "language[_territory][.codeset][@modifier]"
- or "C", where:
-
- \list
- \li language is a lowercase, two-letter, ISO 639 language code,
- \li territory is an uppercase, two-letter, ISO 3166 country code,
- \li and codeset and modifier are ignored.
- \endlist
-
- If the string violates the locale format, or language is not a
- valid ISO 369 code, the "C" locale is used instead. If country
- is not present, or is not a valid ISO 3166 code, the most
- appropriate country is chosen for the specified language.
-
- \sa QtQuick2::Locale
-*/
-v8::Handle<v8::Value> locale(const v8::Arguments &args)
+QV4::Value GlobalExtensions::method_gc(SimpleCallContext *ctx)
{
- QString code;
- if (args.Length() > 1)
- V8THROW_ERROR("locale() requires 0 or 1 argument");
- if (args.Length() == 1 && !args[0]->IsString())
- V8THROW_TYPE("locale(): argument (locale code) must be a string");
-
- QV8Engine *v8engine = V8ENGINE();
- if (args.Length() == 1)
- code = v8engine->toString(args[0]);
+ ctx->engine->memoryManager->runGC();
- return QQmlLocale::locale(v8engine, code);
+ return QV4::Value::undefinedValue();
}
-/*!
- \qmlmethod Qt::binding(function)
-
- Returns a JS object representing a binding expression which may be
- assigned to any property in imperative code to cause a binding
- assignment.
- There are two main use-cases for the function: firstly, in imperative
- JavaScript code to cause a binding assignment:
- \snippet qml/qtBinding.1.qml 0
-
- and secondly, when defining initial property values of dynamically
- constructed objects (via Component.createObject() or
- Loader.setSource()) as being bound to the result of an expression.
-
- For example, assuming the existence of a DynamicText component:
- \snippet qml/DynamicText.qml 0
-
- the output from:
- \snippet qml/qtBinding.2.qml 0
-
- and from:
- \snippet qml/qtBinding.3.qml 0
-
- should both be:
- \code
- Root text extra text
- Modified root text extra text
- Dynamic text extra text
- Modified dynamic text extra text
- \endcode
-
- This function cannot be used in property binding declarations
- (see the documentation on \l{qml-javascript-assignment}{binding
- declarations and binding assignments}) except when the result is
- stored in an array bound to a var property.
-
- \snippet qml/qtBinding.4.qml 0
-
- \note In \l {Qt Quick 1}, all function assignment was treated as
- binding assignment, so the Qt.binding() function is new in
- \l {Qt Quick}{Qt Quick 2}.
-
- \since QtQuick 2.0
-*/
-v8::Handle<v8::Value> binding(const v8::Arguments &args)
+Value GlobalExtensions::string_arg(SimpleCallContext *ctx)
{
- QString code;
- if (args.Length() != 1)
- V8THROW_ERROR("binding() requires 1 argument");
- if (!args[0]->IsFunction())
- V8THROW_TYPE("binding(): argument (binding expression) must be a function");
-
- v8::Handle<v8::Object> rv = args[0]->ToObject()->Clone();
- rv->SetHiddenValue(V8ENGINE()->bindingFlagKey(), v8::Boolean::New(true));
- return rv;
+ QString value = ctx->thisObject.toQString();
+ if (ctx->argumentCount != 1)
+ V4THROW_ERROR("String.arg(): Invalid arguments");
+
+ QV4::Value arg = ctx->arguments[0];
+ if (arg.isInteger())
+ return Value::fromString(ctx, value.arg(arg.integerValue()));
+ else if (arg.isDouble())
+ return Value::fromString(ctx, value.arg(arg.doubleValue()));
+ else if (arg.isBoolean())
+ return Value::fromString(ctx, value.arg(arg.booleanValue()));
+
+ return Value::fromString(ctx, value.arg(arg.toQString()));
}
-} // namespace QQmlBuiltinFunctions
QT_END_NAMESPACE
+
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
index f73802b136..c0effacbb4 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
@@ -54,63 +54,98 @@
//
#include <QtCore/qglobal.h>
-#include <private/qv8_p.h>
+#include <private/qv4object_p.h>
+
+class QQmlEngine;
+class QV8Engine;
QT_BEGIN_NAMESPACE
-namespace QQmlBuiltinFunctions
+namespace QV4 {
+
+struct QtObject : Object
+{
+ Q_MANAGED
+ QtObject(ExecutionEngine *v4, QQmlEngine *qmlEngine);
+
+ static Value method_isQtObject(SimpleCallContext *ctx);
+ static Value method_rgba(SimpleCallContext *ctx);
+ static Value method_hsla(SimpleCallContext *ctx);
+ static Value method_colorEqual(SimpleCallContext *ctx);
+ static Value method_font(SimpleCallContext *ctx);
+ static Value method_rect(SimpleCallContext *ctx);
+ static Value method_point(SimpleCallContext *ctx);
+ static Value method_size(SimpleCallContext *ctx);
+ static Value method_vector2d(SimpleCallContext *ctx);
+ static Value method_vector3d(SimpleCallContext *ctx);
+ static Value method_vector4d(SimpleCallContext *ctx);
+ static Value method_quaternion(SimpleCallContext *ctx);
+ static Value method_matrix4x4(SimpleCallContext *ctx);
+ static Value method_lighter(SimpleCallContext *ctx);
+ static Value method_darker(SimpleCallContext *ctx);
+ static Value method_tint(SimpleCallContext *ctx);
+ static Value method_formatDate(SimpleCallContext *ctx);
+ static Value method_formatTime(SimpleCallContext *ctx);
+ static Value method_formatDateTime(SimpleCallContext *ctx);
+ static Value method_openUrlExternally(SimpleCallContext *ctx);
+ static Value method_fontFamilies(SimpleCallContext *ctx);
+ static Value method_md5(SimpleCallContext *ctx);
+ static Value method_btoa(SimpleCallContext *ctx);
+ static Value method_atob(SimpleCallContext *ctx);
+ static Value method_quit(SimpleCallContext *ctx);
+ static Value method_resolvedUrl(SimpleCallContext *ctx);
+ static Value method_createQmlObject(SimpleCallContext *ctx);
+ static Value method_createComponent(SimpleCallContext *ctx);
+ static Value method_locale(SimpleCallContext *ctx);
+ static Value method_binding(SimpleCallContext *ctx);
+
+ static Value method_get_platform(SimpleCallContext *ctx);
+ static Value method_get_application(SimpleCallContext *ctx);
+#ifndef QT_NO_IM
+ static Value method_get_inputMethod(SimpleCallContext *ctx);
+#endif
+
+ QObject *m_platform;
+ QObject *m_application;
+};
+
+struct ConsoleObject : Object
{
-v8::Handle<v8::Value> gc(const v8::Arguments &args);
-v8::Handle<v8::Value> consoleError(const v8::Arguments &args);
-v8::Handle<v8::Value> consoleLog(const v8::Arguments &args);
-v8::Handle<v8::Value> consoleProfile(const v8::Arguments &args);
-v8::Handle<v8::Value> consoleProfileEnd(const v8::Arguments &args);
-v8::Handle<v8::Value> consoleTime(const v8::Arguments &args);
-v8::Handle<v8::Value> consoleTimeEnd(const v8::Arguments &args);
-v8::Handle<v8::Value> consoleCount(const v8::Arguments &args);
-v8::Handle<v8::Value> consoleTrace(const v8::Arguments &args);
-v8::Handle<v8::Value> consoleWarn(const v8::Arguments &args);
-v8::Handle<v8::Value> consoleAssert(const v8::Arguments &args);
-v8::Handle<v8::Value> consoleException(const v8::Arguments &args);
-v8::Handle<v8::Value> isQtObject(const v8::Arguments &args);
-v8::Handle<v8::Value> rgba(const v8::Arguments &args);
-v8::Handle<v8::Value> hsla(const v8::Arguments &args);
-v8::Handle<v8::Value> colorEqual(const v8::Arguments &args);
-v8::Handle<v8::Value> font(const v8::Arguments &args);
-v8::Handle<v8::Value> rect(const v8::Arguments &args);
-v8::Handle<v8::Value> point(const v8::Arguments &args);
-v8::Handle<v8::Value> size(const v8::Arguments &args);
-v8::Handle<v8::Value> vector2d(const v8::Arguments &args);
-v8::Handle<v8::Value> vector3d(const v8::Arguments &args);
-v8::Handle<v8::Value> vector4d(const v8::Arguments &args);
-v8::Handle<v8::Value> quaternion(const v8::Arguments &args);
-v8::Handle<v8::Value> matrix4x4(const v8::Arguments &args);
-v8::Handle<v8::Value> lighter(const v8::Arguments &args);
-v8::Handle<v8::Value> darker(const v8::Arguments &args);
-v8::Handle<v8::Value> tint(const v8::Arguments &args);
-v8::Handle<v8::Value> formatDate(const v8::Arguments &args);
-v8::Handle<v8::Value> formatTime(const v8::Arguments &args);
-v8::Handle<v8::Value> formatDateTime(const v8::Arguments &args);
-v8::Handle<v8::Value> openUrlExternally(const v8::Arguments &args);
-v8::Handle<v8::Value> fontFamilies(const v8::Arguments &args);
-v8::Handle<v8::Value> md5(const v8::Arguments &args);
-v8::Handle<v8::Value> btoa(const v8::Arguments &args);
-v8::Handle<v8::Value> atob(const v8::Arguments &args);
-v8::Handle<v8::Value> quit(const v8::Arguments &args);
-v8::Handle<v8::Value> resolvedUrl(const v8::Arguments &args);
-v8::Handle<v8::Value> createQmlObject(const v8::Arguments &args);
-v8::Handle<v8::Value> createComponent(const v8::Arguments &args);
+ ConsoleObject(ExecutionEngine *v4);
+
+ static Value method_error(SimpleCallContext *ctx);
+ static Value method_log(SimpleCallContext *ctx);
+ static Value method_profile(SimpleCallContext *ctx);
+ static Value method_profileEnd(SimpleCallContext *ctx);
+ static Value method_time(SimpleCallContext *ctx);
+ static Value method_timeEnd(SimpleCallContext *ctx);
+ static Value method_count(SimpleCallContext *ctx);
+ static Value method_trace(SimpleCallContext *ctx);
+ static Value method_warn(SimpleCallContext *ctx);
+ static Value method_assert(SimpleCallContext *ctx);
+ static Value method_exception(SimpleCallContext *ctx);
+
+};
+
+struct GlobalExtensions {
+ static void init(QQmlEngine *qmlEngine, Object *globalObject);
+
#ifndef QT_NO_TRANSLATION
-v8::Handle<v8::Value> qsTranslate(const v8::Arguments &args);
-v8::Handle<v8::Value> qsTranslateNoOp(const v8::Arguments &args);
-v8::Handle<v8::Value> qsTr(const v8::Arguments &args);
-v8::Handle<v8::Value> qsTrNoOp(const v8::Arguments &args);
-v8::Handle<v8::Value> qsTrId(const v8::Arguments &args);
-v8::Handle<v8::Value> qsTrIdNoOp(const v8::Arguments &args);
+ static Value method_qsTranslate(SimpleCallContext *ctx);
+ static Value method_qsTranslateNoOp(SimpleCallContext *ctx);
+ static Value method_qsTr(SimpleCallContext *ctx);
+ static Value method_qsTrNoOp(SimpleCallContext *ctx);
+ static Value method_qsTrId(SimpleCallContext *ctx);
+ static Value method_qsTrIdNoOp(SimpleCallContext *ctx);
#endif
-v8::Handle<v8::Value> stringArg(const v8::Arguments &args);
-v8::Handle<v8::Value> locale(const v8::Arguments &args);
-v8::Handle<v8::Value> binding(const v8::Arguments &args);
+ static Value method_gc(SimpleCallContext *ctx);
+
+ // on String:prototype
+ static Value string_arg(SimpleCallContext *ctx);
+
+};
+
+
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qscript_impl_p.h b/src/qml/qml/v8/qscript_impl_p.h
deleted file mode 100644
index 41791189a7..0000000000
--- a/src/qml/qml/v8/qscript_impl_p.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//
-// 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 QSCRIPT_IMPL_P_H
-#define QSCRIPT_IMPL_P_H
-
-#include "qv8engine_impl_p.h"
-#include "qjsvalue_impl_p.h"
-#include "qjsvalueiterator_impl_p.h"
-#include "qjsconverter_impl_p.h"
-
-#endif //QSCRIPT_IMPL_P_H
diff --git a/src/qml/qml/v8/qscriptisolate_p.h b/src/qml/qml/v8/qscriptisolate_p.h
deleted file mode 100644
index da35069e33..0000000000
--- a/src/qml/qml/v8/qscriptisolate_p.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef APIPREAMBLE_P_H
-#define APIPREAMBLE_P_H
-
-#include <private/qv8_p.h>
-#include "qv8engine_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/**
- \internal
- Class used to switch to the right isolate. It does the same thing as v8::Isolate::Scope but
- it checks for a null engine.
- \attention We decided to put context switching "up" which means that it should be as high
- as possible on call stack. And it should be switched at most once per public API function call.
-*/
-class QScriptIsolate {
-public:
- // OperationMode was introduced to reduce number of checking for a null engine pointer. If we
- // know that given pointer is not null than we should pass NotNullEngine as constructor argument
- // that would nicely remove checking on compilation time.
- enum OperationMode {Default, NotNullEngine};
- inline QScriptIsolate(const QV8Engine *engine, const OperationMode mode = Default)
- : m_engine(engine)
- , m_mode(mode)
- {
- if (m_mode == NotNullEngine || m_engine) {
- Q_ASSERT(m_engine);
- m_engine->context()->Enter();
- }
- }
-
- inline ~QScriptIsolate()
- {
- if (m_mode == NotNullEngine || m_engine) {
- m_engine->context()->Exit();
- }
- }
-
-private:
- Q_DISABLE_COPY(QScriptIsolate)
- const QV8Engine *m_engine;
- const OperationMode m_mode;
-};
-
-
-QT_END_NAMESPACE
-
-#endif // APIPREAMBLE_P_H
diff --git a/src/qml/qml/v8/qscriptoriginalglobalobject_p.h b/src/qml/qml/v8/qscriptoriginalglobalobject_p.h
deleted file mode 100644
index 2ecdbdac91..0000000000
--- a/src/qml/qml/v8/qscriptoriginalglobalobject_p.h
+++ /dev/null
@@ -1,177 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCRIPTORIGINALGLOBALOBJECT_P_H
-#define QSCRIPTORIGINALGLOBALOBJECT_P_H
-
-#include "QtCore/qglobal.h"
-#include "qjsvalue_p.h"
-
-#include <private/qv8_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QV8Engine;
-
-/*!
- \internal
- This class is a workaround for missing V8 API functionality. This class keeps all important
- properties of an original (default) global object, so we can use it even if the global object was
- changed.
-
- FIXME this class is a container for workarounds :-) it should be replaced by proper API calls.
-
- The class have to be created on the QV8Engine creation time (before any change got applied to
- global object).
-
- \attention All methods (apart from constructor) assumes that a context and a scope are prepared correctly.
-*/
-class QScriptOriginalGlobalObject
-{
-public:
- inline QScriptOriginalGlobalObject() {}
- inline void init(v8::Handle<v8::Context> context);
- inline void destroy();
-
- inline QJSValuePrivate::PropertyFlags getPropertyFlags(v8::Handle<v8::Object> object, v8::Handle<v8::Value> property);
- inline v8::Local<v8::Object> getOwnPropertyDescriptor(v8::Handle<v8::Object> object, v8::Handle<v8::Value> property) const;
- inline bool strictlyEquals(v8::Handle<v8::Object> object);
-private:
- Q_DISABLE_COPY(QScriptOriginalGlobalObject)
-
- // Copy of constructors and prototypes used in isType functions.
- v8::Persistent<v8::Function> m_ownPropertyDescriptor;
- v8::Persistent<v8::Object> m_globalObject;
-};
-
-void QScriptOriginalGlobalObject::init(v8::Handle<v8::Context> context)
-{
- // Please notice that engine is not fully initialized at this point.
-
- v8::Context::Scope contextScope(context);
-
- v8::HandleScope scope;
-
- m_globalObject = v8::Persistent<v8::Object>::New(context->Global());
-
- v8::Local<v8::Object> objectConstructor = m_globalObject->Get(v8::String::New("Object"))->ToObject();
- Q_ASSERT(objectConstructor->IsObject());
- { // Initialize m_ownPropertyDescriptor.
- v8::Local<v8::Value> ownPropertyDescriptor = objectConstructor->Get(v8::String::New("getOwnPropertyDescriptor"));
- Q_ASSERT(!ownPropertyDescriptor.IsEmpty());
- m_ownPropertyDescriptor = v8::Persistent<v8::Function>::New(v8::Local<v8::Function>::Cast(ownPropertyDescriptor));
- }
-}
-
-/*!
- \internal
- QScriptOriginalGlobalObject lives as long as QV8Engine that keeps it. In ~QSEP
- the v8 context is removed, so we need to remove our handlers before. to break this dependency
- destroy method should be called before or insight QSEP destructor.
-*/
-inline void QScriptOriginalGlobalObject::destroy()
-{
- m_ownPropertyDescriptor.Dispose();
- m_globalObject.Dispose();
- // After this line this instance is unusable.
-}
-
-inline QJSValuePrivate::PropertyFlags QScriptOriginalGlobalObject::getPropertyFlags(v8::Handle<v8::Object> object, v8::Handle<v8::Value> property)
-{
- Q_ASSERT(object->IsObject());
- Q_ASSERT(!property.IsEmpty());
- v8::Local<v8::Object> descriptor = getOwnPropertyDescriptor(object, property);
- if (descriptor.IsEmpty()) {
-// // Property isn't owned by this object.
-// if (!(mode & QScriptValue::ResolvePrototype))
-// return 0;
- v8::Local<v8::Value> prototype = object->GetPrototype();
- if (prototype->IsNull())
- return 0;
- return getPropertyFlags(v8::Local<v8::Object>::Cast(prototype), property);
- }
- v8::Local<v8::String> writableName = v8::String::New("writable");
- v8::Local<v8::String> configurableName = v8::String::New("configurable");
- v8::Local<v8::String> enumerableName = v8::String::New("enumerable");
-// v8::Local<v8::String> getName = v8::String::New("get");
-// v8::Local<v8::String> setName = v8::String::New("set");
-
- unsigned flags = 0;
-
- if (!descriptor->Get(configurableName)->BooleanValue())
- flags |= QJSValuePrivate::Undeletable;
- if (!descriptor->Get(enumerableName)->BooleanValue())
- flags |= QJSValuePrivate::SkipInEnumeration;
-
- //"writable" is only a property of the descriptor if it is not an accessor
- if (descriptor->Has(writableName)) {
- if (!descriptor->Get(writableName)->BooleanValue())
- flags |= QJSValuePrivate::ReadOnly;
- } else {
-// if (descriptor->Get(getName)->IsObject())
-// flags |= QScriptValue::PropertyGetter;
-// if (descriptor->Get(setName)->IsObject())
-// flags |= QScriptValue::PropertySetter;
- }
-
- return QJSValuePrivate::PropertyFlag(flags);
-}
-
-inline v8::Local<v8::Object> QScriptOriginalGlobalObject::getOwnPropertyDescriptor(v8::Handle<v8::Object> object, v8::Handle<v8::Value> property) const
-{
- Q_ASSERT(object->IsObject());
- Q_ASSERT(!property.IsEmpty());
- // FIXME do we need try catch here?
- v8::Handle<v8::Value> argv[] = {object, property};
- v8::Local<v8::Value> descriptor = m_ownPropertyDescriptor->Call(m_globalObject, /* argc */ 2, argv);
- if (descriptor.IsEmpty() || !descriptor->IsObject())
- return v8::Local<v8::Object>();
- return v8::Local<v8::Object>::Cast(descriptor);
-}
-
-inline bool QScriptOriginalGlobalObject::strictlyEquals(v8::Handle<v8::Object> object)
-{
- return m_globalObject->GetPrototype()->StrictEquals(object);
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/qml/qml/v8/qscriptshareddata_p.h b/src/qml/qml/v8/qscriptshareddata_p.h
deleted file mode 100644
index 70289cba46..0000000000
--- a/src/qml/qml/v8/qscriptshareddata_p.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//
-// 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 QSCRIPTSHAREDDATA_P_H
-#define QSCRIPTSHAREDDATA_P_H
-
-#include "qglobal.h"
-#include "qshareddata.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \internal
- This class should have the same interface as the QSharedData, but implementation doesn't
- need to be thread safe, so atomic ref count was replaced by normal integer value.
-*/
-class QScriptSharedData
-{
-public:
- class ReferenceCounter {
- // FIXME shouldn't it be uint or something longer?
- mutable int m_ref;
- ReferenceCounter(int ref) : m_ref(ref) {}
- ~ReferenceCounter() { Q_ASSERT_X(!m_ref, Q_FUNC_INFO, "Memory problem found"); }
- public:
- bool ref() { return ++m_ref; }
- bool deref() { return --m_ref; }
- friend class QScriptSharedData;
- };
-
- ReferenceCounter ref;
- inline QScriptSharedData() : ref(0) { }
-
-private:
- Q_DISABLE_COPY(QScriptSharedData)
-};
-
-
-template <class T> class QScriptPassPointer;
-
-// FIXME: that could be reimplemented to not check for a null value.
-template<class T>
-class QScriptSharedDataPointer : public QExplicitlySharedDataPointer<T>
-{
-public:
- inline QScriptSharedDataPointer() {}
- explicit QScriptSharedDataPointer(QScriptPassPointer<T> data) : QExplicitlySharedDataPointer<T>(data.give()) {}
- explicit QScriptSharedDataPointer(T *data) : QExplicitlySharedDataPointer<T>(data) {}
-
- inline QScriptSharedDataPointer<T> &operator=(const QScriptPassPointer<T> &other)
- {
- this->QExplicitlySharedDataPointer<T>::operator =(other.give());
- return *this;
- }
- inline QScriptSharedDataPointer<T> &operator=(T *other)
- {
- this->QExplicitlySharedDataPointer<T>::operator =(other);
- return *this;
- }
-};
-
-// FIXME: that could be reimplemented to not check for a null value.
-template <class T>
-class QScriptPassPointer {
-public:
- QScriptPassPointer(T *data) : m_ptr(data) {}
- inline QScriptPassPointer() { m_ptr = 0; }
- inline QScriptPassPointer(const QScriptPassPointer<T> &other) : m_ptr(other.give()) {}
- inline ~QScriptPassPointer() { Q_ASSERT_X(!m_ptr, Q_FUNC_INFO, "Ownership of the QScriptPassPointer hasn't been taken"); }
-
- inline T &operator*() const { return *m_ptr; }
- inline T *operator->() { return m_ptr; }
- inline T *operator->() const { return m_ptr; }
- inline T *data() const { return m_ptr; }
- inline const T *constData() const { return m_ptr; }
-
- inline bool operator==(const QScriptPassPointer<T> &other) const { return m_ptr == other.m_ptr; }
- inline bool operator!=(const QScriptPassPointer<T> &other) const { return m_ptr != other.m_ptr; }
- inline bool operator==(const QScriptSharedDataPointer<T> &other) const { return m_ptr == other.m_ptr; }
- inline bool operator!=(const QScriptSharedDataPointer<T> &other) const { return m_ptr != other.m_ptr; }
- inline bool operator==(const T *ptr) const { return m_ptr == ptr; }
- inline bool operator!=(const T *ptr) const { return m_ptr != ptr; }
-
- inline operator bool () const { return m_ptr != 0; }
- inline bool operator!() const { return !m_ptr; }
-
- inline QScriptPassPointer<T> & operator=(const QScriptPassPointer<T> &other)
- {
- if (other.m_ptr != m_ptr) {
- if (m_ptr)
- delete m_ptr;
- m_ptr = other.give();
- }
- return *this;
- }
-
- inline QScriptPassPointer &operator=(T *other)
- {
- if (other != m_ptr) {
- if (m_ptr)
- delete m_ptr;
- m_ptr = other;
- }
- return *this;
- }
-
- inline T* give() const
- {
- T* result = m_ptr;
- m_ptr = 0;
- return result;
- }
-
-private:
- mutable T* m_ptr;
-};
-
-QT_END_NAMESPACE
-
-#endif // QSCRIPTSHAREDDATA_P_H
diff --git a/src/qml/qml/v8/qscripttools_p.h b/src/qml/qml/v8/qscripttools_p.h
deleted file mode 100644
index 29adfa4ef9..0000000000
--- a/src/qml/qml/v8/qscripttools_p.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//
-// 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 QSCRIPTTOOLS_P_H
-#define QSCRIPTTOOLS_P_H
-
-#include <private/qintrusivelist_p.h>
-
-QT_BEGIN_NAMESPACE
-
-template<class N, QIntrusiveListNode N::*member>
-class QScriptIntrusiveList : public QIntrusiveList<N, member>
-{
-public:
- inline void insert(N *n);
- inline void remove(N *n);
-};
-
-template<class N, QIntrusiveListNode N::*member>
-void QScriptIntrusiveList<N, member>::insert(N *n)
-{
- Q_ASSERT_X(!this->contains(n), Q_FUNC_INFO, "Can't insert a value which is in the list already");
- Q_ASSERT_X(!(n->*member).isInList(), Q_FUNC_INFO, "Can't insert a value which is in another list");
- QIntrusiveList<N, member>::insert(n);
-}
-
-template<class N, QIntrusiveListNode N::*member>
-void QScriptIntrusiveList<N, member>::remove(N *n)
-{
- Q_ASSERT_X(this->contains(n), Q_FUNC_INFO, "Can't remove a value which is not in the list");
- QIntrusiveList<N, member>::remove(n);
-}
-
-QT_END_NAMESPACE
-
-#endif //QSCRIPTTOOLS_P_H
diff --git a/src/qml/qml/v8/qv4domerrors.cpp b/src/qml/qml/v8/qv4domerrors.cpp
new file mode 100644
index 0000000000..63c79f85c2
--- /dev/null
+++ b/src/qml/qml/v8/qv4domerrors.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** 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 "qv4domerrors_p.h"
+#include "qv4object_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QV4;
+
+void qt_add_domexceptions(ExecutionEngine *e)
+{
+ Object *domexception = e->newObject();
+ domexception->defineReadonlyProperty(e, QStringLiteral("INDEX_SIZE_ERR"), Value::fromInt32(DOMEXCEPTION_INDEX_SIZE_ERR));
+ domexception->defineReadonlyProperty(e, QStringLiteral("DOMSTRING_SIZE_ERR"), Value::fromInt32(DOMEXCEPTION_DOMSTRING_SIZE_ERR));
+ domexception->defineReadonlyProperty(e, QStringLiteral("HIERARCHY_REQUEST_ERR"), Value::fromInt32(DOMEXCEPTION_HIERARCHY_REQUEST_ERR));
+ domexception->defineReadonlyProperty(e, QStringLiteral("WRONG_DOCUMENT_ERR"), Value::fromInt32(DOMEXCEPTION_WRONG_DOCUMENT_ERR));
+ domexception->defineReadonlyProperty(e, QStringLiteral("INVALID_CHARACTER_ERR"), Value::fromInt32(DOMEXCEPTION_INVALID_CHARACTER_ERR));
+ domexception->defineReadonlyProperty(e, QStringLiteral("NO_DATA_ALLOWED_ERR"), Value::fromInt32(DOMEXCEPTION_NO_DATA_ALLOWED_ERR));
+ domexception->defineReadonlyProperty(e, QStringLiteral("NO_MODIFICATION_ALLOWED_ERR"), Value::fromInt32(DOMEXCEPTION_NO_MODIFICATION_ALLOWED_ERR));
+ domexception->defineReadonlyProperty(e, QStringLiteral("NOT_FOUND_ERR"), Value::fromInt32(DOMEXCEPTION_NOT_FOUND_ERR));
+ domexception->defineReadonlyProperty(e, QStringLiteral("NOT_SUPPORTED_ERR"), Value::fromInt32(DOMEXCEPTION_NOT_SUPPORTED_ERR));
+ domexception->defineReadonlyProperty(e, QStringLiteral("INUSE_ATTRIBUTE_ERR"), Value::fromInt32(DOMEXCEPTION_INUSE_ATTRIBUTE_ERR));
+ domexception->defineReadonlyProperty(e, QStringLiteral("INVALID_STATE_ERR"), Value::fromInt32(DOMEXCEPTION_INVALID_STATE_ERR));
+ domexception->defineReadonlyProperty(e, QStringLiteral("SYNTAX_ERR"), Value::fromInt32(DOMEXCEPTION_SYNTAX_ERR));
+ domexception->defineReadonlyProperty(e, QStringLiteral("INVALID_MODIFICATION_ERR"), Value::fromInt32(DOMEXCEPTION_INVALID_MODIFICATION_ERR));
+ domexception->defineReadonlyProperty(e, QStringLiteral("NAMESPACE_ERR"), Value::fromInt32(DOMEXCEPTION_NAMESPACE_ERR));
+ domexception->defineReadonlyProperty(e, QStringLiteral("INVALID_ACCESS_ERR"), Value::fromInt32(DOMEXCEPTION_INVALID_ACCESS_ERR));
+ domexception->defineReadonlyProperty(e, QStringLiteral("VALIDATION_ERR"), Value::fromInt32(DOMEXCEPTION_VALIDATION_ERR));
+ domexception->defineReadonlyProperty(e, QStringLiteral("TYPE_MISMATCH_ERR"), Value::fromInt32(DOMEXCEPTION_TYPE_MISMATCH_ERR));
+ e->globalObject->defineDefaultProperty(e->current, QStringLiteral("DOMException"), Value::fromObject(domexception));
+}
+
+QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv8domerrors_p.h b/src/qml/qml/v8/qv4domerrors_p.h
index 8fd1ccb6d6..ed38886e15 100644
--- a/src/qml/qml/v8/qv8domerrors_p.h
+++ b/src/qml/qml/v8/qv4domerrors_p.h
@@ -76,14 +76,19 @@ QT_BEGIN_NAMESPACE
#define DOMEXCEPTION_VALIDATION_ERR 16
#define DOMEXCEPTION_TYPE_MISMATCH_ERR 17
-#define V8THROW_DOM(error, string) { \
- v8::Local<v8::Value> v = v8::Exception::Error(v8::String::New(string)); \
- v->ToObject()->Set(v8::String::New("code"), v8::Integer::New(error)); \
- v8::ThrowException(v); \
- return v8::Handle<v8::Value>(); \
+#define V4THROW_DOM(error, string) { \
+ QV4::Value v = QV4::Value::fromString(ctx, QStringLiteral(string)); \
+ QV4::Object *ex = ctx->engine->newErrorObject(v); \
+ ex->put(ctx->engine->newIdentifier(QStringLiteral("code")), QV4::Value::fromInt32(error)); \
+ ctx->throwError(QV4::Value::fromObject(ex)); \
}
-class QV8Engine;
-void qt_add_domexceptions(QV8Engine *engine);
+
+namespace QV4 {
+struct ExecutionEngine;
+}
+
+
+void qt_add_domexceptions(QV4::ExecutionEngine *e);
QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv8stringwrapper.cpp b/src/qml/qml/v8/qv4sqlerrors.cpp
index f069c57b52..bd5a9fdc83 100644
--- a/src/qml/qml/v8/qv8stringwrapper.cpp
+++ b/src/qml/qml/v8/qv4sqlerrors.cpp
@@ -39,40 +39,26 @@
**
****************************************************************************/
-#include "qv8stringwrapper_p.h"
-#include "qjsconverter_p.h"
-#include "qjsconverter_impl_p.h"
+#include "qv4sqlerrors_p.h"
+#include "private/qv4engine_p.h"
+#include "private/qv4object_p.h"
QT_BEGIN_NAMESPACE
-QV8StringWrapper::QV8StringWrapper()
-{
-}
-
-QV8StringWrapper::~QV8StringWrapper()
-{
-}
-
-void QV8StringWrapper::init()
-{
-}
-
-void QV8StringWrapper::destroy()
-{
-}
-
-v8::Local<v8::String> QV8StringWrapper::toString(const QString &qstr)
-{
- return QJSConverter::toString(qstr);
-}
+using namespace QV4;
-QString QV8StringWrapper::toString(v8::Handle<v8::String> jsstr)
+void qt_add_sqlexceptions(QV4::ExecutionEngine *engine)
{
- if (jsstr.IsEmpty()) {
- return QString();
- } else {
- return QJSConverter::toString(jsstr);
- }
+ Object *sqlexception = engine->newObject();
+ sqlexception->defineReadonlyProperty(engine, QStringLiteral("UNKNOWN_ERR"), Value::fromInt32(SQLEXCEPTION_UNKNOWN_ERR));
+ sqlexception->defineReadonlyProperty(engine, QStringLiteral("DATABASE_ERR"), Value::fromInt32(SQLEXCEPTION_DATABASE_ERR));
+ sqlexception->defineReadonlyProperty(engine, QStringLiteral("VERSION_ERR"), Value::fromInt32(SQLEXCEPTION_VERSION_ERR));
+ sqlexception->defineReadonlyProperty(engine, QStringLiteral("TOO_LARGE_ERR"), Value::fromInt32(SQLEXCEPTION_TOO_LARGE_ERR));
+ sqlexception->defineReadonlyProperty(engine, QStringLiteral("QUOTA_ERR"), Value::fromInt32(SQLEXCEPTION_QUOTA_ERR));
+ sqlexception->defineReadonlyProperty(engine, QStringLiteral("SYNTAX_ERR"), Value::fromInt32(SQLEXCEPTION_SYNTAX_ERR));
+ sqlexception->defineReadonlyProperty(engine, QStringLiteral("CONSTRAINT_ERR"), Value::fromInt32(SQLEXCEPTION_CONSTRAINT_ERR));
+ sqlexception->defineReadonlyProperty(engine, QStringLiteral("TIMEOUT_ERR"), Value::fromInt32(SQLEXCEPTION_TIMEOUT_ERR));
+ engine->globalObject->defineDefaultProperty(engine->current, QStringLiteral("SQLException"), Value::fromObject(sqlexception));
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv8sqlerrors_p.h b/src/qml/qml/v8/qv4sqlerrors_p.h
index 8a612d69ab..0433d534f9 100644
--- a/src/qml/qml/v8/qv8sqlerrors_p.h
+++ b/src/qml/qml/v8/qv4sqlerrors_p.h
@@ -65,8 +65,11 @@ QT_BEGIN_NAMESPACE
#define SQLEXCEPTION_CONSTRAINT_ERR 7
#define SQLEXCEPTION_TIMEOUT_ERR 8
-class QV8Engine;
-void qt_add_sqlexceptions(QV8Engine *engine);
+namespace QV4 {
+struct ExecutionEngine;
+}
+
+void qt_add_sqlexceptions(QV4::ExecutionEngine *engine);
QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv8_p.h b/src/qml/qml/v8/qv8_p.h
deleted file mode 100644
index dc5ecc31bc..0000000000
--- a/src/qml/qml/v8/qv8_p.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/v8.h>
diff --git a/src/qml/qml/v8/qv8bindings.cpp b/src/qml/qml/v8/qv8bindings.cpp
deleted file mode 100644
index 757d9d9cf6..0000000000
--- a/src/qml/qml/v8/qv8bindings.cpp
+++ /dev/null
@@ -1,334 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv8bindings_p.h"
-
-#include <private/qv8_p.h>
-#include <private/qqmlbinding_p.h>
-#include <private/qqmlcompiler_p.h>
-#include <private/qqmlproperty_p.h>
-#include <private/qqmlexpression_p.h>
-#include <private/qobject_p.h>
-#include <private/qqmltrace_p.h>
-#include <private/qqmlprofilerservice_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QQmlAbstractBinding::VTable QV8Bindings_Binding_vtable = {
- QV8Bindings::Binding::destroy,
- QQmlAbstractBinding::default_expression,
- QV8Bindings::Binding::propertyIndex,
- QV8Bindings::Binding::object,
- QV8Bindings::Binding::setEnabled,
- QV8Bindings::Binding::update,
- QV8Bindings::Binding::retargetBinding
-};
-
-static QQmlJavaScriptExpression::VTable QV8Bindings_Binding_jsvtable = {
- QV8Bindings::Binding::expressionIdentifier,
- QV8Bindings::Binding::expressionChanged
-};
-
-QV8Bindings::Binding::Binding()
-: QQmlJavaScriptExpression(&QV8Bindings_Binding_jsvtable), QQmlAbstractBinding(V8), parent(0)
-{
-}
-
-void QV8Bindings::Binding::setEnabled(QQmlAbstractBinding *_This, bool e,
- QQmlPropertyPrivate::WriteFlags flags)
-{
- QV8Bindings::Binding *This = static_cast<QV8Bindings::Binding *>(_This);
-
- if (This->enabledFlag() != e) {
- This->setEnabledFlag(e);
-
- if (e) This->update(flags);
- }
-}
-
-void QV8Bindings::refresh()
-{
- int count = functions()->Length();
- for (int ii = 0; ii < count; ++ii)
- bindings[ii].refresh();
-}
-
-void QV8Bindings::Binding::refresh()
-{
- update();
-}
-
-int QV8Bindings::Binding::propertyIndex(const QQmlAbstractBinding *_This)
-{
- const QV8Bindings::Binding *This = static_cast<const QV8Bindings::Binding *>(_This);
- if (This->target.hasValue()) return This->target.constValue()->targetProperty;
- else return This->instruction->property.encodedIndex();
-}
-
-QObject *QV8Bindings::Binding::object(const QQmlAbstractBinding *_This)
-{
- const QV8Bindings::Binding *This = static_cast<const QV8Bindings::Binding *>(_This);
-
- if (This->target.hasValue()) return This->target.constValue()->target;
- else return *This->target;
-}
-
-QObject *QV8Bindings::Binding::object() const
-{
- if (target.hasValue()) return target.constValue()->target;
- else return *target;
-}
-
-void QV8Bindings::Binding::retargetBinding(QQmlAbstractBinding *_This, QObject *t, int i)
-{
- QV8Bindings::Binding *This = static_cast<QV8Bindings::Binding *>(_This);
-
- This->target.value().target = t;
- This->target.value().targetProperty = i;
-}
-
-void QV8Bindings::Binding::update(QQmlAbstractBinding *_This, QQmlPropertyPrivate::WriteFlags flags)
-{
- QV8Bindings::Binding *This = static_cast<QV8Bindings::Binding *>(_This);
- This->update(flags);
-}
-
-void QV8Bindings::Binding::dump()
-{
- qWarning() << parent->url() << instruction->line << instruction->column;
-}
-
-void QV8Bindings::Binding::update(QQmlPropertyPrivate::WriteFlags flags)
-{
- if (!enabledFlag())
- return;
-
- QQmlContextData *context = parent->context();
-
- if (!context || !context->isValid())
- return;
-
- // Check that the target has not been deleted
- if (QQmlData::wasDeleted(object()))
- return;
-
- int lineNo = qmlSourceCoordinate(instruction->line);
- int columnNo = qmlSourceCoordinate(instruction->column);
-
- QQmlTrace trace("V8 Binding Update");
- trace.addDetail("URL", parent->url());
- trace.addDetail("Line", lineNo);
- trace.addDetail("Column", columnNo);
-
- QQmlBindingProfiler prof(parent->urlString(), lineNo, columnNo, QQmlProfilerService::V8Binding);
-
- if (!updatingFlag()) {
- setUpdatingFlag(true);
-
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context->engine);
-
- bool isUndefined = false;
-
- DeleteWatcher watcher(this);
- ep->referenceScarceResources();
-
- v8::HandleScope handle_scope;
- v8::Context::Scope scope(ep->v8engine()->context());
- v8::Local<v8::Value> result =
- evaluate(context,
- v8::Handle<v8::Function>::Cast(parent->functions()->Get(instruction->value)),
- &isUndefined);
-
- trace.event("writing V8 result");
- bool needsErrorLocationData = false;
- if (!watcher.wasDeleted() && !destroyedFlag() && !hasError()) {
- typedef QQmlPropertyPrivate PP;
- needsErrorLocationData = !PP::writeBinding(*target, instruction->property, context, this, result,
- isUndefined, flags);
- }
-
- if (!watcher.wasDeleted() && !destroyedFlag()) {
-
- if (needsErrorLocationData)
- delayedError()->setErrorLocation(parent->url(), instruction->line, 0);
-
- if (hasError()) {
- delayedError()->setErrorObject(object());
- if (!delayedError()->addError(ep)) ep->warning(this->error(context->engine));
- } else {
- clearError();
- }
-
- setUpdatingFlag(false);
- }
-
- ep->dereferenceScarceResources();
-
- } else {
- QQmlProperty p = QQmlPropertyPrivate::restore(*target, instruction->property, context);
- QQmlAbstractBinding::printBindingLoopError(p);
- }
-}
-
-QString QV8Bindings::Binding::expressionIdentifier(QQmlJavaScriptExpression *e)
-{
- Binding *This = static_cast<Binding *>(e);
- return This->parent->urlString() + QLatin1Char(':') +
- QString::number(qmlSourceCoordinate(This->instruction->line));
-}
-
-void QV8Bindings::Binding::expressionChanged(QQmlJavaScriptExpression *e)
-{
- Binding *This = static_cast<Binding *>(e);
- This->update(QQmlPropertyPrivate::DontRemoveBinding);
-}
-
-void QV8Bindings::Binding::destroy(QQmlAbstractBinding *_This, QQmlAbstractBinding::DestroyMode mode)
-{
- QV8Bindings::Binding *This = static_cast<QV8Bindings::Binding *>(_This);
-
- if (mode == QQmlAbstractBinding::DisconnectBinding)
- This->clearGuards();
-
- This->setEnabledFlag(false);
- This->setDestroyedFlag(true);
- This->removeFromObject();
- This->clear();
- This->clearError();
- This->parent->release();
-}
-
-QV8Bindings::QV8Bindings(QQmlCompiledData::V8Program *program,
- quint16 line,
- QQmlContextData *context)
-: program(program), bindings(0), refCount(1)
-{
- QV8Engine *engine = QQmlEnginePrivate::getV8Engine(context->engine);
-
- if (program->bindings.IsEmpty()) {
- v8::HandleScope handle_scope;
- v8::Context::Scope scope(engine->context());
-
- v8::Local<v8::Script> script;
- bool compileFailed = false;
- {
- v8::TryCatch try_catch;
- const QByteArray &source = program->program;
- script = engine->qmlModeCompile(source.constData(), source.length(),
- program->cdata->name, line);
- if (try_catch.HasCaught()) {
- // The binding was not compiled. There are some exceptional cases which the
- // expression rewriter does not rewrite properly (e.g., \r-terminated lines
- // are not rewritten correctly but this bug is demed out-of-scope to fix for
- // performance reasons; see QTBUG-24064).
- compileFailed = true;
- QQmlError error;
- error.setDescription(QString(QLatin1String("Exception occurred during compilation of binding at line: %1")).arg(line));
- v8::Local<v8::Message> message = try_catch.Message();
- if (!message.IsEmpty())
- QQmlExpressionPrivate::exceptionToError(message, error);
- QQmlEnginePrivate::get(engine->engine())->warning(error);
- program->bindings = qPersistentNew(v8::Array::New());
- }
- }
-
- if (!compileFailed) {
- v8::Local<v8::Value> result = script->Run(engine->contextWrapper()->sharedContext());
- if (result->IsArray()) {
- program->bindings = qPersistentNew(v8::Local<v8::Array>::Cast(result));
- program->program.clear(); // We don't need the source anymore
- }
- }
- }
-
- int bindingsCount = functions()->Length();
- if (bindingsCount) bindings = new QV8Bindings::Binding[bindingsCount];
-
- setContext(context);
-}
-
-QV8Bindings::~QV8Bindings()
-{
- program = 0;
-
- delete [] bindings;
- bindings = 0;
-}
-
-QQmlAbstractBinding *
-QV8Bindings::configBinding(QObject *target, QObject *scope,
- const QQmlInstruction::instr_assignBinding *i)
-{
- if (!bindings) // initialization failed.
- return 0;
-
- QV8Bindings::Binding *rv = bindings + i->value;
-
- rv->instruction = i;
- rv->target = target;
- rv->setScopeObject(scope);
- rv->setUseSharedContext(true);
- rv->setNotifyOnValueChanged(true);
- rv->parent = this;
-
- if (!i->isFallback)
- addref(); // This is decremented in Binding::destroy()
-
- return rv;
-}
-
-const QUrl &QV8Bindings::url() const
-{
- return program->cdata->url;
-}
-
-const QString &QV8Bindings::urlString() const
-{
- return program->cdata->name;
-}
-
-v8::Persistent<v8::Array> &QV8Bindings::functions() const
-{
- return program->bindings;
-}
-
-
-QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv8bindings_p.h b/src/qml/qml/v8/qv8bindings_p.h
deleted file mode 100644
index 98b367ac72..0000000000
--- a/src/qml/qml/v8/qv8bindings_p.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV8BINDINGS_P_H
-#define QV8BINDINGS_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 <private/qpointervaluepair_p.h>
-#include <private/qqmlpropertycache_p.h>
-#include <private/qqmlinstruction_p.h>
-#include <private/qqmlexpression_p.h>
-#include <private/qqmlcompiler_p.h>
-#include <private/qflagpointer_p.h>
-#include <private/qqmlbinding_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQmlCompiledData;
-
-class QV8BindingsPrivate;
-class QV8Bindings : public QQmlAbstractExpression
-{
-public:
- QV8Bindings(QQmlCompiledData::V8Program *,
- quint16 line,
- QQmlContextData *context);
- virtual ~QV8Bindings();
-
- QQmlAbstractBinding *configBinding(QObject *target, QObject *scope,
- const QQmlInstruction::instr_assignBinding *);
-
- // Inherited from QQmlAbstractExpression
- virtual void refresh();
-
- struct Binding : public QQmlJavaScriptExpression,
- public QQmlAbstractBinding {
- Binding();
-
- void update() { QQmlAbstractBinding::update(); }
- void refresh();
-
- // "Inherited" from QQmlJavaScriptExpression
- static QString expressionIdentifier(QQmlJavaScriptExpression *);
- static void expressionChanged(QQmlJavaScriptExpression *);
-
- // "Inherited" from QQmlAbstractBinding
- static void destroy(QQmlAbstractBinding *, QQmlAbstractBinding::DestroyMode mode);
- static int propertyIndex(const QQmlAbstractBinding *);
- static QObject *object(const QQmlAbstractBinding *);
- static void setEnabled(QQmlAbstractBinding *, bool, QQmlPropertyPrivate::WriteFlags);
- static void update(QQmlAbstractBinding *, QQmlPropertyPrivate::WriteFlags);
- static void retargetBinding(QQmlAbstractBinding *, QObject *, int);
-
- QObject *object() const;
- void update(QQmlPropertyPrivate::WriteFlags flags);
-
- void dump();
-
- QV8Bindings *parent;
-
- struct Retarget {
- QObject *target;
- int targetProperty;
- };
-
- // To save memory, we store flags inside the instruction pointer.
- // target.flag1: destroyed
- // instruction.flag1: enabled
- // instruction.flag2: updating
- QPointerValuePair<QObject, Retarget> target;
- QFlagPointer<const QQmlInstruction::instr_assignBinding> instruction;
-
- inline bool destroyedFlag() const { return target.flag(); }
- inline void setDestroyedFlag(bool v) { return target.setFlagValue(v); }
- inline bool enabledFlag() const { return instruction.flag(); }
- inline void setEnabledFlag(bool v) { instruction.setFlagValue(v); }
- inline bool updatingFlag() const { return instruction.flag2(); }
- inline void setUpdatingFlag(bool v) { instruction.setFlag2Value(v); }
- };
-
- inline void addref();
- inline void release();
-
- QQmlAbstractBinding *binding(int index) const { return bindings + index; }
-
-private:
- Q_DISABLE_COPY(QV8Bindings)
-
- const QUrl &url() const;
- const QString &urlString() const;
- v8::Persistent<v8::Array> &functions() const;
-
- QQmlCompiledData::V8Program *program;
- Binding *bindings;
- int refCount;
-};
-
-void QV8Bindings::addref()
-{
- ++refCount;
-}
-
-void QV8Bindings::release()
-{
- if (0 == --refCount)
- delete this;
-}
-
-QT_END_NAMESPACE
-
-#endif // QV8BINDINGS_P_H
-
-
diff --git a/src/qml/qml/v8/qv8contextwrapper.cpp b/src/qml/qml/v8/qv8contextwrapper.cpp
deleted file mode 100644
index 630a3e5a7c..0000000000
--- a/src/qml/qml/v8/qv8contextwrapper.cpp
+++ /dev/null
@@ -1,430 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv8contextwrapper_p.h"
-#include "qv8engine_p.h"
-
-#include <private/qqmlengine_p.h>
-#include <private/qqmlcontext_p.h>
-
-QT_BEGIN_NAMESPACE
-
-static QString internal(QLatin1String("You've stumbled onto an internal implementation detail "
- "that should never have been exposed."));
-
-class QV8ContextResource : public QV8ObjectResource
-{
- V8_RESOURCE_TYPE(ContextType)
-
-public:
- QV8ContextResource(QV8Engine *engine, QQmlContextData *context, QObject *scopeObject, bool ownsContext = false);
- ~QV8ContextResource();
-
- inline QQmlContextData *getContext() const;
- inline QObject *getScopeObject() const;
-
- quint32 isSharedContext:1;
- quint32 hasSubContexts:1;
- quint32 readOnly:1;
- quint32 ownsContext:1;
- quint32 dummy:28;
-
- // This is a pretty horrible hack, and an abuse of external strings. When we create a
- // sub-context (a context created by a Qt.include() in an external javascript file),
- // we pass a specially crafted SubContext external string as the v8::Script::Data() to
- // the script, which contains a pointer to the context. We can then access the
- // v8::Script::Data() later on to resolve names and URLs against the sub-context instead
- // of the main outer context.
- struct SubContext : public v8::String::ExternalStringResource {
- SubContext(QQmlContextData *context) : context(context) {}
- QQmlGuardedContextData context;
-
- virtual const uint16_t* data() const { return (const uint16_t *)internal.constData(); }
- virtual size_t length() const { return internal.length(); }
- };
-
-private:
- QQmlGuardedContextData context;
- QQmlGuard<QObject> scopeObject;
-
-};
-
-QV8ContextResource::QV8ContextResource(QV8Engine *engine, QQmlContextData *context, QObject *scopeObject, bool ownsContext)
-: QV8ObjectResource(engine), isSharedContext(false), hasSubContexts(false), readOnly(true),
- ownsContext(ownsContext), context(context), scopeObject(scopeObject)
-{
-}
-
-QV8ContextResource::~QV8ContextResource()
-{
- if (context && ownsContext)
- context->destroy();
-}
-
-// Returns the scope object
-QObject *QV8ContextResource::getScopeObject() const
-{
- if (isSharedContext)
- return QQmlEnginePrivate::get(engine->engine())->sharedScope;
- else
- return scopeObject;
-}
-
-// Returns the context, including resolving a subcontext
-QQmlContextData *QV8ContextResource::getContext() const
-{
- if (isSharedContext)
- return QQmlEnginePrivate::get(engine->engine())->sharedContext;
-
- if (!hasSubContexts)
- return context;
-
- v8::Local<v8::Value> callingdata = v8::Context::GetCallingScriptData();
- if (callingdata.IsEmpty() || !callingdata->IsString())
- return context;
-
- v8::Local<v8::String> callingstring = callingdata->ToString();
- Q_ASSERT(callingstring->IsExternal());
- Q_ASSERT(callingstring->GetExternalStringResource());
-
- SubContext *sc = static_cast<SubContext *>(callingstring->GetExternalStringResource());
- return sc->context;
-}
-
-QV8ContextWrapper::QV8ContextWrapper()
-: m_engine(0)
-{
-}
-
-QV8ContextWrapper::~QV8ContextWrapper()
-{
-}
-
-void QV8ContextWrapper::destroy()
-{
- qPersistentDispose(m_sharedContext);
- qPersistentDispose(m_urlConstructor);
- qPersistentDispose(m_constructor);
-}
-
-void QV8ContextWrapper::init(QV8Engine *engine)
-{
- m_engine = engine;
- {
- v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
- ft->InstanceTemplate()->SetHasExternalResource(true);
- ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter);
- m_constructor = qPersistentNew<v8::Function>(ft->GetFunction());
- }
- {
- v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
- ft->InstanceTemplate()->SetHasExternalResource(true);
- ft->InstanceTemplate()->SetFallbackPropertyHandler(NullGetter, NullSetter);
- m_urlConstructor = qPersistentNew<v8::Function>(ft->GetFunction());
- }
- {
- v8::Local<v8::Object> sharedContext = m_constructor->NewInstance();
- QV8ContextResource *r = new QV8ContextResource(engine, 0, 0);
- r->isSharedContext = true;
- sharedContext->SetExternalResource(r);
- m_sharedContext = qPersistentNew<v8::Object>(sharedContext);
- }
-}
-
-v8::Local<v8::Object> QV8ContextWrapper::qmlScope(QQmlContextData *ctxt, QObject *scope)
-{
- // XXX NewInstance() should be optimized
- v8::Local<v8::Object> rv = m_constructor->NewInstance();
- QV8ContextResource *r = new QV8ContextResource(m_engine, ctxt, scope);
- rv->SetExternalResource(r);
- return rv;
-}
-
-v8::Local<v8::Object> QV8ContextWrapper::urlScope(const QUrl &url)
-{
- QQmlContextData *context = new QQmlContextData;
- context->url = url;
- context->isInternal = true;
- context->isJSContext = true;
-
- // XXX NewInstance() should be optimized
- v8::Local<v8::Object> rv = m_urlConstructor->NewInstance();
- QV8ContextResource *r = new QV8ContextResource(m_engine, context, 0, true);
- rv->SetExternalResource(r);
- return rv;
-}
-
-void QV8ContextWrapper::setReadOnly(v8::Handle<v8::Object> qmlglobal, bool readOnly)
-{
- QV8ContextResource *resource = v8_resource_cast<QV8ContextResource>(qmlglobal);
- Q_ASSERT(resource);
- resource->readOnly = readOnly;
-}
-
-void QV8ContextWrapper::addSubContext(v8::Handle<v8::Object> qmlglobal, v8::Handle<v8::Script> script,
- QQmlContextData *ctxt)
-{
- QV8ContextResource *resource = v8_resource_cast<QV8ContextResource>(qmlglobal);
- Q_ASSERT(resource);
- resource->hasSubContexts = true;
- script->SetData(v8::String::NewExternal(new QV8ContextResource::SubContext(ctxt)));
-}
-
-QQmlContextData *QV8ContextWrapper::callingContext()
-{
- v8::Local<v8::Object> qmlglobal = v8::Context::GetCallingQmlGlobal();
- if (qmlglobal.IsEmpty()) return 0;
-
- QV8ContextResource *r = v8_resource_cast<QV8ContextResource>(qmlglobal);
- return r?r->getContext():0;
-}
-
-QQmlContextData *QV8ContextWrapper::context(v8::Handle<v8::Value> value)
-{
- if (!value->IsObject())
- return 0;
-
- v8::Handle<v8::Object> qmlglobal = v8::Handle<v8::Object>::Cast(value);
- QV8ContextResource *r = v8_resource_cast<QV8ContextResource>(qmlglobal);
- return r?r->getContext():0;
-}
-
-void QV8ContextWrapper::takeContextOwnership(v8::Handle<v8::Object> qmlglobal)
-{
- QV8ContextResource *r = v8_resource_cast<QV8ContextResource>(qmlglobal);
- r->ownsContext = true;
-}
-
-v8::Handle<v8::Value> QV8ContextWrapper::NullGetter(v8::Local<v8::String>,
- const v8::AccessorInfo &)
-{
- // V8 will throw a ReferenceError if appropriate ("typeof" should not throw)
- return v8::Handle<v8::Value>();
-}
-
-v8::Handle<v8::Value> QV8ContextWrapper::Getter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info)
-{
- QV8ContextResource *resource = v8_resource_check<QV8ContextResource>(info.This());
-
- // Its possible we could delay the calculation of the "actual" context (in the case
- // of sub contexts) until it is definately needed.
- QQmlContextData *context = resource->getContext();
- QQmlContextData *expressionContext = context;
-
- if (!context)
- return v8::Undefined();
-
- if (v8::Context::GetCallingQmlGlobal() != info.This())
- return v8::Handle<v8::Value>();
-
- // Search type (attached property/enum/imported scripts) names
- // while (context) {
- // Search context properties
- // Search scope object
- // Search context object
- // context = context->parent
- // }
-
- QV8Engine *engine = resource->engine;
-
- QObject *scopeObject = resource->getScopeObject();
-
- QHashedV8String propertystring(property);
-
- if (context->imports && QV8Engine::startsWithUpper(property)) {
- // Search for attached properties, enums and imported scripts
- QQmlTypeNameCache::Result r = context->imports->query(propertystring);
-
- if (r.isValid()) {
- if (r.scriptIndex != -1) {
- int index = r.scriptIndex;
- if (index < context->importedScripts.count())
- return context->importedScripts.at(index);
- else
- return v8::Undefined();
- } else if (r.type) {
- return engine->typeWrapper()->newObject(scopeObject, r.type);
- } else if (r.importNamespace) {
- return engine->typeWrapper()->newObject(scopeObject, context->imports, r.importNamespace);
- }
- Q_ASSERT(!"Unreachable");
- }
-
- // Fall through
- }
-
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine->engine());
- QV8QObjectWrapper *qobjectWrapper = engine->qobjectWrapper();
-
- while (context) {
- // Search context properties
- if (context->propertyNames) {
- int propertyIdx = context->propertyNames->value(propertystring);
-
- if (propertyIdx != -1) {
-
- if (propertyIdx < context->idValueCount) {
-
- ep->captureProperty(&context->idValues[propertyIdx].bindings);
- return engine->newQObject(context->idValues[propertyIdx]);
- } else {
-
- QQmlContextPrivate *cp = context->asQQmlContextPrivate();
-
- ep->captureProperty(context->asQQmlContext(), -1,
- propertyIdx + cp->notifyIndex);
-
- const QVariant &value = cp->propertyValues.at(propertyIdx);
- if (value.userType() == qMetaTypeId<QList<QObject*> >()) {
- QQmlListProperty<QObject> prop(context->asQQmlContext(), (void*) qintptr(propertyIdx),
- QQmlContextPrivate::context_count,
- QQmlContextPrivate::context_at);
- return engine->listWrapper()->newList(prop, qMetaTypeId<QQmlListProperty<QObject> >());
- } else {
- return engine->fromVariant(cp->propertyValues.at(propertyIdx));
- }
- }
- }
- }
-
- // Search scope object
- if (scopeObject) {
- v8::Handle<v8::Value> result = qobjectWrapper->getProperty(scopeObject, propertystring,
- context, QV8QObjectWrapper::CheckRevision);
- if (!result.IsEmpty()) return result;
- }
- scopeObject = 0;
-
-
- // Search context object
- if (context->contextObject) {
- v8::Handle<v8::Value> result = qobjectWrapper->getProperty(context->contextObject, propertystring,
- context, QV8QObjectWrapper::CheckRevision);
- if (!result.IsEmpty()) return result;
- }
-
- context = context->parent;
- }
-
- expressionContext->unresolvedNames = true;
-
- // V8 will throw a ReferenceError if appropriate ("typeof" should not throw)
- return v8::Handle<v8::Value>();
-}
-
-v8::Handle<v8::Value> QV8ContextWrapper::NullSetter(v8::Local<v8::String> property,
- v8::Local<v8::Value>,
- const v8::AccessorInfo &info)
-{
- QV8ContextResource *resource = v8_resource_check<QV8ContextResource>(info.This());
-
- QV8Engine *engine = resource->engine;
-
- if (!resource->readOnly) {
- return v8::Handle<v8::Value>();
- } else {
- QString error = QLatin1String("Invalid write to global property \"") + engine->toString(property) +
- QLatin1Char('"');
- v8::ThrowException(v8::Exception::Error(engine->toString(error)));
- return v8::Handle<v8::Value>();
- }
-}
-
-v8::Handle<v8::Value> QV8ContextWrapper::Setter(v8::Local<v8::String> property,
- v8::Local<v8::Value> value,
- const v8::AccessorInfo &info)
-{
- QV8ContextResource *resource = v8_resource_check<QV8ContextResource>(info.This());
-
- // Its possible we could delay the calculation of the "actual" context (in the case
- // of sub contexts) until it is definately needed.
- QQmlContextData *context = resource->getContext();
- QQmlContextData *expressionContext = context;
-
- if (!context)
- return v8::Undefined();
-
- if (v8::Context::GetCallingQmlGlobal() != info.This())
- return v8::Handle<v8::Value>();
-
- // See QV8ContextWrapper::Getter for resolution order
-
- QV8Engine *engine = resource->engine;
- QObject *scopeObject = resource->getScopeObject();
-
- QHashedV8String propertystring(property);
-
- QV8QObjectWrapper *qobjectWrapper = engine->qobjectWrapper();
-
- while (context) {
- // Search context properties
- if (context->propertyNames && -1 != context->propertyNames->value(propertystring))
- return value;
-
- // Search scope object
- if (scopeObject &&
- qobjectWrapper->setProperty(scopeObject, propertystring, context, value, QV8QObjectWrapper::CheckRevision))
- return value;
- scopeObject = 0;
-
- // Search context object
- if (context->contextObject &&
- qobjectWrapper->setProperty(context->contextObject, propertystring, context, value,
- QV8QObjectWrapper::CheckRevision))
- return value;
-
- context = context->parent;
- }
-
- expressionContext->unresolvedNames = true;
-
- if (!resource->readOnly) {
- return v8::Handle<v8::Value>();
- } else {
- QString error = QLatin1String("Invalid write to global property \"") + engine->toString(property) +
- QLatin1Char('"');
- v8::ThrowException(v8::Exception::Error(engine->toString(error)));
- return v8::Undefined();
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv8contextwrapper_p.h b/src/qml/qml/v8/qv8contextwrapper_p.h
deleted file mode 100644
index 3e14a019a7..0000000000
--- a/src/qml/qml/v8/qv8contextwrapper_p.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV8CONTEXTWRAPPER_P_H
-#define QV8CONTEXTWRAPPER_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/qglobal.h>
-#include <private/qtqmlglobal_p.h>
-#include <private/qv8_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QUrl;
-class QObject;
-class QV8Engine;
-class QQmlContextData;
-class Q_QML_PRIVATE_EXPORT QV8ContextWrapper
-{
-public:
- QV8ContextWrapper();
- ~QV8ContextWrapper();
-
- void init(QV8Engine *);
- void destroy();
-
- v8::Local<v8::Object> qmlScope(QQmlContextData *ctxt, QObject *scope);
- v8::Local<v8::Object> urlScope(const QUrl &);
-
- void setReadOnly(v8::Handle<v8::Object>, bool);
-
- void addSubContext(v8::Handle<v8::Object> qmlglobal, v8::Handle<v8::Script>,
- QQmlContextData *ctxt);
-
- QQmlContextData *callingContext();
- QQmlContextData *context(v8::Handle<v8::Value>);
-
- inline v8::Handle<v8::Object> sharedContext() const;
-
- void takeContextOwnership(v8::Handle<v8::Object> qmlglobal);
-
-private:
- static v8::Handle<v8::Value> NullGetter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> NullSetter(v8::Local<v8::String> property,
- v8::Local<v8::Value> value,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> Setter(v8::Local<v8::String> property,
- v8::Local<v8::Value> value,
- const v8::AccessorInfo &info);
-
- QV8Engine *m_engine;
- v8::Persistent<v8::Function> m_constructor;
- v8::Persistent<v8::Function> m_urlConstructor;
- v8::Persistent<v8::Object> m_sharedContext;
-};
-
-v8::Handle<v8::Object> QV8ContextWrapper::sharedContext() const
-{
- return m_sharedContext;
-}
-
-QT_END_NAMESPACE
-
-#endif // QV8CONTEXTWRAPPER_P_H
-
diff --git a/src/qml/qml/v8/qv8debug_p.h b/src/qml/qml/v8/qv8debug_p.h
index 6576839e42..87e4e13c7d 100644
--- a/src/qml/qml/v8/qv8debug_p.h
+++ b/src/qml/qml/v8/qv8debug_p.h
@@ -39,4 +39,4 @@
**
****************************************************************************/
-#include <private/v8-debug.h>
+//#include <private/v8-debug.h>
diff --git a/src/qml/qml/v8/qv8domerrors.cpp b/src/qml/qml/v8/qv8domerrors.cpp
deleted file mode 100644
index d3a36f75c1..0000000000
--- a/src/qml/qml/v8/qv8domerrors.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv8domerrors_p.h"
-#include "qv8engine_p.h"
-
-QT_BEGIN_NAMESPACE
-
-void qt_add_domexceptions(QV8Engine *engine)
-{
- // DOM Exception
- v8::PropertyAttribute attributes = (v8::PropertyAttribute)(v8::ReadOnly | v8::DontEnum | v8::DontDelete);
-
- v8::Local<v8::Object> domexception = v8::Object::New();
- domexception->Set(v8::String::New("INDEX_SIZE_ERR"), v8::Integer::New(DOMEXCEPTION_INDEX_SIZE_ERR), attributes);
- domexception->Set(v8::String::New("DOMSTRING_SIZE_ERR"), v8::Integer::New(DOMEXCEPTION_DOMSTRING_SIZE_ERR), attributes);
- domexception->Set(v8::String::New("HIERARCHY_REQUEST_ERR"), v8::Integer::New(DOMEXCEPTION_HIERARCHY_REQUEST_ERR), attributes);
- domexception->Set(v8::String::New("WRONG_DOCUMENT_ERR"), v8::Integer::New(DOMEXCEPTION_WRONG_DOCUMENT_ERR), attributes);
- domexception->Set(v8::String::New("INVALID_CHARACTER_ERR"), v8::Integer::New(DOMEXCEPTION_INVALID_CHARACTER_ERR), attributes);
- domexception->Set(v8::String::New("NO_DATA_ALLOWED_ERR"), v8::Integer::New(DOMEXCEPTION_NO_DATA_ALLOWED_ERR), attributes);
- domexception->Set(v8::String::New("NO_MODIFICATION_ALLOWED_ERR"), v8::Integer::New(DOMEXCEPTION_NO_MODIFICATION_ALLOWED_ERR), attributes);
- domexception->Set(v8::String::New("NOT_FOUND_ERR"), v8::Integer::New(DOMEXCEPTION_NOT_FOUND_ERR), attributes);
- domexception->Set(v8::String::New("NOT_SUPPORTED_ERR"), v8::Integer::New(DOMEXCEPTION_NOT_SUPPORTED_ERR), attributes);
- domexception->Set(v8::String::New("INUSE_ATTRIBUTE_ERR"), v8::Integer::New(DOMEXCEPTION_INUSE_ATTRIBUTE_ERR), attributes);
- domexception->Set(v8::String::New("INVALID_STATE_ERR"), v8::Integer::New(DOMEXCEPTION_INVALID_STATE_ERR), attributes);
- domexception->Set(v8::String::New("SYNTAX_ERR"), v8::Integer::New(DOMEXCEPTION_SYNTAX_ERR), attributes);
- domexception->Set(v8::String::New("INVALID_MODIFICATION_ERR"), v8::Integer::New(DOMEXCEPTION_INVALID_MODIFICATION_ERR), attributes);
- domexception->Set(v8::String::New("NAMESPACE_ERR"), v8::Integer::New(DOMEXCEPTION_NAMESPACE_ERR), attributes);
- domexception->Set(v8::String::New("INVALID_ACCESS_ERR"), v8::Integer::New(DOMEXCEPTION_INVALID_ACCESS_ERR), attributes);
- domexception->Set(v8::String::New("VALIDATION_ERR"), v8::Integer::New(DOMEXCEPTION_VALIDATION_ERR), attributes);
- domexception->Set(v8::String::New("TYPE_MISMATCH_ERR"), v8::Integer::New(DOMEXCEPTION_TYPE_MISMATCH_ERR), attributes);
- engine->global()->Set(v8::String::New("DOMException"), domexception);
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index e80da46fc9..51605cead7 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -41,10 +41,7 @@
#include "qv8engine_p.h"
-#include "qv8contextwrapper_p.h"
-#include "qv8valuetypewrapper_p.h"
-#include "qv8sequencewrapper_p.h"
-#include "qv8include_p.h"
+#include "qv4sequenceobject_p.h"
#include "qjsengine_p.h"
#include <private/qqmlbuiltinfunctions_p.h>
@@ -55,14 +52,31 @@
#include <private/qqmlglobal_p.h>
#include <private/qqmlmemoryprofiler_p.h>
#include <private/qqmlplatform_p.h>
+#include <private/qjsvalue_p.h>
+#include <private/qqmltypewrapper_p.h>
+#include <private/qqmlcontextwrapper_p.h>
+#include <private/qqmlvaluetypewrapper_p.h>
+#include <private/qqmllistwrapper_p.h>
-#include "qscript_impl_p.h"
-#include "qv8domerrors_p.h"
-#include "qv8sqlerrors_p.h"
+#include "qv4domerrors_p.h"
+#include "qv4sqlerrors_p.h"
#include <QtCore/qjsonarray.h>
#include <QtCore/qjsonobject.h>
#include <QtCore/qjsonvalue.h>
+#include <QtCore/qdatetime.h>
+
+#include <private/qv4value_p.h>
+#include <private/qv4dateobject_p.h>
+#include <private/qv4objectiterator_p.h>
+#include <private/qv4mm_p.h>
+#include <private/qv4objectproto_p.h>
+#include <private/qv4globalobject_p.h>
+#include <private/qv4regexpobject_p.h>
+#include <private/qv4variantobject_p.h>
+#include <private/qv4script_p.h>
+#include <private/qv4include_p.h>
+#include <private/qv4jsonobject_p.h>
Q_DECLARE_METATYPE(QList<int>)
@@ -71,107 +85,25 @@ Q_DECLARE_METATYPE(QList<int>)
// QQmlEngine is not available
QT_BEGIN_NAMESPACE
-static bool ObjectComparisonCallback(v8::Local<v8::Object> lhs, v8::Local<v8::Object> rhs)
-{
- if (lhs == rhs)
- return true;
-
- if (lhs.IsEmpty() || rhs.IsEmpty())
- return false;
- QV8ObjectResource *lhsr = static_cast<QV8ObjectResource*>(lhs->GetExternalResource());
- QV8ObjectResource *rhsr = static_cast<QV8ObjectResource*>(rhs->GetExternalResource());
-
- if (lhsr && rhsr) {
- Q_ASSERT(lhsr->engine == rhsr->engine);
- QV8ObjectResource::ResourceType lhst = lhsr->resourceType();
- QV8ObjectResource::ResourceType rhst = rhsr->resourceType();
-
- switch (lhst) {
- case QV8ObjectResource::ValueTypeType:
- // a value type might be equal to a variant or another value type
- if (rhst == QV8ObjectResource::ValueTypeType) {
- return lhsr->engine->valueTypeWrapper()->isEqual(lhsr, lhsr->engine->valueTypeWrapper()->toVariant(rhsr));
- } else if (rhst == QV8ObjectResource::VariantType) {
- return lhsr->engine->valueTypeWrapper()->isEqual(lhsr, lhsr->engine->variantWrapper()->toVariant(rhsr));
- }
- break;
- case QV8ObjectResource::VariantType:
- // a variant might be equal to a value type or other variant.
- if (rhst == QV8ObjectResource::VariantType) {
- return lhsr->engine->variantWrapper()->toVariant(lhsr) ==
- lhsr->engine->variantWrapper()->toVariant(rhsr);
- } else if (rhst == QV8ObjectResource::ValueTypeType) {
- return rhsr->engine->valueTypeWrapper()->isEqual(rhsr, rhsr->engine->variantWrapper()->toVariant(lhsr));
- }
- break;
- case QV8ObjectResource::SequenceType:
- // a sequence might be equal to itself.
- if (rhst == QV8ObjectResource::SequenceType) {
- return lhsr->engine->sequenceWrapper()->isEqual(lhsr, rhsr);
- }
- break;
- default:
- break;
- }
- }
-
- return false;
-}
-
-
-QV8Engine::QV8Engine(QJSEngine* qq, ContextOwnership ownership)
+QV8Engine::QV8Engine(QJSEngine* qq)
: q(qq)
, m_engine(0)
- , m_ownsV8Context(ownership == CreateNewContext)
, m_xmlHttpRequestData(0)
, m_listModelData(0)
- , m_platform(0)
- , m_application(0)
{
QML_MEMORY_SCOPE_STRING("QV8Engine::QV8Engine");
qMetaTypeId<QJSValue>();
qMetaTypeId<QList<int> >();
- QByteArray v8args = qgetenv("V8ARGS");
- // change default v8 behaviour to not relocate breakpoints across lines
- if (!v8args.contains("breakpoint_relocation"))
- v8args.append(" --nobreakpoint_relocation");
- v8::V8::SetFlagsFromString(v8args.constData(), v8args.length());
-
- ensurePerThreadIsolate();
-
- v8::HandleScope handle_scope;
- m_context = (ownership == CreateNewContext) ? v8::Context::New() : v8::Persistent<v8::Context>::New(v8::Context::GetCurrent());
- qPersistentRegister(m_context);
- m_originalGlobalObject.init(m_context);
- v8::Context::Scope context_scope(m_context);
-
- v8::V8::SetUserObjectComparisonCallbackFunction(ObjectComparisonCallback);
- QV8GCCallback::registerGcPrologueCallback();
- m_strongReferencer = qPersistentNew(v8::Object::New());
-
- m_bindingFlagKey = qPersistentNew(v8::String::New("qml::binding"));
+ m_v4Engine = new QV4::ExecutionEngine;
+ m_v4Engine->v8Engine = this;
- m_stringWrapper.init();
- m_contextWrapper.init(this);
- m_qobjectWrapper.init(this);
- m_typeWrapper.init(this);
- m_listWrapper.init(this);
- m_variantWrapper.init(this);
- m_valueTypeWrapper.init(this);
- m_sequenceWrapper.init(this);
- m_jsonWrapper.init(this);
-
- {
- v8::Handle<v8::Value> v = global()->Get(v8::String::New("Object"))->ToObject()->Get(v8::String::New("getOwnPropertyNames"));
- m_getOwnPropertyNames = qPersistentNew<v8::Function>(v8::Handle<v8::Function>::Cast(v));
- }
+ QV4::QObjectWrapper::initializeBindings(m_v4Engine);
}
QV8Engine::~QV8Engine()
{
- Q_ASSERT_X(v8::Isolate::GetCurrent(), "QV8Engine::~QV8Engine()", "called after v8::Isolate has exited");
for (int ii = 0; ii < m_extensionData.count(); ++ii)
delete m_extensionData[ii];
m_extensionData.clear();
@@ -181,105 +113,52 @@ QV8Engine::~QV8Engine()
delete m_listModelData;
m_listModelData = 0;
- qPersistentDispose(m_freezeObject);
- qPersistentDispose(m_getOwnPropertyNames);
-
- invalidateAllValues();
-
- qPersistentDispose(m_strongReferencer);
-
- m_jsonWrapper.destroy();
- m_sequenceWrapper.destroy();
- m_valueTypeWrapper.destroy();
- m_variantWrapper.destroy();
- m_listWrapper.destroy();
- m_typeWrapper.destroy();
- m_qobjectWrapper.destroy();
- m_contextWrapper.destroy();
- m_stringWrapper.destroy();
-
- qPersistentDispose(m_bindingFlagKey);
-
- m_originalGlobalObject.destroy();
-
- if (m_ownsV8Context)
- qPersistentDispose(m_context);
-}
-
-QString QV8Engine::toStringStatic(v8::Handle<v8::Value> jsstr)
-{
- return toStringStatic(jsstr->ToString());
-}
-
-QString QV8Engine::toStringStatic(v8::Handle<v8::String> jsstr)
-{
- QString qstr;
- qstr.resize(jsstr->Length());
- jsstr->Write((uint16_t*)qstr.data());
- return qstr;
+ delete m_v4Engine;
}
-QVariant QV8Engine::toVariant(v8::Handle<v8::Value> value, int typeHint)
+QVariant QV8Engine::toVariant(const QV4::Value &value, int typeHint)
{
- if (value.IsEmpty())
+ if (value.isEmpty())
return QVariant();
+ if (QV4::VariantObject *v = value.as<QV4::VariantObject>())
+ return v->data;
+
if (typeHint == QVariant::Bool)
- return QVariant(value->BooleanValue());
+ return QVariant(value.toBoolean());
if (typeHint == QMetaType::QJsonValue)
- return QVariant::fromValue(jsonValueFromJS(value));
+ return QVariant::fromValue(QV4::JsonObject::toJsonValue(value));
if (typeHint == qMetaTypeId<QJSValue>())
- return QVariant::fromValue(scriptValueFromInternal(value));
-
- if (value->IsObject()) {
- QV8ObjectResource *r = (QV8ObjectResource *)value->ToObject()->GetExternalResource();
- if (r) {
- switch (r->resourceType()) {
- case QV8ObjectResource::Context2DStyleType:
- case QV8ObjectResource::Context2DPixelArrayType:
- case QV8ObjectResource::SignalHandlerType:
- case QV8ObjectResource::IncubatorType:
- case QV8ObjectResource::VisualDataItemType:
- case QV8ObjectResource::ContextType:
- case QV8ObjectResource::XMLHttpRequestType:
- case QV8ObjectResource::DOMNodeType:
- case QV8ObjectResource::SQLDatabaseType:
- case QV8ObjectResource::ListModelType:
- case QV8ObjectResource::Context2DType:
- case QV8ObjectResource::ParticleDataType:
- case QV8ObjectResource::LocaleDataType:
- case QV8ObjectResource::ChangeSetArrayType:
- return QVariant();
- case QV8ObjectResource::TypeType:
- return m_typeWrapper.toVariant(r);
- case QV8ObjectResource::QObjectType:
- return qVariantFromValue<QObject *>(m_qobjectWrapper.toQObject(r));
- case QV8ObjectResource::ListType:
- return m_listWrapper.toVariant(r);
- case QV8ObjectResource::VariantType:
- return m_variantWrapper.toVariant(r);
- case QV8ObjectResource::ValueTypeType:
- return m_valueTypeWrapper.toVariant(r);
- case QV8ObjectResource::SequenceType:
- return m_sequenceWrapper.toVariant(r);
- }
- } else if (typeHint == QMetaType::QJsonObject
- && !value->IsArray() && !value->IsFunction()) {
- return QVariant::fromValue(jsonObjectFromJS(value));
- }
- }
-
- if (value->IsArray()) {
- v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value);
+ return QVariant::fromValue(QJSValue(new QJSValuePrivate(m_v4Engine, value)));
+
+ if (QV4::Object *object = value.asObject()) {
+ if (typeHint == QMetaType::QJsonObject
+ && !value.asArrayObject() && !value.asFunctionObject()) {
+ return QVariant::fromValue(QV4::JsonObject::toJsonObject(object));
+ } else if (QV4::QObjectWrapper *wrapper = object->as<QV4::QObjectWrapper>()) {
+ return qVariantFromValue<QObject *>(wrapper->object());
+ } else if (QV4::QmlContextWrapper *wrapper = object->as<QV4::QmlContextWrapper>()) {
+ return QVariant();
+ } else if (QV4::QmlTypeWrapper *w = object->as<QV4::QmlTypeWrapper>()) {
+ return w->toVariant();
+ } else if (QV4::QmlValueTypeWrapper *v = object->as<QV4::QmlValueTypeWrapper>()) {
+ return v->toVariant();
+ } else if (QV4::QmlListWrapper *l = object->as<QV4::QmlListWrapper>()) {
+ return l->toVariant();
+ } else if (object->isListType())
+ return QV4::SequencePrototype::toVariant(object);
+ }
+
+ if (QV4::ArrayObject *a = value.asArrayObject()) {
if (typeHint == qMetaTypeId<QList<QObject *> >()) {
QList<QObject *> list;
- uint32_t length = array->Length();
+ uint32_t length = a->arrayLength();
for (uint32_t ii = 0; ii < length; ++ii) {
- v8::Local<v8::Value> arrayItem = array->Get(ii);
- if (arrayItem->IsObject()) {
- list << toQObject(arrayItem->ToObject());
+ QV4::Value arrayItem = a->getIndexed(ii);
+ if (QV4::QObjectWrapper *qobjectWrapper = arrayItem.as<QV4::QObjectWrapper>()) {
+ list << qobjectWrapper->object();
} else {
list << 0;
}
@@ -287,11 +166,11 @@ QVariant QV8Engine::toVariant(v8::Handle<v8::Value> value, int typeHint)
return qVariantFromValue<QList<QObject*> >(list);
} else if (typeHint == QMetaType::QJsonArray) {
- return QVariant::fromValue(jsonArrayFromJS(value));
+ return QVariant::fromValue(QV4::JsonObject::toJsonArray(a));
}
bool succeeded = false;
- QVariant retn = m_sequenceWrapper.toVariant(array, typeHint, &succeeded);
+ QVariant retn = QV4::SequencePrototype::toVariant(value, typeHint, &succeeded);
if (succeeded)
return retn;
}
@@ -299,36 +178,44 @@ QVariant QV8Engine::toVariant(v8::Handle<v8::Value> value, int typeHint)
return toBasicVariant(value);
}
-static v8::Handle<v8::Array> arrayFromStringList(QV8Engine *engine, const QStringList &list)
+static QV4::Value arrayFromStringList(QV8Engine *engine, const QStringList &list)
{
- v8::Context::Scope scope(engine->context());
- v8::Local<v8::Array> result = v8::Array::New(list.count());
- for (int ii = 0; ii < list.count(); ++ii)
- result->Set(ii, engine->toString(list.at(ii)));
- return result;
+ QV4::ExecutionEngine *e = QV8Engine::getV4(engine);
+ QV4::ArrayObject *a = e->newArrayObject();
+ int len = list.count();
+ a->arrayReserve(len);
+ for (int ii = 0; ii < len; ++ii)
+ a->arrayData[ii].value = QV4::Value::fromString(e->newString(list.at(ii)));
+ a->arrayDataLen = len;
+ a->setArrayLengthUnchecked(len);
+ return QV4::Value::fromObject(a);
}
-static v8::Handle<v8::Array> arrayFromVariantList(QV8Engine *engine, const QVariantList &list)
+static QV4::Value arrayFromVariantList(QV8Engine *engine, const QVariantList &list)
{
- v8::Context::Scope scope(engine->context());
- v8::Local<v8::Array> result = v8::Array::New(list.count());
- for (int ii = 0; ii < list.count(); ++ii)
- result->Set(ii, engine->fromVariant(list.at(ii)));
- return result;
+ QV4::ExecutionEngine *e = QV8Engine::getV4(engine);
+ QV4::ArrayObject *a = e->newArrayObject();
+ int len = list.count();
+ a->arrayReserve(len);
+ for (int ii = 0; ii < len; ++ii)
+ a->arrayData[ii].value = engine->fromVariant(list.at(ii));
+ a->arrayDataLen = len;
+ a->setArrayLengthUnchecked(len);
+ return QV4::Value::fromObject(a);
}
-static v8::Handle<v8::Object> objectFromVariantMap(QV8Engine *engine, const QVariantMap &map)
+static QV4::Value objectFromVariantMap(QV8Engine *engine, const QVariantMap &map)
{
- v8::Context::Scope scope(engine->context());
- v8::Local<v8::Object> object = v8::Object::New();
+ QV4::ExecutionEngine *e = QV8Engine::getV4(engine);
+ QV4::Object *o = e->newObject();
for (QVariantMap::ConstIterator iter = map.begin(); iter != map.end(); ++iter)
- object->Set(engine->toString(iter.key()), engine->fromVariant(iter.value()));
- return object;
+ o->put(e->newString(iter.key()), engine->fromVariant(iter.value()));
+ return QV4::Value::fromObject(o);
}
Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax);
-v8::Handle<v8::Value> QV8Engine::fromVariant(const QVariant &variant)
+QV4::Value QV8Engine::fromVariant(const QVariant &variant)
{
int type = variant.userType();
const void *ptr = variant.constData();
@@ -337,47 +224,47 @@ v8::Handle<v8::Value> QV8Engine::fromVariant(const QVariant &variant)
switch (QMetaType::Type(type)) {
case QMetaType::UnknownType:
case QMetaType::Void:
- return v8::Undefined();
+ return QV4::Value::undefinedValue();
case QMetaType::Bool:
- return v8::Boolean::New(*reinterpret_cast<const bool*>(ptr));
+ return QV4::Value::fromBoolean(*reinterpret_cast<const bool*>(ptr));
case QMetaType::Int:
- return v8::Integer::New(*reinterpret_cast<const int*>(ptr));
+ return QV4::Value::fromInt32(*reinterpret_cast<const int*>(ptr));
case QMetaType::UInt:
- return v8::Integer::NewFromUnsigned(*reinterpret_cast<const uint*>(ptr));
+ return QV4::Value::fromUInt32(*reinterpret_cast<const uint*>(ptr));
case QMetaType::LongLong:
- return v8::Number::New(*reinterpret_cast<const qlonglong*>(ptr));
+ return QV4::Value::fromDouble(*reinterpret_cast<const qlonglong*>(ptr));
case QMetaType::ULongLong:
- return v8::Number::New(*reinterpret_cast<const qulonglong*>(ptr));
+ return QV4::Value::fromDouble(*reinterpret_cast<const qulonglong*>(ptr));
case QMetaType::Double:
- return v8::Number::New(*reinterpret_cast<const double*>(ptr));
+ return QV4::Value::fromDouble(*reinterpret_cast<const double*>(ptr));
case QMetaType::QString:
- return m_stringWrapper.toString(*reinterpret_cast<const QString*>(ptr));
+ return QV4::Value::fromString(m_v4Engine->current, *reinterpret_cast<const QString*>(ptr));
case QMetaType::Float:
- return v8::Number::New(*reinterpret_cast<const float*>(ptr));
+ return QV4::Value::fromDouble(*reinterpret_cast<const float*>(ptr));
case QMetaType::Short:
- return v8::Integer::New(*reinterpret_cast<const short*>(ptr));
+ return QV4::Value::fromInt32(*reinterpret_cast<const short*>(ptr));
case QMetaType::UShort:
- return v8::Integer::NewFromUnsigned(*reinterpret_cast<const unsigned short*>(ptr));
+ return QV4::Value::fromUInt32(*reinterpret_cast<const unsigned short*>(ptr));
case QMetaType::Char:
- return v8::Integer::New(*reinterpret_cast<const char*>(ptr));
+ return QV4::Value::fromInt32(*reinterpret_cast<const char*>(ptr));
case QMetaType::UChar:
- return v8::Integer::NewFromUnsigned(*reinterpret_cast<const unsigned char*>(ptr));
+ return QV4::Value::fromUInt32(*reinterpret_cast<const unsigned char*>(ptr));
case QMetaType::QChar:
- return v8::Integer::New((*reinterpret_cast<const QChar*>(ptr)).unicode());
+ return QV4::Value::fromInt32((*reinterpret_cast<const QChar*>(ptr)).unicode());
case QMetaType::QDateTime:
- return v8::Date::New(qtDateTimeToJsDate(*reinterpret_cast<const QDateTime *>(ptr)));
+ return QV4::Value::fromObject(m_v4Engine->newDateObject(*reinterpret_cast<const QDateTime *>(ptr)));
case QMetaType::QDate:
- return v8::Date::New(qtDateTimeToJsDate(QDateTime(*reinterpret_cast<const QDate *>(ptr))));
+ return QV4::Value::fromObject(m_v4Engine->newDateObject(QDateTime(*reinterpret_cast<const QDate *>(ptr))));
case QMetaType::QTime:
- return v8::Date::New(qtDateTimeToJsDate(QDateTime(QDate(1970,1,1), *reinterpret_cast<const QTime *>(ptr))));
+ return QV4::Value::fromObject(m_v4Engine->newDateObject(QDateTime(QDate(1970,1,1), *reinterpret_cast<const QTime *>(ptr))));
case QMetaType::QRegExp:
- return QJSConverter::toRegExp(*reinterpret_cast<const QRegExp *>(ptr));
+ return QV4::Value::fromObject(m_v4Engine->newRegExpObject(*reinterpret_cast<const QRegExp *>(ptr)));
case QMetaType::QObjectStar:
- return newQObject(*reinterpret_cast<QObject* const *>(ptr));
+ return QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast<QObject* const *>(ptr));
case QMetaType::QStringList:
{
bool succeeded = false;
- v8::Handle<v8::Value> retn = m_sequenceWrapper.fromVariant(variant, &succeeded);
+ QV4::Value retn = QV4::SequencePrototype::fromVariant(m_v4Engine, variant, &succeeded);
if (succeeded)
return retn;
return arrayFromStringList(this, *reinterpret_cast<const QStringList *>(ptr));
@@ -387,97 +274,63 @@ v8::Handle<v8::Value> QV8Engine::fromVariant(const QVariant &variant)
case QMetaType::QVariantMap:
return objectFromVariantMap(this, *reinterpret_cast<const QVariantMap *>(ptr));
case QMetaType::QJsonValue:
- return jsonValueToJS(*reinterpret_cast<const QJsonValue *>(ptr));
+ return QV4::JsonObject::fromJsonValue(m_v4Engine, *reinterpret_cast<const QJsonValue *>(ptr));
case QMetaType::QJsonObject:
- return jsonObjectToJS(*reinterpret_cast<const QJsonObject *>(ptr));
+ return QV4::JsonObject::fromJsonObject(m_v4Engine, *reinterpret_cast<const QJsonObject *>(ptr));
case QMetaType::QJsonArray:
- return jsonArrayToJS(*reinterpret_cast<const QJsonArray *>(ptr));
+ return QV4::JsonObject::fromJsonArray(m_v4Engine, *reinterpret_cast<const QJsonArray *>(ptr));
default:
break;
}
if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(type))
- return m_valueTypeWrapper.newValueType(variant, vt);
+ return QV4::QmlValueTypeWrapper::create(this, variant, vt);
} else {
if (type == qMetaTypeId<QQmlListReference>()) {
typedef QQmlListReferencePrivate QDLRP;
QDLRP *p = QDLRP::get((QQmlListReference*)ptr);
if (p->object) {
- return m_listWrapper.newList(p->property, p->propertyType);
+ return QV4::QmlListWrapper::create(this, p->property, p->propertyType);
} else {
- return v8::Null();
+ return QV4::Value::nullValue();
}
} else if (type == qMetaTypeId<QJSValue>()) {
const QJSValue *value = reinterpret_cast<const QJSValue *>(ptr);
QJSValuePrivate *valuep = QJSValuePrivate::get(*value);
- if (valuep->assignEngine(this))
- return v8::Local<v8::Value>::New(*valuep);
+ return valuep->getValue(m_v4Engine);
} else if (type == qMetaTypeId<QList<QObject *> >()) {
// XXX Can this be made more by using Array as a prototype and implementing
// directly against QList<QObject*>?
const QList<QObject *> &list = *(QList<QObject *>*)ptr;
- v8::Local<v8::Array> array = v8::Array::New(list.count());
+ QV4::ArrayObject *a = m_v4Engine->newArrayObject();
+ a->arrayReserve(list.count());
for (int ii = 0; ii < list.count(); ++ii)
- array->Set(ii, newQObject(list.at(ii)));
- return array;
+ a->arrayData[ii].value = QV4::QObjectWrapper::wrap(m_v4Engine, list.at(ii));
+ a->arrayDataLen = list.count();
+ a->setArrayLengthUnchecked(list.count());
+ return QV4::Value::fromObject(a);
}
bool objOk;
QObject *obj = QQmlMetaType::toQObject(variant, &objOk);
if (objOk)
- return newQObject(obj);
+ return QV4::QObjectWrapper::wrap(m_v4Engine, obj);
bool succeeded = false;
- v8::Handle<v8::Value> retn = m_sequenceWrapper.fromVariant(variant, &succeeded);
+ QV4::Value retn = QV4::SequencePrototype::fromVariant(m_v4Engine, variant, &succeeded);
if (succeeded)
return retn;
if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(type))
- return m_valueTypeWrapper.newValueType(variant, vt);
+ return QV4::QmlValueTypeWrapper::create(this, variant, vt);
}
// XXX TODO: To be compatible, we still need to handle:
// + QObjectList
// + QList<int>
- return m_variantWrapper.newVariant(variant);
-}
-
-// A handle scope and context must be entered
-v8::Local<v8::Script> QV8Engine::qmlModeCompile(const QString &source,
- const QString &fileName,
- quint16 lineNumber)
-{
- v8::Local<v8::String> v8source = m_stringWrapper.toString(source);
- v8::Local<v8::String> v8fileName = m_stringWrapper.toString(fileName);
-
- v8::ScriptOrigin origin(v8fileName, v8::Integer::New(lineNumber - 1));
-
- v8::Local<v8::Script> script = v8::Script::Compile(v8source, &origin, 0, v8::Handle<v8::String>(),
- v8::Script::QmlMode);
-
- return script;
-}
-
-// A handle scope and context must be entered.
-// source can be either ascii or utf8.
-v8::Local<v8::Script> QV8Engine::qmlModeCompile(const char *source, int sourceLength,
- const QString &fileName,
- quint16 lineNumber)
-{
- if (sourceLength == -1)
- sourceLength = int(strlen(source));
-
- v8::Local<v8::String> v8source = v8::String::New(source, sourceLength);
- v8::Local<v8::String> v8fileName = m_stringWrapper.toString(fileName);
-
- v8::ScriptOrigin origin(v8fileName, v8::Integer::New(lineNumber - 1));
-
- v8::Local<v8::Script> script = v8::Script::Compile(v8source, &origin, 0, v8::Handle<v8::String>(),
- v8::Script::QmlMode);
-
- return script;
+ return QV4::Value::fromObject(m_v4Engine->newVariantObject(variant));
}
QNetworkAccessManager *QV8Engine::networkAccessManager()
@@ -490,22 +343,9 @@ const QStringHash<bool> &QV8Engine::illegalNames() const
return m_illegalNames;
}
-// Requires a handle scope
-v8::Local<v8::Array> QV8Engine::getOwnPropertyNames(v8::Handle<v8::Object> o)
-{
- // FIXME Newer v8 have API for this function
- v8::TryCatch tc;
- v8::Handle<v8::Value> args[] = { o };
- v8::Local<v8::Value> r = m_getOwnPropertyNames->Call(global(), 1, args);
- if (tc.HasCaught())
- return v8::Array::New();
- else
- return v8::Local<v8::Array>::Cast(r);
-}
-
QQmlContextData *QV8Engine::callingContext()
{
- return m_contextWrapper.callingContext();
+ return QV4::QmlContextWrapper::callingContext(m_v4Engine);
}
// Converts a JS value to a QVariant.
@@ -517,178 +357,58 @@ QQmlContextData *QV8Engine::callingContext()
// Date -> QVariant(QDateTime)
// RegExp -> QVariant(QRegExp)
// [Any other object] -> QVariantMap(...)
-QVariant QV8Engine::toBasicVariant(v8::Handle<v8::Value> value)
+QVariant QV8Engine::toBasicVariant(const QV4::Value &value)
{
- if (value->IsNull() || value->IsUndefined())
+ if (value.isNull() || value.isUndefined())
return QVariant();
- if (value->IsBoolean())
- return value->ToBoolean()->Value();
- if (value->IsInt32())
- return value->ToInt32()->Value();
- if (value->IsNumber())
- return value->ToNumber()->Value();
- if (value->IsString())
- return m_stringWrapper.toString(value->ToString());
- if (value->IsDate())
- return qtDateTimeFromJsDate(v8::Handle<v8::Date>::Cast(value)->NumberValue());
+ if (value.isBoolean())
+ return value.booleanValue();
+ if (value.isInteger())
+ return value.integerValue();
+ if (value.isNumber())
+ return value.asDouble();
+ if (value.isString())
+ return value.stringValue()->toQString();
+ if (QV4::DateObject *d = value.asDateObject())
+ return d->toQDateTime();
// NOTE: since we convert QTime to JS Date, round trip will change the variant type (to QDateTime)!
- Q_ASSERT(value->IsObject());
+ Q_ASSERT(value.isObject());
- if (value->IsRegExp()) {
- v8::Context::Scope scope(context());
- return QJSConverter::toRegExp(v8::Handle<v8::RegExp>::Cast(value));
- }
- if (value->IsArray()) {
- v8::Context::Scope scope(context());
+ if (QV4::RegExpObject *re = value.as<QV4::RegExpObject>())
+ return re->toQRegExp();
+ if (QV4::ArrayObject *a = value.asArrayObject()) {
QVariantList rv;
- v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value);
- int length = array->Length();
+ int length = a->arrayLength();
for (int ii = 0; ii < length; ++ii)
- rv << toVariant(array->Get(ii), -1);
+ rv << toVariant(a->getIndexed(ii), -1);
return rv;
}
- if (!value->IsFunction()) {
- v8::Context::Scope scope(context());
- v8::Handle<v8::Object> object = value->ToObject();
- return variantMapFromJS(object);
- }
+ if (!value.asFunctionObject())
+ return variantMapFromJS(value.asObject());
return QVariant();
}
-struct StaticQtMetaObject : public QObject
+void QV8Engine::initializeGlobal()
{
- static const QMetaObject *get()
- { return &staticQtMetaObject; }
-};
+ QV4::GlobalExtensions::init(m_engine, m_v4Engine->globalObject);
-void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global)
-{
- using namespace QQmlBuiltinFunctions;
-
- v8::Local<v8::Object> console = v8::Object::New();
- v8::Local<v8::Function> consoleLogFn = V8FUNCTION(consoleLog, this);
-
- console->Set(v8::String::New("debug"), consoleLogFn);
- console->Set(v8::String::New("log"), consoleLogFn);
- console->Set(v8::String::New("info"), consoleLogFn);
- console->Set(v8::String::New("warn"), V8FUNCTION(consoleWarn, this));
- console->Set(v8::String::New("error"), V8FUNCTION(consoleError, this));
- console->Set(v8::String::New("assert"), V8FUNCTION(consoleAssert, this));
-
- console->Set(v8::String::New("count"), V8FUNCTION(consoleCount, this));
- console->Set(v8::String::New("profile"), V8FUNCTION(consoleProfile, this));
- console->Set(v8::String::New("profileEnd"), V8FUNCTION(consoleProfileEnd, this));
- console->Set(v8::String::New("time"), V8FUNCTION(consoleTime, this));
- console->Set(v8::String::New("timeEnd"), V8FUNCTION(consoleTimeEnd, this));
- console->Set(v8::String::New("trace"), V8FUNCTION(consoleTrace, this));
- console->Set(v8::String::New("exception"), V8FUNCTION(consoleException, this));
-
- v8::Local<v8::Object> qt = v8::Object::New();
-
- // Set all the enums from the "Qt" namespace
- const QMetaObject *qtMetaObject = StaticQtMetaObject::get();
- for (int ii = 0; ii < qtMetaObject->enumeratorCount(); ++ii) {
- QMetaEnum enumerator = qtMetaObject->enumerator(ii);
- for (int jj = 0; jj < enumerator.keyCount(); ++jj) {
- qt->Set(v8::String::New(enumerator.key(jj)), v8::Integer::New(enumerator.value(jj)));
- }
- }
- qt->Set(v8::String::New("Asynchronous"), v8::Integer::New(0));
- qt->Set(v8::String::New("Synchronous"), v8::Integer::New(1));
-
- qt->Set(v8::String::New("include"), V8FUNCTION(QV8Include::include, this));
- qt->Set(v8::String::New("isQtObject"), V8FUNCTION(isQtObject, this));
- qt->Set(v8::String::New("rgba"), V8FUNCTION(rgba, this));
- qt->Set(v8::String::New("hsla"), V8FUNCTION(hsla, this));
- qt->Set(v8::String::New("colorEqual"), V8FUNCTION(colorEqual, this));
- qt->Set(v8::String::New("font"), V8FUNCTION(font, this));
- qt->Set(v8::String::New("rect"), V8FUNCTION(rect, this));
- qt->Set(v8::String::New("point"), V8FUNCTION(point, this));
- qt->Set(v8::String::New("size"), V8FUNCTION(size, this));
-
- qt->Set(v8::String::New("vector2d"), V8FUNCTION(vector2d, this));
- qt->Set(v8::String::New("vector3d"), V8FUNCTION(vector3d, this));
- qt->Set(v8::String::New("vector4d"), V8FUNCTION(vector4d, this));
- qt->Set(v8::String::New("quaternion"), V8FUNCTION(quaternion, this));
- qt->Set(v8::String::New("matrix4x4"), V8FUNCTION(matrix4x4, this));
-
- qt->Set(v8::String::New("formatDate"), V8FUNCTION(formatDate, this));
- qt->Set(v8::String::New("formatTime"), V8FUNCTION(formatTime, this));
- qt->Set(v8::String::New("formatDateTime"), V8FUNCTION(formatDateTime, this));
-
- qt->Set(v8::String::New("openUrlExternally"), V8FUNCTION(openUrlExternally, this));
- qt->Set(v8::String::New("fontFamilies"), V8FUNCTION(fontFamilies, this));
- qt->Set(v8::String::New("md5"), V8FUNCTION(md5, this));
- qt->Set(v8::String::New("btoa"), V8FUNCTION(btoa, this));
- qt->Set(v8::String::New("atob"), V8FUNCTION(atob, this));
- qt->Set(v8::String::New("resolvedUrl"), V8FUNCTION(resolvedUrl, this));
- qt->Set(v8::String::New("locale"), V8FUNCTION(locale, this));
- qt->Set(v8::String::New("binding"), V8FUNCTION(binding, this));
-
- if (m_engine) {
- qt->SetAccessor(v8::String::New("platform"), getPlatform, 0, v8::External::New(this));
- qt->SetAccessor(v8::String::New("application"), getApplication, 0, v8::External::New(this));
-#ifndef QT_NO_IM
- qt->SetAccessor(v8::String::New("inputMethod"), getInputMethod, 0, v8::External::New(this));
-#endif
- qt->Set(v8::String::New("lighter"), V8FUNCTION(lighter, this));
- qt->Set(v8::String::New("darker"), V8FUNCTION(darker, this));
- qt->Set(v8::String::New("tint"), V8FUNCTION(tint, this));
- qt->Set(v8::String::New("quit"), V8FUNCTION(quit, this));
- qt->Set(v8::String::New("createQmlObject"), V8FUNCTION(createQmlObject, this));
- qt->Set(v8::String::New("createComponent"), V8FUNCTION(createComponent, this));
- }
-
-#ifndef QT_NO_TRANSLATION
- global->Set(v8::String::New("qsTranslate"), V8FUNCTION(qsTranslate, this));
- global->Set(v8::String::New("QT_TRANSLATE_NOOP"), V8FUNCTION(qsTranslateNoOp, this));
- global->Set(v8::String::New("qsTr"), V8FUNCTION(qsTr, this));
- global->Set(v8::String::New("QT_TR_NOOP"), V8FUNCTION(qsTrNoOp, this));
- global->Set(v8::String::New("qsTrId"), V8FUNCTION(qsTrId, this));
- global->Set(v8::String::New("QT_TRID_NOOP"), V8FUNCTION(qsTrIdNoOp, this));
-#endif
+ QQmlLocale::registerStringLocaleCompare(m_v4Engine);
+ QQmlDateExtension::registerExtension(m_v4Engine);
+ QQmlNumberExtension::registerExtension(m_v4Engine);
- global->Set(v8::String::New("print"), consoleLogFn);
- global->Set(v8::String::New("console"), console);
- global->Set(v8::String::New("Qt"), qt);
- global->Set(v8::String::New("gc"), V8FUNCTION(QQmlBuiltinFunctions::gc, this));
-
- {
-#define STRING_ARG "(function(stringArg) { "\
- " String.prototype.arg = (function() {"\
- " return stringArg.apply(this, arguments);"\
- " })"\
- "})"
-
- v8::Local<v8::Script> registerArg = v8::Script::New(v8::String::New(STRING_ARG), 0, 0, v8::Handle<v8::String>(), v8::Script::NativeMode);
- v8::Local<v8::Value> result = registerArg->Run();
- Q_ASSERT(result->IsFunction());
- v8::Local<v8::Function> registerArgFunc = v8::Local<v8::Function>::Cast(result);
- v8::Handle<v8::Value> args = V8FUNCTION(stringArg, this);
- registerArgFunc->Call(v8::Local<v8::Object>::Cast(registerArgFunc), 1, &args);
-#undef STRING_ARG
- }
-
- QQmlLocale::registerStringLocaleCompare(this);
- QQmlDateExtension::registerExtension(this);
- QQmlNumberExtension::registerExtension(this);
-
- qt_add_domexceptions(this);
+ qt_add_domexceptions(m_v4Engine);
m_xmlHttpRequestData = qt_add_qmlxmlhttprequest(this);
- qt_add_sqlexceptions(this);
+ qt_add_sqlexceptions(m_v4Engine);
{
- v8::Handle<v8::Value> args[] = { global };
- v8::Local<v8::Value> names = m_getOwnPropertyNames->Call(global, 1, args);
- v8::Local<v8::Array> namesArray = v8::Local<v8::Array>::Cast(names);
- for (quint32 ii = 0; ii < namesArray->Length(); ++ii)
- m_illegalNames.insert(toString(namesArray->Get(ii)), true);
+ for (uint i = 0; i < m_v4Engine->globalObject->internalClass->size; ++i)
+ m_illegalNames.insert(m_v4Engine->globalObject->internalClass->nameMap.at(i)->toQString(), true);
}
{
@@ -710,63 +430,24 @@ void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global)
" }"\
"})"
- v8::Local<v8::Script> freeze = v8::Script::New(v8::String::New(FREEZE_SOURCE));
- v8::Local<v8::Value> result = freeze->Run();
- Q_ASSERT(result->IsFunction());
- m_freezeObject = qPersistentNew(v8::Local<v8::Function>::Cast(result));
+ QV4::Value result = QV4::Script::evaluate(m_v4Engine, QString::fromUtf8(FREEZE_SOURCE), 0);
+ Q_ASSERT(result.asFunctionObject());
+ m_freezeObject = result;
#undef FREEZE_SOURCE
}
}
-void QV8Engine::freezeObject(v8::Handle<v8::Value> value)
+void QV8Engine::freezeObject(const QV4::Value &value)
{
- v8::Handle<v8::Value> args[] = { value };
- m_freezeObject->Call(global(), 1, args);
+ QV4::Value args = value;
+ m_freezeObject.value().asFunctionObject()->call(QV4::Value::fromObject(m_v4Engine->globalObject), &args, 1);
}
void QV8Engine::gc()
{
- v8::V8::LowMemoryNotification();
- while (!v8::V8::IdleNotification()) {}
-}
-
-#ifdef QML_GLOBAL_HANDLE_DEBUGGING
-#include <QtCore/qthreadstorage.h>
-static QThreadStorage<QSet<void *> *> QV8Engine_activeHandles;
-
-void QV8Engine::registerHandle(void *handle)
-{
- if (!handle) {
- qWarning("Attempting to register a null handle");
- return;
- }
-
- if (!QV8Engine_activeHandles.hasLocalData())
- QV8Engine_activeHandles.setLocalData(new QSet<void *>);
-
- if (QV8Engine_activeHandles.localData()->contains(handle)) {
- qFatal("Handle %p already alive", handle);
- } else {
- QV8Engine_activeHandles.localData()->insert(handle);
- }
+ m_v4Engine->memoryManager->runGC();
}
-void QV8Engine::releaseHandle(void *handle)
-{
- if (!handle)
- return;
-
- if (!QV8Engine_activeHandles.hasLocalData())
- QV8Engine_activeHandles.setLocalData(new QSet<void *>);
-
- if (QV8Engine_activeHandles.localData()->contains(handle)) {
- QV8Engine_activeHandles.localData()->remove(handle);
- } else {
- qFatal("Handle %p already dead", handle);
- }
-}
-#endif
-
struct QV8EngineRegistrationData
{
QV8EngineRegistrationData() : extensionCount(0) {}
@@ -797,115 +478,10 @@ void QV8Engine::setExtensionData(int index, Deletable *data)
m_extensionData[index] = data;
}
-double QV8Engine::qtDateTimeToJsDate(const QDateTime &dt)
-{
- if (!dt.isValid()) {
- return qSNaN();
- }
-
- return dt.toMSecsSinceEpoch();
-}
-
-QDateTime QV8Engine::qtDateTimeFromJsDate(double jsDate)
-{
- if (qIsNaN(jsDate))
- return QDateTime();
-
- return QDateTime::fromMSecsSinceEpoch(jsDate);
-}
-
-v8::Persistent<v8::Object> *QV8Engine::findOwnerAndStrength(QObject *object, bool *shouldBeStrong)
-{
- QQmlData *data = QQmlData::get(object);
- if (data && data->rootObjectInCreation) { // When the object is still being created it may not show up to the GC.
- *shouldBeStrong = true;
- return 0;
- }
-
- QObject *parent = object->parent();
- if (!parent) {
- // if the object has JS ownership, the object's v8object owns the lifetime of the persistent value.
- if (QQmlEngine::objectOwnership(object) == QQmlEngine::JavaScriptOwnership) {
- *shouldBeStrong = false;
- return &(QQmlData::get(object)->v8object);
- }
-
- // no parent, and has CPP ownership - doesn't have an implicit parent.
- *shouldBeStrong = true;
- return 0;
- }
-
- // if it is owned by CPP, it's root parent may still be owned by JS.
- // in that case, the owner of the persistent handle is the root parent's v8object.
- while (parent->parent())
- parent = parent->parent();
-
- if (QQmlEngine::objectOwnership(parent) == QQmlEngine::JavaScriptOwnership) {
- // root parent is owned by JS. It's v8object owns the persistent value in question.
- *shouldBeStrong = false;
- return &(QQmlData::get(parent)->v8object);
- } else {
- // root parent has CPP ownership. The persistent value should not be made weak.
- *shouldBeStrong = true;
- return 0;
- }
-}
-
-void QV8Engine::addRelationshipForGC(QObject *object, v8::Persistent<v8::Value> handle)
-{
- if (!object || handle.IsEmpty())
- return;
-
- bool handleShouldBeStrong = false;
- v8::Persistent<v8::Object> *implicitOwner = findOwnerAndStrength(object, &handleShouldBeStrong);
- if (handleShouldBeStrong) {
- v8::V8::AddImplicitReferences(m_strongReferencer, &handle, 1);
- } else if (!implicitOwner->IsEmpty()) {
- v8::V8::AddImplicitReferences(*implicitOwner, &handle, 1);
- }
-}
-
-void QV8Engine::addRelationshipForGC(QObject *object, QObject *other)
-{
- if (!object || !other)
- return;
-
- bool handleShouldBeStrong = false;
- v8::Persistent<v8::Object> *implicitOwner = findOwnerAndStrength(object, &handleShouldBeStrong);
- v8::Persistent<v8::Value> handle = QQmlData::get(other, true)->v8object;
- if (handle.IsEmpty()) // no JS data to keep alive.
- return;
- else if (handleShouldBeStrong)
- v8::V8::AddImplicitReferences(m_strongReferencer, &handle, 1);
- else if (!implicitOwner->IsEmpty())
- v8::V8::AddImplicitReferences(*implicitOwner, &handle, 1);
-}
-
-static QThreadStorage<QV8Engine::ThreadData*> perThreadEngineData;
-
-bool QV8Engine::hasThreadData()
-{
- return perThreadEngineData.hasLocalData();
-}
-
-QV8Engine::ThreadData *QV8Engine::threadData()
-{
- Q_ASSERT(perThreadEngineData.hasLocalData());
- return perThreadEngineData.localData();
-}
-
-void QV8Engine::ensurePerThreadIsolate()
-{
- if (!perThreadEngineData.hasLocalData())
- perThreadEngineData.setLocalData(new ThreadData);
-}
-
void QV8Engine::initQmlGlobalObject()
{
- v8::HandleScope handels;
- v8::Context::Scope contextScope(m_context);
- initializeGlobal(m_context->Global());
- freezeObject(m_context->Global());
+ initializeGlobal();
+ freezeObject(QV4::Value::fromObject(m_v4Engine->globalObject));
}
void QV8Engine::setEngine(QQmlEngine *engine)
@@ -914,40 +490,51 @@ void QV8Engine::setEngine(QQmlEngine *engine)
initQmlGlobalObject();
}
-v8::Handle<v8::Value> QV8Engine::throwException(v8::Handle<v8::Value> value)
+QV4::Value QV8Engine::global()
{
- v8::ThrowException(value);
- return value;
+ return QV4::Value::fromObject(m_v4Engine->globalObject);
}
// Converts a QVariantList to JS.
// The result is a new Array object with length equal to the length
// of the QVariantList, and the elements being the QVariantList's
// elements converted to JS, recursively.
-v8::Local<v8::Array> QV8Engine::variantListToJS(const QVariantList &lst)
+QV4::Value QV8Engine::variantListToJS(const QVariantList &lst)
{
- v8::Local<v8::Array> result = v8::Array::New(lst.size());
- for (int i = 0; i < lst.size(); ++i)
- result->Set(i, variantToJS(lst.at(i)));
- return result;
+ QV4::ArrayObject *a = m_v4Engine->newArrayObject();
+ a->arrayReserve(lst.size());
+ for (int i = 0; i < lst.size(); i++)
+ a->arrayData[i].value = variantToJS(lst.at(i));
+ a->arrayDataLen = lst.size();
+ a->setArrayLengthUnchecked(lst.size());
+ return QV4::Value::fromObject(a);
}
// Converts a JS Array object to a QVariantList.
// The result is a QVariantList with length equal to the length
// of the JS Array, and elements being the JS Array's elements
// converted to QVariants, recursively.
-QVariantList QV8Engine::variantListFromJS(v8::Handle<v8::Array> jsArray,
+QVariantList QV8Engine::variantListFromJS(QV4::ArrayObject *a,
V8ObjectSet &visitedObjects)
{
QVariantList result;
- if (visitedObjects.contains(jsArray))
- return result; // Avoid recursion.
- v8::HandleScope handleScope;
- visitedObjects.insert(jsArray);
- uint32_t length = jsArray->Length();
- for (uint32_t i = 0; i < length; ++i)
- result.append(variantFromJS(jsArray->Get(i), visitedObjects));
- visitedObjects.remove(jsArray);
+ if (!a)
+ return result;
+
+ if (visitedObjects.contains(a))
+ // Avoid recursion.
+ return result;
+
+ visitedObjects.insert(a);
+
+ quint32 length = a->arrayLength();
+ for (quint32 i = 0; i < length; ++i) {
+ QV4::Value v = a->getIndexed(i);
+ result.append(variantFromJS(v, visitedObjects));
+ }
+
+ visitedObjects.remove(a);
+
return result;
}
@@ -955,91 +542,100 @@ QVariantList QV8Engine::variantListFromJS(v8::Handle<v8::Array> jsArray,
// The result is a new Object object with property names being
// the keys of the QVariantMap, and values being the values of
// the QVariantMap converted to JS, recursively.
-v8::Local<v8::Object> QV8Engine::variantMapToJS(const QVariantMap &vmap)
+QV4::Value QV8Engine::variantMapToJS(const QVariantMap &vmap)
{
- v8::Local<v8::Object> result = v8::Object::New();
+ QV4::Object *o = m_v4Engine->newObject();
QVariantMap::const_iterator it;
- for (it = vmap.constBegin(); it != vmap.constEnd(); ++it)
- result->Set(QJSConverter::toString(it.key()), variantToJS(it.value()));
- return result;
+ for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) {
+ QV4::Property *p = o->insertMember(m_v4Engine->newIdentifier(it.key()), QV4::Attr_Data);
+ p->value = variantToJS(it.value());
+ }
+ return QV4::Value::fromObject(o);
}
// Converts a JS Object to a QVariantMap.
// The result is a QVariantMap with keys being the property names
// of the object, and values being the values of the JS object's
// properties converted to QVariants, recursively.
-QVariantMap QV8Engine::variantMapFromJS(v8::Handle<v8::Object> jsObject,
+QVariantMap QV8Engine::variantMapFromJS(QV4::Object *o,
V8ObjectSet &visitedObjects)
{
QVariantMap result;
- v8::HandleScope handleScope;
- v8::Handle<v8::Array> propertyNames = jsObject->GetPropertyNames();
- uint32_t length = propertyNames->Length();
- if (length == 0)
+ if (!o || o->asFunctionObject())
return result;
- if (visitedObjects.contains(jsObject))
- return result; // Avoid recursion.
+ if (visitedObjects.contains(o)) {
+ // Avoid recursion.
+ // For compatibility with QVariant{List,Map} conversion, we return an
+ // empty object (and no error is thrown).
+ return result;
+ }
+
+ visitedObjects.insert(o);
+
+ QV4::ObjectIterator it(o, QV4::ObjectIterator::EnumerableOnly);
+ while (1) {
+ QV4::Value v;
+ QV4::Value name = it.nextPropertyNameAsString(&v);
+ if (name.isNull())
+ break;
- visitedObjects.insert(jsObject);
- // TODO: Only object's own property names. Include non-enumerable properties.
- for (uint32_t i = 0; i < length; ++i) {
- v8::Handle<v8::Value> name = propertyNames->Get(i);
- result.insert(QJSConverter::toString(name->ToString()),
- variantFromJS(jsObject->Get(name), visitedObjects));
+ QString key = name.toQString();
+ result.insert(key, variantFromJS(v, visitedObjects));
}
- visitedObjects.remove(jsObject);
+
+ visitedObjects.remove(o);
return result;
}
// Converts the meta-type defined by the given type and data to JS.
// Returns the value if conversion succeeded, an empty handle otherwise.
-v8::Handle<v8::Value> QV8Engine::metaTypeToJS(int type, const void *data)
+QV4::Value QV8Engine::metaTypeToJS(int type, const void *data)
{
Q_ASSERT(data != 0);
- v8::Handle<v8::Value> result;
+ QV4::Value result;
// check if it's one of the types we know
switch (QMetaType::Type(type)) {
case QMetaType::UnknownType:
case QMetaType::Void:
- return v8::Undefined();
+ return QV4::Value::undefinedValue();
case QMetaType::Bool:
- return v8::Boolean::New(*reinterpret_cast<const bool*>(data));
+ return QV4::Value::fromBoolean(*reinterpret_cast<const bool*>(data));
case QMetaType::Int:
- return v8::Int32::New(*reinterpret_cast<const int*>(data));
+ return QV4::Value::fromInt32(*reinterpret_cast<const int*>(data));
case QMetaType::UInt:
- return v8::Uint32::New(*reinterpret_cast<const uint*>(data));
+ return QV4::Value::fromUInt32(*reinterpret_cast<const uint*>(data));
case QMetaType::LongLong:
- return v8::Number::New(double(*reinterpret_cast<const qlonglong*>(data)));
+ return QV4::Value::fromDouble(double(*reinterpret_cast<const qlonglong*>(data)));
case QMetaType::ULongLong:
#if defined(Q_OS_WIN) && defined(_MSC_FULL_VER) && _MSC_FULL_VER <= 12008804
#pragma message("** NOTE: You need the Visual Studio Processor Pack to compile support for 64bit unsigned integers.")
- return v8::Number::New(double((qlonglong)*reinterpret_cast<const qulonglong*>(data)));
+ return QV4::Value::fromDouble(double((qlonglong)*reinterpret_cast<const qulonglong*>(data)));
#elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
- return v8::Number::New(double((qlonglong)*reinterpret_cast<const qulonglong*>(data)));
+ return QV4::Value::fromDouble(double((qlonglong)*reinterpret_cast<const qulonglong*>(data)));
#else
- return v8::Number::New(double(*reinterpret_cast<const qulonglong*>(data)));
+ return QV4::Value::fromDouble(double(*reinterpret_cast<const qulonglong*>(data)));
#endif
case QMetaType::Double:
- return v8::Number::New(double(*reinterpret_cast<const double*>(data)));
+ return QV4::Value::fromDouble(*reinterpret_cast<const double*>(data));
case QMetaType::QString:
- return QJSConverter::toString(*reinterpret_cast<const QString*>(data));
+ return QV4::Value::fromString(m_v4Engine->current, *reinterpret_cast<const QString*>(data));
case QMetaType::Float:
- return v8::Number::New(*reinterpret_cast<const float*>(data));
+ return QV4::Value::fromDouble(*reinterpret_cast<const float*>(data));
case QMetaType::Short:
- return v8::Int32::New(*reinterpret_cast<const short*>(data));
+ return QV4::Value::fromInt32(*reinterpret_cast<const short*>(data));
case QMetaType::UShort:
- return v8::Uint32::New(*reinterpret_cast<const unsigned short*>(data));
+ return QV4::Value::fromUInt32(*reinterpret_cast<const unsigned short*>(data));
case QMetaType::Char:
- return v8::Int32::New(*reinterpret_cast<const char*>(data));
+ return QV4::Value::fromInt32(*reinterpret_cast<const char*>(data));
case QMetaType::UChar:
- return v8::Uint32::New(*reinterpret_cast<const unsigned char*>(data));
+ return QV4::Value::fromUInt32(*reinterpret_cast<const unsigned char*>(data));
case QMetaType::QChar:
- return v8::Uint32::New((*reinterpret_cast<const QChar*>(data)).unicode());
+ return QV4::Value::fromUInt32((*reinterpret_cast<const QChar*>(data)).unicode());
case QMetaType::QStringList:
- result = QJSConverter::toStringList(*reinterpret_cast<const QStringList *>(data));
+ result = QV4::Value::fromObject(m_v4Engine->newArrayObject(*reinterpret_cast<const QStringList *>(data)));
break;
case QMetaType::QVariantList:
result = variantListToJS(*reinterpret_cast<const QVariantList *>(data));
@@ -1048,39 +644,39 @@ v8::Handle<v8::Value> QV8Engine::metaTypeToJS(int type, const void *data)
result = variantMapToJS(*reinterpret_cast<const QVariantMap *>(data));
break;
case QMetaType::QDateTime:
- result = QJSConverter::toDateTime(*reinterpret_cast<const QDateTime *>(data));
+ result = QV4::Value::fromObject(m_v4Engine->newDateObject(*reinterpret_cast<const QDateTime *>(data)));
break;
case QMetaType::QDate:
- result = QJSConverter::toDateTime(QDateTime(*reinterpret_cast<const QDate *>(data)));
+ result = QV4::Value::fromObject(m_v4Engine->newDateObject(QDateTime(*reinterpret_cast<const QDate *>(data))));
break;
case QMetaType::QRegExp:
- result = QJSConverter::toRegExp(*reinterpret_cast<const QRegExp *>(data));
+ result = QV4::Value::fromObject(m_v4Engine->newRegExpObject(*reinterpret_cast<const QRegExp *>(data)));
break;
case QMetaType::QObjectStar:
- result = newQObject(*reinterpret_cast<QObject* const *>(data));
+ result = QV4::QObjectWrapper::wrap(m_v4Engine, *reinterpret_cast<QObject* const *>(data));
break;
case QMetaType::QVariant:
result = variantToJS(*reinterpret_cast<const QVariant*>(data));
break;
case QMetaType::QJsonValue:
- result = jsonValueToJS(*reinterpret_cast<const QJsonValue *>(data));
+ result = QV4::JsonObject::fromJsonValue(m_v4Engine, *reinterpret_cast<const QJsonValue *>(data));
break;
case QMetaType::QJsonObject:
- result = jsonObjectToJS(*reinterpret_cast<const QJsonObject *>(data));
+ result = QV4::JsonObject::fromJsonObject(m_v4Engine, *reinterpret_cast<const QJsonObject *>(data));
break;
case QMetaType::QJsonArray:
- result = jsonArrayToJS(*reinterpret_cast<const QJsonArray *>(data));
+ result = QV4::JsonObject::fromJsonArray(m_v4Engine, *reinterpret_cast<const QJsonArray *>(data));
break;
default:
if (type == qMetaTypeId<QJSValue>()) {
- return QJSValuePrivate::get(*reinterpret_cast<const QJSValue*>(data))->asV8Value(this);
+ return QJSValuePrivate::get(*reinterpret_cast<const QJSValue*>(data))->getValue(m_v4Engine);
} else {
QByteArray typeName = QMetaType::typeName(type);
if (typeName.endsWith('*') && !*reinterpret_cast<void* const *>(data)) {
- return v8::Null();
+ return QV4::Value::nullValue();
} else {
// Fall back to wrapping in a QVariant.
- result = newVariant(QVariant(type, data));
+ result = QV4::Value::fromObject(m_v4Engine->newVariantObject(QVariant(type, data)));
}
}
}
@@ -1090,102 +686,104 @@ v8::Handle<v8::Value> QV8Engine::metaTypeToJS(int type, const void *data)
// Converts a JS value to a meta-type.
// data must point to a place that can store a value of the given type.
// Returns true if conversion succeeded, false otherwise.
-bool QV8Engine::metaTypeFromJS(v8::Handle<v8::Value> value, int type, void *data) {
+bool QV8Engine::metaTypeFromJS(const QV4::Value &value, int type, void *data) {
// check if it's one of the types we know
switch (QMetaType::Type(type)) {
case QMetaType::Bool:
- *reinterpret_cast<bool*>(data) = value->ToBoolean()->Value();
+ *reinterpret_cast<bool*>(data) = value.toBoolean();
return true;
case QMetaType::Int:
- *reinterpret_cast<int*>(data) = value->ToInt32()->Value();
+ *reinterpret_cast<int*>(data) = value.toInt32();
return true;
case QMetaType::UInt:
- *reinterpret_cast<uint*>(data) = value->ToUint32()->Value();
+ *reinterpret_cast<uint*>(data) = value.toUInt32();
return true;
case QMetaType::LongLong:
- *reinterpret_cast<qlonglong*>(data) = qlonglong(value->ToInteger()->Value());
+ *reinterpret_cast<qlonglong*>(data) = qlonglong(value.toInteger());
return true;
case QMetaType::ULongLong:
- *reinterpret_cast<qulonglong*>(data) = qulonglong(value->ToInteger()->Value());
+ *reinterpret_cast<qulonglong*>(data) = qulonglong(value.toInteger());
return true;
case QMetaType::Double:
- *reinterpret_cast<double*>(data) = value->ToNumber()->Value();
+ *reinterpret_cast<double*>(data) = value.toNumber();
return true;
case QMetaType::QString:
- if (value->IsUndefined() || value->IsNull())
+ if (value.isUndefined() || value.isNull())
*reinterpret_cast<QString*>(data) = QString();
else
- *reinterpret_cast<QString*>(data) = QJSConverter::toString(value->ToString());
+ *reinterpret_cast<QString*>(data) = value.toString(m_v4Engine->current)->toQString();
return true;
case QMetaType::Float:
- *reinterpret_cast<float*>(data) = value->ToNumber()->Value();
+ *reinterpret_cast<float*>(data) = value.toNumber();
return true;
case QMetaType::Short:
- *reinterpret_cast<short*>(data) = short(value->ToInt32()->Value());
+ *reinterpret_cast<short*>(data) = short(value.toInt32());
return true;
case QMetaType::UShort:
- *reinterpret_cast<unsigned short*>(data) = ushort(value->ToInt32()->Value()); // ### QScript::ToUInt16()
+ *reinterpret_cast<unsigned short*>(data) = value.toUInt16();
return true;
case QMetaType::Char:
- *reinterpret_cast<char*>(data) = char(value->ToInt32()->Value());
+ *reinterpret_cast<char*>(data) = char(value.toInt32());
return true;
case QMetaType::UChar:
- *reinterpret_cast<unsigned char*>(data) = (unsigned char)(value->ToInt32()->Value());
+ *reinterpret_cast<unsigned char*>(data) = (unsigned char)(value.toInt32());
return true;
case QMetaType::QChar:
- if (value->IsString()) {
- QString str = QJSConverter::toString(v8::Handle<v8::String>::Cast(value));
+ if (value.isString()) {
+ QString str = value.stringValue()->toQString();
*reinterpret_cast<QChar*>(data) = str.isEmpty() ? QChar() : str.at(0);
} else {
- *reinterpret_cast<QChar*>(data) = QChar(ushort(value->ToInt32()->Value())); // ### QScript::ToUInt16()
+ *reinterpret_cast<QChar*>(data) = QChar(ushort(value.toUInt16()));
}
return true;
case QMetaType::QDateTime:
- if (value->IsDate()) {
- *reinterpret_cast<QDateTime *>(data) = QJSConverter::toDateTime(v8::Handle<v8::Date>::Cast(value));
+ if (QV4::DateObject *d = value.asDateObject()) {
+ *reinterpret_cast<QDateTime *>(data) = d->toQDateTime();
return true;
} break;
case QMetaType::QDate:
- if (value->IsDate()) {
- *reinterpret_cast<QDate *>(data) = QJSConverter::toDateTime(v8::Handle<v8::Date>::Cast(value)).date();
+ if (QV4::DateObject *d = value.asDateObject()) {
+ *reinterpret_cast<QDate *>(data) = d->toQDateTime().date();
return true;
} break;
case QMetaType::QRegExp:
- if (value->IsRegExp()) {
- *reinterpret_cast<QRegExp *>(data) = QJSConverter::toRegExp(v8::Handle<v8::RegExp>::Cast(value));
+ if (QV4::RegExpObject *r = value.as<QV4::RegExpObject>()) {
+ *reinterpret_cast<QRegExp *>(data) = r->toQRegExp();
return true;
} break;
- case QMetaType::QObjectStar:
- if (isQObject(value) || value->IsNull()) {
+ case QMetaType::QObjectStar: {
+ QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>();
+ if (qobjectWrapper || value.isNull()) {
*reinterpret_cast<QObject* *>(data) = qtObjectFromJS(value);
return true;
} break;
+ }
case QMetaType::QStringList:
- if (value->IsArray()) {
- *reinterpret_cast<QStringList *>(data) = QJSConverter::toStringList(v8::Handle<v8::Array>::Cast(value));
+ if (QV4::ArrayObject *a = value.asArrayObject()) {
+ *reinterpret_cast<QStringList *>(data) = a->toQStringList();
return true;
} break;
case QMetaType::QVariantList:
- if (value->IsArray()) {
- *reinterpret_cast<QVariantList *>(data) = variantListFromJS(v8::Handle<v8::Array>::Cast(value));
+ if (QV4::ArrayObject *a = value.asArrayObject()) {
+ *reinterpret_cast<QVariantList *>(data) = variantListFromJS(a);
return true;
} break;
case QMetaType::QVariantMap:
- if (value->IsObject()) {
- *reinterpret_cast<QVariantMap *>(data) = variantMapFromJS(v8::Handle<v8::Object>::Cast(value));
+ if (QV4::Object *o = value.asObject()) {
+ *reinterpret_cast<QVariantMap *>(data) = variantMapFromJS(o);
return true;
} break;
case QMetaType::QVariant:
*reinterpret_cast<QVariant*>(data) = variantFromJS(value);
return true;
case QMetaType::QJsonValue:
- *reinterpret_cast<QJsonValue *>(data) = jsonValueFromJS(value);
+ *reinterpret_cast<QJsonValue *>(data) = QV4::JsonObject::toJsonValue(value);
return true;
case QMetaType::QJsonObject:
- *reinterpret_cast<QJsonObject *>(data) = jsonObjectFromJS(value);
+ *reinterpret_cast<QJsonObject *>(data) = QV4::JsonObject::toJsonObject(value.asObject());
return true;
case QMetaType::QJsonArray:
- *reinterpret_cast<QJsonArray *>(data) = jsonArrayFromJS(value);
+ *reinterpret_cast<QJsonArray *>(data) = QV4::JsonObject::toJsonArray(value.asArrayObject());
return true;
default:
;
@@ -1215,25 +813,25 @@ bool QV8Engine::metaTypeFromJS(v8::Handle<v8::Value> value, int type, void *data
QByteArray name = QMetaType::typeName(type);
if (convertToNativeQObject(value, name, reinterpret_cast<void* *>(data)))
return true;
- if (isVariant(value) && name.endsWith('*')) {
+ if (value.as<QV4::VariantObject>() && name.endsWith('*')) {
int valueType = QMetaType::type(name.left(name.size()-1));
- QVariant &var = variantValue(value);
+ QVariant &var = value.as<QV4::VariantObject>()->data;
if (valueType == var.userType()) {
// We have T t, T* is requested, so return &t.
*reinterpret_cast<void* *>(data) = var.data();
return true;
- } else {
+ } else if (QV4::Object *o = value.asObject()) {
// Look in the prototype chain.
- v8::Handle<v8::Value> proto = value->ToObject()->GetPrototype();
- while (proto->IsObject()) {
+ QV4::Object *proto = o->prototype;
+ while (proto) {
bool canCast = false;
- if (isVariant(proto)) {
- canCast = (type == variantValue(proto).userType())
- || (valueType && (valueType == variantValue(proto).userType()));
+ if (QV4::VariantObject *vo = proto->as<QV4::VariantObject>()) {
+ const QVariant &v = vo->data;
+ canCast = (type == v.userType()) || (valueType && (valueType == v.userType()));
}
- else if (isQObject(proto)) {
+ else if (proto->as<QV4::QObjectWrapper>()) {
QByteArray className = name.left(name.size()-1);
- if (QObject *qobject = qtObjectFromJS(proto))
+ if (QObject *qobject = qtObjectFromJS(QV4::Value::fromObject(proto)))
canCast = qobject->qt_metacast(className) != 0;
}
if (canCast) {
@@ -1244,14 +842,14 @@ bool QV8Engine::metaTypeFromJS(v8::Handle<v8::Value> value, int type, void *data
*reinterpret_cast<void* *>(data) = var.data();
return true;
}
- proto = proto->ToObject()->GetPrototype();
+ proto = proto->prototype;
}
}
- } else if (value->IsNull() && name.endsWith('*')) {
+ } else if (value.isNull() && name.endsWith('*')) {
*reinterpret_cast<void* *>(data) = 0;
return true;
} else if (type == qMetaTypeId<QJSValue>()) {
- *reinterpret_cast<QJSValue*>(data) = QJSValuePrivate::get(new QJSValuePrivate(this, value));
+ *reinterpret_cast<QJSValue*>(data) = QJSValuePrivate::get(new QJSValuePrivate(m_v4Engine, value));
return true;
}
@@ -1259,7 +857,7 @@ bool QV8Engine::metaTypeFromJS(v8::Handle<v8::Value> value, int type, void *data
}
// Converts a QVariant to JS.
-v8::Handle<v8::Value> QV8Engine::variantToJS(const QVariant &value)
+QV4::Value QV8Engine::variantToJS(const QVariant &value)
{
return metaTypeToJS(value.userType(), value.constData());
}
@@ -1274,71 +872,40 @@ v8::Handle<v8::Value> QV8Engine::variantToJS(const QVariant &value)
// Date -> QVariant(QDateTime)
// RegExp -> QVariant(QRegExp)
// [Any other object] -> QVariantMap(...)
-QVariant QV8Engine::variantFromJS(v8::Handle<v8::Value> value,
+QVariant QV8Engine::variantFromJS(const QV4::Value &value,
V8ObjectSet &visitedObjects)
{
- Q_ASSERT(!value.IsEmpty());
- if (value->IsUndefined())
+ Q_ASSERT(!value.isEmpty());
+ if (value.isUndefined())
return QVariant();
- if (value->IsNull())
+ if (value.isNull())
return QVariant(QMetaType::VoidStar, 0);
- if (value->IsBoolean())
- return value->ToBoolean()->Value();
- if (value->IsInt32())
- return value->ToInt32()->Value();
- if (value->IsNumber())
- return value->ToNumber()->Value();
- if (value->IsString())
- return QJSConverter::toString(value->ToString());
- Q_ASSERT(value->IsObject());
- if (value->IsArray())
- return variantListFromJS(v8::Handle<v8::Array>::Cast(value), visitedObjects);
- if (value->IsDate())
- return QJSConverter::toDateTime(v8::Handle<v8::Date>::Cast(value));
- if (value->IsRegExp())
- return QJSConverter::toRegExp(v8::Handle<v8::RegExp>::Cast(value));
- if (isVariant(value))
- return variantValue(value);
- if (isQObject(value))
+ if (value.isBoolean())
+ return value.booleanValue();
+ if (value.isInteger())
+ return value.integerValue();
+ if (value.isNumber())
+ return value.asDouble();
+ if (value.isString())
+ return value.stringValue()->toQString();
+ Q_ASSERT(value.isObject());
+ if (QV4::ArrayObject *a = value.asArrayObject())
+ return variantListFromJS(a, visitedObjects);
+ if (QV4::DateObject *d = value.asDateObject())
+ return d->toQDateTime();
+ if (QV4::RegExpObject *re = value.as<QV4::RegExpObject>())
+ return re->toQRegExp();
+ if (QV4::VariantObject *v = value.as<QV4::VariantObject>())
+ return v->data;
+ if (value.as<QV4::QObjectWrapper>())
return qVariantFromValue(qtObjectFromJS(value));
- if (isValueType(value))
- return toValueType(value);
- return variantMapFromJS(value->ToObject(), visitedObjects);
+ if (QV4::QmlValueTypeWrapper *v = value.as<QV4::QmlValueTypeWrapper>())
+ return v->toVariant();
+ return variantMapFromJS(value.asObject(), visitedObjects);
}
-v8::Handle<v8::Value> QV8Engine::jsonValueToJS(const QJsonValue &value)
-{
- return m_jsonWrapper.fromJsonValue(value);
-}
-QJsonValue QV8Engine::jsonValueFromJS(v8::Handle<v8::Value> value)
-{
- return m_jsonWrapper.toJsonValue(value);
-}
-
-v8::Local<v8::Object> QV8Engine::jsonObjectToJS(const QJsonObject &object)
-{
- return m_jsonWrapper.fromJsonObject(object);
-}
-
-QJsonObject QV8Engine::jsonObjectFromJS(v8::Handle<v8::Value> value)
-{
- return m_jsonWrapper.toJsonObject(value);
-}
-
-v8::Local<v8::Array> QV8Engine::jsonArrayToJS(const QJsonArray &array)
-{
- return m_jsonWrapper.fromJsonArray(array);
-}
-
-QJsonArray QV8Engine::jsonArrayFromJS(v8::Handle<v8::Value> value)
-{
- return m_jsonWrapper.toJsonArray(value);
-}
-
-bool QV8Engine::convertToNativeQObject(v8::Handle<v8::Value> value,
- const QByteArray &targetType,
- void **result)
+bool QV8Engine::convertToNativeQObject(const QV4::Value &value, const QByteArray &targetType, void **result)
{
if (!targetType.endsWith('*'))
return false;
@@ -1353,73 +920,22 @@ bool QV8Engine::convertToNativeQObject(v8::Handle<v8::Value> value,
return false;
}
-QObject *QV8Engine::qtObjectFromJS(v8::Handle<v8::Value> value)
+QObject *QV8Engine::qtObjectFromJS(const QV4::Value &value)
{
- if (!value->IsObject())
+ if (!value.isObject())
return 0;
- QV8ObjectResource *r = (QV8ObjectResource *)value->ToObject()->GetExternalResource();
- if (!r)
- return 0;
- QV8ObjectResource::ResourceType type = r->resourceType();
- if (type == QV8ObjectResource::QObjectType)
- return qobjectWrapper()->toQObject(r);
- else if (type == QV8ObjectResource::VariantType) {
- QVariant variant = variantWrapper()->toVariant(r);
+
+ if (QV4::VariantObject *v = value.as<QV4::VariantObject>()) {
+ QVariant variant = v->data;
int type = variant.userType();
if (type == QMetaType::QObjectStar)
return *reinterpret_cast<QObject* const *>(variant.constData());
}
- return 0;
-}
-
-
-QVariant &QV8Engine::variantValue(v8::Handle<v8::Value> value)
-{
- return variantWrapper()->variantValue(value);
-}
-
-// Creates a QVariant wrapper object.
-v8::Local<v8::Object> QV8Engine::newVariant(const QVariant &value)
-{
- return variantWrapper()->newVariant(value);
-}
-
-QScriptPassPointer<QJSValuePrivate> QV8Engine::evaluate(v8::Handle<v8::Script> script, v8::TryCatch& tryCatch)
-{
- v8::HandleScope handleScope;
-
- if (script.IsEmpty()) {
- v8::Handle<v8::Value> exception = tryCatch.Exception();
- if (exception.IsEmpty()) {
- // This is possible on syntax errors like { a:12, b:21 } <- missing "(", ")" around expression.
- return new QJSValuePrivate(this);
- }
- return new QJSValuePrivate(this, exception);
- }
- v8::Handle<v8::Value> result;
- result = script->Run();
- if (result.IsEmpty()) {
- v8::Handle<v8::Value> exception = tryCatch.Exception();
- // TODO: figure out why v8 doesn't always produce an exception value
- //Q_ASSERT(!exception.IsEmpty());
- if (exception.IsEmpty())
- exception = v8::Exception::Error(v8::String::New("missing exception value"));
- return new QJSValuePrivate(this, exception);
- }
- return new QJSValuePrivate(this, result);
-}
-
-QJSValue QV8Engine::scriptValueFromInternal(v8::Handle<v8::Value> value) const
-{
- if (value.IsEmpty())
- return QJSValuePrivate::get(new QJSValuePrivate(const_cast<QV8Engine*>(this)));
- return QJSValuePrivate::get(new QJSValuePrivate(const_cast<QV8Engine*>(this), value));
-}
-
-QScriptPassPointer<QJSValuePrivate> QV8Engine::newArray(uint length)
-{
- return new QJSValuePrivate(this, v8::Array::New(length));
+ QV4::QObjectWrapper *wrapper = value.as<QV4::QObjectWrapper>();
+ if (!wrapper)
+ return 0;
+ return wrapper->object();
}
void QV8Engine::startTimer(const QString &timerName)
@@ -1449,107 +965,9 @@ int QV8Engine::consoleCountHelper(const QString &file, quint16 line, quint16 col
return number;
}
-v8::Handle<v8::Value> QV8Engine::getPlatform(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
- QV8Engine *engine = reinterpret_cast<QV8Engine*>(v8::External::Cast(*info.Data())->Value());
- if (!engine->m_platform) {
- // Only allocate a platform object once
- engine->m_platform = new QQmlPlatform(engine->m_engine);
- }
- return engine->newQObject(engine->m_platform);
-}
-
-v8::Handle<v8::Value> QV8Engine::getApplication(v8::Local<v8::String>, const v8::AccessorInfo &info)
+QV4::Value QV8Engine::toString(const QString &string)
{
- QV8Engine *engine = reinterpret_cast<QV8Engine*>(v8::External::Cast(*info.Data())->Value());
- if (!engine->m_application) {
- // Only allocate an application object once
- engine->m_application = QQml_guiProvider()->application(engine->m_engine);
- }
- return engine->newQObject(engine->m_application);
-}
-
-#ifndef QT_NO_IM
-v8::Handle<v8::Value> QV8Engine::getInputMethod(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
- QV8Engine *engine = reinterpret_cast<QV8Engine*>(v8::External::Cast(*info.Data())->Value());
- return engine->newQObject(QQml_guiProvider()->inputMethod(), CppOwnership);
-}
-#endif
-
-void QV8GCCallback::registerGcPrologueCallback()
-{
- QV8Engine::ThreadData *td = QV8Engine::threadData();
- if (!td->gcPrologueCallbackRegistered) {
- td->gcPrologueCallbackRegistered = true;
- v8::V8::AddGCPrologueCallback(QV8GCCallback::garbageCollectorPrologueCallback, v8::kGCTypeMarkSweepCompact);
- }
-}
-
-QV8GCCallback::Node::Node(PrologueCallback callback)
- : prologueCallback(callback)
-{
-}
-
-QV8GCCallback::Node::~Node()
-{
- node.remove();
-}
-
-/*
- Ensure that each persistent handle is strong if it has CPP ownership
- and has no implicitly JS owned object owner in its parent chain, and
- weak otherwise.
-
- Any weak handle whose parent object is still alive will have an implicit
- reference (between the parent and the handle) added, so that it will
- not be collected.
-
- Note that this callback is registered only for kGCTypeMarkSweepCompact
- collection cycles, as it is during collection cycles of that type
- in which weak persistent handle callbacks are called when required.
- */
-void QV8GCCallback::garbageCollectorPrologueCallback(v8::GCType, v8::GCCallbackFlags)
-{
- if (!QV8Engine::hasThreadData())
- return;
-
- QV8Engine::ThreadData *td = QV8Engine::threadData();
- QV8GCCallback::Node *currNode = td->gcCallbackNodes.first();
-
- while (currNode) {
- // The client which adds itself to the list is responsible
- // for maintaining the correct implicit references in the
- // specified callback.
- currNode->prologueCallback(currNode);
- currNode = td->gcCallbackNodes.next(currNode);
- }
-}
-
-void QV8GCCallback::addGcCallbackNode(QV8GCCallback::Node *node)
-{
- QV8Engine::ThreadData *td = QV8Engine::threadData();
- td->gcCallbackNodes.insert(node);
-}
-
-QV8Engine::ThreadData::ThreadData()
- : gcPrologueCallbackRegistered(false)
-{
- if (!v8::Isolate::GetCurrent()) {
- isolate = v8::Isolate::New();
- isolate->Enter();
- } else {
- isolate = 0;
- }
-}
-
-QV8Engine::ThreadData::~ThreadData()
-{
- if (isolate) {
- isolate->Exit();
- isolate->Dispose();
- isolate = 0;
- }
+ return QV4::Value::fromString(m_v4Engine->newString(string));
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv8engine_impl_p.h b/src/qml/qml/v8/qv8engine_impl_p.h
deleted file mode 100644
index 8879b67ebb..0000000000
--- a/src/qml/qml/v8/qv8engine_impl_p.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV8ENGINE_IMPL_P_H
-#define QV8ENGINE_IMPL_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 "qv8engine_p.h"
-#include "qjsvalue_p.h"
-#include "qjsconverter_p.h"
-#include "qjsvalueiterator_p.h"
-
-QT_BEGIN_NAMESPACE
-
-inline v8::Handle<v8::Value> QV8Engine::makeJSValue(bool value)
-{
- return value ? v8::True() : v8::False();
-}
-
-inline v8::Local<v8::Value> QV8Engine::makeJSValue(int value)
-{
- return v8::Integer::New(value);
-}
-
-inline v8::Local<v8::Value> QV8Engine::makeJSValue(uint value)
-{
- return v8::Integer::NewFromUnsigned(value);
-}
-
-inline v8::Local<v8::Value> QV8Engine::makeJSValue(double value)
-{
- return v8::Number::New(value);
-}
-
-inline v8::Handle<v8::Value> QV8Engine::makeJSValue(QJSValue::SpecialValue value) {
- if (value == QJSValue::NullValue)
- return v8::Null();
- return v8::Undefined();
-}
-
-inline v8::Local<v8::Value> QV8Engine::makeJSValue(const QString &value)
-{
- return QJSConverter::toString(value);
-}
-
-class QtScriptBagCleaner
-{
-public:
- template<class T>
- void operator () (T* value) const
- {
- value->reinitialize();
- }
- void operator () (QJSValueIteratorPrivate *iterator) const
- {
- iterator->invalidate();
- }
-};
-
-inline void QV8Engine::registerValue(QJSValuePrivate *data)
-{
- m_values.insert(data);
-}
-
-inline void QV8Engine::unregisterValue(QJSValuePrivate *data)
-{
- m_values.remove(data);
-}
-
-inline void QV8Engine::invalidateAllValues()
-{
- ValueList::iterator it;
- for (it = m_values.begin(); it != m_values.end(); it = it.erase())
- (*it)->invalidate();
- Q_ASSERT(m_values.isEmpty());
-}
-
-inline void QV8Engine::registerValueIterator(QJSValueIteratorPrivate *data)
-{
- m_valueIterators.insert(data);
-}
-
-inline void QV8Engine::unregisterValueIterator(QJSValueIteratorPrivate *data)
-{
- m_valueIterators.remove(data);
-}
-
-inline void QV8Engine::invalidateAllIterators()
-{
- ValueIteratorList::iterator it;
- for (it = m_valueIterators.begin(); it != m_valueIterators.end(); it = it.erase())
- (*it)->invalidate();
- Q_ASSERT(m_valueIterators.isEmpty());
-}
-
-/*!
- \internal
- \note property can be index (v8::Integer) or a property (v8::String) name, according to ECMA script
- property would be converted to a string.
-*/
-inline QJSValuePrivate::PropertyFlags QV8Engine::getPropertyFlags(v8::Handle<v8::Object> object, v8::Handle<v8::Value> property)
-{
- QJSValuePrivate::PropertyFlags flags = m_originalGlobalObject.getPropertyFlags(object, property);
- return flags;
-}
-
-QScriptPassPointer<QJSValuePrivate> QV8Engine::evaluate(const QString& program, const QString& fileName, quint16 lineNumber)
-{
- v8::TryCatch tryCatch;
- v8::ScriptOrigin scriptOrigin(QJSConverter::toString(fileName), v8::Integer::New(lineNumber - 1));
- v8::Handle<v8::Script> script;
- script = v8::Script::Compile(QJSConverter::toString(program), &scriptOrigin);
- if (script.IsEmpty()) {
- // TODO: Why don't we get the exception, as with Script::Compile()?
- // Q_ASSERT(tryCatch.HasCaught());
- v8::Handle<v8::Value> error = v8::Exception::SyntaxError(v8::String::New(""));
- return new QJSValuePrivate(this, error);
- }
- return evaluate(script, tryCatch);
-}
-
-QT_END_NAMESPACE
-
-#endif // QV8ENGINE_IMPL_P_H
diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h
index 5ae0963178..61db8a79b3 100644
--- a/src/qml/qml/v8/qv8engine_p.h
+++ b/src/qml/qml/v8/qv8engine_p.h
@@ -62,39 +62,24 @@
#include <QtCore/QElapsedTimer>
#include <QtCore/QThreadStorage>
-#include <private/qv8_p.h>
#include <qjsengine.h>
#include <qjsvalue.h>
-#include "qjsvalue_p.h"
#include "qjsvalueiterator_p.h"
-#include "qscriptoriginalglobalobject_p.h"
-#include "qscripttools_p.h"
+#include "private/qintrusivelist_p.h"
#include <private/qqmlpropertycache_p.h>
-#include "qv8objectresource_p.h"
-#include "qv8contextwrapper_p.h"
-#include "qv8qobjectwrapper_p.h"
-#include "qv8stringwrapper_p.h"
-#include "qv8typewrapper_p.h"
-#include "qv8listwrapper_p.h"
-#include "qv8variantwrapper_p.h"
-#include "qv8valuetypewrapper_p.h"
-#include "qv8sequencewrapper_p.h"
-#include "qv8jsonwrapper_p.h"
-
-namespace v8 {
-
-// Needed for V8ObjectSet
-inline uint qHash(const v8::Handle<v8::Object> &object, uint seed = 0)
-{
- return (object->GetIdentityHash() ^ seed);
-}
-
-}
+#include <private/qv4qobjectwrapper_p.h>
+#include <private/qv4value_p.h>
+#include <private/qv4object_p.h>
QT_BEGIN_NAMESPACE
+namespace QV4 {
+ struct ArrayObject;
+ struct ExecutionEngine;
+ struct Value;
+}
// Uncomment the following line to enable global handle debugging. When enabled, all the persistent
// handles allocated using qPersistentNew() (or registered with qPersistentRegsiter()) and disposed
@@ -102,32 +87,11 @@ QT_BEGIN_NAMESPACE
// a handle, qFatal() is called.
// #define QML_GLOBAL_HANDLE_DEBUGGING
-#define V8ENGINE() ((QV8Engine *)v8::External::Cast(*args.Data())->Value())
-#define V8FUNCTION(function, engine) v8::FunctionTemplate::New(function, v8::External::New((QV8Engine*)engine))->GetFunction()
-#define V8THROW_ERROR(string) { \
- v8::ThrowException(v8::Exception::Error(v8::String::New(string))); \
- return v8::Handle<v8::Value>(); \
-}
-#define V8THROW_TYPE(string) { \
- v8::ThrowException(v8::Exception::TypeError(v8::String::New(string))); \
- return v8::Handle<v8::Value>(); \
-}
-#define V8ENGINE_ACCESSOR() ((QV8Engine *)v8::External::Cast(*info.Data())->Value());
-#define V8THROW_ERROR_SETTER(string) { \
- v8::ThrowException(v8::Exception::Error(v8::String::New(string))); \
- return; \
-}
+#define V4THROW_ERROR(string) \
+ ctx->throwError(QString::fromUtf8(string));
-#define V8ASSERT_TYPE(condition, string) \
- if (!(condition)) { \
- v8::ThrowException(v8::Exception::TypeError(v8::String::New(string))); \
- return v8::Handle<v8::Value>(); \
- }
-#define V8ASSERT_TYPE_SETTER(condition, string) \
- if (!(condition)) { \
- v8::ThrowException(v8::Exception::TypeError(v8::String::New(string))); \
- return; \
- }
+#define V4THROW_TYPE(string) \
+ ctx->throwTypeError(QStringLiteral(string));
#define V8_DEFINE_EXTENSION(dataclass, datafunction) \
static inline dataclass *datafunction(QV8Engine *engine) \
@@ -147,19 +111,6 @@ QT_BEGIN_NAMESPACE
return rv; \
} \
-template<class T>
-inline T *v8_resource_cast(v8::Handle<v8::Object> object) {
- QV8ObjectResource *resource = static_cast<QV8ObjectResource *>(object->GetExternalResource());
- return (resource && (quint32)resource->resourceType() == (quint32)T::V8ResourceType)?static_cast<T *>(resource):0;
-}
-
-template<class T>
-inline T *v8_resource_check(v8::Handle<v8::Object> object) {
- T *resource = static_cast<T *>(object->GetExternalResource());
- Q_ASSERT(resource && resource->resourceType() == (quint32)T::V8ResourceType);
- return resource;
-}
-
// Used to allow a QObject method take and return raw V8 handles without having to expose
// v8 in the public API.
// Use like this:
@@ -172,50 +123,52 @@ inline T *v8_resource_check(v8::Handle<v8::Object> object) {
// valid during the call. If the return value isn't set within myMethod(), the will return
// undefined.
class QV8Engine;
-class QQmlV8Function
+class QQmlV4Function
{
public:
- int Length() const { return _ac; }
- v8::Local<v8::Value> operator[](int idx) { return (*_a)->Get(idx); }
- QQmlContextData *context() { return _c; }
- v8::Handle<v8::Object> qmlGlobal() { return *_g; }
- void returnValue(v8::Handle<v8::Value> rv) { *_r = rv; }
- QV8Engine *engine() const { return _e; }
+ int length() const { return argc; }
+ QV4::Value operator[](int idx) { return args[idx]; }
+ QQmlContextData *context() { return ctx; }
+ QV4::Value qmlGlobal() { return global; }
+ void setReturnValue(const QV4::Value &rv) { *retVal = rv; }
+ QV8Engine *engine() const { return e; }
private:
friend class QV8QObjectWrapper;
- QQmlV8Function();
- QQmlV8Function(const QQmlV8Function &);
- QQmlV8Function &operator=(const QQmlV8Function &);
+ friend struct QV4::QObjectMethod;
+ QQmlV4Function();
+ QQmlV4Function(const QQmlV4Function &);
+ QQmlV4Function &operator=(const QQmlV4Function &);
- QQmlV8Function(int length, v8::Handle<v8::Object> &args,
- v8::Handle<v8::Value> &rv, v8::Handle<v8::Object> &global,
+ QQmlV4Function(int length, QV4::Value *args,
+ QV4::Value *rv, const QV4::Value &global,
QQmlContextData *c, QV8Engine *e)
- : _ac(length), _a(&args), _r(&rv), _g(&global), _c(c), _e(e) {}
-
- int _ac;
- v8::Handle<v8::Object> *_a;
- v8::Handle<v8::Value> *_r;
- v8::Handle<v8::Object> *_g;
- QQmlContextData *_c;
- QV8Engine *_e;
+ : argc(length), args(args), retVal(rv), global(global), ctx(c), e(e) {}
+
+ int argc;
+ QV4::Value *args;
+ QV4::Value *retVal;
+ QV4::Value global;
+ QQmlContextData *ctx;
+ QV8Engine *e;
};
-class QQmlV8Handle
+class Q_QML_PRIVATE_EXPORT QQmlV4Handle
{
public:
- QQmlV8Handle() : d(0) {}
- QQmlV8Handle(const QQmlV8Handle &other) : d(other.d) {}
- QQmlV8Handle &operator=(const QQmlV8Handle &other) { d = other.d; return *this; }
-
- static QQmlV8Handle fromHandle(v8::Handle<v8::Value> h) {
- return QQmlV8Handle(*h);
- }
- v8::Handle<v8::Value> toHandle() const {
- return v8::Handle<v8::Value>((v8::Value *)d);
+ QQmlV4Handle() : d(0) {}
+ QQmlV4Handle(const QQmlV4Handle &other) : d(other.d) {}
+ QQmlV4Handle &operator=(const QQmlV4Handle &other) { d = other.d; return *this; }
+ explicit QQmlV4Handle(const QV4::Value &v) : d(v.val) {}
+
+ QV4::Value toValue() const {
+ QV4::Value v;
+ v.val = d;
+ return v;
}
+
private:
- QQmlV8Handle(void *d) : d(d) {}
- void *d;
+ QQmlV4Handle(quint64 h) : d(h) {}
+ quint64 d;
};
class QObject;
@@ -224,39 +177,17 @@ class QQmlValueType;
class QNetworkAccessManager;
class QQmlContextData;
-class Q_AUTOTEST_EXPORT QV8GCCallback
-{
-private:
- class ThreadData;
-public:
- static void garbageCollectorPrologueCallback(v8::GCType, v8::GCCallbackFlags);
- static void registerGcPrologueCallback();
-
- class Q_AUTOTEST_EXPORT Node {
- public:
- typedef void (*PrologueCallback)(Node *node);
- Node(PrologueCallback callback);
- ~Node();
-
- QIntrusiveListNode node;
- PrologueCallback prologueCallback;
- };
-
- static void addGcCallbackNode(Node *node);
-};
-
class Q_QML_PRIVATE_EXPORT QV8Engine
{
- typedef QSet<v8::Handle<v8::Object> > V8ObjectSet;
+ friend class QJSEngine;
+ typedef QSet<QV4::Object *> V8ObjectSet;
public:
static QV8Engine* get(QJSEngine* q) { Q_ASSERT(q); return q->handle(); }
- static QJSEngine* get(QV8Engine* d) { Q_ASSERT(d); return d->q; }
+// static QJSEngine* get(QV8Engine* d) { Q_ASSERT(d); return d->q; }
+ static QV4::ExecutionEngine *getV4(QJSEngine *q) { return q->handle()->m_v4Engine; }
+ static QV4::ExecutionEngine *getV4(QV8Engine *d) { return d->m_v4Engine; }
- enum ContextOwnership {
- AdoptCurrentContext,
- CreateNewContext
- };
- QV8Engine(QJSEngine* qq, ContextOwnership ownership = CreateNewContext);
+ QV8Engine(QJSEngine* qq);
virtual ~QV8Engine();
// This enum should be in sync with QQmlEngine::ObjectOwnership
@@ -269,24 +200,8 @@ public:
void initQmlGlobalObject();
void setEngine(QQmlEngine *engine);
QQmlEngine *engine() { return m_engine; }
- v8::Local<v8::Object> global() { return m_context->Global(); }
- v8::Handle<v8::Context> context() const { return m_context; }
-
- inline void registerValue(QJSValuePrivate *data);
- inline void unregisterValue(QJSValuePrivate *data);
- inline void invalidateAllValues();
-
- inline void registerValueIterator(QJSValueIteratorPrivate *data);
- inline void unregisterValueIterator(QJSValueIteratorPrivate *data);
- inline void invalidateAllIterators();
-
- QV8ContextWrapper *contextWrapper() { return &m_contextWrapper; }
- QV8QObjectWrapper *qobjectWrapper() { return &m_qobjectWrapper; }
- QV8TypeWrapper *typeWrapper() { return &m_typeWrapper; }
- QV8ListWrapper *listWrapper() { return &m_listWrapper; }
- QV8VariantWrapper *variantWrapper() { return &m_variantWrapper; }
- QV8ValueTypeWrapper *valueTypeWrapper() { return &m_valueTypeWrapper; }
- QV8SequenceWrapper *sequenceWrapper() { return &m_sequenceWrapper; }
+ QJSEngine *publicEngine() { return q; }
+ QV4::Value global();
void *xmlHttpRequestData() { return m_xmlHttpRequestData; }
@@ -295,55 +210,13 @@ public:
QQmlContextData *callingContext();
- v8::Local<v8::Array> getOwnPropertyNames(v8::Handle<v8::Object>);
- inline QJSValuePrivate::PropertyFlags getPropertyFlags(v8::Handle<v8::Object> object, v8::Handle<v8::Value> property);
- void freezeObject(v8::Handle<v8::Value>);
-
- inline QString toString(v8::Handle<v8::Value> string);
- inline QString toString(v8::Handle<v8::String> string);
- static QString toStringStatic(v8::Handle<v8::Value>);
- static QString toStringStatic(v8::Handle<v8::String>);
- static inline bool startsWithUpper(v8::Handle<v8::String>);
-
- QVariant toVariant(v8::Handle<v8::Value>, int typeHint);
- v8::Handle<v8::Value> fromVariant(const QVariant &);
- inline bool isVariant(v8::Handle<v8::Value>);
-
- // Compile \a source (from \a fileName at \a lineNumber) in QML mode
- v8::Local<v8::Script> qmlModeCompile(const QString &source,
- const QString &fileName = QString(),
- quint16 lineNumber = 1);
- v8::Local<v8::Script> qmlModeCompile(const char *source, int sourceLength = -1,
- const QString &fileName = QString(),
- quint16 lineNumber = 1);
-
- // Return the QML global "scope" object for the \a ctxt context and \a scope object.
- inline v8::Local<v8::Object> qmlScope(QQmlContextData *ctxt, QObject *scope);
-
- // Return a JS wrapper for the given QObject \a object
- inline v8::Handle<v8::Value> newQObject(QObject *object);
- inline v8::Handle<v8::Value> newQObject(QObject *object, const ObjectOwnership ownership);
- inline bool isQObject(v8::Handle<v8::Value>);
- inline QObject *toQObject(v8::Handle<v8::Value>);
-
- // Return a JS string for the given QString \a string
- inline v8::Local<v8::String> toString(const QString &string);
-
- // Create a new value type object
- inline v8::Handle<v8::Value> newValueType(QObject *, int coreIndex, QQmlValueType *);
- inline v8::Handle<v8::Value> newValueType(const QVariant &, QQmlValueType *);
- inline bool isValueType(v8::Handle<v8::Value>) const;
- inline QVariant toValueType(v8::Handle<v8::Value> obj);
+ void freezeObject(const QV4::Value &value);
- // Create a new sequence type object
- inline v8::Handle<v8::Value> newSequence(int sequenceType, QObject *, int coreIndex, bool *succeeded);
+ QVariant toVariant(const QV4::Value &value, int typeHint);
+ QV4::Value fromVariant(const QVariant &);
- // Create a new QVariant object. This doesn't examine the type of the variant, but always returns
- // a QVariant wrapper
- inline v8::Handle<v8::Value> newQVariant(const QVariant &);
-
- // Return the JS string key for the "function is a binding" flag
- inline v8::Handle<v8::String> bindingFlagKey() const;
+ // Return a JS string for the given QString \a string
+ QV4::Value toString(const QString &string);
// Return the network access manager for this engine. By default this returns the network
// access manager of the QQmlEngine. It is overridden in the case of a threaded v8
@@ -354,15 +227,7 @@ public:
const QStringHash<bool> &illegalNames() const;
inline void collectGarbage() { gc(); }
- static void gc();
-
- v8::Handle<v8::Value> throwException(v8::Handle<v8::Value> value);
-
-#ifdef QML_GLOBAL_HANDLE_DEBUGGING
- // Used for handle debugging
- static void registerHandle(void *);
- static void releaseHandle(void *);
-#endif
+ void gc();
static QMutex *registrationMutex();
static int registerExtension();
@@ -370,49 +235,25 @@ public:
inline Deletable *extensionData(int) const;
void setExtensionData(int, Deletable *);
- inline v8::Handle<v8::Value> makeJSValue(bool value);
- inline v8::Local<v8::Value> makeJSValue(int value);
- inline v8::Local<v8::Value> makeJSValue(uint value);
- inline v8::Local<v8::Value> makeJSValue(double value);
- inline v8::Handle<v8::Value> makeJSValue(QJSValue::SpecialValue value);
- inline v8::Local<v8::Value> makeJSValue(const QString &value);
-
- inline QScriptPassPointer<QJSValuePrivate> evaluate(const QString &program, const QString &fileName = QString(), quint16 lineNumber = 1);
- QScriptPassPointer<QJSValuePrivate> evaluate(v8::Handle<v8::Script> script, v8::TryCatch& tryCatch);
-
- QScriptPassPointer<QJSValuePrivate> newArray(uint length);
- v8::Local<v8::Object> newVariant(const QVariant &variant);
-
- v8::Local<v8::Array> variantListToJS(const QVariantList &lst);
- inline QVariantList variantListFromJS(v8::Handle<v8::Array> jsArray)
- { V8ObjectSet visitedObjects; return variantListFromJS(jsArray, visitedObjects); }
+ QV4::Value variantListToJS(const QVariantList &lst);
+ inline QVariantList variantListFromJS(QV4::ArrayObject *array)
+ { V8ObjectSet visitedObjects; return variantListFromJS(array, visitedObjects); }
- v8::Local<v8::Object> variantMapToJS(const QVariantMap &vmap);
- inline QVariantMap variantMapFromJS(v8::Handle<v8::Object> jsObject)
- { V8ObjectSet visitedObjects; return variantMapFromJS(jsObject, visitedObjects); }
+ QV4::Value variantMapToJS(const QVariantMap &vmap);
+ inline QVariantMap variantMapFromJS(QV4::Object *object)
+ { V8ObjectSet visitedObjects; return variantMapFromJS(object, visitedObjects); }
- v8::Handle<v8::Value> variantToJS(const QVariant &value);
- inline QVariant variantFromJS(v8::Handle<v8::Value> value)
+ QV4::Value variantToJS(const QVariant &value);
+ inline QVariant variantFromJS(const QV4::Value &value)
{ V8ObjectSet visitedObjects; return variantFromJS(value, visitedObjects); }
- v8::Handle<v8::Value> jsonValueToJS(const QJsonValue &value);
- QJsonValue jsonValueFromJS(v8::Handle<v8::Value> value);
- v8::Local<v8::Object> jsonObjectToJS(const QJsonObject &object);
- QJsonObject jsonObjectFromJS(v8::Handle<v8::Value> value);
- v8::Local<v8::Array> jsonArrayToJS(const QJsonArray &array);
- QJsonArray jsonArrayFromJS(v8::Handle<v8::Value> value);
+ QV4::Value metaTypeToJS(int type, const void *data);
+ bool metaTypeFromJS(const QV4::Value &value, int type, void *data);
- v8::Handle<v8::Value> metaTypeToJS(int type, const void *data);
- bool metaTypeFromJS(v8::Handle<v8::Value> value, int type, void *data);
-
- bool convertToNativeQObject(v8::Handle<v8::Value> value,
+ bool convertToNativeQObject(const QV4::Value &value,
const QByteArray &targetType,
void **result);
- QVariant &variantValue(v8::Handle<v8::Value> value);
-
- QJSValue scriptValueFromInternal(v8::Handle<v8::Value>) const;
-
// used for console.time(), console.timeEnd()
void startTimer(const QString &timerName);
qint64 stopTimer(const QString &timerName, bool *wasRunning);
@@ -420,54 +261,15 @@ public:
// used for console.count()
int consoleCountHelper(const QString &file, quint16 line, quint16 column);
- QObject *qtObjectFromJS(v8::Handle<v8::Value> value);
-
- static QDateTime qtDateTimeFromJsDate(double jsDate);
-
- void addRelationshipForGC(QObject *object, v8::Persistent<v8::Value> handle);
- void addRelationshipForGC(QObject *object, QObject *other);
-
- static v8::Handle<v8::Value> getPlatform(v8::Local<v8::String> property, const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> getApplication(v8::Local<v8::String> property, const v8::AccessorInfo &info);
-#ifndef QT_NO_IM
- static v8::Handle<v8::Value> getInputMethod(v8::Local<v8::String> property, const v8::AccessorInfo &info);
-#endif
-
- struct ThreadData {
- ThreadData();
- ~ThreadData();
- v8::Isolate* isolate;
- bool gcPrologueCallbackRegistered;
- QIntrusiveList<QV8GCCallback::Node, &QV8GCCallback::Node::node> gcCallbackNodes;
- };
-
- static bool hasThreadData();
- static ThreadData* threadData();
- static void ensurePerThreadIsolate();
-
- v8::Persistent<v8::Object> m_strongReferencer;
+ QObject *qtObjectFromJS(const QV4::Value &value);
protected:
QJSEngine* q;
QQmlEngine *m_engine;
- bool m_ownsV8Context;
- v8::Persistent<v8::Context> m_context;
- QScriptOriginalGlobalObject m_originalGlobalObject;
- v8::Persistent<v8::String> m_bindingFlagKey;
+ QV4::ExecutionEngine *m_v4Engine;
- QV8StringWrapper m_stringWrapper;
- QV8ContextWrapper m_contextWrapper;
- QV8QObjectWrapper m_qobjectWrapper;
- QV8TypeWrapper m_typeWrapper;
- QV8ListWrapper m_listWrapper;
- QV8VariantWrapper m_variantWrapper;
- QV8ValueTypeWrapper m_valueTypeWrapper;
- QV8SequenceWrapper m_sequenceWrapper;
- QV8JsonWrapper m_jsonWrapper;
-
- v8::Persistent<v8::Function> m_getOwnPropertyNames;
- v8::Persistent<v8::Function> m_freezeObject;
+ QV4::PersistentValue m_freezeObject;
void *m_xmlHttpRequestData;
@@ -481,161 +283,18 @@ protected:
QHash<QString, quint32> m_consoleCount;
- QObject *m_platform;
- QObject *m_application;
-
- QVariant toBasicVariant(v8::Handle<v8::Value>);
+ QVariant toBasicVariant(const QV4::Value &);
- void initializeGlobal(v8::Handle<v8::Object>);
-
- double qtDateTimeToJsDate(const QDateTime &dt);
+ void initializeGlobal();
private:
- QVariantList variantListFromJS(v8::Handle<v8::Array> jsArray, V8ObjectSet &visitedObjects);
- QVariantMap variantMapFromJS(v8::Handle<v8::Object> jsObject, V8ObjectSet &visitedObjects);
- QVariant variantFromJS(v8::Handle<v8::Value> value, V8ObjectSet &visitedObjects);
-
- static v8::Persistent<v8::Object> *findOwnerAndStrength(QObject *object, bool *shouldBeStrong);
-
- typedef QScriptIntrusiveList<QJSValuePrivate, &QJSValuePrivate::m_node> ValueList;
- ValueList m_values;
- typedef QScriptIntrusiveList<QJSValueIteratorPrivate, &QJSValueIteratorPrivate::m_node> ValueIteratorList;
- ValueIteratorList m_valueIterators;
+ QVariantList variantListFromJS(QV4::ArrayObject *array, V8ObjectSet &visitedObjects);
+ QVariantMap variantMapFromJS(QV4::Object *object, V8ObjectSet &visitedObjects);
+ QVariant variantFromJS(const QV4::Value &value, V8ObjectSet &visitedObjects);
Q_DISABLE_COPY(QV8Engine)
};
-// Allocate a new Persistent handle. *ALL* persistent handles in QML must be allocated
-// using this method.
-template<class T>
-v8::Persistent<T> qPersistentNew(v8::Handle<T> that)
-{
- v8::Persistent<T> rv = v8::Persistent<T>::New(that);
-#ifdef QML_GLOBAL_HANDLE_DEBUGGING
- QV8Engine::registerHandle(*rv);
-#endif
- return rv;
-}
-
-// Register a Persistent handle that was returned to you by V8 (such as by
-// v8::Context::New). This allows us to do handle tracking on these handles too.
-template<class T>
-void qPersistentRegister(v8::Persistent<T> handle)
-{
-#ifdef QML_GLOBAL_HANDLE_DEBUGGING
- QV8Engine::registerHandle(*handle);
-#else
- Q_UNUSED(handle);
-#endif
-}
-
-// Dispose and clear a persistent handle. *ALL* persistent handles in QML must be
-// disposed using this method.
-template<class T>
-void qPersistentDispose(v8::Persistent<T> &that)
-{
-#ifdef QML_GLOBAL_HANDLE_DEBUGGING
- QV8Engine::releaseHandle(*that);
-#endif
- that.Dispose();
- that.Clear();
-}
-
-QString QV8Engine::toString(v8::Handle<v8::Value> string)
-{
- return m_stringWrapper.toString(string->ToString());
-}
-
-QString QV8Engine::toString(v8::Handle<v8::String> string)
-{
- return m_stringWrapper.toString(string);
-}
-
-bool QV8Engine::isVariant(v8::Handle<v8::Value> value)
-{
- return m_variantWrapper.isVariant(value);
-}
-
-v8::Local<v8::Object> QV8Engine::qmlScope(QQmlContextData *ctxt, QObject *scope)
-{
- return m_contextWrapper.qmlScope(ctxt, scope);
-}
-
-bool QV8Engine::isQObject(v8::Handle<v8::Value> obj)
-{
- return obj->IsObject()?m_qobjectWrapper.isQObject(v8::Handle<v8::Object>::Cast(obj)):false;
-}
-
-QObject *QV8Engine::toQObject(v8::Handle<v8::Value> obj)
-{
- return obj->IsObject()?m_qobjectWrapper.toQObject(v8::Handle<v8::Object>::Cast(obj)):0;
-}
-
-v8::Handle<v8::Value> QV8Engine::newQObject(QObject *object)
-{
- return m_qobjectWrapper.newQObject(object);
-}
-
-v8::Handle<v8::Value> QV8Engine::newQObject(QObject *object, const ObjectOwnership ownership)
-{
- if (!object)
- return v8::Null();
-
- v8::Handle<v8::Value> result = newQObject(object);
- QQmlData *ddata = QQmlData::get(object, true);
- if (ownership == JavaScriptOwnership && ddata) {
- ddata->indestructible = false;
- ddata->explicitIndestructibleSet = true;
- }
- return result;
-}
-
-v8::Local<v8::String> QV8Engine::toString(const QString &string)
-{
- return m_stringWrapper.toString(string);
-}
-
-v8::Handle<v8::Value> QV8Engine::newValueType(QObject *object, int property, QQmlValueType *type)
-{
- return m_valueTypeWrapper.newValueType(object, property, type);
-}
-
-v8::Handle<v8::Value> QV8Engine::newValueType(const QVariant &value, QQmlValueType *type)
-{
- return m_valueTypeWrapper.newValueType(value, type);
-}
-
-bool QV8Engine::isValueType(v8::Handle<v8::Value> obj) const
-{
- return obj->IsObject()?m_valueTypeWrapper.isValueType(v8::Handle<v8::Object>::Cast(obj)):false;
-}
-
-QVariant QV8Engine::toValueType(v8::Handle<v8::Value> obj)
-{
- return obj->IsObject()?m_valueTypeWrapper.toVariant(v8::Handle<v8::Object>::Cast(obj)):QVariant();
-}
-
-v8::Handle<v8::Value> QV8Engine::newSequence(int sequenceType, QObject *object, int property, bool *succeeded)
-{
- return m_sequenceWrapper.newSequence(sequenceType, object, property, succeeded);
-}
-
-v8::Handle<v8::String> QV8Engine::bindingFlagKey() const
-{
- return m_bindingFlagKey;
-}
-
-// XXX Can this be made more optimal? It is called prior to resolving each and every
-// unqualified name in QV8ContextWrapper.
-bool QV8Engine::startsWithUpper(v8::Handle<v8::String> string)
-{
- v8::String::Value value(string);
- Q_ASSERT(*value != NULL);
- uint16_t c = **value;
- return (c >= 'A' && c <= 'Z') ||
- (c > 127 && QChar::category(c) == QChar::Letter_Uppercase);
-}
-
QV8Engine::Deletable *QV8Engine::extensionData(int index) const
{
if (index < m_extensionData.count())
@@ -646,6 +305,6 @@ QV8Engine::Deletable *QV8Engine::extensionData(int index) const
QT_END_NAMESPACE
-Q_DECLARE_METATYPE(QQmlV8Handle)
+Q_DECLARE_METATYPE(QQmlV4Handle)
#endif // QQMLV8ENGINE_P_H
diff --git a/src/qml/qml/v8/qv8include.cpp b/src/qml/qml/v8/qv8include.cpp
deleted file mode 100644
index 101c3d24c3..0000000000
--- a/src/qml/qml/v8/qv8include.cpp
+++ /dev/null
@@ -1,245 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv8include_p.h"
-
-#include <QtQml/qjsengine.h>
-#include <QtNetwork/qnetworkrequest.h>
-#include <QtNetwork/qnetworkreply.h>
-#include <QtCore/qfile.h>
-#include <QtQml/qqmlfile.h>
-
-#include <private/qqmlengine_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QV8Include::QV8Include(const QUrl &url, QV8Engine *engine, QQmlContextData *context,
- v8::Handle<v8::Object> qmlglobal, v8::Handle<v8::Function> callback)
-: m_engine(engine), m_network(0), m_reply(0), m_url(url), m_redirectCount(0), m_context(context)
-{
- m_qmlglobal = qPersistentNew<v8::Object>(qmlglobal);
- if (!callback.IsEmpty())
- m_callbackFunction = qPersistentNew<v8::Function>(callback);
-
- m_resultObject = qPersistentNew<v8::Object>(resultValue());
-
- m_network = engine->networkAccessManager();
-
- QNetworkRequest request;
- request.setUrl(url);
-
- m_reply = m_network->get(request);
- QObject::connect(m_reply, SIGNAL(finished()), this, SLOT(finished()));
-}
-
-QV8Include::~QV8Include()
-{
- delete m_reply; m_reply = 0;
- qPersistentDispose(m_callbackFunction);
- qPersistentDispose(m_resultObject);
-}
-
-v8::Local<v8::Object> QV8Include::resultValue(Status status)
-{
- // XXX It seems inefficient to create this object from scratch each time.
- v8::Local<v8::Object> result = v8::Object::New();
- result->Set(v8::String::New("OK"), v8::Integer::New(Ok));
- result->Set(v8::String::New("LOADING"), v8::Integer::New(Loading));
- result->Set(v8::String::New("NETWORK_ERROR"), v8::Integer::New(NetworkError));
- result->Set(v8::String::New("EXCEPTION"), v8::Integer::New(Exception));
-
- result->Set(v8::String::New("status"), v8::Integer::New(status));
-
- return result;
-}
-
-void QV8Include::callback(QV8Engine *engine, v8::Handle<v8::Function> callback, v8::Handle<v8::Object> status)
-{
- if (!callback.IsEmpty()) {
- v8::Handle<v8::Value> args[] = { status };
- v8::TryCatch tc;
- callback->Call(engine->global(), 1, args);
- }
-}
-
-v8::Handle<v8::Object> QV8Include::result()
-{
- return m_resultObject;
-}
-
-#define INCLUDE_MAXIMUM_REDIRECT_RECURSION 15
-void QV8Include::finished()
-{
- m_redirectCount++;
-
- if (m_redirectCount < INCLUDE_MAXIMUM_REDIRECT_RECURSION) {
- QVariant redirect = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
- if (redirect.isValid()) {
- m_url = m_url.resolved(redirect.toUrl());
- delete m_reply;
-
- QNetworkRequest request;
- request.setUrl(m_url);
-
- m_reply = m_network->get(request);
- QObject::connect(m_reply, SIGNAL(finished()), this, SLOT(finished()));
- return;
- }
- }
-
- v8::HandleScope handle_scope;
-
- if (m_reply->error() == QNetworkReply::NoError) {
- QByteArray data = m_reply->readAll();
-
- QString code = QString::fromUtf8(data);
- QQmlScript::Parser::extractPragmas(code);
-
- QQmlContextData *importContext = new QQmlContextData;
- importContext->isInternal = true;
- importContext->isJSContext = true;
- importContext->url = m_url;
- importContext->isPragmaLibraryContext = m_context->isPragmaLibraryContext;
- importContext->setParent(m_context, true);
-
- v8::Context::Scope ctxtscope(m_engine->context());
- v8::TryCatch try_catch;
-
- v8::Local<v8::Script> script = m_engine->qmlModeCompile(code, m_url.toString());
-
- if (!try_catch.HasCaught()) {
- m_engine->contextWrapper()->addSubContext(m_qmlglobal, script, importContext);
- script->Run(m_qmlglobal);
- }
-
- if (try_catch.HasCaught()) {
- m_resultObject->Set(v8::String::New("status"), v8::Integer::New(Exception));
- m_resultObject->Set(v8::String::New("exception"), try_catch.Exception());
- } else {
- m_resultObject->Set(v8::String::New("status"), v8::Integer::New(Ok));
- }
- } else {
- m_resultObject->Set(v8::String::New("status"), v8::Integer::New(NetworkError));
- }
-
- callback(m_engine, m_callbackFunction, m_resultObject);
-
- disconnect();
- deleteLater();
-}
-
-/*
- Documented in qv8engine.cpp
-*/
-v8::Handle<v8::Value> QV8Include::include(const v8::Arguments &args)
-{
- if (args.Length() == 0)
- return v8::Undefined();
-
- QV8Engine *engine = V8ENGINE();
- QQmlContextData *context = engine->callingContext();
-
- if (!context || !context->isJSContext)
- V8THROW_ERROR("Qt.include(): Can only be called from JavaScript files");
-
- QUrl url(context->resolvedUrl(QUrl(engine->toString(args[0]->ToString()))));
-
- v8::Local<v8::Function> callbackFunction;
- if (args.Length() >= 2 && args[1]->IsFunction())
- callbackFunction = v8::Local<v8::Function>::Cast(args[1]);
-
- QString localFile = QQmlFile::urlToLocalFileOrQrc(url);
-
- v8::Local<v8::Object> result;
-
- if (localFile.isEmpty()) {
-
- QV8Include *i = new QV8Include(url, engine, context,
- v8::Context::GetCallingQmlGlobal(),
- callbackFunction);
- result = v8::Local<v8::Object>::New(i->result());
-
- } else {
-
- QFile f(localFile);
-
- if (f.open(QIODevice::ReadOnly)) {
- QByteArray data = f.readAll();
- QString code = QString::fromUtf8(data);
- QQmlScript::Parser::extractPragmas(code);
-
- QQmlContextData *importContext = new QQmlContextData;
- importContext->isInternal = true;
- importContext->isJSContext = true;
- importContext->url = url;
- importContext->setParent(context, true);
-
- v8::TryCatch try_catch;
-
- v8::Local<v8::Script> script = engine->qmlModeCompile(code, url.toString());
-
- if (!try_catch.HasCaught()) {
- v8::Local<v8::Object> qmlglobal = v8::Context::GetCallingQmlGlobal();
- engine->contextWrapper()->addSubContext(qmlglobal, script, importContext);
- script->Run(qmlglobal);
- }
-
- if (try_catch.HasCaught()) {
- result = resultValue(Exception);
- result->Set(v8::String::New("exception"), try_catch.Exception());
- } else {
- result = resultValue(Ok);
- }
-
- } else {
- result = resultValue(NetworkError);
- }
-
- callback(engine, callbackFunction, result);
- }
-
- if (result.IsEmpty())
- return v8::Undefined();
- else
- return result;
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv8include_p.h b/src/qml/qml/v8/qv8include_p.h
deleted file mode 100644
index 9f850e82b6..0000000000
--- a/src/qml/qml/v8/qv8include_p.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV8INCLUDE_P_H
-#define QV8INCLUDE_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/qobject.h>
-#include <QtCore/qurl.h>
-
-#include <private/qqmlcontext_p.h>
-#include <private/qqmlguard_p.h>
-
-#include <private/qv8_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQmlEngine;
-class QNetworkAccessManager;
-class QNetworkReply;
-class QV8Engine;
-class QV8Include : public QObject
-{
- Q_OBJECT
-public:
- enum Status {
- Ok = 0,
- Loading = 1,
- NetworkError = 2,
- Exception = 3
- };
-
- static v8::Handle<v8::Value> include(const v8::Arguments &args);
-
-private slots:
- void finished();
-
-private:
- QV8Include(const QUrl &, QV8Engine *, QQmlContextData *,
- v8::Handle<v8::Object>, v8::Handle<v8::Function>);
- ~QV8Include();
-
- v8::Handle<v8::Object> result();
-
- static v8::Local<v8::Object> resultValue(Status status = Loading);
- static void callback(QV8Engine *engine, v8::Handle<v8::Function> callback, v8::Handle<v8::Object> status);
-
- QV8Engine *m_engine;
- QNetworkAccessManager *m_network;
- QQmlGuard<QNetworkReply> m_reply;
-
- QUrl m_url;
- int m_redirectCount;
-
- v8::Persistent<v8::Function> m_callbackFunction;
- v8::Persistent<v8::Object> m_resultObject;
-
- QQmlGuardedContextData m_context;
- v8::Persistent<v8::Object> m_qmlglobal;
-};
-
-QT_END_NAMESPACE
-
-#endif // QV8INCLUDE_P_H
-
diff --git a/src/qml/qml/v8/qv8jsonwrapper.cpp b/src/qml/qml/v8/qv8jsonwrapper.cpp
deleted file mode 100644
index 4d89551894..0000000000
--- a/src/qml/qml/v8/qv8jsonwrapper.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv8jsonwrapper_p.h"
-#include "qv8engine_p.h"
-#include "qjsconverter_impl_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QV8JsonWrapper::QV8JsonWrapper()
-: m_engine(0)
-{
-}
-
-QV8JsonWrapper::~QV8JsonWrapper()
-{
-}
-
-void QV8JsonWrapper::init(QV8Engine *engine)
-{
- m_engine = engine;
-}
-
-void QV8JsonWrapper::destroy()
-{
-}
-
-v8::Handle<v8::Value> QV8JsonWrapper::fromJsonValue(const QJsonValue &value)
-{
- if (value.isString())
- return QJSConverter::toString(value.toString());
- else if (value.isDouble())
- return v8::Number::New(value.toDouble());
- else if (value.isBool())
- return value.toBool() ? v8::True() : v8::False();
- else if (value.isArray())
- return fromJsonArray(value.toArray());
- else if (value.isObject())
- return fromJsonObject(value.toObject());
- else if (value.isNull())
- return v8::Null();
- else
- return v8::Undefined();
-}
-
-QJsonValue QV8JsonWrapper::toJsonValue(v8::Handle<v8::Value> value,
- V8ObjectSet &visitedObjects)
-{
- if (value->IsString())
- return QJsonValue(QJSConverter::toString(value.As<v8::String>()));
- else if (value->IsNumber())
- return QJsonValue(value->NumberValue());
- else if (value->IsBoolean())
- return QJsonValue(value->BooleanValue());
- else if (value->IsArray())
- return toJsonArray(value.As<v8::Array>(), visitedObjects);
- else if (value->IsObject())
- return toJsonObject(value.As<v8::Object>(), visitedObjects);
- else if (value->IsNull())
- return QJsonValue(QJsonValue::Null);
- else
- return QJsonValue(QJsonValue::Undefined);
-}
-
-v8::Local<v8::Object> QV8JsonWrapper::fromJsonObject(const QJsonObject &object)
-{
- v8::Local<v8::Object> v8object = v8::Object::New();
- for (QJsonObject::const_iterator it = object.begin(); it != object.end(); ++it)
- v8object->Set(QJSConverter::toString(it.key()), fromJsonValue(it.value()));
- return v8object;
-}
-
-QJsonObject QV8JsonWrapper::toJsonObject(v8::Handle<v8::Value> value,
- V8ObjectSet &visitedObjects)
-{
- QJsonObject result;
- if (!value->IsObject() || value->IsArray() || value->IsFunction())
- return result;
-
- v8::Handle<v8::Object> v8object(value.As<v8::Object>());
- if (visitedObjects.contains(v8object)) {
- // Avoid recursion.
- // For compatibility with QVariant{List,Map} conversion, we return an
- // empty object (and no error is thrown).
- return result;
- }
-
- visitedObjects.insert(v8object);
-
- v8::Local<v8::Array> propertyNames = m_engine->getOwnPropertyNames(v8object);
- uint32_t length = propertyNames->Length();
- for (uint32_t i = 0; i < length; ++i) {
- v8::Local<v8::Value> name = propertyNames->Get(i);
- v8::Local<v8::Value> propertyValue = v8object->Get(name);
- if (!propertyValue->IsFunction())
- result.insert(QJSConverter::toString(name->ToString()),
- toJsonValue(propertyValue, visitedObjects));
- }
-
- visitedObjects.remove(v8object);
-
- return result;
-}
-
-v8::Local<v8::Array> QV8JsonWrapper::fromJsonArray(const QJsonArray &array)
-{
- int size = array.size();
- v8::Local<v8::Array> v8array = v8::Array::New(size);
- for (int i = 0; i < size; i++)
- v8array->Set(i, fromJsonValue(array.at(i)));
- return v8array;
-}
-
-QJsonArray QV8JsonWrapper::toJsonArray(v8::Handle<v8::Value> value,
- V8ObjectSet &visitedObjects)
-{
- QJsonArray result;
- if (!value->IsArray())
- return result;
-
- v8::Handle<v8::Array> v8array(value.As<v8::Array>());
- if (visitedObjects.contains(v8array)) {
- // Avoid recursion.
- // For compatibility with QVariant{List,Map} conversion, we return an
- // empty array (and no error is thrown).
- return result;
- }
-
- visitedObjects.insert(v8array);
-
- uint32_t length = v8array->Length();
- for (uint32_t i = 0; i < length; ++i) {
- v8::Local<v8::Value> element = v8array->Get(i);
- if (!element->IsFunction())
- result.append(toJsonValue(element, visitedObjects));
- }
-
- visitedObjects.remove(v8array);
-
- return result;
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv8jsonwrapper_p.h b/src/qml/qml/v8/qv8jsonwrapper_p.h
deleted file mode 100644
index eb4a197819..0000000000
--- a/src/qml/qml/v8/qv8jsonwrapper_p.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV8JSONWRAPPER_P_H
-#define QV8JSONWRAPPER_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/qglobal.h>
-#include <QtCore/qset.h>
-#include <private/qv8_p.h>
-
-#include <QtCore/qjsonarray.h>
-#include <QtCore/qjsonobject.h>
-#include <QtCore/qjsonvalue.h>
-
-QT_BEGIN_NAMESPACE
-
-class QV8Engine;
-class QV8JsonWrapper
-{
- typedef QSet<v8::Handle<v8::Object> > V8ObjectSet;
-public:
- QV8JsonWrapper();
- ~QV8JsonWrapper();
-
- void init(QV8Engine *);
- void destroy();
-
- v8::Handle<v8::Value> fromJsonValue(const QJsonValue &value);
- inline QJsonValue toJsonValue(v8::Handle<v8::Value> value)
- { V8ObjectSet visitedObjects; return toJsonValue(value, visitedObjects); }
-
- v8::Local<v8::Object> fromJsonObject(const QJsonObject &object);
- inline QJsonObject toJsonObject(v8::Handle<v8::Value> value)
- { V8ObjectSet visitedObjects; return toJsonObject(value, visitedObjects); }
-
- v8::Local<v8::Array> fromJsonArray(const QJsonArray &array);
- inline QJsonArray toJsonArray(v8::Handle<v8::Value> value)
- { V8ObjectSet visitedObjects; return toJsonArray(value, visitedObjects); }
-
-private:
- QJsonValue toJsonValue(v8::Handle<v8::Value> value, V8ObjectSet &visitedObjects);
- QJsonObject toJsonObject(v8::Handle<v8::Value> value, V8ObjectSet &visitedObjects);
- QJsonArray toJsonArray(v8::Handle<v8::Value> value, V8ObjectSet &visitedObjects);
-
- QV8Engine *m_engine;
-};
-
-QT_END_NAMESPACE
-
-#endif // QV8JSONWRAPPER_P_H
-
diff --git a/src/qml/qml/v8/qv8listwrapper.cpp b/src/qml/qml/v8/qv8listwrapper.cpp
deleted file mode 100644
index d3ce9f8fc2..0000000000
--- a/src/qml/qml/v8/qv8listwrapper.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv8listwrapper_p.h"
-#include "qv8engine_p.h"
-#include <private/qqmllist_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QV8ListResource : public QV8ObjectResource
-{
- V8_RESOURCE_TYPE(ListType)
-public:
- QV8ListResource(QV8Engine *engine) : QV8ObjectResource(engine) {}
-
- QQmlGuard<QObject> object;
- QQmlListProperty<QObject> property;
- int propertyType;
-};
-
-QV8ListWrapper::QV8ListWrapper()
-: m_engine(0)
-{
-}
-
-QV8ListWrapper::~QV8ListWrapper()
-{
-}
-
-void QV8ListWrapper::init(QV8Engine *engine)
-{
- m_engine = engine;
- v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
- ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter, 0, 0, Enumerator);
- ft->InstanceTemplate()->SetIndexedPropertyHandler(IndexedGetter);
- ft->InstanceTemplate()->SetAccessor(v8::String::New("length"), LengthGetter, 0,
- v8::Handle<v8::Value>(), v8::DEFAULT,
- v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete | v8::DontEnum));
- ft->InstanceTemplate()->SetHasExternalResource(true);
- m_constructor = qPersistentNew<v8::Function>(ft->GetFunction());
-}
-
-void QV8ListWrapper::destroy()
-{
- qPersistentDispose(m_constructor);
-}
-
-v8::Handle<v8::Value> QV8ListWrapper::newList(QObject *object, int propId, int propType)
-{
- if (!object || propId == -1)
- return v8::Null();
-
- // XXX NewInstance() should be optimized
- v8::Local<v8::Object> rv = m_constructor->NewInstance();
- QV8ListResource *r = new QV8ListResource(m_engine);
- r->object = object;
- r->propertyType = propType;
- void *args[] = { &r->property, 0 };
- QMetaObject::metacall(object, QMetaObject::ReadProperty, propId, args);
- rv->SetExternalResource(r);
- return rv;
-}
-
-v8::Handle<v8::Value> QV8ListWrapper::newList(const QQmlListProperty<QObject> &prop, int propType)
-{
- // XXX NewInstance() should be optimized
- v8::Local<v8::Object> rv = m_constructor->NewInstance();
- QV8ListResource *r = new QV8ListResource(m_engine);
- r->object = prop.object;
- r->property = prop;
- r->propertyType = propType;
- rv->SetExternalResource(r);
- return rv;
-}
-
-QVariant QV8ListWrapper::toVariant(v8::Handle<v8::Object> obj)
-{
- QV8ListResource *resource = v8_resource_cast<QV8ListResource>(obj);
- if (resource) return toVariant(resource);
- else return QVariant();
-}
-
-QVariant QV8ListWrapper::toVariant(QV8ObjectResource *r)
-{
- Q_ASSERT(r->resourceType() == QV8ObjectResource::ListType);
- QV8ListResource *resource = static_cast<QV8ListResource *>(r);
-
- if (!resource->object)
- return QVariant();
-
- return QVariant::fromValue(QQmlListReferencePrivate::init(resource->property, resource->propertyType,
- m_engine->engine()));
-}
-
-v8::Handle<v8::Value> QV8ListWrapper::Getter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info)
-{
- Q_UNUSED(property);
- Q_UNUSED(info);
- return v8::Handle<v8::Value>();
-}
-
-v8::Handle<v8::Value> QV8ListWrapper::Setter(v8::Local<v8::String> property,
- v8::Local<v8::Value> value,
- const v8::AccessorInfo &info)
-{
- Q_UNUSED(property);
- Q_UNUSED(info);
- return value;
-}
-
-v8::Handle<v8::Value> QV8ListWrapper::IndexedGetter(uint32_t index, const v8::AccessorInfo &info)
-{
- QV8ListResource *resource = v8_resource_cast<QV8ListResource>(info.This());
-
- if (!resource || resource->object.isNull()) return v8::Undefined();
-
- quint32 count = resource->property.count?resource->property.count(&resource->property):0;
- if (index < count && resource->property.at) {
- return resource->engine->newQObject(resource->property.at(&resource->property, index));
- } else {
- return v8::Undefined();
- }
-}
-
-v8::Handle<v8::Value> QV8ListWrapper::LengthGetter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info)
-{
- Q_UNUSED(property);
-
- QV8ListResource *resource = v8_resource_cast<QV8ListResource>(info.This());
-
- if (!resource || resource->object.isNull()) return v8::Undefined();
-
- quint32 count = resource->property.count?resource->property.count(&resource->property):0;
-
- return v8::Integer::NewFromUnsigned(count);
-}
-
-v8::Handle<v8::Array> QV8ListWrapper::Enumerator(const v8::AccessorInfo &info)
-{
- QV8ListResource *resource = v8_resource_cast<QV8ListResource>(info.This());
-
- if (!resource || resource->object.isNull()) return v8::Array::New();
-
- quint32 count = resource->property.count?resource->property.count(&resource->property):0;
-
- v8::Local<v8::Array> rv = v8::Array::New(count);
-
- for (uint ii = 0; ii < count; ++ii)
- rv->Set(ii, v8::Number::New(ii));
-
- return rv;
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv8listwrapper_p.h b/src/qml/qml/v8/qv8listwrapper_p.h
deleted file mode 100644
index 3d780dc12c..0000000000
--- a/src/qml/qml/v8/qv8listwrapper_p.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV8LISTWRAPPER_P_H
-#define QV8LISTWRAPPER_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/qglobal.h>
-#include <QtQml/qqmllist.h>
-#include <private/qv8_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QV8Engine;
-class QV8ObjectResource;
-class QV8ListWrapper
-{
-public:
- QV8ListWrapper();
- ~QV8ListWrapper();
-
- void init(QV8Engine *);
- void destroy();
-
- v8::Handle<v8::Value> newList(QObject *, int, int);
- v8::Handle<v8::Value> newList(const QQmlListProperty<QObject> &, int);
- QVariant toVariant(v8::Handle<v8::Object>);
- QVariant toVariant(QV8ObjectResource *);
-
-private:
- static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> Setter(v8::Local<v8::String> property,
- v8::Local<v8::Value> value,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> IndexedGetter(uint32_t index,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> LengthGetter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Array> Enumerator(const v8::AccessorInfo &info);
-
- QV8Engine *m_engine;
- v8::Persistent<v8::Function> m_constructor;
-};
-
-QT_END_NAMESPACE
-
-#endif // QV8LISTWRAPPER_P_H
-
diff --git a/src/qml/qml/v8/qv8objectresource_p.h b/src/qml/qml/v8/qv8objectresource_p.h
deleted file mode 100644
index 78fd835431..0000000000
--- a/src/qml/qml/v8/qv8objectresource_p.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV8OBJECTRESOURCE_P_H
-#define QV8OBJECTRESOURCE_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/qglobal.h>
-#include <private/qv8_p.h>
-
-QT_BEGIN_NAMESPACE
-
-#define V8_RESOURCE_TYPE(resourcetype) \
-public: \
- enum { V8ResourceType = QV8ObjectResource:: resourcetype }; \
- virtual QV8ObjectResource::ResourceType resourceType() const { return QV8ObjectResource:: resourcetype; } \
-private:
-
-class QV8Engine;
-class QV8ObjectResource : public v8::Object::ExternalResource
-{
-public:
- QV8ObjectResource(QV8Engine *engine) : engine(engine) { Q_ASSERT(engine); }
- enum ResourceType { ContextType, QObjectType, TypeType, ListType, VariantType,
- ValueTypeType, XMLHttpRequestType, DOMNodeType, SQLDatabaseType,
- ListModelType, Context2DType, Context2DStyleType, Context2DPixelArrayType,
- ParticleDataType, SignalHandlerType, IncubatorType, VisualDataItemType,
- SequenceType, LocaleDataType, ChangeSetArrayType };
- virtual ResourceType resourceType() const = 0;
-
- QV8Engine *engine;
-};
-
-QT_END_NAMESPACE
-
-#endif // QV8OBJECTRESOURCE_P_H
diff --git a/src/qml/qml/v8/qv8profiler_p.h b/src/qml/qml/v8/qv8profiler_p.h
index 458532dd7d..39a87f2156 100644
--- a/src/qml/qml/v8/qv8profiler_p.h
+++ b/src/qml/qml/v8/qv8profiler_p.h
@@ -39,4 +39,4 @@
**
****************************************************************************/
-#include <private/v8-profiler.h>
+//#include <private/v8-profiler.h>
diff --git a/src/qml/qml/v8/qv8qobjectwrapper.cpp b/src/qml/qml/v8/qv8qobjectwrapper.cpp
deleted file mode 100644
index 53f70ad132..0000000000
--- a/src/qml/qml/v8/qv8qobjectwrapper.cpp
+++ /dev/null
@@ -1,2283 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv8qobjectwrapper_p.h"
-#include "qv8contextwrapper_p.h"
-#include "qv8engine_p.h"
-
-#include <private/qqmlguard_p.h>
-#include <private/qqmlpropertycache_p.h>
-#include <private/qqmlengine_p.h>
-#include <private/qqmlvmemetaobject_p.h>
-#include <private/qqmlbinding_p.h>
-#include <private/qjsvalue_p.h>
-#include <private/qscript_impl_p.h>
-#include <private/qqmlaccessors_p.h>
-#include <private/qqmlexpression_p.h>
-#include <private/qqmlglobal_p.h>
-
-#include <QtQml/qjsvalue.h>
-#include <QtCore/qjsonarray.h>
-#include <QtCore/qjsonobject.h>
-#include <QtCore/qjsonvalue.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qatomic.h>
-
-QT_BEGIN_NAMESPACE
-
-#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
-// The code in this file does not violate strict aliasing, but GCC thinks it does
-// so turn off the warnings for us to have a clean build
-# pragma GCC diagnostic ignored "-Wstrict-aliasing"
-# endif
-#endif
-
-#define QOBJECT_TOSTRING_INDEX -2
-#define QOBJECT_DESTROY_INDEX -3
-
-// XXX TODO: Need to review all calls to QQmlEngine *engine() to confirm QObjects work
-// correctly in a worker thread
-
-class QV8QObjectInstance : public QQmlGuard<QObject>
-{
-public:
- QV8QObjectInstance(QObject *o, QV8QObjectWrapper *w)
- : QQmlGuard<QObject>(o), wrapper(w)
- {
- }
-
- ~QV8QObjectInstance()
- {
- qPersistentDispose(v8object);
- }
-
- virtual void objectDestroyed(QObject *o)
- {
- if (wrapper)
- wrapper->m_taintedObjects.remove(o);
- delete this;
- }
-
- v8::Persistent<v8::Object> v8object;
- QV8QObjectWrapper *wrapper;
-};
-
-class QV8SignalHandlerResource : public QV8ObjectResource
-{
- V8_RESOURCE_TYPE(SignalHandlerType)
-public:
- QV8SignalHandlerResource(QV8Engine *engine, QObject *object, int index);
-
- QQmlGuard<QObject> object;
- int index;
-};
-
-namespace {
-
-template<typename A, typename B, typename C, typename D, typename E,
- typename F, typename G, typename H>
-class MaxSizeOf8 {
- template<typename Z, typename X>
- struct SMax {
- char dummy[sizeof(Z) > sizeof(X) ? sizeof(Z) : sizeof(X)];
- };
-public:
- static const size_t Size = sizeof(SMax<A, SMax<B, SMax<C, SMax<D, SMax<E, SMax<F, SMax<G, H> > > > > > >);
-};
-
-struct CallArgument {
- inline CallArgument();
- inline ~CallArgument();
- inline void *dataPtr();
-
- inline void initAsType(int type);
- inline void fromValue(int type, QV8Engine *, v8::Handle<v8::Value>);
- inline v8::Handle<v8::Value> toValue(QV8Engine *);
-
-private:
- CallArgument(const CallArgument &);
-
- inline void cleanup();
-
- union {
- float floatValue;
- double doubleValue;
- quint32 intValue;
- bool boolValue;
- QObject *qobjectPtr;
-
- char allocData[MaxSizeOf8<QVariant,
- QString,
- QList<QObject *>,
- QJSValue,
- QQmlV8Handle,
- QJsonArray,
- QJsonObject,
- QJsonValue>::Size];
- qint64 q_for_alignment;
- };
-
- // Pointers to allocData
- union {
- QString *qstringPtr;
- QVariant *qvariantPtr;
- QList<QObject *> *qlistPtr;
- QJSValue *qjsValuePtr;
- QQmlV8Handle *handlePtr;
- QJsonArray *jsonArrayPtr;
- QJsonObject *jsonObjectPtr;
- QJsonValue *jsonValuePtr;
- };
-
- int type;
-};
-}
-
-QV8QObjectResource::QV8QObjectResource(QV8Engine *engine, QObject *object)
-: QV8ObjectResource(engine), object(object)
-{
-}
-
-QV8SignalHandlerResource::QV8SignalHandlerResource(QV8Engine *engine, QObject *object, int index)
-: QV8ObjectResource(engine), object(object), index(index)
-{
-}
-
-static QAtomicInt objectIdCounter(1);
-
-QV8QObjectWrapper::QV8QObjectWrapper()
-: m_engine(0), m_id(objectIdCounter.fetchAndAddOrdered(1))
-{
-}
-
-QV8QObjectWrapper::~QV8QObjectWrapper()
-{
- for (TaintedHash::Iterator iter = m_taintedObjects.begin();
- iter != m_taintedObjects.end();
- ++iter) {
- (*iter)->wrapper = 0;
- }
- m_taintedObjects.clear();
-}
-
-void QV8QObjectWrapper::destroy()
-{
- qDeleteAll(m_connections);
- m_connections.clear();
-
- qPersistentDispose(m_hiddenObject);
- qPersistentDispose(m_destroySymbol);
- qPersistentDispose(m_toStringSymbol);
- qPersistentDispose(m_signalHandlerConstructor);
- qPersistentDispose(m_methodConstructor);
- qPersistentDispose(m_constructor);
-
- QIntrusiveList<QV8QObjectResource, &QV8QObjectResource::weakResource>::iterator i = m_javaScriptOwnedWeakQObjects.begin();
- for (; i != m_javaScriptOwnedWeakQObjects.end(); ++i) {
- QV8QObjectResource *resource = *i;
- Q_ASSERT(resource);
- deleteWeakQObject(resource, true);
- }
-}
-
-struct ReadAccessor {
- static inline void Indirect(QObject *object, const QQmlPropertyData &property,
- void *output, QQmlNotifier **n)
- {
- Q_ASSERT(n == 0);
- Q_UNUSED(n);
-
- void *args[] = { output, 0 };
- QMetaObject::metacall(object, QMetaObject::ReadProperty, property.coreIndex, args);
- }
-
- static inline void Direct(QObject *object, const QQmlPropertyData &property,
- void *output, QQmlNotifier **n)
- {
- Q_ASSERT(n == 0);
- Q_UNUSED(n);
-
- void *args[] = { output, 0 };
- object->qt_metacall(QMetaObject::ReadProperty, property.coreIndex, args);
- }
-
- static inline void Accessor(QObject *object, const QQmlPropertyData &property,
- void *output, QQmlNotifier **n)
- {
- Q_ASSERT(property.accessors);
-
- property.accessors->read(object, property.accessorData, output);
- if (n) property.accessors->notifier(object, property.accessorData, n);
- }
-};
-
-static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *, int v)
-{ return v8::Integer::New(v); }
-static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *, uint v)
-{ return v8::Integer::NewFromUnsigned(v); }
-static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *, bool v)
-{ return v8::Boolean::New(v); }
-static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *e, const QString &v)
-{ return e->toString(v); }
-static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *, float v)
-{ return v8::Number::New(v); }
-static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *, double v)
-{ return v8::Number::New(v); }
-static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *e, QObject *v)
-{ return e->newQObject(v); }
-
-template<typename T, void (*ReadFunction)(QObject *, const QQmlPropertyData &,
- void *, QQmlNotifier **)>
-static v8::Handle<v8::Value> GenericValueGetter(v8::Local<v8::String>, const v8::AccessorInfo &info)
-{
- v8::Handle<v8::Object> This = info.This();
- QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(This);
-
- QObject *object = resource->object;
- if (QQmlData::wasDeleted(object)) return v8::Undefined();
-
- QQmlPropertyData *property =
- (QQmlPropertyData *)v8::External::Cast(*info.Data())->Value();
-
- QQmlEngine *engine = resource->engine->engine();
- QQmlEnginePrivate *ep = engine?QQmlEnginePrivate::get(engine):0;
-
- T value = T();
-
- if (ep && ep->propertyCapture) {
- if (ReadFunction == ReadAccessor::Accessor && property->accessors->notifier) {
- QQmlNotifier *notifier = 0;
- ReadFunction(object, *property, &value, &notifier);
- if (notifier) ep->captureProperty(notifier);
- } else if (!property->isConstant()) {
- ep->captureProperty(object, property->coreIndex, property->notifyIndex);
- ReadFunction(object, *property, &value, 0);
- } else {
- ReadFunction(object, *property, &value, 0);
- }
- } else {
- ReadFunction(object, *property, &value, 0);
- }
-
- return valueToHandle(resource->engine, value);
-}
-
-#define FAST_GETTER_FUNCTION(property, cpptype) \
- (property->hasAccessors()?((v8::AccessorGetter)GenericValueGetter<cpptype, &ReadAccessor::Accessor>):(property->isDirect()?((v8::AccessorGetter)GenericValueGetter<cpptype, &ReadAccessor::Direct>):((v8::AccessorGetter)GenericValueGetter<cpptype, &ReadAccessor::Indirect>)))
-
-static quint32 toStringHash = quint32(-1);
-static quint32 destroyHash = quint32(-1);
-
-void QV8QObjectWrapper::init(QV8Engine *engine)
-{
- m_engine = engine;
-
- m_toStringSymbol = qPersistentNew<v8::String>(v8::String::NewSymbol("toString"));
- m_destroySymbol = qPersistentNew<v8::String>(v8::String::NewSymbol("destroy"));
- m_hiddenObject = qPersistentNew<v8::Object>(v8::Object::New());
-
- m_toStringString = QHashedV8String(m_toStringSymbol);
- m_destroyString = QHashedV8String(m_destroySymbol);
-
- toStringHash = m_toStringString.hash();
- destroyHash = m_destroyString.hash();
-
- {
- v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
- ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter, Query, 0, Enumerator);
- ft->InstanceTemplate()->SetHasExternalResource(true);
- m_constructor = qPersistentNew<v8::Function>(ft->GetFunction());
- }
- {
- v8::ScriptOrigin origin(m_hiddenObject); // Hack to allow us to identify these functions
-#define CREATE_FUNCTION_SOURCE \
- "(function(method) { "\
- "return (function(object, data, qmlglobal) { "\
- "return (function() { "\
- "return method(object, data, qmlglobal, arguments.length, arguments); "\
- "});"\
- "});"\
- "})"
- v8::Local<v8::Script> script = v8::Script::New(v8::String::New(CREATE_FUNCTION_SOURCE), &origin, 0,
- v8::Handle<v8::String>(), v8::Script::NativeMode);
-#undef CREATE_FUNCTION_SOURCE
- v8::Local<v8::Function> fn = v8::Local<v8::Function>::Cast(script->Run());
- v8::Handle<v8::Value> invokeFn = v8::FunctionTemplate::New(Invoke)->GetFunction();
- v8::Handle<v8::Value> args[] = { invokeFn };
- v8::Local<v8::Function> createFn = v8::Local<v8::Function>::Cast(fn->Call(engine->global(), 1, args));
- m_methodConstructor = qPersistentNew<v8::Function>(createFn);
- }
-
- v8::Local<v8::Function> connect = V8FUNCTION(Connect, engine);
- v8::Local<v8::Function> disconnect = V8FUNCTION(Disconnect, engine);
-
- {
- v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
- ft->InstanceTemplate()->SetHasExternalResource(true);
- ft->PrototypeTemplate()->Set(v8::String::New("connect"), connect, v8::DontEnum);
- ft->PrototypeTemplate()->Set(v8::String::New("disconnect"), disconnect, v8::DontEnum);
- m_signalHandlerConstructor = qPersistentNew<v8::Function>(ft->GetFunction());
- }
-
- {
- v8::Local<v8::Object> prototype = engine->global()->Get(v8::String::New("Function"))->ToObject()->Get(v8::String::New("prototype"))->ToObject();
- prototype->Set(v8::String::New("connect"), connect, v8::DontEnum);
- prototype->Set(v8::String::New("disconnect"), disconnect, v8::DontEnum);
- }
-}
-
-bool QV8QObjectWrapper::isQObject(v8::Handle<v8::Object> obj)
-{
- return v8_resource_cast<QV8QObjectResource>(obj) != 0;
-}
-
-QObject *QV8QObjectWrapper::toQObject(v8::Handle<v8::Object> obj)
-{
- QV8QObjectResource *r = v8_resource_cast<QV8QObjectResource>(obj);
- return r?r->object:0;
-}
-
-// r *MUST* be a QV8ObjectResource (r->type() == QV8ObjectResource::QObjectType)
-QObject *QV8QObjectWrapper::toQObject(QV8ObjectResource *r)
-{
- Q_ASSERT(r->resourceType() == QV8ObjectResource::QObjectType);
- return static_cast<QV8QObjectResource *>(r)->object;
-}
-
-// Load value properties
-template<void (*ReadFunction)(QObject *, const QQmlPropertyData &,
- void *, QQmlNotifier **)>
-static v8::Handle<v8::Value> LoadProperty(QV8Engine *engine, QObject *object,
- const QQmlPropertyData &property,
- QQmlNotifier **notifier)
-{
- Q_ASSERT(!property.isFunction());
-
- if (property.isQObject()) {
- QObject *rv = 0;
- ReadFunction(object, property, &rv, notifier);
- return engine->newQObject(rv);
- } else if (property.isQList()) {
- return engine->listWrapper()->newList(object, property.coreIndex, property.propType);
- } else if (property.propType == QMetaType::QReal) {
- qreal v = 0;
- ReadFunction(object, property, &v, notifier);
- return valueToHandle(engine, v);
- } else if (property.propType == QMetaType::Int || property.isEnum()) {
- int v = 0;
- ReadFunction(object, property, &v, notifier);
- return valueToHandle(engine, v);
- } else if (property.propType == QMetaType::Bool) {
- bool v = false;
- ReadFunction(object, property, &v, notifier);
- return valueToHandle(engine, v);
- } else if (property.propType == QMetaType::QString) {
- QString v;
- ReadFunction(object, property, &v, notifier);
- return valueToHandle(engine, v);
- } else if (property.propType == QMetaType::UInt) {
- uint v = 0;
- ReadFunction(object, property, &v, notifier);
- return valueToHandle(engine, v);
- } else if (property.propType == QMetaType::Float) {
- float v = 0;
- ReadFunction(object, property, &v, notifier);
- return valueToHandle(engine, v);
- } else if (property.propType == QMetaType::Double) {
- double v = 0;
- ReadFunction(object, property, &v, notifier);
- return valueToHandle(engine, v);
- } else if (property.isV8Handle()) {
- QQmlV8Handle handle;
- ReadFunction(object, property, &handle, notifier);
- return handle.toHandle();
- } else if (property.propType == qMetaTypeId<QJSValue>()) {
- QJSValue v;
- ReadFunction(object, property, &v, notifier);
- return QJSValuePrivate::get(v)->asV8Value(engine);
- } else if (property.isQVariant()) {
- QVariant v;
- ReadFunction(object, property, &v, notifier);
-
- if (QQmlValueTypeFactory::isValueType(v.userType())) {
- if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(v.userType()))
- return engine->newValueType(object, property.coreIndex, valueType); // VariantReference value-type.
- }
-
- return engine->fromVariant(v);
- } else if (QQmlValueTypeFactory::isValueType(property.propType)) {
- Q_ASSERT(notifier == 0);
-
- if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(property.propType))
- return engine->newValueType(object, property.coreIndex, valueType);
- } else {
- Q_ASSERT(notifier == 0);
-
- // see if it's a sequence type
- bool succeeded = false;
- v8::Handle<v8::Value> retn = engine->newSequence(property.propType, object, property.coreIndex,
- &succeeded);
- if (succeeded)
- return retn;
- }
-
- if (property.propType == QMetaType::UnknownType) {
- QMetaProperty p = object->metaObject()->property(property.coreIndex);
- qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property "
- "'%s::%s'", p.typeName(), object->metaObject()->className(), p.name());
- return v8::Undefined();
- } else {
- QVariant v(property.propType, (void *)0);
- ReadFunction(object, property, v.data(), notifier);
- return engine->fromVariant(v);
- }
-}
-
-v8::Handle<v8::Value> QV8QObjectWrapper::GetProperty(QV8Engine *engine, QObject *object,
- v8::Handle<v8::Value> *objectHandle,
- const QHashedV8String &property,
- QQmlContextData *context,
- QV8QObjectWrapper::RevisionMode revisionMode)
-{
- // XXX More recent versions of V8 introduced "Callable" objects. It is possible that these
- // will be a faster way of creating QObject method objects.
- struct MethodClosure {
- static v8::Handle<v8::Value> create(QV8Engine *engine, QObject *object,
- v8::Handle<v8::Value> *objectHandle,
- int index) {
- v8::Handle<v8::Value> argv[] = {
- objectHandle?*objectHandle:engine->newQObject(object),
- v8::Integer::New(index)
- };
- Q_ASSERT(argv[0]->IsObject());
- return engine->qobjectWrapper()->m_methodConstructor->Call(engine->global(), 2, argv);
- }
- static v8::Handle<v8::Value> createWithGlobal(QV8Engine *engine, QObject *object,
- v8::Handle<v8::Value> *objectHandle,
- int index) {
- v8::Handle<v8::Value> argv[] = {
- objectHandle?*objectHandle:engine->newQObject(object),
- v8::Integer::New(index),
- v8::Context::GetCallingQmlGlobal()
- };
- Q_ASSERT(argv[0]->IsObject());
- return engine->qobjectWrapper()->m_methodConstructor->Call(engine->global(), 3, argv);
- }
- };
-
- if (QQmlData::wasDeleted(object))
- return v8::Handle<v8::Value>();
-
- {
- // Comparing the hash first actually makes a measurable difference here, at least on x86
- quint32 hash = property.hash();
- if (hash == toStringHash && engine->qobjectWrapper()->m_toStringString == property) {
- return MethodClosure::create(engine, object, objectHandle, QOBJECT_TOSTRING_INDEX);
- } else if (hash == destroyHash && engine->qobjectWrapper()->m_destroyString == property) {
- return MethodClosure::create(engine, object, objectHandle, QOBJECT_DESTROY_INDEX);
- }
- }
-
- QQmlPropertyData local;
- QQmlPropertyData *result = 0;
- {
- QQmlData *ddata = QQmlData::get(object, false);
- if (ddata && ddata->propertyCache)
- result = ddata->propertyCache->property(property, object, context);
- if (!result)
- result = QQmlPropertyCache::property(engine->engine(), object, property, context, local);
- }
-
- if (!result)
- return v8::Handle<v8::Value>();
-
- QQmlData::flushPendingBinding(object, result->coreIndex);
-
- if (revisionMode == QV8QObjectWrapper::CheckRevision && result->hasRevision()) {
- QQmlData *ddata = QQmlData::get(object);
- if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(result))
- return v8::Handle<v8::Value>();
- }
-
- if (result->isFunction() && !result->isVarProperty()) {
- if (result->isVMEFunction()) {
- QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(object);
- Q_ASSERT(vmemo);
- return vmemo->vmeMethod(result->coreIndex);
- } else if (result->isV8Function()) {
- return MethodClosure::createWithGlobal(engine, object, objectHandle, result->coreIndex);
- } else if (result->isSignalHandler()) {
- v8::Local<v8::Object> handler = engine->qobjectWrapper()->m_signalHandlerConstructor->NewInstance();
- QV8SignalHandlerResource *r = new QV8SignalHandlerResource(engine, object, result->coreIndex);
- handler->SetExternalResource(r);
- return handler;
- } else {
- return MethodClosure::create(engine, object, objectHandle, result->coreIndex);
- }
- }
-
- QQmlEnginePrivate *ep =
- engine->engine()?QQmlEnginePrivate::get(engine->engine()):0;
-
- if (result->hasAccessors()) {
- QQmlNotifier *n = 0;
- QQmlNotifier **nptr = 0;
-
- if (ep && ep->propertyCapture && result->accessors->notifier)
- nptr = &n;
-
- v8::Handle<v8::Value> rv = LoadProperty<ReadAccessor::Accessor>(engine, object, *result, nptr);
-
- if (result->accessors->notifier) {
- if (n) ep->captureProperty(n);
- } else {
- ep->captureProperty(object, result->coreIndex, result->notifyIndex);
- }
-
- return rv;
- }
-
- if (ep && !result->isConstant())
- ep->captureProperty(object, result->coreIndex, result->notifyIndex);
-
- if (result->isVarProperty()) {
- QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(object);
- Q_ASSERT(vmemo);
- return vmemo->vmeProperty(result->coreIndex);
- } else if (result->isDirect()) {
- return LoadProperty<ReadAccessor::Direct>(engine, object, *result, 0);
- } else {
- return LoadProperty<ReadAccessor::Indirect>(engine, object, *result, 0);
- }
-}
-
-// Setter for writable properties. Shared between the interceptor and fast property accessor
-static inline void StoreProperty(QV8Engine *engine, QObject *object, QQmlPropertyData *property,
- v8::Handle<v8::Value> value)
-{
- QQmlBinding *newBinding = 0;
- if (value->IsFunction()) {
- if (value->ToObject()->GetHiddenValue(engine->bindingFlagKey()).IsEmpty()) {
- if (!property->isVarProperty() && property->propType != qMetaTypeId<QJSValue>()) {
- // assigning a JS function to a non var or QJSValue property or is not allowed.
- QString error = QLatin1String("Cannot assign JavaScript function to ");
- if (!QMetaType::typeName(property->propType))
- error += QLatin1String("[unknown property type]");
- else
- error += QLatin1String(QMetaType::typeName(property->propType));
- v8::ThrowException(v8::Exception::Error(engine->toString(error)));
- return;
- }
- } else {
- // binding assignment.
- QQmlContextData *context = engine->callingContext();
- v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(value);
-
- v8::Local<v8::StackTrace> trace =
- v8::StackTrace::CurrentStackTrace(1, (v8::StackTrace::StackTraceOptions)(v8::StackTrace::kLineNumber |
- v8::StackTrace::kScriptName));
- v8::Local<v8::StackFrame> frame = trace->GetFrame(0);
- int lineNumber = frame->GetLineNumber();
- int columnNumber = frame->GetColumn();
- QString url = engine->toString(frame->GetScriptName());
-
- newBinding = new QQmlBinding(&function, object, context, url, qmlSourceCoordinate(lineNumber), qmlSourceCoordinate(columnNumber));
- newBinding->setTarget(object, *property, context);
- newBinding->setEvaluateFlags(newBinding->evaluateFlags() |
- QQmlBinding::RequiresThisObject);
- }
- }
-
- QQmlAbstractBinding *oldBinding =
- QQmlPropertyPrivate::setBinding(object, property->coreIndex, -1, newBinding);
- if (oldBinding)
- oldBinding->destroy();
-
- if (!newBinding && property->isVarProperty()) {
- // allow assignment of "special" values (null, undefined, function) to var properties
- QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(object);
- Q_ASSERT(vmemo);
- vmemo->setVMEProperty(property->coreIndex, value);
- return;
- }
-
-#define PROPERTY_STORE(cpptype, value) \
- cpptype o = value; \
- int status = -1; \
- int flags = 0; \
- void *argv[] = { &o, 0, &status, &flags }; \
- QMetaObject::metacall(object, QMetaObject::WriteProperty, property->coreIndex, argv);
-
- if (value->IsNull() && property->isQObject()) {
- PROPERTY_STORE(QObject*, 0);
- } else if (value->IsUndefined() && property->isResettable()) {
- void *a[] = { 0 };
- QMetaObject::metacall(object, QMetaObject::ResetProperty, property->coreIndex, a);
- } else if (value->IsUndefined() && property->propType == qMetaTypeId<QVariant>()) {
- PROPERTY_STORE(QVariant, QVariant());
- } else if (value->IsUndefined() && property->propType == QMetaType::QJsonValue) {
- PROPERTY_STORE(QJsonValue, QJsonValue(QJsonValue::Undefined));
- } else if (!newBinding && property->propType == qMetaTypeId<QJSValue>()) {
- PROPERTY_STORE(QJSValue, engine->scriptValueFromInternal(value));
- } else if (value->IsUndefined()) {
- QString error = QLatin1String("Cannot assign [undefined] to ");
- if (!QMetaType::typeName(property->propType))
- error += QLatin1String("[unknown property type]");
- else
- error += QLatin1String(QMetaType::typeName(property->propType));
- v8::ThrowException(v8::Exception::Error(engine->toString(error)));
- } else if (value->IsFunction()) {
- // this is handled by the binding creation above
- } else if (property->propType == QMetaType::Int && value->IsNumber()) {
- PROPERTY_STORE(int, qRound(value->ToNumber()->Value()));
- } else if (property->propType == QMetaType::QReal && value->IsNumber()) {
- PROPERTY_STORE(qreal, qreal(value->ToNumber()->Value()));
- } else if (property->propType == QMetaType::Float && value->IsNumber()) {
- PROPERTY_STORE(float, float(value->ToNumber()->Value()));
- } else if (property->propType == QMetaType::Double && value->IsNumber()) {
- PROPERTY_STORE(double, double(value->ToNumber()->Value()));
- } else if (property->propType == QMetaType::QString && value->IsString()) {
- PROPERTY_STORE(QString, engine->toString(value->ToString()));
- } else if (property->isVarProperty()) {
- QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(object);
- Q_ASSERT(vmemo);
- vmemo->setVMEProperty(property->coreIndex, value);
- } else {
- QVariant v;
- if (property->isQList())
- v = engine->toVariant(value, qMetaTypeId<QList<QObject *> >());
- else
- v = engine->toVariant(value, property->propType);
-
- QQmlContextData *context = engine->callingContext();
- if (!QQmlPropertyPrivate::write(object, *property, v, context)) {
- const char *valueType = 0;
- if (v.userType() == QVariant::Invalid) valueType = "null";
- else valueType = QMetaType::typeName(v.userType());
-
- const char *targetTypeName = QMetaType::typeName(property->propType);
- if (!targetTypeName)
- targetTypeName = "an unregistered type";
-
- QString error = QLatin1String("Cannot assign ") +
- QLatin1String(valueType) +
- QLatin1String(" to ") +
- QLatin1String(targetTypeName);
- v8::ThrowException(v8::Exception::Error(engine->toString(error)));
- }
- }
-}
-
-bool QV8QObjectWrapper::SetProperty(QV8Engine *engine, QObject *object, const QHashedV8String &property, QQmlContextData *context,
- v8::Handle<v8::Value> value, QV8QObjectWrapper::RevisionMode revisionMode)
-{
- if (engine->qobjectWrapper()->m_toStringString == property ||
- engine->qobjectWrapper()->m_destroyString == property)
- return true;
-
- if (QQmlData::wasDeleted(object))
- return false;
-
- QQmlPropertyData local;
- QQmlPropertyData *result = 0;
- result = QQmlPropertyCache::property(engine->engine(), object, property, context, local);
-
- if (!result)
- return false;
-
- if (revisionMode == QV8QObjectWrapper::CheckRevision && result->hasRevision()) {
- QQmlData *ddata = QQmlData::get(object);
- if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(result))
- return false;
- }
-
- if (!result->isWritable() && !result->isQList()) {
- QString error = QLatin1String("Cannot assign to read-only property \"") +
- engine->toString(property.string()) + QLatin1Char('\"');
- v8::ThrowException(v8::Exception::Error(engine->toString(error)));
- return true;
- }
-
- StoreProperty(engine, object, result, value);
-
- return true;
-}
-
-v8::Handle<v8::Value> QV8QObjectWrapper::Getter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info)
-{
- QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(info.This());
-
- if (QQmlData::wasDeleted(resource->object))
- return v8::Handle<v8::Value>();
-
- QObject *object = resource->object;
-
- QHashedV8String propertystring(property);
-
- QV8Engine *v8engine = resource->engine;
- QQmlContextData *context = v8engine->callingContext();
-
- v8::Handle<v8::Value> This = info.This();
- v8::Handle<v8::Value> result = GetProperty(v8engine, object, &This, propertystring,
- context, QV8QObjectWrapper::IgnoreRevision);
- if (!result.IsEmpty())
- return result;
-
- if (QV8Engine::startsWithUpper(property)) {
- // Check for attached properties
- if (context && context->imports) {
- QQmlTypeNameCache::Result r = context->imports->query(propertystring);
-
- if (r.isValid()) {
- if (r.scriptIndex != -1) {
- return v8::Undefined();
- } else if (r.type) {
- return v8engine->typeWrapper()->newObject(object, r.type, QV8TypeWrapper::ExcludeEnums);
- } else if (r.importNamespace) {
- return v8engine->typeWrapper()->newObject(object, context->imports, r.importNamespace,
- QV8TypeWrapper::ExcludeEnums);
- }
- Q_ASSERT(!"Unreachable");
- }
- }
- }
-
- return v8::Handle<v8::Value>();
-}
-
-v8::Handle<v8::Value> QV8QObjectWrapper::Setter(v8::Local<v8::String> property,
- v8::Local<v8::Value> value,
- const v8::AccessorInfo &info)
-{
- QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(info.This());
-
- if (QQmlData::wasDeleted(resource->object))
- return value;
-
- QObject *object = resource->object;
-
- QHashedV8String propertystring(property);
-
- QV8Engine *v8engine = resource->engine;
- QQmlContextData *context = v8engine->callingContext();
- bool result = SetProperty(v8engine, object, propertystring, context, value, QV8QObjectWrapper::IgnoreRevision);
-
- if (!result) {
- QString error = QLatin1String("Cannot assign to non-existent property \"") +
- v8engine->toString(property) + QLatin1Char('\"');
- v8::ThrowException(v8::Exception::Error(v8engine->toString(error)));
- return value;
- }
-
- return value;
-}
-
-v8::Handle<v8::Integer> QV8QObjectWrapper::Query(v8::Local<v8::String> property,
- const v8::AccessorInfo &info)
-{
- QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(info.This());
-
- if (resource->object.isNull())
- return v8::Handle<v8::Integer>();
-
- QV8Engine *engine = resource->engine;
- QObject *object = resource->object;
- QQmlContextData *context = engine->callingContext();
-
- QHashedV8String propertystring(property);
-
- QQmlPropertyData local;
- QQmlPropertyData *result = 0;
- result = QQmlPropertyCache::property(engine->engine(), object, propertystring, context, local);
-
- if (!result)
- return v8::Handle<v8::Integer>();
- else if (!result->isWritable() && !result->isQList())
- return v8::Integer::New(v8::ReadOnly | v8::DontDelete);
- else
- return v8::Integer::New(v8::DontDelete);
-}
-
-v8::Handle<v8::Array> QV8QObjectWrapper::Enumerator(const v8::AccessorInfo &info)
-{
- QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(info.This());
-
- if (resource->object.isNull())
- return v8::Array::New();
-
- QObject *object = resource->object;
-
- QStringList result;
-
- QQmlEnginePrivate *ep = resource->engine->engine()
- ? QQmlEnginePrivate::get(resource->engine->engine())
- : 0;
-
- QQmlPropertyCache *cache = 0;
- QQmlData *ddata = QQmlData::get(object);
- if (ddata)
- cache = ddata->propertyCache;
-
- if (!cache) {
- cache = ep ? ep->cache(object) : 0;
- if (cache) {
- if (ddata) { cache->addref(); ddata->propertyCache = cache; }
- } else {
- // Not cachable - fall back to QMetaObject (eg. dynamic meta object)
- const QMetaObject *mo = object->metaObject();
- int pc = mo->propertyCount();
- int po = mo->propertyOffset();
- for (int i=po; i<pc; ++i)
- result << QString::fromUtf8(mo->property(i).name());
- }
- } else {
- result = cache->propertyNames();
- }
-
- v8::Local<v8::Array> rv = v8::Array::New(result.count());
-
- for (int ii = 0; ii < result.count(); ++ii)
- rv->Set(ii, resource->engine->toString(result.at(ii)));
-
- return rv;
-}
-
-static void FastValueSetter(v8::Local<v8::String>, v8::Local<v8::Value> value,
- const v8::AccessorInfo& info)
-{
- QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(info.This());
-
- if (QQmlData::wasDeleted(resource->object))
- return;
-
- QObject *object = resource->object;
-
- QQmlPropertyData *property =
- (QQmlPropertyData *)v8::External::Cast(*info.Data())->Value();
-
- int index = property->coreIndex;
-
- QQmlData *ddata = QQmlData::get(object, false);
- Q_ASSERT(ddata);
- Q_ASSERT(ddata->propertyCache);
-
- QQmlPropertyData *pdata = ddata->propertyCache->property(index);
- Q_ASSERT(pdata);
-
- Q_ASSERT(pdata->isWritable() || pdata->isQList());
-
- StoreProperty(resource->engine, object, pdata, value);
-}
-
-static void FastValueSetterReadOnly(v8::Local<v8::String> property, v8::Local<v8::Value>,
- const v8::AccessorInfo& info)
-{
- QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(info.This());
-
- if (QQmlData::wasDeleted(resource->object))
- return;
-
- QV8Engine *v8engine = resource->engine;
-
- QString error = QLatin1String("Cannot assign to read-only property \"") +
- v8engine->toString(property) + QLatin1Char('\"');
- v8::ThrowException(v8::Exception::Error(v8engine->toString(error)));
-}
-
-void QV8QObjectWrapper::WeakQObjectReferenceCallback(v8::Persistent<v8::Value> handle, void *wrapper)
-{
- Q_ASSERT(handle->IsObject());
- v8::Handle<v8::Object> v8object = handle->ToObject();
- QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(v8object);
- Q_ASSERT(resource);
-
- static_cast<QV8QObjectWrapper*>(wrapper)->unregisterWeakQObjectReference(resource);
- if (static_cast<QV8QObjectWrapper*>(wrapper)->deleteWeakQObject(resource, false)) {
- // dispose
- v8object->SetExternalResource(0);
- delete resource;
- qPersistentDispose(handle);
- } else {
- handle.MakeWeak(0, WeakQObjectReferenceCallback); // revive.
- }
-}
-
-static void WeakQObjectInstanceCallback(v8::Persistent<v8::Value> handle, void *data)
-{
- QV8QObjectInstance *instance = (QV8QObjectInstance *)data;
- instance->v8object.Clear();
- qPersistentDispose(handle);
-}
-
-v8::Local<v8::Object> QQmlPropertyCache::newQObject(QObject *object, QV8Engine *engine)
-{
- Q_ASSERT(object);
- Q_ASSERT(this->engine);
-
- Q_ASSERT(QQmlData::get(object, false));
- Q_ASSERT(QQmlData::get(object, false)->propertyCache == this);
-
- // Setup constructor
- if (constructor.IsEmpty()) {
- v8::Local<v8::FunctionTemplate> ft;
-
- const QHashedString toString(QStringLiteral("toString"));
- const QHashedString destroy(QStringLiteral("destroy"));
-
- // As we use hash linking, or with property overrides, it is possible that iterating
- // over the values can yield duplicates. To combat this, we must unique'ify our properties.
- const bool checkForDuplicates = stringCache.isLinked() || _hasPropertyOverrides;
-
- StringCache uniqueHash;
- if (checkForDuplicates)
- uniqueHash.reserve(stringCache.count());
-
- // XXX TODO: Enables fast property accessors. These more than double the property access
- // performance, but the cost of setting up this structure hasn't been measured so
- // its not guaranteed that this is a win overall. We need to try and measure the cost.
- for (StringCache::ConstIterator iter = stringCache.begin(); iter != stringCache.end(); ++iter) {
- if (iter.equals(toString) || iter.equals(destroy))
- continue;
-
- if (checkForDuplicates) {
- if (uniqueHash.contains(iter))
- continue;
- uniqueHash.insert(iter);
- }
-
- QQmlPropertyData *property = (*iter).second;
- if (property->notFullyResolved()) resolve(property);
-
- if (property->isFunction())
- continue;
-
- v8::AccessorGetter fastgetter = 0;
-
- if (property->isQObject())
- fastgetter = FAST_GETTER_FUNCTION(property, QObject*);
- else if (property->propType == QMetaType::Int || property->isEnum())
- fastgetter = FAST_GETTER_FUNCTION(property, int);
- else if (property->propType == QMetaType::Bool)
- fastgetter = FAST_GETTER_FUNCTION(property, bool);
- else if (property->propType == QMetaType::QString)
- fastgetter = FAST_GETTER_FUNCTION(property, QString);
- else if (property->propType == QMetaType::UInt)
- fastgetter = FAST_GETTER_FUNCTION(property, uint);
- else if (property->propType == QMetaType::Float)
- fastgetter = FAST_GETTER_FUNCTION(property, float);
- else if (property->propType == QMetaType::Double)
- fastgetter = FAST_GETTER_FUNCTION(property, double);
-
- if (fastgetter) {
- if (ft.IsEmpty()) {
- ft = v8::FunctionTemplate::New();
- ft->InstanceTemplate()->SetFallbackPropertyHandler(QV8QObjectWrapper::Getter,
- QV8QObjectWrapper::Setter,
- QV8QObjectWrapper::Query,
- 0,
- QV8QObjectWrapper::Enumerator);
- ft->InstanceTemplate()->SetHasExternalResource(true);
- }
-
- v8::AccessorSetter fastsetter = FastValueSetter;
- if (!property->isWritable())
- fastsetter = FastValueSetterReadOnly;
-
- // We wrap the raw QQmlPropertyData pointer here. This is safe as the
- // pointer will remain valid at least as long as the lifetime of any QObject's of
- // this type and the property accessor checks if the object is 0 (deleted) before
- // dereferencing the pointer.
- ft->InstanceTemplate()->SetAccessor(engine->toString(iter.key()), fastgetter, fastsetter,
- v8::External::New(property));
- }
- }
-
- if (ft.IsEmpty()) {
- constructor = qPersistentNew<v8::Function>(engine->qobjectWrapper()->m_constructor);
- } else {
- ft->InstanceTemplate()->SetFallbackPropertyHandler(QV8QObjectWrapper::Getter,
- QV8QObjectWrapper::Setter,
- QV8QObjectWrapper::Query,
- 0,
- QV8QObjectWrapper::Enumerator);
- ft->InstanceTemplate()->SetHasExternalResource(true);
- constructor = qPersistentNew<v8::Function>(ft->GetFunction());
- }
-
- QQmlCleanup::addToEngine(this->engine);
- }
-
- v8::Local<v8::Object> result = constructor->NewInstance();
- QV8QObjectResource *r = new QV8QObjectResource(engine, object);
- result->SetExternalResource(r);
- return result;
-}
-
-v8::Local<v8::Object> QV8QObjectWrapper::newQObject(QObject *object, QQmlData *ddata, QV8Engine *engine)
-{
- v8::Local<v8::Object> rv;
-
- if (!ddata->propertyCache && engine->engine()) {
- ddata->propertyCache = QQmlEnginePrivate::get(engine->engine())->cache(object);
- if (ddata->propertyCache) ddata->propertyCache->addref();
- }
-
- if (ddata->propertyCache && ddata->propertyCache->qmlEngine() == engine->engine()) {
- rv = ddata->propertyCache->newQObject(object, engine);
- } else {
- // XXX NewInstance() should be optimized
- rv = m_constructor->NewInstance();
- QV8QObjectResource *r = new QV8QObjectResource(engine, object);
- rv->SetExternalResource(r);
- }
-
- return rv;
-}
-
-/*
-As V8 doesn't support an equality callback, for QObject's we have to return exactly the same
-V8 handle for subsequent calls to newQObject for the same QObject. To do this we have a two
-pronged strategy:
- 1. If there is no current outstanding V8 handle to the QObject, we create one and store a
- persistent handle in QQmlData::v8object. We mark the QV8QObjectWrapper that
- "owns" this handle by setting the QQmlData::v8objectid to the id of this
- QV8QObjectWrapper.
- 2. If another QV8QObjectWrapper has create the handle in QQmlData::v8object we create
- an entry in the m_taintedObject hash where we store the handle and mark the object as
- "tainted" in the QQmlData::hasTaintedV8Object flag.
-We have to mark the object as tainted to ensure that we search our m_taintedObject hash even
-in the case that the original QV8QObjectWrapper owner of QQmlData::v8object has
-released the handle.
-*/
-v8::Handle<v8::Value> QV8QObjectWrapper::newQObject(QObject *object)
-{
- if (QQmlData::wasDeleted(object))
- return v8::Null();
-
- QQmlData *ddata = QQmlData::get(object, true);
- if (!ddata)
- return v8::Undefined();
-
- if (ddata->v8objectid == m_id && !ddata->v8object.IsEmpty()) {
- // We own the v8object
- return v8::Local<v8::Object>::New(ddata->v8object);
- } else if (ddata->v8object.IsEmpty() &&
- (ddata->v8objectid == m_id || // We own the QObject
- ddata->v8objectid == 0 || // No one owns the QObject
- !ddata->hasTaintedV8Object)) { // Someone else has used the QObject, but it isn't tainted
-
- v8::Local<v8::Object> rv = newQObject(object, ddata, m_engine);
- ddata->v8object = qPersistentNew<v8::Object>(rv);
- ddata->v8object.MakeWeak(this, WeakQObjectReferenceCallback);
- ddata->v8objectid = m_id;
- QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(rv);
- registerWeakQObjectReference(resource);
- return rv;
-
- } else {
- // If this object is tainted, we have to check to see if it is in our
- // tainted object list
- TaintedHash::Iterator iter =
- ddata->hasTaintedV8Object?m_taintedObjects.find(object):m_taintedObjects.end();
- bool found = iter != m_taintedObjects.end();
-
- // If our tainted handle doesn't exist or has been collected, and there isn't
- // a handle in the ddata, we can assume ownership of the ddata->v8object
- if ((!found || (*iter)->v8object.IsEmpty()) && ddata->v8object.IsEmpty()) {
- v8::Local<v8::Object> rv = newQObject(object, ddata, m_engine);
- ddata->v8object = qPersistentNew<v8::Object>(rv);
- ddata->v8object.MakeWeak(this, WeakQObjectReferenceCallback);
- ddata->v8objectid = m_id;
- QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(rv);
- registerWeakQObjectReference(resource);
-
- if (found) {
- delete (*iter);
- m_taintedObjects.erase(iter);
- }
-
- return rv;
- } else if (!found) {
- QV8QObjectInstance *instance = new QV8QObjectInstance(object, this);
- iter = m_taintedObjects.insert(object, instance);
- ddata->hasTaintedV8Object = true;
- }
-
- if ((*iter)->v8object.IsEmpty()) {
- v8::Local<v8::Object> rv = newQObject(object, ddata, m_engine);
- (*iter)->v8object = qPersistentNew<v8::Object>(rv);
- (*iter)->v8object.MakeWeak((*iter), WeakQObjectInstanceCallback);
- }
-
- return v8::Local<v8::Object>::New((*iter)->v8object);
- }
-}
-
-// returns true if the object's qqmldata v8object handle should
-// be disposed by the caller, false if it should not be (due to
-// creation status, etc).
-bool QV8QObjectWrapper::deleteWeakQObject(QV8QObjectResource *resource, bool calledFromEngineDtor)
-{
- QObject *object = resource->object;
- if (object) {
- QQmlData *ddata = QQmlData::get(object, false);
- if (ddata) {
- if (!calledFromEngineDtor && ddata->rootObjectInCreation) {
- // if weak ref callback is triggered (by gc) for a root object
- // prior to completion of creation, we should NOT delete it.
- return false;
- }
-
- ddata->v8object.Clear();
- if (!object->parent() && !ddata->indestructible) {
- // This object is notionally destroyed now
- if (ddata->ownContext && ddata->context)
- ddata->context->emitDestruction();
- ddata->isQueuedForDeletion = true;
- if (calledFromEngineDtor)
- delete object;
- else
- object->deleteLater();
- }
- }
- }
-
- return true;
-}
-
-QPair<QObject *, int> QV8QObjectWrapper::ExtractQtSignal(QV8Engine *engine, v8::Handle<v8::Object> object)
-{
- if (object->IsFunction())
- return ExtractQtMethod(engine, v8::Handle<v8::Function>::Cast(object));
-
- if (QV8SignalHandlerResource *resource = v8_resource_cast<QV8SignalHandlerResource>(object))
- return qMakePair(resource->object.data(), resource->index);
-
- return qMakePair((QObject *)0, -1);
-}
-
-QPair<QObject *, int> QV8QObjectWrapper::ExtractQtMethod(QV8Engine *engine, v8::Handle<v8::Function> function)
-{
- v8::ScriptOrigin origin = function->GetScriptOrigin();
- if (origin.ResourceName()->StrictEquals(engine->qobjectWrapper()->m_hiddenObject)) {
-
- // This is one of our special QObject method wrappers
- v8::Handle<v8::Value> args[] = { engine->qobjectWrapper()->m_hiddenObject };
- v8::Local<v8::Value> data = function->Call(engine->global(), 1, args);
-
- if (data->IsArray()) {
- v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(data);
- return qMakePair(engine->toQObject(array->Get(0)), array->Get(1)->Int32Value());
- }
-
- // In theory this can't fall through, but I suppose V8 might run out of memory or something
- }
-
- return qMakePair((QObject *)0, -1);
-}
-
-class QV8QObjectConnectionList : public QObject, public QQmlGuard<QObject>
-{
-public:
- QV8QObjectConnectionList(QObject *object, QV8Engine *engine);
- ~QV8QObjectConnectionList();
-
- struct Connection {
- Connection()
- : needsDestroy(false) {}
- Connection(const Connection &other)
- : thisObject(other.thisObject), function(other.function), needsDestroy(false) {}
- Connection &operator=(const Connection &other) {
- thisObject = other.thisObject;
- function = other.function;
- needsDestroy = other.needsDestroy;
- return *this;
- }
-
- v8::Persistent<v8::Object> thisObject;
- v8::Persistent<v8::Function> function;
-
- void dispose() {
- qPersistentDispose(thisObject);
- qPersistentDispose(function);
- }
-
- bool needsDestroy;
- };
-
- struct ConnectionList : public QList<Connection> {
- ConnectionList() : connectionsInUse(0), connectionsNeedClean(false) {}
- int connectionsInUse;
- bool connectionsNeedClean;
- };
-
- QV8Engine *engine;
-
- typedef QHash<int, ConnectionList> SlotHash;
- SlotHash slotHash;
- bool needsDestroy;
- int inUse;
-
- virtual void objectDestroyed(QObject *);
- virtual int qt_metacall(QMetaObject::Call, int, void **);
-};
-
-QV8QObjectConnectionList::QV8QObjectConnectionList(QObject *object, QV8Engine *engine)
-: QQmlGuard<QObject>(object), engine(engine), needsDestroy(false), inUse(0)
-{
-}
-
-QV8QObjectConnectionList::~QV8QObjectConnectionList()
-{
- for (SlotHash::Iterator iter = slotHash.begin(); iter != slotHash.end(); ++iter) {
- QList<Connection> &connections = *iter;
- for (int ii = 0; ii < connections.count(); ++ii) {
- qPersistentDispose(connections[ii].thisObject);
- qPersistentDispose(connections[ii].function);
- }
- }
- slotHash.clear();
-}
-
-void QV8QObjectConnectionList::objectDestroyed(QObject *object)
-{
- engine->qobjectWrapper()->m_connections.remove(object);
-
- if (inUse)
- needsDestroy = true;
- else
- delete this;
-}
-
-int QV8QObjectConnectionList::qt_metacall(QMetaObject::Call method, int index, void **metaArgs)
-{
- if (method == QMetaObject::InvokeMetaMethod) {
- SlotHash::Iterator iter = slotHash.find(index);
- if (iter == slotHash.end())
- return -1;
- ConnectionList &connectionList = *iter;
- if (connectionList.isEmpty())
- return -1;
-
- inUse++;
-
- connectionList.connectionsInUse++;
-
- QList<Connection> connections = connectionList;
-
- QVarLengthArray<int, 9> dummy;
- int *argsTypes = QQmlPropertyCache::methodParameterTypes(data(), index, dummy, 0);
-
- v8::HandleScope handle_scope;
- v8::Context::Scope scope(engine->context());
-
- int argCount = argsTypes?argsTypes[0]:0;
- QVarLengthArray<v8::Handle<v8::Value>, 9> args(argCount);
-
- for (int ii = 0; ii < argCount; ++ii) {
- int type = argsTypes[ii + 1];
- if (type == qMetaTypeId<QVariant>()) {
- args[ii] = engine->fromVariant(*((QVariant *)metaArgs[ii + 1]));
- } else {
- args[ii] = engine->fromVariant(QVariant(type, metaArgs[ii + 1]));
- }
- }
-
- for (int ii = 0; ii < connections.count(); ++ii) {
- Connection &connection = connections[ii];
- if (connection.needsDestroy)
- continue;
-
- v8::TryCatch try_catch;
- if (connection.thisObject.IsEmpty()) {
- connection.function->Call(engine->global(), argCount, args.data());
- } else {
- connection.function->Call(connection.thisObject, argCount, args.data());
- }
-
- if (try_catch.HasCaught()) {
- QQmlError error;
- error.setDescription(QString(QLatin1String("Unknown exception occurred during evaluation of connected function: %1")).arg(engine->toString(connection.function->GetName())));
- v8::Local<v8::Message> message = try_catch.Message();
- if (!message.IsEmpty())
- QQmlExpressionPrivate::exceptionToError(message, error);
- QQmlEnginePrivate::get(engine->engine())->warning(error);
- }
- }
-
- connectionList.connectionsInUse--;
- if (connectionList.connectionsInUse == 0 && connectionList.connectionsNeedClean) {
- for (QList<Connection>::Iterator iter = connectionList.begin();
- iter != connectionList.end(); ) {
- if (iter->needsDestroy) {
- iter->dispose();
- iter = connectionList.erase(iter);
- } else {
- ++iter;
- }
- }
- }
-
- inUse--;
- if (inUse == 0 && needsDestroy)
- delete this;
- }
-
- return -1;
-}
-
-v8::Handle<v8::Value> QV8QObjectWrapper::Connect(const v8::Arguments &args)
-{
- if (args.Length() == 0)
- V8THROW_ERROR("Function.prototype.connect: no arguments given");
-
- QV8Engine *engine = V8ENGINE();
-
- QPair<QObject *, int> signalInfo = ExtractQtSignal(engine, args.This());
- QObject *signalObject = signalInfo.first;
- int signalIndex = signalInfo.second;
-
- if (signalIndex < 0)
- V8THROW_ERROR("Function.prototype.connect: this object is not a signal");
-
- if (!signalObject)
- V8THROW_ERROR("Function.prototype.connect: cannot connect to deleted QObject");
-
- if (signalObject->metaObject()->method(signalIndex).methodType() != QMetaMethod::Signal)
- V8THROW_ERROR("Function.prototype.connect: this object is not a signal");
-
- v8::Local<v8::Value> functionValue;
- v8::Local<v8::Value> functionThisValue;
-
- if (args.Length() == 1) {
- functionValue = args[0];
- } else {
- functionThisValue = args[0];
- functionValue = args[1];
- }
-
- if (!functionValue->IsFunction())
- V8THROW_ERROR("Function.prototype.connect: target is not a function");
-
- if (!functionThisValue.IsEmpty() && !functionThisValue->IsObject())
- V8THROW_ERROR("Function.prototype.connect: target this is not an object");
-
- QV8QObjectWrapper *qobjectWrapper = engine->qobjectWrapper();
- QHash<QObject *, QV8QObjectConnectionList *> &connections = qobjectWrapper->m_connections;
- QHash<QObject *, QV8QObjectConnectionList *>::Iterator iter = connections.find(signalObject);
- if (iter == connections.end())
- iter = connections.insert(signalObject, new QV8QObjectConnectionList(signalObject, engine));
-
- QV8QObjectConnectionList *connectionList = *iter;
- QV8QObjectConnectionList::SlotHash::Iterator slotIter = connectionList->slotHash.find(signalIndex);
- if (slotIter == connectionList->slotHash.end()) {
- slotIter = connectionList->slotHash.insert(signalIndex, QV8QObjectConnectionList::ConnectionList());
- QMetaObject::connect(signalObject, signalIndex, connectionList, signalIndex);
- }
-
- QV8QObjectConnectionList::Connection connection;
- if (!functionThisValue.IsEmpty())
- connection.thisObject = qPersistentNew<v8::Object>(functionThisValue->ToObject());
- connection.function = qPersistentNew<v8::Function>(v8::Handle<v8::Function>::Cast(functionValue));
-
- slotIter->append(connection);
-
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> QV8QObjectWrapper::Disconnect(const v8::Arguments &args)
-{
- if (args.Length() == 0)
- V8THROW_ERROR("Function.prototype.disconnect: no arguments given");
-
- QV8Engine *engine = V8ENGINE();
-
- QPair<QObject *, int> signalInfo = ExtractQtSignal(engine, args.This());
- QObject *signalObject = signalInfo.first;
- int signalIndex = signalInfo.second;
-
- if (signalIndex == -1)
- V8THROW_ERROR("Function.prototype.disconnect: this object is not a signal");
-
- if (!signalObject)
- V8THROW_ERROR("Function.prototype.disconnect: cannot disconnect from deleted QObject");
-
- if (signalIndex < 0 || signalObject->metaObject()->method(signalIndex).methodType() != QMetaMethod::Signal)
- V8THROW_ERROR("Function.prototype.disconnect: this object is not a signal");
-
- v8::Local<v8::Value> functionValue;
- v8::Local<v8::Value> functionThisValue;
-
- if (args.Length() == 1) {
- functionValue = args[0];
- } else {
- functionThisValue = args[0];
- functionValue = args[1];
- }
-
- if (!functionValue->IsFunction())
- V8THROW_ERROR("Function.prototype.disconnect: target is not a function");
-
- if (!functionThisValue.IsEmpty() && !functionThisValue->IsObject())
- V8THROW_ERROR("Function.prototype.disconnect: target this is not an object");
-
- QV8QObjectWrapper *qobjectWrapper = engine->qobjectWrapper();
- QHash<QObject *, QV8QObjectConnectionList *> &connectionsList = qobjectWrapper->m_connections;
- QHash<QObject *, QV8QObjectConnectionList *>::Iterator iter = connectionsList.find(signalObject);
- if (iter == connectionsList.end())
- return v8::Undefined(); // Nothing to disconnect from
-
- QV8QObjectConnectionList *connectionList = *iter;
- QV8QObjectConnectionList::SlotHash::Iterator slotIter = connectionList->slotHash.find(signalIndex);
- if (slotIter == connectionList->slotHash.end())
- return v8::Undefined(); // Nothing to disconnect from
-
- QV8QObjectConnectionList::ConnectionList &connections = *slotIter;
-
- v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(functionValue);
- QPair<QObject *, int> functionData = ExtractQtMethod(engine, function);
-
- if (functionData.second != -1) {
- // This is a QObject function wrapper
- for (int ii = 0; ii < connections.count(); ++ii) {
- QV8QObjectConnectionList::Connection &connection = connections[ii];
-
- if (connection.thisObject.IsEmpty() == functionThisValue.IsEmpty() &&
- (connection.thisObject.IsEmpty() || connection.thisObject->StrictEquals(functionThisValue))) {
-
- QPair<QObject *, int> connectedFunctionData = ExtractQtMethod(engine, connection.function);
- if (connectedFunctionData == functionData) {
- // Match!
- if (connections.connectionsInUse) {
- connection.needsDestroy = true;
- connections.connectionsNeedClean = true;
- } else {
- connection.dispose();
- connections.removeAt(ii);
- }
- return v8::Undefined();
- }
- }
- }
-
- } else {
- // This is a normal JS function
- for (int ii = 0; ii < connections.count(); ++ii) {
- QV8QObjectConnectionList::Connection &connection = connections[ii];
- if (connection.function->StrictEquals(function) &&
- connection.thisObject.IsEmpty() == functionThisValue.IsEmpty() &&
- (connection.thisObject.IsEmpty() || connection.thisObject->StrictEquals(functionThisValue))) {
- // Match!
- if (connections.connectionsInUse) {
- connection.needsDestroy = true;
- connections.connectionsNeedClean = true;
- } else {
- connection.dispose();
- connections.removeAt(ii);
- }
- return v8::Undefined();
- }
- }
- }
-
- return v8::Undefined();
-}
-
-/*!
- \fn v8::Handle<v8::Value> QV8QObjectWrapper::getProperty(QObject *object, const QHashedV8String &property, QV8QObjectWrapper::RevisionMode revisionMode)
-
- Get the \a property of \a object. Returns an empty handle if the property doesn't exist.
-
- Only searches for real properties of \a object (including methods), not attached properties etc.
-*/
-
-/*
- \fn bool QV8QObjectWrapper::setProperty(QObject *object, const QHashedV8String &property, v8::Handle<v8::Value> value, RevisionMode revisionMode)
-
- Set the \a property of \a object to \a value.
-
- Returns true if the property was "set" - even if this results in an exception being thrown -
- and false if the object has no such property.
-
- Only searches for real properties of \a object (including methods), not attached properties etc.
-*/
-
-namespace {
-struct CallArgs
-{
- CallArgs(int length, v8::Handle<v8::Object> *args) : _length(length), _args(args) {}
- int Length() const { return _length; }
- v8::Local<v8::Value> operator[](int idx) { return (*_args)->Get(idx); }
-
-private:
- int _length;
- v8::Handle<v8::Object> *_args;
-};
-}
-
-static v8::Handle<v8::Value> CallMethod(QObject *object, int index, int returnType, int argCount,
- int *argTypes, QV8Engine *engine, CallArgs &callArgs)
-{
- if (argCount > 0) {
-
- // Special handling is required for value types.
- // We need to save the current value in a temporary,
- // and reapply it after converting all arguments.
- // This avoids the "overwriting copy-value-type-value"
- // problem during Q_INVOKABLE function invocation.
- QQmlValueType *valueTypeObject = qobject_cast<QQmlValueType*>(object);
- QVariant valueTypeValue;
- if (valueTypeObject)
- valueTypeValue = valueTypeObject->value();
-
- // Convert all arguments.
- QVarLengthArray<CallArgument, 9> args(argCount + 1);
- args[0].initAsType(returnType);
- for (int ii = 0; ii < argCount; ++ii)
- args[ii + 1].fromValue(argTypes[ii], engine, callArgs[ii]);
- QVarLengthArray<void *, 9> argData(args.count());
- for (int ii = 0; ii < args.count(); ++ii)
- argData[ii] = args[ii].dataPtr();
-
- // Reinstate saved value type object value if required.
- if (valueTypeObject)
- valueTypeObject->setValue(valueTypeValue);
-
- QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, argData.data());
-
- return args[0].toValue(engine);
-
- } else if (returnType != QMetaType::Void) {
-
- CallArgument arg;
- arg.initAsType(returnType);
-
- void *args[] = { arg.dataPtr() };
-
- QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, args);
-
- return arg.toValue(engine);
-
- } else {
-
- void *args[] = { 0 };
- QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, args);
- return v8::Undefined();
-
- }
-}
-
-/*!
- Returns the match score for converting \a actual to be of type \a conversionType. A
- zero score means "perfect match" whereas a higher score is worse.
-
- The conversion table is copied out of the \l QScript::callQtMethod()
- function.
-*/
-static int MatchScore(v8::Handle<v8::Value> actual, int conversionType)
-{
- if (actual->IsNumber()) {
- switch (conversionType) {
- case QMetaType::Double:
- return 0;
- case QMetaType::Float:
- return 1;
- case QMetaType::LongLong:
- case QMetaType::ULongLong:
- return 2;
- case QMetaType::Long:
- case QMetaType::ULong:
- return 3;
- case QMetaType::Int:
- case QMetaType::UInt:
- return 4;
- case QMetaType::Short:
- case QMetaType::UShort:
- return 5;
- break;
- case QMetaType::Char:
- case QMetaType::UChar:
- return 6;
- case QMetaType::QJsonValue:
- return 5;
- default:
- return 10;
- }
- } else if (actual->IsString()) {
- switch (conversionType) {
- case QMetaType::QString:
- return 0;
- case QMetaType::QJsonValue:
- return 5;
- default:
- return 10;
- }
- } else if (actual->IsBoolean()) {
- switch (conversionType) {
- case QMetaType::Bool:
- return 0;
- case QMetaType::QJsonValue:
- return 5;
- default:
- return 10;
- }
- } else if (actual->IsDate()) {
- switch (conversionType) {
- case QMetaType::QDateTime:
- return 0;
- case QMetaType::QDate:
- return 1;
- case QMetaType::QTime:
- return 2;
- default:
- return 10;
- }
- } else if (actual->IsRegExp()) {
- switch (conversionType) {
- case QMetaType::QRegExp:
- return 0;
- default:
- return 10;
- }
- } else if (actual->IsArray()) {
- switch (conversionType) {
- case QMetaType::QJsonArray:
- return 3;
- case QMetaType::QStringList:
- case QMetaType::QVariantList:
- return 5;
- case QMetaType::QVector4D:
- case QMetaType::QMatrix4x4:
- return 6;
- case QMetaType::QVector3D:
- return 7;
- default:
- return 10;
- }
- } else if (actual->IsNull()) {
- switch (conversionType) {
- case QMetaType::VoidStar:
- case QMetaType::QObjectStar:
- case QMetaType::QJsonValue:
- return 0;
- default: {
- const char *typeName = QMetaType::typeName(conversionType);
- if (typeName && typeName[strlen(typeName) - 1] == '*')
- return 0;
- else
- return 10;
- }
- }
- } else if (actual->IsObject()) {
- v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(actual);
-
- QV8ObjectResource *r = static_cast<QV8ObjectResource *>(obj->GetExternalResource());
- if (r && r->resourceType() == QV8ObjectResource::QObjectType) {
- switch (conversionType) {
- case QMetaType::QObjectStar:
- return 0;
- default:
- return 10;
- }
- } else if (r && r->resourceType() == QV8ObjectResource::VariantType) {
- if (conversionType == qMetaTypeId<QVariant>())
- return 0;
- else if (r->engine->toVariant(actual, -1).userType() == conversionType)
- return 0;
- else
- return 10;
- } else if (r && r->resourceType() == QV8ObjectResource::ValueTypeType) {
- if (r->engine->toVariant(actual, -1).userType() == conversionType)
- return 0;
- return 10;
- } else if (conversionType == QMetaType::QJsonObject) {
- return 5;
- } else {
- return 10;
- }
-
- } else {
- return 10;
- }
-}
-
-static inline int QMetaObject_methods(const QMetaObject *metaObject)
-{
- struct Private
- {
- int revision;
- int className;
- int classInfoCount, classInfoData;
- int methodCount, methodData;
- };
-
- return reinterpret_cast<const Private *>(metaObject->d.data)->methodCount;
-}
-
-/*!
-Returns the next related method, if one, or 0.
-*/
-static const QQmlPropertyData * RelatedMethod(QObject *object,
- const QQmlPropertyData *current,
- QQmlPropertyData &dummy)
-{
- QQmlPropertyCache *cache = QQmlData::get(object)->propertyCache;
- if (!current->isOverload())
- return 0;
-
- Q_ASSERT(!current->overrideIndexIsProperty);
-
- if (cache) {
- return cache->method(current->overrideIndex);
- } else {
- const QMetaObject *mo = object->metaObject();
- int methodOffset = mo->methodCount() - QMetaObject_methods(mo);
-
- while (methodOffset > current->overrideIndex) {
- mo = mo->superClass();
- methodOffset -= QMetaObject_methods(mo);
- }
-
- QMetaMethod method = mo->method(current->overrideIndex);
- dummy.load(method);
-
- // Look for overloaded methods
- QByteArray methodName = method.name();
- for (int ii = current->overrideIndex - 1; ii >= methodOffset; --ii) {
- if (methodName == mo->method(ii).name()) {
- dummy.setFlags(dummy.getFlags() | QQmlPropertyData::IsOverload);
- dummy.overrideIndexIsProperty = 0;
- dummy.overrideIndex = ii;
- return &dummy;
- }
- }
-
- return &dummy;
- }
-}
-
-static v8::Handle<v8::Value> CallPrecise(QObject *object, const QQmlPropertyData &data,
- QV8Engine *engine, CallArgs &callArgs)
-{
- QByteArray unknownTypeError;
-
- int returnType = QQmlPropertyCache::methodReturnType(object, data, &unknownTypeError);
-
- if (returnType == QMetaType::UnknownType) {
- QString typeName = QString::fromLatin1(unknownTypeError);
- QString error = QString::fromLatin1("Unknown method return type: %1").arg(typeName);
- v8::ThrowException(v8::Exception::Error(engine->toString(error)));
- return v8::Handle<v8::Value>();
- }
-
- if (data.hasArguments()) {
-
- int *args = 0;
- QVarLengthArray<int, 9> dummy;
-
- args = QQmlPropertyCache::methodParameterTypes(object, data.coreIndex, dummy,
- &unknownTypeError);
-
- if (!args) {
- QString typeName = QString::fromLatin1(unknownTypeError);
- QString error = QString::fromLatin1("Unknown method parameter type: %1").arg(typeName);
- v8::ThrowException(v8::Exception::Error(engine->toString(error)));
- return v8::Handle<v8::Value>();
- }
-
- if (args[0] > callArgs.Length()) {
- QString error = QLatin1String("Insufficient arguments");
- v8::ThrowException(v8::Exception::Error(engine->toString(error)));
- return v8::Handle<v8::Value>();
- }
-
- return CallMethod(object, data.coreIndex, returnType, args[0], args + 1, engine, callArgs);
-
- } else {
-
- return CallMethod(object, data.coreIndex, returnType, 0, 0, engine, callArgs);
-
- }
-}
-
-/*!
-Resolve the overloaded method to call. The algorithm works conceptually like this:
- 1. Resolve the set of overloads it is *possible* to call.
- Impossible overloads include those that have too many parameters or have parameters
- of unknown type.
- 2. Filter the set of overloads to only contain those with the closest number of
- parameters.
- For example, if we are called with 3 parameters and there are 2 overloads that
- take 2 parameters and one that takes 3, eliminate the 2 parameter overloads.
- 3. Find the best remaining overload based on its match score.
- If two or more overloads have the same match score, call the last one. The match
- score is constructed by adding the matchScore() result for each of the parameters.
-*/
-static v8::Handle<v8::Value> CallOverloaded(QObject *object, const QQmlPropertyData &data,
- QV8Engine *engine, CallArgs &callArgs)
-{
- int argumentCount = callArgs.Length();
-
- const QQmlPropertyData *best = 0;
- int bestParameterScore = INT_MAX;
- int bestMatchScore = INT_MAX;
-
- // Special handling is required for value types.
- // We need to save the current value in a temporary,
- // and reapply it after converting all arguments.
- // This avoids the "overwriting copy-value-type-value"
- // problem during Q_INVOKABLE function invocation.
- QQmlValueType *valueTypeObject = qobject_cast<QQmlValueType*>(object);
- QVariant valueTypeValue;
- if (valueTypeObject)
- valueTypeValue = valueTypeObject->value();
-
- QQmlPropertyData dummy;
- const QQmlPropertyData *attempt = &data;
-
- do {
- QVarLengthArray<int, 9> dummy;
- int methodArgumentCount = 0;
- int *methodArgTypes = 0;
- if (attempt->hasArguments()) {
- typedef QQmlPropertyCache PC;
- int *args = PC::methodParameterTypes(object, attempt->coreIndex, dummy, 0);
- if (!args) // Must be an unknown argument
- continue;
-
- methodArgumentCount = args[0];
- methodArgTypes = args + 1;
- }
-
- if (methodArgumentCount > argumentCount)
- continue; // We don't have sufficient arguments to call this method
-
- int methodParameterScore = argumentCount - methodArgumentCount;
- if (methodParameterScore > bestParameterScore)
- continue; // We already have a better option
-
- int methodMatchScore = 0;
- for (int ii = 0; ii < methodArgumentCount; ++ii)
- methodMatchScore += MatchScore(callArgs[ii], methodArgTypes[ii]);
-
- if (bestParameterScore > methodParameterScore || bestMatchScore > methodMatchScore) {
- best = attempt;
- bestParameterScore = methodParameterScore;
- bestMatchScore = methodMatchScore;
- }
-
- if (bestParameterScore == 0 && bestMatchScore == 0)
- break; // We can't get better than that
-
- } while((attempt = RelatedMethod(object, attempt, dummy)) != 0);
-
- if (best) {
- if (valueTypeObject)
- valueTypeObject->setValue(valueTypeValue);
- return CallPrecise(object, *best, engine, callArgs);
- } else {
- QString error = QLatin1String("Unable to determine callable overload. Candidates are:");
- const QQmlPropertyData *candidate = &data;
- while (candidate) {
- error += QLatin1String("\n ") +
- QString::fromUtf8(object->metaObject()->method(candidate->coreIndex).methodSignature().constData());
- candidate = RelatedMethod(object, candidate, dummy);
- }
-
- v8::ThrowException(v8::Exception::Error(engine->toString(error)));
- return v8::Handle<v8::Value>();
- }
-}
-
-static v8::Handle<v8::Value> ToString(QV8Engine *engine, QObject *object, int, v8::Handle<v8::Object>)
-{
- QString result;
- if (object) {
- QString objectName = object->objectName();
-
- result += QString::fromUtf8(object->metaObject()->className());
- result += QLatin1String("(0x");
- result += QString::number((quintptr)object,16);
-
- if (!objectName.isEmpty()) {
- result += QLatin1String(", \"");
- result += objectName;
- result += QLatin1Char('\"');
- }
-
- result += QLatin1Char(')');
- } else {
- result = QLatin1String("null");
- }
-
- return engine->toString(result);
-}
-
-static v8::Handle<v8::Value> Destroy(QV8Engine *, QObject *object, int argCount, v8::Handle<v8::Object> args)
-{
- QQmlData *ddata = QQmlData::get(object, false);
- if (!ddata || ddata->indestructible || ddata->rootObjectInCreation) {
- const char *error = "Invalid attempt to destroy() an indestructible object";
- v8::ThrowException(v8::Exception::Error(v8::String::New(error)));
- return v8::Undefined();
- }
-
- int delay = 0;
- if (argCount > 0)
- delay = args->Get(0)->Uint32Value();
-
- if (delay > 0)
- QTimer::singleShot(delay, object, SLOT(deleteLater()));
- else
- object->deleteLater();
-
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> QV8QObjectWrapper::Invoke(const v8::Arguments &args)
-{
- // object, index, qmlglobal, argCount, args
- Q_ASSERT(args.Length() == 5);
- Q_ASSERT(args[0]->IsObject());
-
- QV8QObjectResource *resource = v8_resource_cast<QV8QObjectResource>(args[0]->ToObject());
-
- if (!resource)
- return v8::Undefined();
-
- int argCount = args[3]->Int32Value();
- v8::Handle<v8::Object> arguments = v8::Handle<v8::Object>::Cast(args[4]);
-
- // Special hack to return info about this closure.
- if (argCount == 1 && arguments->Get(0)->StrictEquals(resource->engine->qobjectWrapper()->m_hiddenObject)) {
- v8::Local<v8::Array> data = v8::Array::New(2);
- data->Set(0, args[0]);
- data->Set(1, args[1]);
- return data;
- }
-
- QObject *object = resource->object;
- int index = args[1]->Int32Value();
-
- if (!object)
- return v8::Undefined();
-
- if (index < 0) {
- // Builtin functions
- if (index == QOBJECT_TOSTRING_INDEX) {
- return ToString(resource->engine, object, argCount, arguments);
- } else if (index == QOBJECT_DESTROY_INDEX) {
- return Destroy(resource->engine, object, argCount, arguments);
- } else {
- return v8::Undefined();
- }
- }
-
- QQmlPropertyData method;
-
- if (QQmlData *ddata = static_cast<QQmlData *>(QObjectPrivate::get(object)->declarativeData)) {
- if (ddata->propertyCache) {
- QQmlPropertyData *d = ddata->propertyCache->method(index);
- if (!d)
- return v8::Undefined();
- method = *d;
- }
- }
-
- if (method.coreIndex == -1) {
- method.load(object->metaObject()->method(index));
-
- if (method.coreIndex == -1)
- return v8::Undefined();
- }
-
- if (method.isV8Function()) {
- v8::Handle<v8::Value> rv;
- v8::Handle<v8::Object> qmlglobal = args[2]->ToObject();
-
- QQmlV8Function func(argCount, arguments, rv, qmlglobal,
- resource->engine->contextWrapper()->context(qmlglobal),
- resource->engine);
- QQmlV8Function *funcptr = &func;
-
- void *args[] = { 0, &funcptr };
- QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, method.coreIndex, args);
-
- if (rv.IsEmpty()) return v8::Undefined();
- return rv;
- }
-
- CallArgs callArgs(argCount, &arguments);
- if (!method.isOverload()) {
- return CallPrecise(object, method, resource->engine, callArgs);
- } else {
- return CallOverloaded(object, method, resource->engine, callArgs);
- }
-}
-
-CallArgument::CallArgument()
-: type(QVariant::Invalid)
-{
-}
-
-CallArgument::~CallArgument()
-{
- cleanup();
-}
-
-void CallArgument::cleanup()
-{
- if (type == QMetaType::QString) {
- qstringPtr->~QString();
- } else if (type == -1 || type == QMetaType::QVariant) {
- qvariantPtr->~QVariant();
- } else if (type == qMetaTypeId<QJSValue>()) {
- qjsValuePtr->~QJSValue();
- } else if (type == qMetaTypeId<QList<QObject *> >()) {
- qlistPtr->~QList<QObject *>();
- } else if (type == QMetaType::QJsonArray) {
- jsonArrayPtr->~QJsonArray();
- } else if (type == QMetaType::QJsonObject) {
- jsonObjectPtr->~QJsonObject();
- } else if (type == QMetaType::QJsonValue) {
- jsonValuePtr->~QJsonValue();
- }
-}
-
-void *CallArgument::dataPtr()
-{
- if (type == -1)
- return qvariantPtr->data();
- else
- return (void *)&allocData;
-}
-
-void CallArgument::initAsType(int callType)
-{
- if (type != 0) { cleanup(); type = 0; }
- if (callType == QMetaType::UnknownType) return;
-
- if (callType == qMetaTypeId<QJSValue>()) {
- qjsValuePtr = new (&allocData) QJSValue();
- type = callType;
- } else if (callType == QMetaType::Int ||
- callType == QMetaType::UInt ||
- callType == QMetaType::Bool ||
- callType == QMetaType::Double ||
- callType == QMetaType::Float) {
- type = callType;
- } else if (callType == QMetaType::QObjectStar) {
- qobjectPtr = 0;
- type = callType;
- } else if (callType == QMetaType::QString) {
- qstringPtr = new (&allocData) QString();
- type = callType;
- } else if (callType == QMetaType::QVariant) {
- type = callType;
- qvariantPtr = new (&allocData) QVariant();
- } else if (callType == qMetaTypeId<QList<QObject *> >()) {
- type = callType;
- qlistPtr = new (&allocData) QList<QObject *>();
- } else if (callType == qMetaTypeId<QQmlV8Handle>()) {
- type = callType;
- handlePtr = new (&allocData) QQmlV8Handle;
- } else if (callType == QMetaType::QJsonArray) {
- type = callType;
- jsonArrayPtr = new (&allocData) QJsonArray();
- } else if (callType == QMetaType::QJsonObject) {
- type = callType;
- jsonObjectPtr = new (&allocData) QJsonObject();
- } else if (callType == QMetaType::QJsonValue) {
- type = callType;
- jsonValuePtr = new (&allocData) QJsonValue();
- } else if (callType == QMetaType::Void) {
- type = -1;
- qvariantPtr = new (&allocData) QVariant();
- } else {
- type = -1;
- qvariantPtr = new (&allocData) QVariant(callType, (void *)0);
- }
-}
-
-void CallArgument::fromValue(int callType, QV8Engine *engine, v8::Handle<v8::Value> value)
-{
- if (type != 0) { cleanup(); type = 0; }
-
- if (callType == qMetaTypeId<QJSValue>()) {
- qjsValuePtr = new (&allocData) QJSValue(QJSValuePrivate::get(new QJSValuePrivate(engine, value)));
- type = qMetaTypeId<QJSValue>();
- } else if (callType == QMetaType::Int) {
- intValue = quint32(value->Int32Value());
- type = callType;
- } else if (callType == QMetaType::UInt) {
- intValue = quint32(value->Uint32Value());
- type = callType;
- } else if (callType == QMetaType::Bool) {
- boolValue = value->BooleanValue();
- type = callType;
- } else if (callType == QMetaType::Double) {
- doubleValue = double(value->NumberValue());
- type = callType;
- } else if (callType == QMetaType::Float) {
- floatValue = float(value->NumberValue());
- type = callType;
- } else if (callType == QMetaType::QString) {
- if (value->IsNull() || value->IsUndefined())
- qstringPtr = new (&allocData) QString();
- else
- qstringPtr = new (&allocData) QString(engine->toString(value->ToString()));
- type = callType;
- } else if (callType == QMetaType::QObjectStar) {
- qobjectPtr = engine->toQObject(value);
- type = callType;
- } else if (callType == qMetaTypeId<QVariant>()) {
- qvariantPtr = new (&allocData) QVariant(engine->toVariant(value, -1));
- type = callType;
- } else if (callType == qMetaTypeId<QList<QObject*> >()) {
- qlistPtr = new (&allocData) QList<QObject *>();
- if (value->IsArray()) {
- v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value);
- uint32_t length = array->Length();
- for (uint32_t ii = 0; ii < length; ++ii)
- qlistPtr->append(engine->toQObject(array->Get(ii)));
- } else {
- qlistPtr->append(engine->toQObject(value));
- }
- type = callType;
- } else if (callType == qMetaTypeId<QQmlV8Handle>()) {
- handlePtr = new (&allocData) QQmlV8Handle(QQmlV8Handle::fromHandle(value));
- type = callType;
- } else if (callType == QMetaType::QJsonArray) {
- jsonArrayPtr = new (&allocData) QJsonArray(engine->jsonArrayFromJS(value));
- type = callType;
- } else if (callType == QMetaType::QJsonObject) {
- jsonObjectPtr = new (&allocData) QJsonObject(engine->jsonObjectFromJS(value));
- type = callType;
- } else if (callType == QMetaType::QJsonValue) {
- jsonValuePtr = new (&allocData) QJsonValue(engine->jsonValueFromJS(value));
- type = callType;
- } else if (callType == QMetaType::Void) {
- *qvariantPtr = QVariant();
- } else {
- qvariantPtr = new (&allocData) QVariant();
- type = -1;
-
- QQmlEnginePrivate *ep = engine->engine() ? QQmlEnginePrivate::get(engine->engine()) : 0;
- QVariant v = engine->toVariant(value, -1); // why -1 instead of callType?
-
- if (v.userType() == callType) {
- *qvariantPtr = v;
- } else if (v.canConvert(callType)) {
- *qvariantPtr = v;
- qvariantPtr->convert(callType);
- } else if (engine->sequenceWrapper()->isSequenceType(callType) && v.userType() == qMetaTypeId<QVariantList>()) {
- // convert the JS array to a sequence of the correct type.
- QVariant seqV = engine->toVariant(value, callType);
- *qvariantPtr = seqV;
- } else {
- QQmlMetaObject mo = ep ? ep->rawMetaObjectForType(callType) : QQmlMetaObject();
- if (!mo.isNull()) {
- QObject *obj = ep->toQObject(v);
-
- if (obj != 0 && !QQmlMetaObject::canConvert(obj, mo))
- obj = 0;
-
- *qvariantPtr = QVariant(callType, &obj);
- } else {
- *qvariantPtr = QVariant(callType, (void *)0);
- }
- }
- }
-}
-
-v8::Handle<v8::Value> CallArgument::toValue(QV8Engine *engine)
-{
- if (type == qMetaTypeId<QJSValue>()) {
- return QJSValuePrivate::get(*qjsValuePtr)->asV8Value(engine);
- } else if (type == QMetaType::Int) {
- return v8::Integer::New(int(intValue));
- } else if (type == QMetaType::UInt) {
- return v8::Integer::NewFromUnsigned(intValue);
- } else if (type == QMetaType::Bool) {
- return v8::Boolean::New(boolValue);
- } else if (type == QMetaType::Double) {
- return v8::Number::New(doubleValue);
- } else if (type == QMetaType::Float) {
- return v8::Number::New(floatValue);
- } else if (type == QMetaType::QString) {
- return engine->toString(*qstringPtr);
- } else if (type == QMetaType::QObjectStar) {
- QObject *object = qobjectPtr;
- if (object)
- QQmlData::get(object, true)->setImplicitDestructible();
- return engine->newQObject(object);
- } else if (type == qMetaTypeId<QList<QObject *> >()) {
- // XXX Can this be made more by using Array as a prototype and implementing
- // directly against QList<QObject*>?
- QList<QObject *> &list = *qlistPtr;
- v8::Local<v8::Array> array = v8::Array::New(list.count());
- for (int ii = 0; ii < list.count(); ++ii)
- array->Set(ii, engine->newQObject(list.at(ii)));
- return array;
- } else if (type == qMetaTypeId<QQmlV8Handle>()) {
- return handlePtr->toHandle();
- } else if (type == QMetaType::QJsonArray) {
- return engine->jsonArrayToJS(*jsonArrayPtr);
- } else if (type == QMetaType::QJsonObject) {
- return engine->jsonObjectToJS(*jsonObjectPtr);
- } else if (type == QMetaType::QJsonValue) {
- return engine->jsonValueToJS(*jsonValuePtr);
- } else if (type == -1 || type == qMetaTypeId<QVariant>()) {
- QVariant value = *qvariantPtr;
- v8::Handle<v8::Value> rv = engine->fromVariant(value);
- if (QObject *object = engine->toQObject(rv))
- QQmlData::get(object, true)->setImplicitDestructible();
- return rv;
- } else {
- return v8::Undefined();
- }
-}
-
-QT_END_NAMESPACE
-
diff --git a/src/qml/qml/v8/qv8qobjectwrapper_p.h b/src/qml/qml/v8/qv8qobjectwrapper_p.h
deleted file mode 100644
index cbd6505846..0000000000
--- a/src/qml/qml/v8/qv8qobjectwrapper_p.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV8QOBJECTWRAPPER_P_H
-#define QV8QOBJECTWRAPPER_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/qglobal.h>
-#include <QtCore/qmetatype.h>
-#include <QtCore/qpair.h>
-#include <QtCore/qhash.h>
-#include <private/qv8_p.h>
-#include <private/qhashedstring_p.h>
-#include <private/qqmldata_p.h>
-#include <private/qqmlpropertycache_p.h>
-#include <private/qintrusivelist_p.h>
-#include "qv8objectresource_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QObject;
-class QV8Engine;
-class QQmlData;
-class QV8ObjectResource;
-class QV8QObjectInstance;
-class QV8QObjectConnectionList;
-class QQmlPropertyCache;
-
-class QV8QObjectResource : public QV8ObjectResource
-{
- V8_RESOURCE_TYPE(QObjectType)
-
-public:
- QV8QObjectResource(QV8Engine *engine, QObject *object);
-
- QQmlGuard<QObject> object;
- QIntrusiveListNode weakResource;
-};
-
-class Q_QML_PRIVATE_EXPORT QV8QObjectWrapper
-{
-public:
- QV8QObjectWrapper();
- ~QV8QObjectWrapper();
-
- void init(QV8Engine *);
- void destroy();
-
- v8::Handle<v8::Value> newQObject(QObject *object);
- bool isQObject(v8::Handle<v8::Object>);
- QObject *toQObject(v8::Handle<v8::Object>);
- static QObject *toQObject(QV8ObjectResource *);
-
- enum RevisionMode { IgnoreRevision, CheckRevision };
- inline v8::Handle<v8::Value> getProperty(QObject *, const QHashedV8String &, QQmlContextData *, RevisionMode);
- inline bool setProperty(QObject *, const QHashedV8String &, QQmlContextData *, v8::Handle<v8::Value>, RevisionMode);
-
- void registerWeakQObjectReference(QV8QObjectResource *resource)
- {
- m_javaScriptOwnedWeakQObjects.insert(resource);
- }
-
- void unregisterWeakQObjectReference(QV8QObjectResource *resource)
- {
- m_javaScriptOwnedWeakQObjects.remove(resource);
- }
-
-private:
- friend class QQmlPropertyCache;
- friend class QV8QObjectConnectionList;
- friend class QV8QObjectInstance;
-
- v8::Local<v8::Object> newQObject(QObject *, QQmlData *, QV8Engine *);
- bool deleteWeakQObject(QV8QObjectResource *resource, bool calledFromEngineDtor = false);
- static v8::Handle<v8::Value> GetProperty(QV8Engine *, QObject *, v8::Handle<v8::Value> *,
- const QHashedV8String &, QQmlContextData *, QV8QObjectWrapper::RevisionMode);
- static bool SetProperty(QV8Engine *, QObject *, const QHashedV8String &, QQmlContextData *,
- v8::Handle<v8::Value>, QV8QObjectWrapper::RevisionMode);
- static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> Setter(v8::Local<v8::String> property,
- v8::Local<v8::Value> value,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Integer> Query(v8::Local<v8::String> property,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Array> Enumerator(const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> Connect(const v8::Arguments &args);
- static v8::Handle<v8::Value> Disconnect(const v8::Arguments &args);
- static v8::Handle<v8::Value> Invoke(const v8::Arguments &args);
- static QPair<QObject *, int> ExtractQtMethod(QV8Engine *, v8::Handle<v8::Function>);
- static QPair<QObject *, int> ExtractQtSignal(QV8Engine *, v8::Handle<v8::Object>);
- static void WeakQObjectReferenceCallback(v8::Persistent<v8::Value> handle, void *wrapper);
-
- QV8Engine *m_engine;
- quint32 m_id;
- v8::Persistent<v8::Function> m_constructor;
- v8::Persistent<v8::Function> m_methodConstructor;
- v8::Persistent<v8::Function> m_signalHandlerConstructor;
- v8::Persistent<v8::String> m_toStringSymbol;
- v8::Persistent<v8::String> m_destroySymbol;
- QHashedV8String m_toStringString;
- QHashedV8String m_destroyString;
- v8::Persistent<v8::Object> m_hiddenObject;
- QHash<QObject *, QV8QObjectConnectionList *> m_connections;
- typedef QHash<QObject *, QV8QObjectInstance *> TaintedHash;
- TaintedHash m_taintedObjects;
- QIntrusiveList<QV8QObjectResource, &QV8QObjectResource::weakResource> m_javaScriptOwnedWeakQObjects;
-};
-
-v8::Handle<v8::Value> QV8QObjectWrapper::getProperty(QObject *object, const QHashedV8String &string,
- QQmlContextData *context, RevisionMode mode)
-{
- QQmlData *dd = QQmlData::get(object, false);
- if (!dd || !dd->propertyCache || m_toStringString == string || m_destroyString == string ||
- dd->propertyCache->property(string, object, context)) {
- return GetProperty(m_engine, object, 0, string, context, mode);
- } else {
- return v8::Handle<v8::Value>();
- }
-}
-
-bool QV8QObjectWrapper::setProperty(QObject *object, const QHashedV8String &string,
- QQmlContextData *context, v8::Handle<v8::Value> value, RevisionMode mode)
-{
- QQmlData *dd = QQmlData::get(object, false);
- if (!dd || !dd->propertyCache || m_toStringString == string || m_destroyString == string ||
- dd->propertyCache->property(string, object, context)) {
- return SetProperty(m_engine, object, string, context, value, mode);
- } else {
- return false;
- }
-}
-
-QT_END_NAMESPACE
-
-#endif // QV8QOBJECTWRAPPER_P_H
-
-
diff --git a/src/qml/qml/v8/qv8sequencewrapper.cpp b/src/qml/qml/v8/qv8sequencewrapper.cpp
deleted file mode 100644
index b1e0c41771..0000000000
--- a/src/qml/qml/v8/qv8sequencewrapper.cpp
+++ /dev/null
@@ -1,323 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtQml/qqml.h>
-
-#include "qv8sequencewrapper_p.h"
-#include "qv8sequencewrapper_p_p.h"
-#include "qv8engine_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QV8SequenceWrapper::QV8SequenceWrapper()
- : m_engine(0)
-{
-}
-
-QV8SequenceWrapper::~QV8SequenceWrapper()
-{
-}
-
-#define REGISTER_QML_SEQUENCE_METATYPE(unused, unused2, SequenceType, unused3) qRegisterMetaType<SequenceType>();
-void QV8SequenceWrapper::init(QV8Engine *engine)
-{
- FOREACH_QML_SEQUENCE_TYPE(REGISTER_QML_SEQUENCE_METATYPE)
-
- m_engine = engine;
- m_toString = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(ToString)->GetFunction());
- m_valueOf = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(ValueOf)->GetFunction());
-
- QString defaultSortString = QLatin1String(
- "(function compare(x,y) {"
- " if (x === y) return 0;"
- " x = x.toString();"
- " y = y.toString();"
- " if (x == y) return 0;"
- " else return x < y ? -1 : 1;"
- "})");
-
- m_sort = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(Sort)->GetFunction());
- m_arrayPrototype = qPersistentNew<v8::Value>(v8::Array::New(1)->GetPrototype());
- v8::Local<v8::Script> defaultSortCompareScript = v8::Script::Compile(engine->toString(defaultSortString));
- m_defaultSortComparer = qPersistentNew<v8::Function>(v8::Handle<v8::Function>(v8::Function::Cast(*defaultSortCompareScript->Run())));
-
- v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
- ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter);
- ft->InstanceTemplate()->SetIndexedPropertyHandler(IndexedGetter, IndexedSetter, 0, IndexedDeleter, IndexedEnumerator);
- ft->InstanceTemplate()->SetAccessor(v8::String::New("length"), LengthGetter, LengthSetter,
- v8::Handle<v8::Value>(), v8::DEFAULT,
- v8::PropertyAttribute(v8::DontDelete | v8::DontEnum));
- ft->InstanceTemplate()->SetAccessor(v8::String::New("toString"), ToStringGetter, 0,
- m_toString, v8::DEFAULT,
- v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete | v8::DontEnum));
- ft->InstanceTemplate()->SetAccessor(v8::String::New("valueOf"), ValueOfGetter, 0,
- m_valueOf, v8::DEFAULT,
- v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete | v8::DontEnum));
- ft->InstanceTemplate()->SetAccessor(v8::String::New("sort"), SortGetter, 0,
- m_sort, v8::DEFAULT,
- v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete | v8::DontEnum));
- ft->InstanceTemplate()->SetHasExternalResource(true);
- ft->InstanceTemplate()->MarkAsUseUserObjectComparison();
- m_constructor = qPersistentNew<v8::Function>(ft->GetFunction());
-}
-#undef REGISTER_QML_SEQUENCE_METATYPE
-
-void QV8SequenceWrapper::destroy()
-{
- qPersistentDispose(m_defaultSortComparer);
- qPersistentDispose(m_sort);
- qPersistentDispose(m_arrayPrototype);
- qPersistentDispose(m_toString);
- qPersistentDispose(m_valueOf);
- qPersistentDispose(m_constructor);
-}
-
-#define IS_SEQUENCE(unused1, unused2, SequenceType, unused3) \
- if (sequenceTypeId == qMetaTypeId<SequenceType>()) { \
- return true; \
- } else
-
-bool QV8SequenceWrapper::isSequenceType(int sequenceTypeId) const
-{
- FOREACH_QML_SEQUENCE_TYPE(IS_SEQUENCE) { /* else */ return false; }
-}
-#undef IS_SEQUENCE
-
-bool QV8SequenceWrapper::isEqual(QV8ObjectResource *lhs, QV8ObjectResource *rhs)
-{
- Q_ASSERT(lhs && rhs && lhs->resourceType() == QV8ObjectResource::SequenceType && rhs->resourceType() == QV8ObjectResource::SequenceType);
- QV8SequenceResource *lr = static_cast<QV8SequenceResource *>(lhs);
- QV8SequenceResource *rr = static_cast<QV8SequenceResource *>(rhs);
- return lr->isEqual(rr);
-}
-
-quint32 QV8SequenceWrapper::sequenceLength(QV8ObjectResource *r)
-{
- Q_ASSERT(r->resourceType() == QV8ObjectResource::SequenceType);
- QV8SequenceResource *sr = static_cast<QV8SequenceResource *>(r);
- Q_ASSERT(sr);
- return sr->lengthGetter();
-}
-
-#define NEW_REFERENCE_SEQUENCE(ElementType, ElementTypeName, SequenceType, unused) \
- if (sequenceType == qMetaTypeId<SequenceType>()) { \
- r = new QV8##ElementTypeName##SequenceResource(m_engine, object, propertyIndex); \
- } else
-
-v8::Local<v8::Object> QV8SequenceWrapper::newSequence(int sequenceType, QObject *object, int propertyIndex, bool *succeeded)
-{
- // This function is called when the property is a QObject Q_PROPERTY of
- // the given sequence type. Internally we store a typed-sequence
- // (as well as object ptr + property index for updated-read and write-back)
- // and so access/mutate avoids variant conversion.
- *succeeded = true;
- QV8SequenceResource *r = 0;
- FOREACH_QML_SEQUENCE_TYPE(NEW_REFERENCE_SEQUENCE) { /* else */ *succeeded = false; return v8::Local<v8::Object>(); }
-
- v8::Local<v8::Object> rv = m_constructor->NewInstance();
- rv->SetExternalResource(r);
- rv->SetPrototype(m_arrayPrototype);
- return rv;
-}
-#undef NEW_REFERENCE_SEQUENCE
-
-#define NEW_COPY_SEQUENCE(ElementType, ElementTypeName, SequenceType, unused) \
- if (sequenceType == qMetaTypeId<SequenceType>()) { \
- r = new QV8##ElementTypeName##SequenceResource(m_engine, v.value<SequenceType>()); \
- } else
-
-v8::Local<v8::Object> QV8SequenceWrapper::fromVariant(const QVariant& v, bool *succeeded)
-{
- // This function is called when assigning a sequence value to a normal JS var
- // in a JS block. Internally, we store a sequence of the specified type.
- // Access and mutation is extremely fast since it will not need to modify any
- // QObject property.
- int sequenceType = v.userType();
- *succeeded = true;
- QV8SequenceResource *r = 0;
- FOREACH_QML_SEQUENCE_TYPE(NEW_COPY_SEQUENCE) { /* else */ *succeeded = false; return v8::Local<v8::Object>(); }
-
- v8::Local<v8::Object> rv = m_constructor->NewInstance();
- rv->SetExternalResource(r);
- rv->SetPrototype(m_arrayPrototype);
- return rv;
-}
-#undef NEW_COPY_SEQUENCE
-
-QVariant QV8SequenceWrapper::toVariant(QV8ObjectResource *r)
-{
- Q_ASSERT(r->resourceType() == QV8ObjectResource::SequenceType);
- QV8SequenceResource *resource = static_cast<QV8SequenceResource *>(r);
- return resource->toVariant();
-}
-
-#define SEQUENCE_TO_VARIANT(ElementType, ElementTypeName, SequenceType, unused) \
- if (typeHint == qMetaTypeId<SequenceType>()) { \
- return QV8##ElementTypeName##SequenceResource::toVariant(m_engine, array, length, succeeded); \
- } else
-
-QVariant QV8SequenceWrapper::toVariant(v8::Handle<v8::Array> array, int typeHint, bool *succeeded)
-{
- *succeeded = true;
- uint32_t length = array->Length();
- FOREACH_QML_SEQUENCE_TYPE(SEQUENCE_TO_VARIANT) { /* else */ *succeeded = false; return QVariant(); }
-}
-#undef SEQUENCE_TO_VARIANT
-
-v8::Handle<v8::Value> QV8SequenceWrapper::IndexedSetter(quint32 index, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
-{
- QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This());
- Q_ASSERT(sr);
- return sr->indexedSetter(index, value);
-}
-
-v8::Handle<v8::Value> QV8SequenceWrapper::IndexedGetter(quint32 index, const v8::AccessorInfo &info)
-{
- QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This());
- Q_ASSERT(sr);
- return sr->indexedGetter(index);
-}
-
-v8::Handle<v8::Boolean> QV8SequenceWrapper::IndexedDeleter(quint32 index, const v8::AccessorInfo &info)
-{
- QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This());
- Q_ASSERT(sr);
- return sr->indexedDeleter(index);
-}
-
-v8::Handle<v8::Array> QV8SequenceWrapper::IndexedEnumerator(const v8::AccessorInfo &info)
-{
- QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This());
- Q_ASSERT(sr);
- return sr->indexedEnumerator();
-}
-
-v8::Handle<v8::Value> QV8SequenceWrapper::LengthGetter(v8::Local<v8::String> property, const v8::AccessorInfo &info)
-{
- Q_UNUSED(property);
- QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This());
- Q_ASSERT(sr);
- return v8::Integer::NewFromUnsigned(sr->lengthGetter());
-}
-
-void QV8SequenceWrapper::LengthSetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo &info)
-{
- Q_UNUSED(property);
- QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This());
- Q_ASSERT(sr);
- sr->lengthSetter(value);
-}
-
-v8::Handle<v8::Value> QV8SequenceWrapper::ToStringGetter(v8::Local<v8::String> property, const v8::AccessorInfo &info)
-{
- Q_UNUSED(property);
- return info.Data();
-}
-
-v8::Handle<v8::Value> QV8SequenceWrapper::ValueOfGetter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info)
-{
- Q_UNUSED(property);
- return info.Data();
-}
-
-v8::Handle<v8::Value> QV8SequenceWrapper::SortGetter(v8::Local<v8::String> property, const v8::AccessorInfo &info)
-{
- Q_UNUSED(property);
- return info.Data();
-}
-
-v8::Handle<v8::Value> QV8SequenceWrapper::Sort(const v8::Arguments &args)
-{
- int argCount = args.Length();
-
- if (argCount < 2) {
- QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(args.This());
- Q_ASSERT(sr);
-
- qint32 length = sr->lengthGetter();
- if (length > 1) {
- v8::Handle<v8::Function> jsCompareFn = sr->engine->sequenceWrapper()->m_defaultSortComparer;
- if (argCount == 1 && args[0]->IsFunction())
- jsCompareFn = v8::Handle<v8::Function>(v8::Function::Cast(*args[0]));
-
- sr->sort(jsCompareFn);
- }
- }
-
- return args.This();
-}
-
-v8::Handle<v8::Value> QV8SequenceWrapper::ToString(const v8::Arguments &args)
-{
- QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(args.This());
- Q_ASSERT(sr);
- return sr->toString();
-}
-
-v8::Handle<v8::Value> QV8SequenceWrapper::ValueOf(const v8::Arguments &args)
-{
- QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(args.This());
- Q_ASSERT(sr);
- v8::Handle<v8::Value> tostringValue = sr->toString();
- if (!tostringValue.IsEmpty())
- return tostringValue;
- return v8::Integer::NewFromUnsigned(sr->lengthGetter());
-}
-
-v8::Handle<v8::Value> QV8SequenceWrapper::Getter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info)
-{
- Q_UNUSED(property);
- Q_UNUSED(info);
- return v8::Handle<v8::Value>();
-}
-
-v8::Handle<v8::Value> QV8SequenceWrapper::Setter(v8::Local<v8::String> property,
- v8::Local<v8::Value> value,
- const v8::AccessorInfo &info)
-{
- Q_UNUSED(property);
- Q_UNUSED(info);
- return value;
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv8sequencewrapper_p.h b/src/qml/qml/v8/qv8sequencewrapper_p.h
deleted file mode 100644
index c403abc6b6..0000000000
--- a/src/qml/qml/v8/qv8sequencewrapper_p.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV8SEQUENCEWRAPPER_P_H
-#define QV8SEQUENCEWRAPPER_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/qglobal.h>
-#include <QtCore/qvariant.h>
-#include <private/qv8_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QV8Engine;
-class QV8ObjectResource;
-
-class QV8SequenceWrapper
-{
-public:
- QV8SequenceWrapper();
- ~QV8SequenceWrapper();
-
- void init(QV8Engine *);
- void destroy();
-
- bool isSequenceType(int sequenceTypeId) const;
-
- bool isEqual(QV8ObjectResource *lhs, const QVariant &rhs);
- bool isEqual(QV8ObjectResource *lhs, QV8ObjectResource *rhs);
- quint32 sequenceLength(QV8ObjectResource *);
-
- v8::Local<v8::Object> newSequence(int sequenceTypeId, QObject *object, int propertyIndex, bool *succeeded);
- v8::Local<v8::Object> fromVariant(const QVariant& v, bool *succeeded);
- QVariant toVariant(QV8ObjectResource *);
- QVariant toVariant(v8::Handle<v8::Array> array, int typeHint, bool *succeeded);
-
-private:
- QV8Engine *m_engine;
-
- v8::Persistent<v8::Function> m_constructor;
- v8::Persistent<v8::Function> m_toString;
- v8::Persistent<v8::Function> m_valueOf;
- v8::Persistent<v8::Function> m_sort;
- v8::Persistent<v8::Value> m_arrayPrototype;
- v8::Persistent<v8::Function> m_defaultSortComparer;
-
- static v8::Handle<v8::Value> IndexedGetter(quint32 index, const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> IndexedSetter(quint32 index, v8::Local<v8::Value> value, const v8::AccessorInfo &info);
- static v8::Handle<v8::Boolean> IndexedDeleter(quint32 index, const v8::AccessorInfo &info);
- static v8::Handle<v8::Array> IndexedEnumerator(const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> LengthGetter(v8::Local<v8::String> property, const v8::AccessorInfo &info);
- static void LengthSetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> ToStringGetter(v8::Local<v8::String> property, const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> ToString(const v8::Arguments &args);
- static v8::Handle<v8::Value> ValueOfGetter(v8::Local<v8::String> property, const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> SortGetter(v8::Local<v8::String> property, const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> ValueOf(const v8::Arguments &args);
- static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property, const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> Setter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> Sort(const v8::Arguments &args);
-};
-
-
-QT_END_NAMESPACE
-
-#endif // QV8SEQUENCEWRAPPER_P_H
diff --git a/src/qml/qml/v8/qv8sequencewrapper_p_p.h b/src/qml/qml/v8/qv8sequencewrapper_p_p.h
deleted file mode 100644
index ff9df7d4a0..0000000000
--- a/src/qml/qml/v8/qv8sequencewrapper_p_p.h
+++ /dev/null
@@ -1,512 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV8SEQUENCEWRAPPER_P_P_H
-#define QV8SEQUENCEWRAPPER_P_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 <private/qqmlengine_p.h>
-#include <private/qqmlmetatype_p.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \internal
- \class QV8SequenceResource
- \brief The abstract base class of the external resource used in sequence type objects
-
- Every sequence type object returned by QV8SequenceWrapper::fromVariant() or
- QV8SequenceWrapper::newSequence() has a type-specific QV8SequenceResource which
- contains the type name, the meta type ids of the sequence and sequence element
- types, as well as either the sequence data (copy) or object pointer and property
- index (reference) data associated with the sequence.
- */
-class QV8SequenceResource : public QV8ObjectResource
-{
- V8_RESOURCE_TYPE(SequenceType)
-
-public:
- virtual ~QV8SequenceResource() {}
-
- enum ObjectType { Reference, Copy };
-
- virtual QVariant toVariant() = 0;
- virtual bool isEqual(const QV8SequenceResource *v) = 0;
-
- virtual quint32 lengthGetter() = 0;
- virtual void lengthSetter(v8::Handle<v8::Value> value) = 0;
- virtual v8::Handle<v8::Value> indexedSetter(quint32 index, v8::Handle<v8::Value> value) = 0;
- virtual v8::Handle<v8::Value> indexedGetter(quint32 index) = 0;
- virtual v8::Handle<v8::Boolean> indexedDeleter(quint32 index) = 0;
- virtual v8::Handle<v8::Array> indexedEnumerator() = 0;
- virtual v8::Handle<v8::Value> toString() = 0;
- virtual void sort(v8::Handle<v8::Function> comparer) = 0;
-
- ObjectType objectType;
- QByteArray typeName;
- int sequenceMetaTypeId;
- int elementMetaTypeId;
-
-protected:
- QV8SequenceResource(QV8Engine *engine, ObjectType type, const QByteArray &name, int sequenceId, int elementId)
- : QV8ObjectResource(engine), objectType(type), typeName(name), sequenceMetaTypeId(sequenceId), elementMetaTypeId(elementId)
- {
- }
-};
-
-// helper function to generate valid warnings if errors occur during sequence operations.
-static void generateWarning(QV8Engine *engine, const QString& description)
-{
- if (!engine)
- return;
- v8::Local<v8::StackTrace> currStack = v8::StackTrace::CurrentStackTrace(1);
- if (currStack.IsEmpty())
- return;
- v8::Local<v8::StackFrame> currFrame = currStack->GetFrame(0);
- if (currFrame.IsEmpty())
- return;
-
- QQmlError retn;
- retn.setDescription(description);
- retn.setLine(currFrame->GetLineNumber());
- retn.setUrl(QUrl(engine->toString(currFrame->GetScriptName())));
- QQmlEnginePrivate::warning(engine->engine(), retn);
-}
-
-
-static int convertV8ValueToInt(QV8Engine *, v8::Handle<v8::Value> v)
-{
- return v->Int32Value();
-}
-
-static v8::Handle<v8::Value> convertIntToV8Value(QV8Engine *, int v)
-{
- return v8::Integer::New(v);
-}
-
-static QString convertIntToString(QV8Engine *, int v)
-{
- return QString::number(v);
-}
-
-static qreal convertV8ValueToReal(QV8Engine *, v8::Handle<v8::Value> v)
-{
- return v->NumberValue();
-}
-
-static v8::Handle<v8::Value> convertRealToV8Value(QV8Engine *, qreal v)
-{
- return v8::Number::New(v);
-}
-
-static QString convertRealToString(QV8Engine *, qreal v)
-{
- return QString::number(v);
-}
-
-static bool convertV8ValueToBool(QV8Engine *, v8::Handle<v8::Value> v)
-{
- return v->BooleanValue();
-}
-
-static v8::Handle<v8::Value> convertBoolToV8Value(QV8Engine *, bool v)
-{
- return v8::Boolean::New(v);
-}
-
-static QString convertBoolToString(QV8Engine *, bool v)
-{
- if (v)
- return QLatin1String("true");
- return QLatin1String("false");
-}
-
-static QString convertV8ValueToString(QV8Engine *e, v8::Handle<v8::Value> v)
-{
- return e->toString(v->ToString());
-}
-
-static v8::Handle<v8::Value> convertStringToV8Value(QV8Engine *e, const QString &v)
-{
- return e->toString(v);
-}
-
-static QString convertStringToString(QV8Engine *, const QString &v)
-{
- return v;
-}
-
-static QString convertV8ValueToQString(QV8Engine *e, v8::Handle<v8::Value> v)
-{
- return e->toString(v->ToString());
-}
-
-static v8::Handle<v8::Value> convertQStringToV8Value(QV8Engine *e, const QString &v)
-{
- return e->toString(v);
-}
-
-static QString convertQStringToString(QV8Engine *, const QString &v)
-{
- return v;
-}
-
-static QUrl convertV8ValueToUrl(QV8Engine *e, v8::Handle<v8::Value> v)
-{
- return QUrl(e->toString(v->ToString()));
-}
-
-static v8::Handle<v8::Value> convertUrlToV8Value(QV8Engine *e, const QUrl &v)
-{
- return e->toString(QLatin1String(v.toEncoded().data()));
-}
-
-static QString convertUrlToString(QV8Engine *, const QUrl &v)
-{
- return v.toString();
-}
-
-
-/*
- \internal
- \class QV8<Type>SequenceResource
- \brief The external resource used in sequence type objects
-
- Every sequence type object returned by QV8SequenceWrapper::newSequence() has
- a QV8<Type>SequenceResource which contains a property index and a pointer
- to the object which contains the property.
-
- Every sequence type object returned by QV8SequenceWrapper::fromVariant() has
- a QV8<Type>SequenceResource which contains a copy of the sequence value.
- Operations on the sequence are implemented directly in terms of that sequence data.
-
- There exists one QV8<Type>SequenceResource instance for every JavaScript Object
- (sequence) instance returned from QV8SequenceWrapper::newSequence() or
- QV8SequenceWrapper::fromVariant().
- */
-
-// F(elementType, elementTypeName, sequenceType, defaultValue)
-#define FOREACH_QML_SEQUENCE_TYPE(F) \
- F(int, Int, QList<int>, 0) \
- F(qreal, Real, QList<qreal>, 0.0) \
- F(bool, Bool, QList<bool>, false) \
- F(QString, String, QList<QString>, QString()) \
- F(QString, QString, QStringList, QString()) \
- F(QUrl, Url, QList<QUrl>, QUrl())
-
-#define QML_SEQUENCE_TYPE_RESOURCE(SequenceElementType, SequenceElementTypeName, SequenceType, DefaultValue, ConversionToV8fn, ConversionFromV8fn, ToStringfn) \
- QT_END_NAMESPACE \
- Q_DECLARE_METATYPE(SequenceType) \
- QT_BEGIN_NAMESPACE \
- class QV8##SequenceElementTypeName##SequenceResource : public QV8SequenceResource { \
- public:\
- QV8##SequenceElementTypeName##SequenceResource(QV8Engine *engine, QObject *obj, int propIdx) \
- : QV8SequenceResource(engine, QV8SequenceResource::Reference, #SequenceType, qMetaTypeId<SequenceType>(), qMetaTypeId<SequenceElementType>()) \
- , object(obj), propertyIndex(propIdx) \
- { \
- } \
- QV8##SequenceElementTypeName##SequenceResource(QV8Engine *engine, const SequenceType &value) \
- : QV8SequenceResource(engine, QV8SequenceResource::Copy, #SequenceType, qMetaTypeId<SequenceType>(), qMetaTypeId<SequenceElementType>()) \
- , object(0), propertyIndex(-1), c(value) \
- { \
- } \
- ~QV8##SequenceElementTypeName##SequenceResource() \
- { \
- } \
- static QVariant toVariant(QV8Engine *e, v8::Handle<v8::Array> array, uint32_t length, bool *succeeded) \
- { \
- SequenceType list; \
- list.reserve(length); \
- for (uint32_t ii = 0; ii < length; ++ii) { \
- list.append(ConversionFromV8fn(e, array->Get(ii))); \
- } \
- *succeeded = true; \
- return QVariant::fromValue<SequenceType>(list); \
- } \
- QVariant toVariant() \
- { \
- if (objectType == QV8SequenceResource::Reference) { \
- if (!object) \
- return QVariant(); \
- loadReference(); \
- } \
- return QVariant::fromValue<SequenceType>(c); \
- } \
- bool isEqual(const QV8SequenceResource *v) \
- { \
- /* Note: two different sequences can never be equal (even if they */ \
- /* contain the same elements in the same order) in order to */ \
- /* maintain JavaScript semantics. However, if they both reference */ \
- /* the same QObject+propertyIndex, they are equal. */ \
- if (objectType == QV8SequenceResource::Reference && v->objectType == QV8SequenceResource::Reference) { \
- if (sequenceMetaTypeId == v->sequenceMetaTypeId) { \
- const QV8##SequenceElementTypeName##SequenceResource *rhs = static_cast<const QV8##SequenceElementTypeName##SequenceResource *>(v); \
- return (object != 0 && object == rhs->object && propertyIndex == rhs->propertyIndex); \
- } \
- } else if (objectType == QV8SequenceResource::Copy && v->objectType == QV8SequenceResource::Copy) { \
- if (sequenceMetaTypeId == v->sequenceMetaTypeId) { \
- const QV8##SequenceElementTypeName##SequenceResource *rhs = static_cast<const QV8##SequenceElementTypeName##SequenceResource *>(v); \
- return (this == rhs); \
- } \
- } \
- return false; \
- } \
- quint32 lengthGetter() \
- { \
- if (objectType == QV8SequenceResource::Reference) { \
- if (!object) \
- return 0; \
- loadReference(); \
- } \
- return static_cast<quint32>(c.count()); \
- } \
- void lengthSetter(v8::Handle<v8::Value> value) \
- { \
- /* Get the new required length */ \
- if (value.IsEmpty() || !value->IsUint32()) \
- return; \
- quint32 newLength = value->Uint32Value(); \
- /* Qt containers have int (rather than uint) allowable indexes. */ \
- if (newLength > INT_MAX) { \
- generateWarning(engine, QLatin1String("Index out of range during length set")); \
- return; \
- } \
- /* Read the sequence from the QObject property if we're a reference */ \
- if (objectType == QV8SequenceResource::Reference) { \
- if (!object) \
- return; \
- loadReference(); \
- } \
- /* Determine whether we need to modify the sequence */ \
- qint32 newCount = static_cast<qint32>(newLength); \
- qint32 count = c.count(); \
- if (newCount == count) { \
- return; \
- } else if (newCount > count) { \
- /* according to ECMA262r3 we need to insert */ \
- /* undefined values increasing length to newLength. */ \
- /* We cannot, so we insert default-values instead. */ \
- c.reserve(newCount); \
- while (newCount > count++) { \
- c.append(DefaultValue); \
- } \
- } else { \
- /* according to ECMA262r3 we need to remove */ \
- /* elements until the sequence is the required length. */ \
- while (newCount < count) { \
- count--; \
- c.removeAt(count); \
- } \
- } \
- /* write back if required. */ \
- if (objectType == QV8SequenceResource::Reference) { \
- /* write back. already checked that object is non-null, so skip that check here. */ \
- storeReference(); \
- } \
- return; \
- } \
- v8::Handle<v8::Value> indexedSetter(quint32 index, v8::Handle<v8::Value> value) \
- { \
- /* Qt containers have int (rather than uint) allowable indexes. */ \
- if (index > INT_MAX) { \
- generateWarning(engine, QLatin1String("Index out of range during indexed set")); \
- return v8::Undefined(); \
- } \
- if (objectType == QV8SequenceResource::Reference) { \
- if (!object) \
- return v8::Undefined(); \
- loadReference(); \
- } \
- /* modify the sequence */ \
- SequenceElementType elementValue = ConversionFromV8fn(engine, value); \
- qint32 count = c.count(); \
- qint32 signedIdx = static_cast<qint32>(index); \
- if (signedIdx == count) { \
- c.append(elementValue); \
- } else if (signedIdx < count) { \
- c[index] = elementValue; \
- } else { \
- /* according to ECMA262r3 we need to insert */ \
- /* the value at the given index, increasing length to index+1. */ \
- c.reserve(signedIdx + 1); \
- while (signedIdx > count++) { \
- c.append(DefaultValue); \
- } \
- c.append(elementValue); \
- } \
- /* write back. already checked that object is non-null, so skip that check here. */ \
- if (objectType == QV8SequenceResource::Reference) \
- storeReference(); \
- return value; \
- } \
- v8::Handle<v8::Value> indexedGetter(quint32 index) \
- { \
- /* Qt containers have int (rather than uint) allowable indexes. */ \
- if (index > INT_MAX) { \
- generateWarning(engine, QLatin1String("Index out of range during indexed get")); \
- return v8::Undefined(); \
- } \
- if (objectType == QV8SequenceResource::Reference) { \
- if (!object) \
- return v8::Undefined(); \
- loadReference(); \
- } \
- qint32 count = c.count(); \
- qint32 signedIdx = static_cast<qint32>(index); \
- if (signedIdx < count) \
- return ConversionToV8fn(engine, c.at(signedIdx)); \
- return v8::Undefined(); \
- } \
- v8::Handle<v8::Boolean> indexedDeleter(quint32 index) \
- { \
- /* Qt containers have int (rather than uint) allowable indexes. */ \
- if (index > INT_MAX) \
- return v8::Boolean::New(false); \
- /* Read in the sequence from the QObject */ \
- if (objectType == QV8SequenceResource::Reference) { \
- if (!object) \
- return v8::Boolean::New(false); \
- loadReference(); \
- } \
- qint32 signedIdx = static_cast<qint32>(index); \
- if (signedIdx < c.count()) { \
- /* according to ECMA262r3 it should be Undefined, */ \
- /* but we cannot, so we insert a default-value instead. */ \
- c.replace(signedIdx, DefaultValue); \
- if (objectType == QV8SequenceResource::Reference) { \
- /* write back. already checked that object is non-null, so skip that check here. */ \
- storeReference(); \
- } \
- return v8::Boolean::New(true); \
- } \
- return v8::Boolean::New(false); \
- } \
- v8::Handle<v8::Array> indexedEnumerator() \
- { \
- if (objectType == QV8SequenceResource::Reference) { \
- if (!object) \
- return v8::Handle<v8::Array>(); \
- loadReference(); \
- } \
- qint32 count = c.count(); \
- v8::Local<v8::Array> retn = v8::Array::New(count); \
- for (qint32 i = 0; i < count; ++i) { \
- retn->Set(static_cast<quint32>(i), v8::Integer::NewFromUnsigned(static_cast<quint32>(i))); \
- } \
- return retn; \
- } \
- v8::Handle<v8::Value> toString() \
- { \
- if (objectType == QV8SequenceResource::Reference) { \
- if (!object) \
- return v8::Undefined(); \
- loadReference(); \
- } \
- QString str; \
- qint32 count = c.count(); \
- for (qint32 i = 0; i < count; ++i) { \
- str += QString(QLatin1String("%1,")).arg(ToStringfn(engine, c[i])); \
- } \
- str.chop(1); \
- return engine->toString(str); \
- } \
- void loadReference() \
- { \
- Q_ASSERT(object); \
- Q_ASSERT(objectType == QV8SequenceResource::Reference); \
- void *a[] = { &c, 0 }; \
- QMetaObject::metacall(object, QMetaObject::ReadProperty, propertyIndex, a); \
- } \
- void storeReference() \
- { \
- Q_ASSERT(object); \
- Q_ASSERT(objectType == QV8SequenceResource::Reference); \
- int status = -1; \
- QQmlPropertyPrivate::WriteFlags flags = \
- QQmlPropertyPrivate::DontRemoveBinding; \
- void *a[] = { &c, 0, &status, &flags }; \
- QMetaObject::metacall(object, QMetaObject::WriteProperty, propertyIndex, a); \
- } \
- class CompareFunctor \
- { \
- public: \
- CompareFunctor(QV8Engine *engine, v8::Handle<v8::Function> f) : jsFn(f), eng(engine) {} \
- bool operator()(SequenceElementType e0, SequenceElementType e1) \
- { \
- v8::Handle<v8::Value> argv[2] = { eng->fromVariant(e0), eng->fromVariant(e1) }; \
- v8::Handle<v8::Value> compareValue = jsFn->Call(eng->global(), 2, argv); \
- return compareValue->NumberValue() < 0; \
- } \
- private: \
- v8::Handle<v8::Function> jsFn; \
- QV8Engine *eng; \
- }; \
- void sort(v8::Handle<v8::Function> jsCompareFunction) \
- { \
- CompareFunctor cf(engine, jsCompareFunction); \
- qSort(c.begin(), c.end(), cf); \
- } \
- private: \
- QQmlGuard<QObject> object; \
- int propertyIndex; \
- SequenceType c; \
- };
-
-#define GENERATE_QML_SEQUENCE_TYPE_RESOURCE(ElementType, ElementTypeName, SequenceType, DefaultValue) \
- QML_SEQUENCE_TYPE_RESOURCE(ElementType, ElementTypeName, SequenceType, DefaultValue, convert##ElementTypeName##ToV8Value, convertV8ValueTo##ElementTypeName, convert##ElementTypeName##ToString)
-
-FOREACH_QML_SEQUENCE_TYPE(GENERATE_QML_SEQUENCE_TYPE_RESOURCE)
-#undef GENERATE_QML_SEQUENCE_TYPE_RESOURCE
-#undef QML_SEQUENCE_TYPE_RESOURCE
-
-QT_END_NAMESPACE
-
-#endif // QV8SEQUENCEWRAPPER_P_P_H
diff --git a/src/qml/qml/v8/qv8sqlerrors.cpp b/src/qml/qml/v8/qv8sqlerrors.cpp
deleted file mode 100644
index e06069cddd..0000000000
--- a/src/qml/qml/v8/qv8sqlerrors.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv8sqlerrors_p.h"
-#include "qv8engine_p.h"
-
-QT_BEGIN_NAMESPACE
-
-void qt_add_sqlexceptions(QV8Engine *engine)
-{
- // SQL Exception
- v8::PropertyAttribute attributes = (v8::PropertyAttribute)(v8::ReadOnly | v8::DontEnum | v8::DontDelete);
-
- v8::Local<v8::Object> sqlexception = v8::Object::New();
- sqlexception->Set(v8::String::New("UNKNOWN_ERR"), v8::Integer::New(SQLEXCEPTION_UNKNOWN_ERR), attributes);
- sqlexception->Set(v8::String::New("DATABASE_ERR"), v8::Integer::New(SQLEXCEPTION_DATABASE_ERR), attributes);
- sqlexception->Set(v8::String::New("VERSION_ERR"), v8::Integer::New(SQLEXCEPTION_VERSION_ERR), attributes);
- sqlexception->Set(v8::String::New("TOO_LARGE_ERR"), v8::Integer::New(SQLEXCEPTION_TOO_LARGE_ERR), attributes);
- sqlexception->Set(v8::String::New("QUOTA_ERR"), v8::Integer::New(SQLEXCEPTION_QUOTA_ERR), attributes);
- sqlexception->Set(v8::String::New("SYNTAX_ERR"), v8::Integer::New(SQLEXCEPTION_SYNTAX_ERR), attributes);
- sqlexception->Set(v8::String::New("CONSTRAINT_ERR"), v8::Integer::New(SQLEXCEPTION_CONSTRAINT_ERR), attributes);
- sqlexception->Set(v8::String::New("TIMEOUT_ERR"), v8::Integer::New(SQLEXCEPTION_TIMEOUT_ERR), attributes);
- engine->global()->Set(v8::String::New("SQLException"), sqlexception);
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv8stringwrapper_p.h b/src/qml/qml/v8/qv8stringwrapper_p.h
deleted file mode 100644
index 6720e06199..0000000000
--- a/src/qml/qml/v8/qv8stringwrapper_p.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQMLV8STRINGWRAPPER_P_H
-#define QQMLV8STRINGWRAPPER_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 <private/qtqmlglobal_p.h>
-
-#include <QtCore/qstring.h>
-#include <private/qv8_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_QML_PRIVATE_EXPORT QV8StringWrapper
-{
-public:
- QV8StringWrapper();
- ~QV8StringWrapper();
-
- void init();
- void destroy();
-
- v8::Local<v8::String> toString(const QString &);
- QString toString(v8::Handle<v8::String>);
-};
-
-QT_END_NAMESPACE
-
-#endif // QQMLV8STRINGWRAPPER_P_H
diff --git a/src/qml/qml/v8/qv8typewrapper.cpp b/src/qml/qml/v8/qv8typewrapper.cpp
deleted file mode 100644
index 820f0b3ee6..0000000000
--- a/src/qml/qml/v8/qv8typewrapper.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv8contextwrapper_p.h"
-#include "qv8engine_p.h"
-
-#include <private/qqmlengine_p.h>
-#include <private/qqmlcontext_p.h>
-
-#include <private/qjsvalue_p.h>
-#include <private/qscript_impl_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QV8TypeResource : public QV8ObjectResource
-{
- V8_RESOURCE_TYPE(TypeType)
-
-public:
- QV8TypeResource(QV8Engine *engine);
- virtual ~QV8TypeResource();
-
- QV8TypeWrapper::TypeNameMode mode;
-
- QQmlGuard<QObject> object;
-
- QQmlType *type;
- QQmlTypeNameCache *typeNamespace;
- const void *importNamespace;
-};
-
-QV8TypeResource::QV8TypeResource(QV8Engine *engine)
-: QV8ObjectResource(engine), mode(QV8TypeWrapper::IncludeEnums), type(0), typeNamespace(0), importNamespace(0)
-{
-}
-
-QV8TypeResource::~QV8TypeResource()
-{
- if (typeNamespace) typeNamespace->release();
-}
-
-QV8TypeWrapper::QV8TypeWrapper()
-: m_engine(0)
-{
-}
-
-QV8TypeWrapper::~QV8TypeWrapper()
-{
-}
-
-void QV8TypeWrapper::destroy()
-{
- qPersistentDispose(m_constructor);
-}
-
-void QV8TypeWrapper::init(QV8Engine *engine)
-{
- m_engine = engine;
- v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
- ft->InstanceTemplate()->SetNamedPropertyHandler(Getter, Setter);
- ft->InstanceTemplate()->SetHasExternalResource(true);
- m_constructor = qPersistentNew<v8::Function>(ft->GetFunction());
-}
-
-// Returns a type wrapper for type t on o. This allows access of enums, and attached properties.
-v8::Local<v8::Object> QV8TypeWrapper::newObject(QObject *o, QQmlType *t, TypeNameMode mode)
-{
- Q_ASSERT(t);
- // XXX NewInstance() should be optimized
- v8::Local<v8::Object> rv = m_constructor->NewInstance();
- QV8TypeResource *r = new QV8TypeResource(m_engine);
- r->mode = mode; r->object = o; r->type = t;
- rv->SetExternalResource(r);
- return rv;
-}
-
-// Returns a type wrapper for importNamespace (of t) on o. This allows nested resolution of a type in a
-// namespace.
-v8::Local<v8::Object> QV8TypeWrapper::newObject(QObject *o, QQmlTypeNameCache *t,
- const void *importNamespace, TypeNameMode mode)
-{
- Q_ASSERT(t);
- Q_ASSERT(importNamespace);
- // XXX NewInstance() should be optimized
- v8::Local<v8::Object> rv = m_constructor->NewInstance();
- QV8TypeResource *r = new QV8TypeResource(m_engine);
- t->addref();
- r->mode = mode; r->object = o; r->typeNamespace = t; r->importNamespace = importNamespace;
- rv->SetExternalResource(r);
- return rv;
-}
-
-QVariant QV8TypeWrapper::toVariant(QV8ObjectResource *r)
-{
- Q_ASSERT(r->resourceType() == QV8ObjectResource::TypeType);
- QV8TypeResource *resource = static_cast<QV8TypeResource *>(r);
- QV8Engine *v8engine = resource->engine;
-
- if (resource->type && resource->type->isSingleton()) {
- QQmlEngine *e = v8engine->engine();
- QQmlType::SingletonInstanceInfo *siinfo = resource->type->singletonInstanceInfo();
- siinfo->init(e); // note: this will also create QJSValue singleton which isn't strictly required.
- QObject *qobjectSingleton = siinfo->qobjectApi(e);
- if (qobjectSingleton) {
- return QVariant::fromValue<QObject*>(qobjectSingleton);
- }
- }
-
- // only QObject Singleton Type can be converted to a variant.
- return QVariant();
-}
-
-v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info)
-{
- QV8TypeResource *resource = v8_resource_cast<QV8TypeResource>(info.This());
-
- if (!resource)
- return v8::Undefined();
-
- QV8Engine *v8engine = resource->engine;
- QQmlContextData *context = v8engine->callingContext();
-
- QObject *object = resource->object;
-
- QHashedV8String propertystring(property);
-
- if (resource->type) {
- QQmlType *type = resource->type;
-
- // singleton types are handled differently to other types.
- if (type->isSingleton()) {
- QQmlEngine *e = v8engine->engine();
- QQmlType::SingletonInstanceInfo *siinfo = type->singletonInstanceInfo();
- siinfo->init(e);
-
- QObject *qobjectSingleton = siinfo->qobjectApi(e);
- if (qobjectSingleton) {
- // check for enum value
- if (QV8Engine::startsWithUpper(property)) {
- if (resource->mode == IncludeEnums) {
- QString name = v8engine->toString(property);
-
- // ### Optimize
- QByteArray enumName = name.toUtf8();
- const QMetaObject *metaObject = qobjectSingleton->metaObject();
- for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) {
- QMetaEnum e = metaObject->enumerator(ii);
- bool ok;
- int value = e.keyToValue(enumName.constData(), &ok);
- if (ok)
- return v8::Integer::New(value);
- }
- }
- }
-
- // check for property.
- v8::Handle<v8::Value> rv = v8engine->qobjectWrapper()->getProperty(qobjectSingleton, propertystring, context, QV8QObjectWrapper::IgnoreRevision);
- return rv;
- } else if (!siinfo->scriptApi(e).isUndefined()) {
- // NOTE: if used in a binding, changes will not trigger re-evaluation since non-NOTIFYable.
- QJSValuePrivate *apiprivate = QJSValuePrivate::get(siinfo->scriptApi(e));
- QScopedPointer<QJSValuePrivate> propertyValue(apiprivate->property(property).give());
- return propertyValue->asV8Value(v8engine);
- }
-
- // Fall through to return empty handle
-
- } else {
-
- if (QV8Engine::startsWithUpper(property)) {
- bool ok = false;
- int value = type->enumValue(propertystring, &ok);
- if (ok)
- return v8::Integer::New(value);
-
- // Fall through to return empty handle
-
- } else if (resource->object) {
- QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object);
- if (ao)
- return v8engine->qobjectWrapper()->getProperty(ao, propertystring, context,
- QV8QObjectWrapper::IgnoreRevision);
-
- // Fall through to return empty handle
- }
-
- // Fall through to return empty handle
- }
-
- // Fall through to return empty handle
-
- } else if (resource->typeNamespace) {
- Q_ASSERT(resource->importNamespace);
- QQmlTypeNameCache::Result r = resource->typeNamespace->query(propertystring,
- resource->importNamespace);
-
- if (r.isValid()) {
- QQmlContextData *context = v8engine->callingContext();
- if (r.type) {
- return v8engine->typeWrapper()->newObject(object, r.type, resource->mode);
- } else if (r.scriptIndex != -1) {
- int index = r.scriptIndex;
- if (index < context->importedScripts.count())
- return context->importedScripts.at(index);
- } else if (r.importNamespace) {
- return v8engine->typeWrapper()->newObject(object, context->imports, r.importNamespace);
- }
-
- return v8::Undefined();
-
- }
-
- // Fall through to return empty handle
-
- } else {
- Q_ASSERT(!"Unreachable");
- }
-
- return v8::Handle<v8::Value>();
-}
-
-v8::Handle<v8::Value> QV8TypeWrapper::Setter(v8::Local<v8::String> property,
- v8::Local<v8::Value> value,
- const v8::AccessorInfo &info)
-{
- QV8TypeResource *resource = v8_resource_cast<QV8TypeResource>(info.This());
-
- if (!resource)
- return value;
-
- QV8Engine *v8engine = resource->engine;
- QQmlContextData *context = v8engine->callingContext();
-
- QHashedV8String propertystring(property);
-
- QQmlType *type = resource->type;
- if (type && !type->isSingleton() && resource->object) {
- QObject *object = resource->object;
- QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object);
- if (ao)
- v8engine->qobjectWrapper()->setProperty(ao, propertystring, context, value,
- QV8QObjectWrapper::IgnoreRevision);
- } else if (type && type->isSingleton()) {
- QQmlEngine *e = v8engine->engine();
- QQmlType::SingletonInstanceInfo *siinfo = type->singletonInstanceInfo();
- siinfo->init(e);
-
- QObject *qobjectSingleton = siinfo->qobjectApi(e);
- if (qobjectSingleton) {
- v8engine->qobjectWrapper()->setProperty(qobjectSingleton, propertystring, context, value,
- QV8QObjectWrapper::IgnoreRevision);
- } else if (!siinfo->scriptApi(e).isUndefined()) {
- QScopedPointer<QJSValuePrivate> setvalp(new QJSValuePrivate(v8engine, value));
- QJSValuePrivate *apiprivate = QJSValuePrivate::get(siinfo->scriptApi(e));
- if (apiprivate->propertyFlags(property) & QJSValuePrivate::ReadOnly) {
- QString error = QLatin1String("Cannot assign to read-only property \"") +
- v8engine->toString(property) + QLatin1Char('\"');
- v8::ThrowException(v8::Exception::Error(v8engine->toString(error)));
- } else {
- apiprivate->setProperty(property, setvalp.data());
- }
- }
- }
-
- return value;
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv8typewrapper_p.h b/src/qml/qml/v8/qv8typewrapper_p.h
deleted file mode 100644
index 852f49770b..0000000000
--- a/src/qml/qml/v8/qv8typewrapper_p.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV8TYPEWRAPPER_P_H
-#define QV8TYPEWRAPPER_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/qglobal.h>
-#include <private/qv8_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QObject;
-class QV8Engine;
-class QQmlType;
-class QQmlTypeNameCache;
-class QV8TypeWrapper
-{
-public:
- QV8TypeWrapper();
- ~QV8TypeWrapper();
-
- void init(QV8Engine *);
- void destroy();
-
- enum TypeNameMode { IncludeEnums, ExcludeEnums };
- v8::Local<v8::Object> newObject(QObject *, QQmlType *, TypeNameMode = IncludeEnums);
- v8::Local<v8::Object> newObject(QObject *, QQmlTypeNameCache *, const void *,
- TypeNameMode = IncludeEnums);
- QVariant toVariant(QV8ObjectResource *);
-
-private:
- static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> Setter(v8::Local<v8::String> property,
- v8::Local<v8::Value> value,
- const v8::AccessorInfo &info);
-
- QV8Engine *m_engine;
- v8::Persistent<v8::Function> m_constructor;
-};
-
-QT_END_NAMESPACE
-
-#endif // QV8TYPEWRAPPER_P_H
-
diff --git a/src/qml/qml/v8/qv8valuetypewrapper.cpp b/src/qml/qml/v8/qv8valuetypewrapper.cpp
deleted file mode 100644
index d5d977d9c4..0000000000
--- a/src/qml/qml/v8/qv8valuetypewrapper.cpp
+++ /dev/null
@@ -1,452 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv8valuetypewrapper_p.h"
-#include "qv8engine_p.h"
-
-#include <private/qqmlvaluetype_p.h>
-#include <private/qqmlbinding_p.h>
-#include <private/qqmlglobal_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QV8ValueTypeResource : public QV8ObjectResource
-{
- V8_RESOURCE_TYPE(ValueTypeType)
-
-public:
- enum ObjectType { Reference, Copy };
-
- QV8ValueTypeResource(QV8Engine *engine, ObjectType objectType);
-
- ObjectType objectType;
- QQmlValueType *type;
-};
-
-class QV8ValueTypeReferenceResource : public QV8ValueTypeResource
-{
-public:
- QV8ValueTypeReferenceResource(QV8Engine *engine);
-
- QQmlGuard<QObject> object;
- int property;
-};
-
-class QV8ValueTypeCopyResource : public QV8ValueTypeResource
-{
-public:
- QV8ValueTypeCopyResource(QV8Engine *engine);
-
- QVariant value;
-};
-
-QV8ValueTypeResource::QV8ValueTypeResource(QV8Engine *engine, ObjectType objectType)
-: QV8ObjectResource(engine), objectType(objectType)
-{
-}
-
-QV8ValueTypeReferenceResource::QV8ValueTypeReferenceResource(QV8Engine *engine)
-: QV8ValueTypeResource(engine, Reference)
-{
-}
-
-QV8ValueTypeCopyResource::QV8ValueTypeCopyResource(QV8Engine *engine)
-: QV8ValueTypeResource(engine, Copy)
-{
-}
-
-QV8ValueTypeWrapper::QV8ValueTypeWrapper()
-: m_engine(0)
-{
-}
-
-QV8ValueTypeWrapper::~QV8ValueTypeWrapper()
-{
-}
-
-void QV8ValueTypeWrapper::destroy()
-{
- qPersistentDispose(m_toString);
- qPersistentDispose(m_constructor);
- qPersistentDispose(m_toStringSymbol);
-}
-
-static quint32 toStringHash = -1;
-
-void QV8ValueTypeWrapper::init(QV8Engine *engine)
-{
- m_engine = engine;
- m_toString = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(ToString)->GetFunction());
- v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
- ft->InstanceTemplate()->SetNamedPropertyHandler(Getter, Setter);
- ft->InstanceTemplate()->SetHasExternalResource(true);
- ft->InstanceTemplate()->MarkAsUseUserObjectComparison();
- ft->InstanceTemplate()->SetAccessor(v8::String::New("toString"), ToStringGetter, 0,
- m_toString, v8::DEFAULT,
- v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
- m_constructor = qPersistentNew<v8::Function>(ft->GetFunction());
-
- m_toStringSymbol = qPersistentNew<v8::String>(v8::String::NewSymbol("toString"));
- m_toStringString = QHashedV8String(m_toStringSymbol);
- toStringHash = m_toStringString.hash();
-}
-
-v8::Local<v8::Object> QV8ValueTypeWrapper::newValueType(QObject *object, int property, QQmlValueType *type)
-{
- // XXX NewInstance() should be optimized
- v8::Local<v8::Object> rv = m_constructor->NewInstance();
- QV8ValueTypeReferenceResource *r = new QV8ValueTypeReferenceResource(m_engine);
- r->type = type; r->object = object; r->property = property;
- rv->SetExternalResource(r);
- return rv;
-}
-
-v8::Local<v8::Object> QV8ValueTypeWrapper::newValueType(const QVariant &value, QQmlValueType *type)
-{
- // XXX NewInstance() should be optimized
- v8::Local<v8::Object> rv = m_constructor->NewInstance();
- QV8ValueTypeCopyResource *r = new QV8ValueTypeCopyResource(m_engine);
- r->type = type; r->value = value;
- rv->SetExternalResource(r);
- return rv;
-}
-
-static bool readReferenceValue(QV8ValueTypeReferenceResource *reference)
-{
- // A reference resource may be either a "true" reference (eg, to a QVector3D property)
- // or a "variant" reference (eg, to a QVariant property which happens to contain a value-type).
- QMetaProperty writebackProperty = reference->object->metaObject()->property(reference->property);
- if (writebackProperty.userType() == QMetaType::QVariant) {
- // variant-containing-value-type reference
- QVariant variantReferenceValue;
- reference->type->readVariantValue(reference->object, reference->property, &variantReferenceValue);
- int variantReferenceType = variantReferenceValue.userType();
- if (variantReferenceType != reference->type->userType()) {
- // This is a stale VariantReference. That is, the variant has been
- // overwritten with a different type in the meantime.
- // We need to modify this reference to the updated value type, if
- // possible, or return false if it is not a value type.
- if (QQmlValueTypeFactory::isValueType(variantReferenceType)) {
- reference->type = QQmlValueTypeFactory::valueType(variantReferenceType);
- if (!reference->type) {
- return false;
- }
- } else {
- return false;
- }
- }
- reference->type->setValue(variantReferenceValue);
- } else {
- // value-type reference
- reference->type->read(reference->object, reference->property);
- }
- return true;
-}
-
-bool QV8ValueTypeWrapper::isValueType(v8::Handle<v8::Object> obj) const
-{
- QV8ValueTypeResource *r = v8_resource_cast<QV8ValueTypeResource>(obj);
- return (r != 0);
-}
-
-QVariant QV8ValueTypeWrapper::toVariant(v8::Handle<v8::Object> obj, int typeHint, bool *succeeded)
-{
- // NOTE: obj must not be an external resource object (ie, wrapper object)
- // instead, it is a normal js object which one of the value-type providers
- // may know how to convert to the given type.
- return QQml_valueTypeProvider()->createVariantFromJsObject(typeHint, QQmlV8Handle::fromHandle(obj), m_engine, succeeded);
-}
-
-QVariant QV8ValueTypeWrapper::toVariant(v8::Handle<v8::Object> obj)
-{
- QV8ValueTypeResource *r = v8_resource_cast<QV8ValueTypeResource>(obj);
- if (r) return toVariant(r);
- else return QVariant();
-}
-
-QVariant QV8ValueTypeWrapper::toVariant(QV8ObjectResource *r)
-{
- Q_ASSERT(r->resourceType() == QV8ObjectResource::ValueTypeType);
- QV8ValueTypeResource *resource = static_cast<QV8ValueTypeResource *>(r);
-
- if (resource->objectType == QV8ValueTypeResource::Reference) {
- QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(resource);
-
- if (reference->object && readReferenceValue(reference)) {
- return reference->type->value();
- } else {
- return QVariant();
- }
-
- } else {
- Q_ASSERT(resource->objectType == QV8ValueTypeResource::Copy);
-
- QV8ValueTypeCopyResource *copy = static_cast<QV8ValueTypeCopyResource *>(resource);
-
- return copy->value;
- }
-}
-
-bool QV8ValueTypeWrapper::isEqual(QV8ObjectResource *r, const QVariant& value)
-{
- Q_ASSERT(r->resourceType() == QV8ObjectResource::ValueTypeType);
- QV8ValueTypeResource *resource = static_cast<QV8ValueTypeResource *>(r);
-
- if (resource->objectType == QV8ValueTypeResource::Reference) {
- QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(resource);
- if (reference->object && readReferenceValue(reference)) {
- return reference->type->isEqual(value);
- } else {
- return false;
- }
- } else {
- Q_ASSERT(resource->objectType == QV8ValueTypeResource::Copy);
- QV8ValueTypeCopyResource *copy = static_cast<QV8ValueTypeCopyResource *>(resource);
- resource->type->setValue(copy->value);
- if (resource->type->isEqual(value))
- return true;
- return (value == copy->value);
- }
-}
-
-v8::Handle<v8::Value> QV8ValueTypeWrapper::ToStringGetter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info)
-{
- Q_UNUSED(property);
- return info.Data();
-}
-
-v8::Handle<v8::Value> QV8ValueTypeWrapper::ToString(const v8::Arguments &args)
-{
- QV8ValueTypeResource *resource = v8_resource_cast<QV8ValueTypeResource>(args.This());
- if (resource) {
- if (resource->objectType == QV8ValueTypeResource::Reference) {
- QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(resource);
- if (reference->object && readReferenceValue(reference)) {
- return resource->engine->toString(resource->type->toString());
- } else {
- return v8::Undefined();
- }
- } else {
- Q_ASSERT(resource->objectType == QV8ValueTypeResource::Copy);
- QV8ValueTypeCopyResource *copy = static_cast<QV8ValueTypeCopyResource *>(resource);
- resource->type->setValue(copy->value);
- return resource->engine->toString(resource->type->toString());
- }
- } else {
- return v8::Undefined();
- }
-}
-
-v8::Handle<v8::Value> QV8ValueTypeWrapper::Getter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info)
-{
- QV8ValueTypeResource *r = v8_resource_cast<QV8ValueTypeResource>(info.This());
- if (!r) return v8::Handle<v8::Value>();
-
- QHashedV8String propertystring(property);
-
- {
- // Comparing the hash first actually makes a measurable difference here, at least on x86
- quint32 hash = propertystring.hash();
- if (hash == toStringHash &&
- r->engine->valueTypeWrapper()->m_toStringString == propertystring) {
- return r->engine->valueTypeWrapper()->m_toString;
- }
- }
-
- // Note: readReferenceValue() can change the reference->type.
- if (r->objectType == QV8ValueTypeResource::Reference) {
- QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(r);
-
- if (!reference->object || !readReferenceValue(reference))
- return v8::Handle<v8::Value>();
-
- } else {
- Q_ASSERT(r->objectType == QV8ValueTypeResource::Copy);
-
- QV8ValueTypeCopyResource *copy = static_cast<QV8ValueTypeCopyResource *>(r);
-
- r->type->setValue(copy->value);
- }
-
- QQmlPropertyData local;
- QQmlPropertyData *result = 0;
- {
- QQmlData *ddata = QQmlData::get(r->type, false);
- if (ddata && ddata->propertyCache)
- result = ddata->propertyCache->property(propertystring, 0, 0);
- else
- result = QQmlPropertyCache::property(r->engine->engine(), r->type,
- propertystring, 0, local);
- }
-
- if (!result)
- return v8::Handle<v8::Value>();
-
- if (result->isFunction()) {
- // calling a Q_INVOKABLE function of a value type
- QQmlContextData *context = r->engine->callingContext();
- return r->engine->qobjectWrapper()->getProperty(r->type, propertystring, context, QV8QObjectWrapper::IgnoreRevision);
- }
-
-#define VALUE_TYPE_LOAD(metatype, cpptype, constructor) \
- if (result->propType == metatype) { \
- cpptype v; \
- void *args[] = { &v, 0 }; \
- r->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args); \
- return constructor(v); \
- }
-
- // These four types are the most common used by the value type wrappers
- VALUE_TYPE_LOAD(QMetaType::QReal, qreal, v8::Number::New);
- VALUE_TYPE_LOAD(QMetaType::Int, int, v8::Integer::New);
- VALUE_TYPE_LOAD(QMetaType::QString, QString, r->engine->toString);
- VALUE_TYPE_LOAD(QMetaType::Bool, bool, v8::Boolean::New);
-
- QVariant v(result->propType, (void *)0);
- void *args[] = { v.data(), 0 };
- r->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args);
- return r->engine->fromVariant(v);
-#undef VALUE_TYPE_ACCESSOR
-}
-
-v8::Handle<v8::Value> QV8ValueTypeWrapper::Setter(v8::Local<v8::String> property,
- v8::Local<v8::Value> value,
- const v8::AccessorInfo &info)
-{
- QV8ValueTypeResource *r = v8_resource_cast<QV8ValueTypeResource>(info.This());
- if (!r) return value;
-
- QByteArray propName = r->engine->toString(property).toUtf8();
- if (r->objectType == QV8ValueTypeResource::Reference) {
- QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(r);
- QMetaProperty writebackProperty = reference->object->metaObject()->property(reference->property);
-
- if (!reference->object || !writebackProperty.isWritable() || !readReferenceValue(reference))
- return value;
-
- // we lookup the index after readReferenceValue() since it can change the reference->type.
- int index = r->type->metaObject()->indexOfProperty(propName.constData());
- if (index == -1)
- return value;
- QMetaProperty p = r->type->metaObject()->property(index);
-
- QQmlBinding *newBinding = 0;
-
- if (value->IsFunction()) {
- if (value->ToObject()->GetHiddenValue(r->engine->bindingFlagKey()).IsEmpty()) {
- // assigning a JS function to a non-var-property is not allowed.
- QString error = QLatin1String("Cannot assign JavaScript function to value-type property");
- v8::ThrowException(v8::Exception::Error(r->engine->toString(error)));
- return value;
- }
-
- QQmlContextData *context = r->engine->callingContext();
- v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(value);
-
- QQmlPropertyData cacheData;
- cacheData.setFlags(QQmlPropertyData::IsWritable |
- QQmlPropertyData::IsValueTypeVirtual);
- cacheData.propType = reference->object->metaObject()->property(reference->property).userType();
- cacheData.coreIndex = reference->property;
- cacheData.valueTypeFlags = 0;
- cacheData.valueTypeCoreIndex = index;
- cacheData.valueTypePropType = p.userType();
-
- v8::Local<v8::StackTrace> trace =
- v8::StackTrace::CurrentStackTrace(1,
- (v8::StackTrace::StackTraceOptions)(v8::StackTrace::kLineNumber |
- v8::StackTrace::kScriptName));
- v8::Local<v8::StackFrame> frame = trace->GetFrame(0);
- int lineNumber = frame->GetLineNumber();
- int columnNumber = frame->GetColumn();
- QString url = r->engine->toString(frame->GetScriptName());
-
- newBinding = new QQmlBinding(&function, reference->object, context,
- url, qmlSourceCoordinate(lineNumber), qmlSourceCoordinate(columnNumber));
- newBinding->setTarget(reference->object, cacheData, context);
- newBinding->setEvaluateFlags(newBinding->evaluateFlags() |
- QQmlBinding::RequiresThisObject);
- }
-
- QQmlAbstractBinding *oldBinding =
- QQmlPropertyPrivate::setBinding(reference->object, reference->property, index, newBinding);
- if (oldBinding)
- oldBinding->destroy();
-
- if (!value->IsFunction()) {
- QVariant v = r->engine->toVariant(value, -1);
-
- if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double)
- v = v.toInt();
-
- p.write(reference->type, v);
-
- if (writebackProperty.userType() == QMetaType::QVariant) {
- QVariant variantReferenceValue = r->type->value();
- reference->type->writeVariantValue(reference->object, reference->property, 0, &variantReferenceValue);
- } else {
- reference->type->write(reference->object, reference->property, 0);
- }
- }
-
- } else {
- Q_ASSERT(r->objectType == QV8ValueTypeResource::Copy);
-
- QV8ValueTypeCopyResource *copy = static_cast<QV8ValueTypeCopyResource *>(r);
-
- int index = r->type->metaObject()->indexOfProperty(propName.constData());
- if (index == -1)
- return value;
-
- QVariant v = r->engine->toVariant(value, -1);
-
- r->type->setValue(copy->value);
- QMetaProperty p = r->type->metaObject()->property(index);
- p.write(r->type, v);
- copy->value = r->type->value();
- }
-
- return value;
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv8valuetypewrapper_p.h b/src/qml/qml/v8/qv8valuetypewrapper_p.h
deleted file mode 100644
index d22874639a..0000000000
--- a/src/qml/qml/v8/qv8valuetypewrapper_p.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV8VALUETYPEWRAPPER_P_H
-#define QV8VALUETYPEWRAPPER_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/qglobal.h>
-#include <QtQml/qqmllist.h>
-#include <private/qtqmlglobal_p.h>
-#include <private/qv8_p.h>
-#include <private/qhashedstring_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QV8Engine;
-class QV8ObjectResource;
-class QQmlValueType;
-class Q_QML_PRIVATE_EXPORT QV8ValueTypeWrapper
-{
-public:
- QV8ValueTypeWrapper();
- ~QV8ValueTypeWrapper();
-
- void init(QV8Engine *);
- void destroy();
-
- v8::Local<v8::Object> newValueType(QObject *, int, QQmlValueType *);
- v8::Local<v8::Object> newValueType(const QVariant &, QQmlValueType *);
-
- bool isValueType(v8::Handle<v8::Object>) const;
-
- QVariant toVariant(v8::Handle<v8::Object>, int typeHint, bool *succeeded);
- QVariant toVariant(v8::Handle<v8::Object>);
- QVariant toVariant(QV8ObjectResource *);
-
- static bool isEqual(QV8ObjectResource *, const QVariant& value);
-
-private:
- static v8::Handle<v8::Value> ToStringGetter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> ToString(const v8::Arguments &args);
- static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> Setter(v8::Local<v8::String> property,
- v8::Local<v8::Value> value,
- const v8::AccessorInfo &info);
-
- QV8Engine *m_engine;
- v8::Persistent<v8::Function> m_constructor;
- v8::Persistent<v8::Function> m_toString;
- v8::Persistent<v8::String> m_toStringSymbol;
- QHashedV8String m_toStringString;
-};
-
-QT_END_NAMESPACE
-
-#endif // QV8VALUETYPEWRAPPER_P_H
-
-
diff --git a/src/qml/qml/v8/qv8variantresource_p.h b/src/qml/qml/v8/qv8variantresource_p.h
deleted file mode 100644
index 1c65861c98..0000000000
--- a/src/qml/qml/v8/qv8variantresource_p.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV8VARIANTRESOURCE_P_H
-#define QV8VARIANTRESOURCE_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/qglobal.h>
-#include <private/qv8_p.h>
-#include <private/qv8engine_p.h>
-#include <private/qqmlengine_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QV8VariantResource : public QV8ObjectResource,
- public QQmlEnginePrivate::ScarceResourceData
-{
- V8_RESOURCE_TYPE(VariantType)
-
-public:
- QV8VariantResource(QV8Engine *engine, const QVariant &data);
-
- void addVmePropertyReference();
- void removeVmePropertyReference();
-
- bool m_isScarceResource;
- int m_vmePropertyReferenceCount;
-};
-
-QT_END_NAMESPACE
-
-#endif // QV8VARIANTRESOURCE_P_H
-
diff --git a/src/qml/qml/v8/qv8variantwrapper.cpp b/src/qml/qml/v8/qv8variantwrapper.cpp
deleted file mode 100644
index bea016a905..0000000000
--- a/src/qml/qml/v8/qv8variantwrapper.cpp
+++ /dev/null
@@ -1,279 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv8variantwrapper_p.h"
-#include "qv8variantresource_p.h"
-#include "qv8engine_p.h"
-#include <private/qqmlengine_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QV8VariantResource::QV8VariantResource(QV8Engine *engine, const QVariant &data)
-: QV8ObjectResource(engine), QQmlEnginePrivate::ScarceResourceData(data), m_isScarceResource(false), m_vmePropertyReferenceCount(0)
-{
-}
-
-void QV8VariantResource::addVmePropertyReference()
-{
- if (m_isScarceResource && ++m_vmePropertyReferenceCount == 1) {
- // remove from the ep->scarceResources list
- // since it is now no longer eligible to be
- // released automatically by the engine.
- node.remove();
- }
-}
-
-void QV8VariantResource::removeVmePropertyReference()
-{
- if (m_isScarceResource && --m_vmePropertyReferenceCount == 0) {
- // and add to the ep->scarceResources list
- // since it is now eligible to be released
- // automatically by the engine.
- QQmlEnginePrivate::get(engine->engine())->scarceResources.insert(this);
- }
-}
-
-QV8VariantWrapper::QV8VariantWrapper()
-: m_engine(0)
-{
-}
-
-QV8VariantWrapper::~QV8VariantWrapper()
-{
-}
-
-void QV8VariantWrapper::init(QV8Engine *engine)
-{
- m_engine = engine;
- m_toString = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(ToString)->GetFunction());
- m_valueOf = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(ValueOf)->GetFunction());
-
- {
- v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
- ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter);
- ft->InstanceTemplate()->SetHasExternalResource(true);
- ft->InstanceTemplate()->MarkAsUseUserObjectComparison();
- ft->InstanceTemplate()->SetAccessor(v8::String::New("toString"), ToStringGetter, 0,
- m_toString, v8::DEFAULT,
- v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
- ft->InstanceTemplate()->SetAccessor(v8::String::New("valueOf"), ValueOfGetter, 0,
- m_valueOf, v8::DEFAULT,
- v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
- m_constructor = qPersistentNew<v8::Function>(ft->GetFunction());
- }
- {
- m_preserve = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(Preserve)->GetFunction());
- m_destroy = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(Destroy)->GetFunction());
- v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
- ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter);
- ft->InstanceTemplate()->SetHasExternalResource(true);
- ft->InstanceTemplate()->MarkAsUseUserObjectComparison();
- ft->InstanceTemplate()->SetAccessor(v8::String::New("preserve"), PreserveGetter, 0,
- m_preserve, v8::DEFAULT,
- v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
- ft->InstanceTemplate()->SetAccessor(v8::String::New("destroy"), DestroyGetter, 0,
- m_destroy, v8::DEFAULT,
- v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
- ft->InstanceTemplate()->SetAccessor(v8::String::New("toString"), ToStringGetter, 0,
- m_toString, v8::DEFAULT,
- v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
- ft->InstanceTemplate()->SetAccessor(v8::String::New("valueOf"), ValueOfGetter, 0,
- m_valueOf, v8::DEFAULT,
- v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
- m_scarceConstructor = qPersistentNew<v8::Function>(ft->GetFunction());
- }
-
-}
-
-void QV8VariantWrapper::destroy()
-{
- qPersistentDispose(m_valueOf);
- qPersistentDispose(m_toString);
- qPersistentDispose(m_destroy);
- qPersistentDispose(m_preserve);
- qPersistentDispose(m_scarceConstructor);
- qPersistentDispose(m_constructor);
-}
-
-v8::Local<v8::Object> QV8VariantWrapper::newVariant(const QVariant &value)
-{
- bool scarceResource = value.type() == QVariant::Pixmap ||
- value.type() == QVariant::Image;
-
- // XXX NewInstance() should be optimized
- v8::Local<v8::Object> rv;
- QV8VariantResource *r = new QV8VariantResource(m_engine, value);
-
- if (scarceResource) {
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(m_engine->engine());
- Q_ASSERT(ep->scarceResourcesRefCount);
- rv = m_scarceConstructor->NewInstance();
- r->m_isScarceResource = true;
- ep->scarceResources.insert(r);
- } else {
- rv = m_constructor->NewInstance();
- }
-
- rv->SetExternalResource(r);
- return rv;
-}
-
-bool QV8VariantWrapper::isVariant(v8::Handle<v8::Value> value)
-{
- return value->IsObject() && v8_resource_cast<QV8VariantResource>(value->ToObject());
-}
-
-QVariant QV8VariantWrapper::toVariant(v8::Handle<v8::Object> obj)
-{
- QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(obj);
- return r?r->data:QVariant();
-}
-
-QVariant QV8VariantWrapper::toVariant(QV8ObjectResource *r)
-{
- Q_ASSERT(r->resourceType() == QV8ObjectResource::VariantType);
- return static_cast<QV8VariantResource *>(r)->data;
-}
-
-QVariant &QV8VariantWrapper::variantValue(v8::Handle<v8::Value> value)
-{
- Q_ASSERT(isVariant(value));
- QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(value->ToObject());
- return static_cast<QV8VariantResource *>(r)->data;
-}
-
-v8::Handle<v8::Value> QV8VariantWrapper::Getter(v8::Local<v8::String> /* property */,
- const v8::AccessorInfo & /* info */)
-{
- return v8::Handle<v8::Value>();
-}
-
-v8::Handle<v8::Value> QV8VariantWrapper::Setter(v8::Local<v8::String> /* property */,
- v8::Local<v8::Value> value,
- const v8::AccessorInfo & /* info */)
-{
- return value;
-}
-
-v8::Handle<v8::Value> QV8VariantWrapper::PreserveGetter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info)
-{
- Q_UNUSED(property);
- return info.Data();
-}
-
-v8::Handle<v8::Value> QV8VariantWrapper::DestroyGetter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info)
-{
- Q_UNUSED(property);
- return info.Data();
-}
-
-v8::Handle<v8::Value> QV8VariantWrapper::ToStringGetter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info)
-{
- Q_UNUSED(property);
- return info.Data();
-}
-
-v8::Handle<v8::Value> QV8VariantWrapper::ValueOfGetter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info)
-{
- Q_UNUSED(property);
- return info.Data();
-}
-
-v8::Handle<v8::Value> QV8VariantWrapper::Preserve(const v8::Arguments &args)
-{
- QV8VariantResource *resource = v8_resource_cast<QV8VariantResource>(args.This());
- if (resource) {
- resource->node.remove();
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> QV8VariantWrapper::Destroy(const v8::Arguments &args)
-{
- QV8VariantResource *resource = v8_resource_cast<QV8VariantResource>(args.This());
- if (resource) {
- resource->data = QVariant();
- resource->node.remove();
- }
- return v8::Undefined();
-}
-
-v8::Handle<v8::Value> QV8VariantWrapper::ToString(const v8::Arguments &args)
-{
- QV8VariantResource *resource = v8_resource_cast<QV8VariantResource>(args.This());
- if (resource) {
- QString result = resource->data.toString();
- if (result.isEmpty() && !resource->data.canConvert(QVariant::String))
- result = QString::fromLatin1("QVariant(%0)").arg(QString::fromLatin1(resource->data.typeName()));
- return resource->engine->toString(result);
- } else {
- return v8::Undefined();
- }
-}
-
-v8::Handle<v8::Value> QV8VariantWrapper::ValueOf(const v8::Arguments &args)
-{
- QV8VariantResource *resource = v8_resource_cast<QV8VariantResource>(args.This());
- if (resource) {
- QVariant v = resource->data;
- switch (v.type()) {
- case QVariant::Invalid:
- return v8::Undefined();
- case QVariant::String:
- return resource->engine->toString(v.toString());
- case QVariant::Int:
- case QVariant::Double:
- case QVariant::UInt:
- return v8::Number::New(v.toDouble());
- case QVariant::Bool:
- return v8::Boolean::New(v.toBool());
- default:
- break;
- }
- }
- return args.This();
-}
-
-QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qv8variantwrapper_p.h b/src/qml/qml/v8/qv8variantwrapper_p.h
deleted file mode 100644
index 9f634b938d..0000000000
--- a/src/qml/qml/v8/qv8variantwrapper_p.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV8VARIANTWRAPPER_P_H
-#define QV8VARIANTWRAPPER_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/qglobal.h>
-#include <QtQml/qqmllist.h>
-#include <private/qv8_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QV8Engine;
-class QV8ObjectResource;
-class QV8VariantWrapper
-{
-public:
- QV8VariantWrapper();
- ~QV8VariantWrapper();
-
- void init(QV8Engine *);
- void destroy();
-
- v8::Local<v8::Object> newVariant(const QVariant &);
- bool isVariant(v8::Handle<v8::Value>);
- static QVariant toVariant(v8::Handle<v8::Object>);
- static QVariant toVariant(QV8ObjectResource *);
- QVariant &variantValue(v8::Handle<v8::Value>);
-
-private:
- static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> Setter(v8::Local<v8::String> property,
- v8::Local<v8::Value> value,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> PreserveGetter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> DestroyGetter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> ToStringGetter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> ValueOfGetter(v8::Local<v8::String> property,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> Preserve(const v8::Arguments &args);
- static v8::Handle<v8::Value> Destroy(const v8::Arguments &args);
- static v8::Handle<v8::Value> ToString(const v8::Arguments &args);
- static v8::Handle<v8::Value> ValueOf(const v8::Arguments &args);
-
- QV8Engine *m_engine;
- v8::Persistent<v8::Function> m_constructor;
- v8::Persistent<v8::Function> m_scarceConstructor;
- v8::Persistent<v8::Function> m_preserve;
- v8::Persistent<v8::Function> m_destroy;
- v8::Persistent<v8::Function> m_toString;
- v8::Persistent<v8::Function> m_valueOf;
-};
-
-QT_END_NAMESPACE
-
-#endif // QV8VARIANTWRAPPER_P_H
-
diff --git a/src/qml/qml/v8/qv8worker.cpp b/src/qml/qml/v8/qv8worker.cpp
deleted file mode 100644
index 9556e146ef..0000000000
--- a/src/qml/qml/v8/qv8worker.cpp
+++ /dev/null
@@ -1,392 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv8worker_p.h"
-
-#include <private/qqmllistmodel_p.h>
-#include <private/qqmllistmodelworkeragent_p.h>
-
-QT_BEGIN_NAMESPACE
-
-// We allow the following JavaScript types to be passed between the main and
-// the secondary thread:
-// + undefined
-// + null
-// + Boolean
-// + String
-// + Function
-// + Array
-// + "Simple" Objects
-// + Number
-// + Date
-// + RegExp
-// <quint8 type><quint24 size><data>
-
-enum Type {
- WorkerUndefined,
- WorkerNull,
- WorkerTrue,
- WorkerFalse,
- WorkerString,
- WorkerFunction,
- WorkerArray,
- WorkerObject,
- WorkerInt32,
- WorkerUint32,
- WorkerNumber,
- WorkerDate,
- WorkerRegexp,
- WorkerListModel,
- WorkerSequence
-};
-
-static inline quint32 valueheader(Type type, quint32 size = 0)
-{
- return quint8(type) << 24 | (size & 0xFFFFFF);
-}
-
-static inline Type headertype(quint32 header)
-{
- return (Type)(header >> 24);
-}
-
-static inline quint32 headersize(quint32 header)
-{
- return header & 0xFFFFFF;
-}
-
-static inline void push(QByteArray &data, quint32 value)
-{
- data.append((const char *)&value, sizeof(quint32));
-}
-
-static inline void push(QByteArray &data, double value)
-{
- data.append((const char *)&value, sizeof(double));
-}
-
-static inline void push(QByteArray &data, void *ptr)
-{
- data.append((const char *)&ptr, sizeof(void *));
-}
-
-static inline void reserve(QByteArray &data, int extra)
-{
- data.reserve(data.size() + extra);
-}
-
-static inline quint32 popUint32(const char *&data)
-{
- quint32 rv = *((quint32 *)data);
- data += sizeof(quint32);
- return rv;
-}
-
-static inline double popDouble(const char *&data)
-{
- double rv = *((double *)data);
- data += sizeof(double);
- return rv;
-}
-
-static inline void *popPtr(const char *&data)
-{
- void *rv = *((void **)data);
- data += sizeof(void *);
- return rv;
-}
-
-// XXX TODO: Check that worker script is exception safe in the case of
-// serialization/deserialization failures
-
-#define ALIGN(size) (((size) + 3) & ~3)
-void QV8Worker::serialize(QByteArray &data, v8::Handle<v8::Value> v, QV8Engine *engine)
-{
- if (v.IsEmpty()) {
- } else if (v->IsUndefined()) {
- push(data, valueheader(WorkerUndefined));
- } else if (v->IsNull()) {
- push(data, valueheader(WorkerNull));
- } else if (v->IsTrue()) {
- push(data, valueheader(WorkerTrue));
- } else if (v->IsFalse()) {
- push(data, valueheader(WorkerFalse));
- } else if (v->IsString()) {
- v8::Handle<v8::String> string = v->ToString();
- int length = string->Length() + 1;
- if (length > 0xFFFFFF) {
- push(data, valueheader(WorkerUndefined));
- return;
- }
- int utf16size = ALIGN(length * sizeof(uint16_t));
-
- reserve(data, utf16size + sizeof(quint32));
- push(data, valueheader(WorkerString, length));
-
- int offset = data.size();
- data.resize(data.size() + utf16size);
- char *buffer = data.data() + offset;
-
- string->Write((uint16_t*)buffer);
- } else if (v->IsFunction()) {
- // XXX TODO: Implement passing function objects between the main and
- // worker scripts
- push(data, valueheader(WorkerUndefined));
- } else if (v->IsArray()) {
- v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(v);
- uint32_t length = array->Length();
- if (length > 0xFFFFFF) {
- push(data, valueheader(WorkerUndefined));
- return;
- }
- reserve(data, sizeof(quint32) + length * sizeof(quint32));
- push(data, valueheader(WorkerArray, length));
- for (uint32_t ii = 0; ii < length; ++ii)
- serialize(data, array->Get(ii), engine);
- } else if (v->IsInt32()) {
- reserve(data, 2 * sizeof(quint32));
- push(data, valueheader(WorkerInt32));
- push(data, (quint32)v->Int32Value());
- } else if (v->IsUint32()) {
- reserve(data, 2 * sizeof(quint32));
- push(data, valueheader(WorkerUint32));
- push(data, v->Uint32Value());
- } else if (v->IsNumber()) {
- reserve(data, sizeof(quint32) + sizeof(double));
- push(data, valueheader(WorkerNumber));
- push(data, v->NumberValue());
- } else if (v->IsDate()) {
- reserve(data, sizeof(quint32) + sizeof(double));
- push(data, valueheader(WorkerDate));
- push(data, v8::Handle<v8::Date>::Cast(v)->NumberValue());
- } else if (v->IsRegExp()) {
- v8::Handle<v8::RegExp> regexp = v8::Handle<v8::RegExp>::Cast(v);
- quint32 flags = regexp->GetFlags();
- v8::Local<v8::String> source = regexp->GetSource();
-
- int length = source->Length() + 1;
- if (length > 0xFFFFFF) {
- push(data, valueheader(WorkerUndefined));
- return;
- }
- int utf16size = ALIGN(length * sizeof(uint16_t));
-
- reserve(data, sizeof(quint32) + utf16size);
- push(data, valueheader(WorkerRegexp, flags));
- push(data, (quint32)length);
- int offset = data.size();
- data.resize(data.size() + utf16size);
- char *buffer = data.data() + offset;
-
- source->Write((uint16_t*)buffer);
- } else if (v->IsObject() && !v->ToObject()->GetExternalResource()) {
- v8::Handle<v8::Object> object = v->ToObject();
- v8::Local<v8::Array> properties = engine->getOwnPropertyNames(object);
- quint32 length = properties->Length();
- if (length > 0xFFFFFF) {
- push(data, valueheader(WorkerUndefined));
- return;
- }
- push(data, valueheader(WorkerObject, length));
- v8::TryCatch tc;
- for (quint32 ii = 0; ii < length; ++ii) {
- v8::Local<v8::String> str = properties->Get(ii)->ToString();
- serialize(data, str, engine);
-
- v8::Local<v8::Value> val = object->Get(str);
- if (tc.HasCaught()) {
- serialize(data, v8::Undefined(), engine);
- tc.Reset();
- } else {
- serialize(data, val, engine);
- }
- }
- } else if (engine->isQObject(v)) {
- // XXX TODO: Generalize passing objects between the main thread and worker scripts so
- // that others can trivially plug in their elements.
- QQmlListModel *lm = qobject_cast<QQmlListModel *>(engine->toQObject(v));
- if (lm && lm->agent()) {
- QQmlListModelWorkerAgent *agent = lm->agent();
- agent->addref();
- push(data, valueheader(WorkerListModel));
- push(data, (void *)agent);
- return;
- }
- // No other QObject's are allowed to be sent
- push(data, valueheader(WorkerUndefined));
- } else {
- // we can convert sequences, but not other types with external data.
- if (v->IsObject()) {
- v8::Handle<v8::Object> seqObj = v->ToObject();
- QV8ObjectResource *r = static_cast<QV8ObjectResource *>(seqObj->GetExternalResource());
- if (r->resourceType() == QV8ObjectResource::SequenceType) {
- QVariant sequenceVariant = engine->sequenceWrapper()->toVariant(r);
- if (!sequenceVariant.isNull()) {
- // valid sequence. we generate a length (sequence length + 1 for the sequence type)
- uint32_t seqLength = engine->sequenceWrapper()->sequenceLength(r);
- uint32_t length = seqLength + 1;
- if (length > 0xFFFFFF) {
- push(data, valueheader(WorkerUndefined));
- return;
- }
- reserve(data, sizeof(quint32) + length * sizeof(quint32));
- push(data, valueheader(WorkerSequence, length));
- serialize(data, v8::Integer::New(sequenceVariant.userType()), engine); // sequence type
- for (uint32_t ii = 0; ii < seqLength; ++ii) {
- serialize(data, seqObj->Get(ii), engine); // sequence elements
- }
-
- return;
- }
- }
- }
-
- // not a sequence.
- push(data, valueheader(WorkerUndefined));
- }
-}
-
-v8::Handle<v8::Value> QV8Worker::deserialize(const char *&data, QV8Engine *engine)
-{
- quint32 header = popUint32(data);
- Type type = headertype(header);
-
- switch (type) {
- case WorkerUndefined:
- return v8::Undefined();
- case WorkerNull:
- return v8::Null();
- case WorkerTrue:
- return v8::True();
- case WorkerFalse:
- return v8::False();
- case WorkerString:
- {
- quint32 size = headersize(header);
- v8::Local<v8::String> string = v8::String::New((uint16_t*)data, size - 1);
- data += ALIGN(size * sizeof(uint16_t));
- return string;
- }
- case WorkerFunction:
- Q_ASSERT(!"Unreachable");
- break;
- case WorkerArray:
- {
- quint32 size = headersize(header);
- v8::Local<v8::Array> array = v8::Array::New(size);
- for (quint32 ii = 0; ii < size; ++ii) {
- array->Set(ii, deserialize(data, engine));
- }
- return array;
- }
- case WorkerObject:
- {
- quint32 size = headersize(header);
- v8::Local<v8::Object> o = v8::Object::New();
- for (quint32 ii = 0; ii < size; ++ii) {
- v8::Handle<v8::Value> name = deserialize(data, engine);
- v8::Handle<v8::Value> value = deserialize(data, engine);
- o->Set(name, value);
- }
- return o;
- }
- case WorkerInt32:
- return v8::Integer::New((qint32)popUint32(data));
- case WorkerUint32:
- return v8::Integer::NewFromUnsigned(popUint32(data));
- case WorkerNumber:
- return v8::Number::New(popDouble(data));
- case WorkerDate:
- return v8::Date::New(popDouble(data));
- case WorkerRegexp:
- {
- quint32 flags = headersize(header);
- quint32 length = popUint32(data);
- v8::Local<v8::String> source = v8::String::New((uint16_t*)data, length - 1);
- data += ALIGN(length * sizeof(uint16_t));
- return v8::RegExp::New(source, (v8::RegExp::Flags)flags);
- }
- case WorkerListModel:
- {
- void *ptr = popPtr(data);
- QQmlListModelWorkerAgent *agent = (QQmlListModelWorkerAgent *)ptr;
- v8::Handle<v8::Value> rv = engine->newQObject(agent);
- if (rv->IsObject()) {
- QQmlListModelWorkerAgent::VariantRef ref(agent);
- QVariant var = qVariantFromValue(ref);
- rv->ToObject()->SetHiddenValue(v8::String::New("qml::ref"), engine->fromVariant(var));
- }
- agent->release();
- agent->setV8Engine(engine);
- return rv;
- }
- case WorkerSequence:
- {
- bool succeeded = false;
- quint32 length = headersize(header);
- quint32 seqLength = length - 1;
- int sequenceType = deserialize(data, engine)->Int32Value();
- v8::Local<v8::Array> array = v8::Array::New(seqLength);
- for (quint32 ii = 0; ii < seqLength; ++ii)
- array->Set(ii, deserialize(data, engine));
- QVariant seqVariant = engine->sequenceWrapper()->toVariant(array, sequenceType, &succeeded);
- return engine->sequenceWrapper()->fromVariant(seqVariant, &succeeded);
- }
- }
- Q_ASSERT(!"Unreachable");
- return v8::Undefined();
-}
-
-QByteArray QV8Worker::serialize(v8::Handle<v8::Value> value, QV8Engine *engine)
-{
- QByteArray rv;
- serialize(rv, value, engine);
- return rv;
-}
-
-v8::Handle<v8::Value> QV8Worker::deserialize(const QByteArray &data, QV8Engine *engine)
-{
- const char *stream = data.constData();
- return deserialize(stream, engine);
-}
-
-QT_END_NAMESPACE
-
diff --git a/src/qml/qml/v8/qv8worker_p.h b/src/qml/qml/v8/qv8worker_p.h
deleted file mode 100644
index 113b0bb37f..0000000000
--- a/src/qml/qml/v8/qv8worker_p.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV8WORKER_P_H
-#define QV8WORKER_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 "qv8engine_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QV8Worker {
-public:
- struct SavedData {
- };
-
- static QByteArray serialize(v8::Handle<v8::Value>, QV8Engine *);
- static v8::Handle<v8::Value> deserialize(const QByteArray &, QV8Engine *);
-
-private:
- static void serialize(QByteArray &, v8::Handle<v8::Value>, QV8Engine *);
- static v8::Handle<v8::Value> deserialize(const char *&, QV8Engine *);
-};
-
-QT_END_NAMESPACE
-
-#endif // QV8WORKER_P_H
diff --git a/src/qml/qml/v8/script.pri b/src/qml/qml/v8/script.pri
index 3439413f5e..f70588ec7b 100644
--- a/src/qml/qml/v8/script.pri
+++ b/src/qml/qml/v8/script.pri
@@ -9,13 +9,4 @@ HEADERS += \
$$PWD/qjsvalue.h \
$$PWD/qjsvalue_p.h \
$$PWD/qjsvalueiterator.h \
- $$PWD/qjsvalue_impl_p.h \
- $$PWD/qjsconverter_p.h \
- $$PWD/qjsconverter_impl_p.h \
- $$PWD/qscriptisolate_p.h \
- $$PWD/qscriptshareddata_p.h \
- $$PWD/qscripttools_p.h \
- $$PWD/qscript_impl_p.h \
- $$PWD/qscriptoriginalglobalobject_p.h \
- $$PWD/qjsvalueiterator_p.h \
- $$PWD/qjsvalueiterator_impl_p.h
+ $$PWD/qjsvalueiterator_p.h
diff --git a/src/qml/qml/v8/v8.pri b/src/qml/qml/v8/v8.pri
index 33a0ad10a1..d3edc591a7 100644
--- a/src/qml/qml/v8/v8.pri
+++ b/src/qml/qml/v8/v8.pri
@@ -1,44 +1,16 @@
include(script.pri)
HEADERS += \
- $$PWD/qv8_p.h \
$$PWD/qv8debug_p.h \
$$PWD/qv8profiler_p.h \
- $$PWD/qv8stringwrapper_p.h \
$$PWD/qv8engine_p.h \
- $$PWD/qv8sequencewrapper_p.h \
- $$PWD/qv8sequencewrapper_p_p.h \
- $$PWD/qv8contextwrapper_p.h \
- $$PWD/qv8qobjectwrapper_p.h \
- $$PWD/qv8typewrapper_p.h \
- $$PWD/qv8listwrapper_p.h \
- $$PWD/qv8variantwrapper_p.h \
- $$PWD/qv8variantresource_p.h \
- $$PWD/qv8valuetypewrapper_p.h \
- $$PWD/qv8jsonwrapper_p.h \
- $$PWD/qv8include_p.h \
- $$PWD/qv8worker_p.h \
- $$PWD/qv8bindings_p.h \
- $$PWD/qv8engine_impl_p.h \
- $$PWD/qv8domerrors_p.h \
- $$PWD/qv8sqlerrors_p.h \
- $$PWD/qqmlbuiltinfunctions_p.h \
- $$PWD/qv8objectresource_p.h
+ $$PWD/qv4domerrors_p.h \
+ $$PWD/qv4sqlerrors_p.h \
+ $$PWD/qqmlbuiltinfunctions_p.h
SOURCES += \
- $$PWD/qv8stringwrapper.cpp \
$$PWD/qv8engine.cpp \
- $$PWD/qv8sequencewrapper.cpp \
- $$PWD/qv8contextwrapper.cpp \
- $$PWD/qv8qobjectwrapper.cpp \
- $$PWD/qv8typewrapper.cpp \
- $$PWD/qv8listwrapper.cpp \
- $$PWD/qv8variantwrapper.cpp \
- $$PWD/qv8valuetypewrapper.cpp \
- $$PWD/qv8jsonwrapper.cpp \
- $$PWD/qv8include.cpp \
- $$PWD/qv8worker.cpp \
- $$PWD/qv8bindings.cpp \
- $$PWD/qv8domerrors.cpp \
- $$PWD/qv8sqlerrors.cpp \
+ $$PWD/qv4domerrors.cpp \
+ $$PWD/qv4sqlerrors.cpp \
$$PWD/qqmlbuiltinfunctions.cpp
+