Move the variant conversion methods from qv8engine to qv4::ExecutionEngine
authorLars Knoll <lars.knoll@theqtcompany.com>
Fri, 2 Jan 2015 13:37:26 +0000 (14:37 +0100)
committerLars Knoll <lars.knoll@digia.com>
Fri, 9 Jan 2015 09:27:55 +0000 (10:27 +0100)
Change-Id: Ibd529ae5cc3ba06f46152e9daa9119a4e7a2561c
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
24 files changed:
src/imports/localstorage/plugin.cpp
src/imports/xmllistmodel/qqmlxmllistmodel.cpp
src/qml/jsapi/qjsengine.cpp
src/qml/jsapi/qjsvalue.cpp
src/qml/jsruntime/qv4engine.cpp
src/qml/jsruntime/qv4engine_p.h
src/qml/jsruntime/qv4qobjectwrapper.cpp
src/qml/jsruntime/qv4serialize.cpp
src/qml/qml/qqmlbinding.cpp
src/qml/qml/qqmlboundsignal.cpp
src/qml/qml/qqmlcontextwrapper.cpp
src/qml/qml/qqmlexpression.cpp
src/qml/qml/qqmlproperty.cpp
src/qml/qml/qqmlvaluetypewrapper.cpp
src/qml/qml/qqmlvmemetaobject.cpp
src/qml/qml/v8/qqmlbuiltinfunctions.cpp
src/qml/qml/v8/qv8engine.cpp
src/qml/qml/v8/qv8engine_p.h
src/qml/types/qqmldelegatemodel.cpp
src/qml/types/qqmllistmodel.cpp
src/qml/util/qqmladaptormodel.cpp
src/qmltest/quicktestresult.cpp
src/quick/items/context2d/qquickcontext2d.cpp
tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp

index 2df859c..726b7d8 100644 (file)
@@ -226,7 +226,7 @@ static ReturnedValue qmlsqldatabase_rows_index(QQmlSqlDatabaseWrapper *r, Execut
         for (int ii = 0; ii < record.count(); ++ii) {
             QVariant v = record.value(ii);
             ScopedString s(scope, v4->newIdentifier(record.fieldName(ii)));
-            ScopedValue val(scope, v.isNull() ? Encode::null() : QV8Engine::fromVariant(v4, v));
+            ScopedValue val(scope, v.isNull() ? Encode::null() : QV4::ExecutionEngine::fromVariant(v4, v));
             row->put(s.getPointer(), val);
         }
         if (hasProperty)
@@ -291,7 +291,7 @@ static ReturnedValue qmlsqldatabase_executeSql(CallContext *ctx)
                 quint32 size = array->getLength();
                 QV4::ScopedValue v(scope);
                 for (quint32 ii = 0; ii < size; ++ii)
-                    query.bindValue(ii, QV8Engine::toVariant(scope.engine, (v = array->getIndexed(ii)), -1));
+                    query.bindValue(ii, QV4::ExecutionEngine::toVariant(scope.engine, (v = array->getIndexed(ii)), -1));
             } else if (values->asObject()) {
                 ScopedObject object(scope, values);
                 ObjectIterator it(scope, object, ObjectIterator::WithProtoChain|ObjectIterator::EnumerableOnly);
@@ -301,7 +301,7 @@ static ReturnedValue qmlsqldatabase_executeSql(CallContext *ctx)
                     key = it.nextPropertyName(val);
                     if (key->isNull())
                         break;
-                    QVariant v = QV8Engine::toVariant(scope.engine, val, -1);
+                    QVariant v = QV4::ExecutionEngine::toVariant(scope.engine, val, -1);
                     if (key->isString()) {
                         query.bindValue(key->stringValue()->toQString(), v);
                     } else {
@@ -310,7 +310,7 @@ static ReturnedValue qmlsqldatabase_executeSql(CallContext *ctx)
                     }
                 }
             } else {
-                query.bindValue(0, QV8Engine::toVariant(scope.engine, values, -1));
+                query.bindValue(0, QV4::ExecutionEngine::toVariant(scope.engine, values, -1));
             }
         }
         if (query.exec()) {
index 7cd1a2f..b3fa14c 100644 (file)
@@ -925,7 +925,7 @@ QQmlV4Handle QQuickXmlListModel::get(int index) const
     ScopedValue value(scope);
     for (int ii = 0; ii < d->roleObjects.count(); ++ii) {
         name = v4engine->newIdentifier(d->roleObjects[ii]->name());
-        value = QV8Engine::fromVariant(v4engine, d->data.value(ii).value(index));
+        value = QV4::ExecutionEngine::fromVariant(v4engine, d->data.value(ii).value(index));
         o->insertMember(name.getPointer(), value);
     }
 
index 49f1dab..b9283c9 100644 (file)
@@ -410,7 +410,7 @@ QJSValue QJSEngine::create(int type, const void *ptr)
 {
     Q_D(QJSEngine);
     QV4::Scope scope(d->m_v4Engine);
-    QV4::ScopedValue v(scope, QV8Engine::metaTypeToJS(scope.engine, type, ptr));
+    QV4::ScopedValue v(scope, QV4::ExecutionEngine::metaTypeToJS(scope.engine, type, ptr));
     return new QJSValuePrivate(d->m_v4Engine, v);
 }
 
@@ -424,7 +424,7 @@ bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr)
     if (vp->engine) {
         QV4::Scope scope(vp->engine);
         QV4::ScopedValue v(scope, vp->getValue(scope.engine));
-        return QV8Engine::metaTypeFromJS(scope.engine, v, type, ptr);
+        return QV4::ExecutionEngine::metaTypeFromJS(scope.engine, v, type, ptr);
     } else if (vp->value.isEmpty()) {
         if (vp->unboundData.userType() == QMetaType::QString) {
             QString string = vp->unboundData.toString();
index 11b7dad..0ad943b 100644 (file)
@@ -58,7 +58,7 @@ QV4::ReturnedValue QJSValuePrivate::getValue(QV4::ExecutionEngine *e)
     }
 
     if (value.isEmpty()) {
-        value = QV4::Encode(QV8Engine::fromVariant(e, unboundData));
+        value = QV4::Encode(QV4::ExecutionEngine::fromVariant(e, unboundData));
         PersistentValuePrivate **listRoot = &engine->memoryManager->m_persistentValues;
         prev = listRoot;
         next = *listRoot;
@@ -517,7 +517,7 @@ QVariant QJSValue::toVariant() const
         return d->unboundData;
 
     if (d->value.asObject())
-        return QV8Engine::toVariant(d->value.engine(), d->value, /*typeHint*/ -1, /*createJSValueForObjects*/ false);
+        return QV4::ExecutionEngine::toVariant(d->value.engine(), d->value, /*typeHint*/ -1, /*createJSValueForObjects*/ false);
 
     if (d->value.isString())
         return QVariant(d->value.stringValue()->toQString());
index 474fc88..4aff72a 100644 (file)
 #include "qv4dataview_p.h"
 #include "qv4typedarray_p.h"
 #include <private/qv8engine_p.h>
+#include <private/qjsvalue_p.h>
+#include <private/qqmlcontextwrapper_p.h>
+#include <private/qqmltypewrapper_p.h>
+#include <private/qqmlvaluetypewrapper_p.h>
+#include <private/qqmlvaluetype_p.h>
+#include <private/qqmllistwrapper_p.h>
+#include <private/qqmllist_p.h>
+#include <private/qqmllocale_p.h>
 
 #include <QtCore/QTextStream>
 #include <QDateTime>
@@ -1173,4 +1181,684 @@ bool ExecutionEngine::recheckCStackLimits()
     return (reinterpret_cast<quintptr>(&dummy) >= cStackLimit);
 }
 
+QVariant ExecutionEngine::toVariant(QV4::ExecutionEngine *e, const QV4::ValueRef value, int typeHint, bool createJSValueForObjects, V4ObjectSet *visitedObjects)
+{
+    Q_ASSERT (!value->isEmpty());
+    QV4::Scope scope(e);
+
+    if (QV4::VariantObject *v = value->as<QV4::VariantObject>())
+        return v->d()->data;
+
+    if (typeHint == QVariant::Bool)
+        return QVariant(value->toBoolean());
+
+    if (typeHint == QMetaType::QJsonValue)
+        return QVariant::fromValue(QV4::JsonObject::toJsonValue(value));
+
+    if (typeHint == qMetaTypeId<QJSValue>())
+        return QVariant::fromValue(QJSValue(new QJSValuePrivate(e, value)));
+
+    if (value->asObject()) {
+        QV4::ScopedObject object(scope, value);
+        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 (object->as<QV4::QmlContextWrapper>()) {
+            return QVariant();
+        } else if (QV4::QmlTypeWrapper *w = object->as<QV4::QmlTypeWrapper>()) {
+            return w->toVariant();
+        } else if (QV4::QQmlValueTypeWrapper *v = object->as<QV4::QQmlValueTypeWrapper>()) {
+            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 (value->asArrayObject()) {
+        QV4::ScopedArrayObject a(scope, value);
+        if (typeHint == qMetaTypeId<QList<QObject *> >()) {
+            QList<QObject *> list;
+            uint length = a->getLength();
+            QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope);
+            for (uint ii = 0; ii < length; ++ii) {
+                qobjectWrapper = a->getIndexed(ii);
+                if (!!qobjectWrapper) {
+                    list << qobjectWrapper->object();
+                } else {
+                    list << 0;
+                }
+            }
+
+            return qVariantFromValue<QList<QObject*> >(list);
+        } else if (typeHint == QMetaType::QJsonArray) {
+            return QVariant::fromValue(QV4::JsonObject::toJsonArray(a));
+        }
+
+        bool succeeded = false;
+        QVariant retn = QV4::SequencePrototype::toVariant(value, typeHint, &succeeded);
+        if (succeeded)
+            return retn;
+    }
+
+    if (value->isUndefined())
+        return QVariant();
+    if (value->isNull())
+        return QVariant(QMetaType::VoidStar, (void *)0);
+    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::QQmlLocaleData *ld = value->as<QV4::QQmlLocaleData>())
+        return ld->d()->locale;
+    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)!
+
+    QV4::ScopedObject o(scope, value);
+    Q_ASSERT(o);
+
+    if (QV4::RegExpObject *re = o->as<QV4::RegExpObject>())
+        return re->toQRegExp();
+
+    if (createJSValueForObjects)
+        return QVariant::fromValue(QJSValue(new QJSValuePrivate(o->asReturnedValue())));
+
+    return objectToVariant(e, o, visitedObjects);
+}
+
+QVariant ExecutionEngine::objectToVariant(QV4::ExecutionEngine *e, QV4::Object *o, V4ObjectSet *visitedObjects)
+{
+    Q_ASSERT(o);
+
+    V4ObjectSet recursionGuardSet;
+    if (!visitedObjects) {
+        visitedObjects = &recursionGuardSet;
+    } else if (visitedObjects->contains(o->d())) {
+        // Avoid recursion.
+        // For compatibility with QVariant{List,Map} conversion, we return an
+        // empty object (and no error is thrown).
+        if (o->asArrayObject())
+            return QVariantList();
+        return QVariantMap();
+    }
+    visitedObjects->insert(o->d());
+
+    QVariant result;
+
+    if (o->asArrayObject()) {
+        QV4::Scope scope(e);
+        QV4::ScopedArrayObject a(scope, o->asReturnedValue());
+        QV4::ScopedValue v(scope);
+        QVariantList list;
+
+        int length = a->getLength();
+        for (int ii = 0; ii < length; ++ii) {
+            v = a->getIndexed(ii);
+            list << toVariant(e, v, -1, /*createJSValueForObjects*/false, visitedObjects);
+        }
+
+        result = list;
+    } else if (!o->asFunctionObject()) {
+        QVariantMap map;
+        QV4::Scope scope(e);
+        QV4::ObjectIterator it(scope, o, QV4::ObjectIterator::EnumerableOnly);
+        QV4::ScopedValue name(scope);
+        QV4::ScopedValue val(scope);
+        while (1) {
+            name = it.nextPropertyNameAsString(val);
+            if (name->isNull())
+                break;
+
+            QString key = name->toQStringNoThrow();
+            map.insert(key, toVariant(e, val, /*type hint*/-1, /*createJSValueForObjects*/false, visitedObjects));
+        }
+
+        result = map;
+    }
+
+    visitedObjects->remove(o->d());
+    return result;
+}
+
+static QV4::ReturnedValue arrayFromVariantList(QV4::ExecutionEngine *e, const QVariantList &list)
+{
+    QV4::Scope scope(e);
+    QV4::ScopedArrayObject a(scope, e->newArrayObject());
+    int len = list.count();
+    a->arrayReserve(len);
+    QV4::ScopedValue v(scope);
+    for (int ii = 0; ii < len; ++ii)
+        a->arrayPut(ii, (v = ExecutionEngine::fromVariant(scope.engine, list.at(ii))));
+
+    a->setArrayLengthUnchecked(len);
+    return a.asReturnedValue();
+}
+
+static QV4::ReturnedValue objectFromVariantMap(QV4::ExecutionEngine *e, const QVariantMap &map)
+{
+    QV4::Scope scope(e);
+    QV4::ScopedObject o(scope, e->newObject());
+    QV4::ScopedString s(scope);
+    QV4::ScopedValue v(scope);
+    for (QVariantMap::ConstIterator iter = map.begin(); iter != map.end(); ++iter) {
+        s = e->newString(iter.key());
+        uint idx = s->asArrayIndex();
+        if (idx > 16 && (!o->arrayData() || idx > o->arrayData()->length() * 2))
+            o->initSparseArray();
+        o->put(s, (v = ExecutionEngine::fromVariant(e, iter.value())));
+    }
+    return o.asReturnedValue();
+}
+
+Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax);
+
+QV4::ReturnedValue ExecutionEngine::fromVariant(QV4::ExecutionEngine *e, const QVariant &variant)
+{
+    int type = variant.userType();
+    const void *ptr = variant.constData();
+
+    if (type < QMetaType::User) {
+        switch (QMetaType::Type(type)) {
+            case QMetaType::UnknownType:
+            case QMetaType::Void:
+                return QV4::Encode::undefined();
+            case QMetaType::VoidStar:
+                return QV4::Encode::null();
+            case QMetaType::Bool:
+                return QV4::Encode(*reinterpret_cast<const bool*>(ptr));
+            case QMetaType::Int:
+                return QV4::Encode(*reinterpret_cast<const int*>(ptr));
+            case QMetaType::UInt:
+                return QV4::Encode(*reinterpret_cast<const uint*>(ptr));
+            case QMetaType::LongLong:
+                return QV4::Encode((double)*reinterpret_cast<const qlonglong*>(ptr));
+            case QMetaType::ULongLong:
+                return QV4::Encode((double)*reinterpret_cast<const qulonglong*>(ptr));
+            case QMetaType::Double:
+                return QV4::Encode(*reinterpret_cast<const double*>(ptr));
+            case QMetaType::QString:
+                return e->currentContext()->engine->newString(*reinterpret_cast<const QString*>(ptr))->asReturnedValue();
+            case QMetaType::Float:
+                return QV4::Encode(*reinterpret_cast<const float*>(ptr));
+            case QMetaType::Short:
+                return QV4::Encode((int)*reinterpret_cast<const short*>(ptr));
+            case QMetaType::UShort:
+                return QV4::Encode((int)*reinterpret_cast<const unsigned short*>(ptr));
+            case QMetaType::Char:
+                return QV4::Encode((int)*reinterpret_cast<const char*>(ptr));
+            case QMetaType::UChar:
+                return QV4::Encode((int)*reinterpret_cast<const unsigned char*>(ptr));
+            case QMetaType::QChar:
+                return QV4::Encode((int)(*reinterpret_cast<const QChar*>(ptr)).unicode());
+            case QMetaType::QDateTime:
+                return QV4::Encode(e->newDateObject(*reinterpret_cast<const QDateTime *>(ptr)));
+            case QMetaType::QDate:
+                return QV4::Encode(e->newDateObject(QDateTime(*reinterpret_cast<const QDate *>(ptr))));
+            case QMetaType::QTime:
+            return QV4::Encode(e->newDateObject(QDateTime(QDate(1970,1,1), *reinterpret_cast<const QTime *>(ptr))));
+            case QMetaType::QRegExp:
+                return QV4::Encode(e->newRegExpObject(*reinterpret_cast<const QRegExp *>(ptr)));
+            case QMetaType::QObjectStar:
+                return QV4::QObjectWrapper::wrap(e, *reinterpret_cast<QObject* const *>(ptr));
+            case QMetaType::QStringList:
+                {
+                bool succeeded = false;
+                QV4::Scope scope(e);
+                QV4::ScopedValue retn(scope, QV4::SequencePrototype::fromVariant(e, variant, &succeeded));
+                if (succeeded)
+                    return retn.asReturnedValue();
+                return QV4::Encode(e->newArrayObject(*reinterpret_cast<const QStringList *>(ptr)));
+                }
+            case QMetaType::QVariantList:
+                return arrayFromVariantList(e, *reinterpret_cast<const QVariantList *>(ptr));
+            case QMetaType::QVariantMap:
+                return objectFromVariantMap(e, *reinterpret_cast<const QVariantMap *>(ptr));
+            case QMetaType::QJsonValue:
+                return QV4::JsonObject::fromJsonValue(e, *reinterpret_cast<const QJsonValue *>(ptr));
+            case QMetaType::QJsonObject:
+                return QV4::JsonObject::fromJsonObject(e, *reinterpret_cast<const QJsonObject *>(ptr));
+            case QMetaType::QJsonArray:
+                return QV4::JsonObject::fromJsonArray(e, *reinterpret_cast<const QJsonArray *>(ptr));
+            case QMetaType::QLocale:
+                return QQmlLocale::wrap(e, *reinterpret_cast<const QLocale*>(ptr));
+            default:
+                break;
+        }
+
+        if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(type))
+            return QV4::QQmlValueTypeWrapper::create(e, variant, vtmo, type);
+    } else {
+        QV4::Scope scope(e);
+        if (type == qMetaTypeId<QQmlListReference>()) {
+            typedef QQmlListReferencePrivate QDLRP;
+            QDLRP *p = QDLRP::get((QQmlListReference*)ptr);
+            if (p->object) {
+                return QV4::QmlListWrapper::create(scope.engine, p->property, p->propertyType);
+            } else {
+                return QV4::Encode::null();
+            }
+        } else if (type == qMetaTypeId<QJSValue>()) {
+            const QJSValue *value = reinterpret_cast<const QJSValue *>(ptr);
+            QJSValuePrivate *valuep = QJSValuePrivate::get(*value);
+            return valuep->getValue(e);
+        } 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;
+            QV4::ScopedArrayObject a(scope, e->newArrayObject());
+            a->arrayReserve(list.count());
+            QV4::ScopedValue v(scope);
+            for (int ii = 0; ii < list.count(); ++ii)
+                a->arrayPut(ii, (v = QV4::QObjectWrapper::wrap(e, list.at(ii))));
+            a->setArrayLengthUnchecked(list.count());
+            return a.asReturnedValue();
+        } else if (QMetaType::typeFlags(type) & QMetaType::PointerToQObject) {
+            return QV4::QObjectWrapper::wrap(e, *reinterpret_cast<QObject* const *>(ptr));
+        }
+
+        bool objOk;
+        QObject *obj = QQmlMetaType::toQObject(variant, &objOk);
+        if (objOk)
+            return QV4::QObjectWrapper::wrap(e, obj);
+
+        bool succeeded = false;
+        QV4::ScopedValue retn(scope, QV4::SequencePrototype::fromVariant(e, variant, &succeeded));
+        if (succeeded)
+            return retn.asReturnedValue();
+
+        if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(type))
+            return QV4::QQmlValueTypeWrapper::create(e, variant, vtmo, type);
+    }
+
+    // XXX TODO: To be compatible, we still need to handle:
+    //    + QObjectList
+    //    + QList<int>
+
+    return QV4::Encode(e->newVariantObject(variant));
+}
+
+QVariantMap ExecutionEngine::variantMapFromJS(Object *o)
+{
+    return objectToVariant(o->engine(), o).toMap();
+}
+
+
+// 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.
+QV4::ReturnedValue ExecutionEngine::variantListToJS(QV4::ExecutionEngine *v4, const QVariantList &lst)
+{
+    QV4::Scope scope(v4);
+    QV4::ScopedArrayObject a(scope, v4->newArrayObject());
+    a->arrayReserve(lst.size());
+    QV4::ScopedValue v(scope);
+    for (int i = 0; i < lst.size(); i++)
+        a->arrayPut(i, (v = variantToJS(v4, lst.at(i))));
+    a->setArrayLengthUnchecked(lst.size());
+    return a.asReturnedValue();
+}
+
+// Converts a QVariantMap to JS.
+// 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.
+QV4::ReturnedValue ExecutionEngine::variantMapToJS(QV4::ExecutionEngine *v4, const QVariantMap &vmap)
+{
+    QV4::Scope scope(v4);
+    QV4::ScopedObject o(scope, v4->newObject());
+    QVariantMap::const_iterator it;
+    QV4::ScopedString s(scope);
+    QV4::ScopedValue v(scope);
+    for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) {
+        s = v4->newIdentifier(it.key());
+        v = variantToJS(v4, it.value());
+        uint idx = s->asArrayIndex();
+        if (idx < UINT_MAX)
+            o->arraySet(idx, v);
+        else
+            o->insertMember(s, v);
+    }
+    return o.asReturnedValue();
+}
+
+// Converts the meta-type defined by the given type and data to JS.
+// Returns the value if conversion succeeded, an empty handle otherwise.
+QV4::ReturnedValue ExecutionEngine::metaTypeToJS(QV4::ExecutionEngine *v4, int type, const void *data)
+{
+    Q_ASSERT(data != 0);
+
+    // check if it's one of the types we know
+    switch (QMetaType::Type(type)) {
+    case QMetaType::UnknownType:
+    case QMetaType::Void:
+        return QV4::Encode::undefined();
+    case QMetaType::VoidStar:
+        return QV4::Encode::null();
+    case QMetaType::Bool:
+        return QV4::Encode(*reinterpret_cast<const bool*>(data));
+    case QMetaType::Int:
+        return QV4::Encode(*reinterpret_cast<const int*>(data));
+    case QMetaType::UInt:
+        return QV4::Encode(*reinterpret_cast<const uint*>(data));
+    case QMetaType::LongLong:
+        return QV4::Encode(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 QV4::Encode(double((qlonglong)*reinterpret_cast<const qulonglong*>(data)));
+#elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
+        return QV4::Encode(double((qlonglong)*reinterpret_cast<const qulonglong*>(data)));
+#else
+        return QV4::Encode(double(*reinterpret_cast<const qulonglong*>(data)));
+#endif
+    case QMetaType::Double:
+        return QV4::Encode(*reinterpret_cast<const double*>(data));
+    case QMetaType::QString:
+        return v4->currentContext()->engine->newString(*reinterpret_cast<const QString*>(data))->asReturnedValue();
+    case QMetaType::Float:
+        return QV4::Encode(*reinterpret_cast<const float*>(data));
+    case QMetaType::Short:
+        return QV4::Encode((int)*reinterpret_cast<const short*>(data));
+    case QMetaType::UShort:
+        return QV4::Encode((int)*reinterpret_cast<const unsigned short*>(data));
+    case QMetaType::Char:
+        return QV4::Encode((int)*reinterpret_cast<const char*>(data));
+    case QMetaType::UChar:
+        return QV4::Encode((int)*reinterpret_cast<const unsigned char*>(data));
+    case QMetaType::QChar:
+        return QV4::Encode((int)(*reinterpret_cast<const QChar*>(data)).unicode());
+    case QMetaType::QStringList:
+        return QV4::Encode(v4->newArrayObject(*reinterpret_cast<const QStringList *>(data)));
+    case QMetaType::QVariantList:
+        return variantListToJS(v4, *reinterpret_cast<const QVariantList *>(data));
+    case QMetaType::QVariantMap:
+        return variantMapToJS(v4, *reinterpret_cast<const QVariantMap *>(data));
+    case QMetaType::QDateTime:
+        return QV4::Encode(v4->newDateObject(*reinterpret_cast<const QDateTime *>(data)));
+    case QMetaType::QDate:
+        return QV4::Encode(v4->newDateObject(QDateTime(*reinterpret_cast<const QDate *>(data))));
+    case QMetaType::QRegExp:
+        return QV4::Encode(v4->newRegExpObject(*reinterpret_cast<const QRegExp *>(data)));
+    case QMetaType::QObjectStar:
+        return QV4::QObjectWrapper::wrap(v4, *reinterpret_cast<QObject* const *>(data));
+    case QMetaType::QVariant:
+        return variantToJS(v4, *reinterpret_cast<const QVariant*>(data));
+    case QMetaType::QJsonValue:
+        return QV4::JsonObject::fromJsonValue(v4, *reinterpret_cast<const QJsonValue *>(data));
+    case QMetaType::QJsonObject:
+        return QV4::JsonObject::fromJsonObject(v4, *reinterpret_cast<const QJsonObject *>(data));
+    case QMetaType::QJsonArray:
+        return QV4::JsonObject::fromJsonArray(v4, *reinterpret_cast<const QJsonArray *>(data));
+    default:
+        if (type == qMetaTypeId<QJSValue>()) {
+            return QJSValuePrivate::get(*reinterpret_cast<const QJSValue*>(data))->getValue(v4);
+        } else {
+            QByteArray typeName = QMetaType::typeName(type);
+            if (typeName.endsWith('*') && !*reinterpret_cast<void* const *>(data)) {
+                return QV4::Encode::null();
+            }
+            QMetaType mt(type);
+            if (mt.flags() & QMetaType::IsGadget) {
+                Q_ASSERT(mt.metaObject());
+                return QV4::QQmlValueTypeWrapper::create(v4, QVariant(type, data), mt.metaObject(), type);
+            }
+            // Fall back to wrapping in a QVariant.
+            return QV4::Encode(v4->newVariantObject(QVariant(type, data)));
+        }
+    }
+    Q_UNREACHABLE();
+    return 0;
+}
+
+// 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 ExecutionEngine::metaTypeFromJS(QV4::ExecutionEngine *engine, const QV4::ValueRef value, int type, void *data)
+{
+    QV4::Scope scope(engine);
+
+    // check if it's one of the types we know
+    switch (QMetaType::Type(type)) {
+    case QMetaType::Bool:
+        *reinterpret_cast<bool*>(data) = value->toBoolean();
+        return true;
+    case QMetaType::Int:
+        *reinterpret_cast<int*>(data) = value->toInt32();
+        return true;
+    case QMetaType::UInt:
+        *reinterpret_cast<uint*>(data) = value->toUInt32();
+        return true;
+    case QMetaType::LongLong:
+        *reinterpret_cast<qlonglong*>(data) = qlonglong(value->toInteger());
+        return true;
+    case QMetaType::ULongLong:
+        *reinterpret_cast<qulonglong*>(data) = qulonglong(value->toInteger());
+        return true;
+    case QMetaType::Double:
+        *reinterpret_cast<double*>(data) = value->toNumber();
+        return true;
+    case QMetaType::QString:
+        if (value->isUndefined() || value->isNull())
+            *reinterpret_cast<QString*>(data) = QString();
+        else
+            *reinterpret_cast<QString*>(data) = value->toQString();
+        return true;
+    case QMetaType::Float:
+        *reinterpret_cast<float*>(data) = value->toNumber();
+        return true;
+    case QMetaType::Short:
+        *reinterpret_cast<short*>(data) = short(value->toInt32());
+        return true;
+    case QMetaType::UShort:
+        *reinterpret_cast<unsigned short*>(data) = value->toUInt16();
+        return true;
+    case QMetaType::Char:
+        *reinterpret_cast<char*>(data) = char(value->toInt32());
+        return true;
+    case QMetaType::UChar:
+        *reinterpret_cast<unsigned char*>(data) = (unsigned char)(value->toInt32());
+        return true;
+    case QMetaType::QChar:
+        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->toUInt16()));
+        }
+        return true;
+    case QMetaType::QDateTime:
+        if (QV4::DateObject *d = value->asDateObject()) {
+            *reinterpret_cast<QDateTime *>(data) = d->toQDateTime();
+            return true;
+        } break;
+    case QMetaType::QDate:
+        if (QV4::DateObject *d = value->asDateObject()) {
+            *reinterpret_cast<QDate *>(data) = d->toQDateTime().date();
+            return true;
+        } break;
+    case QMetaType::QRegExp:
+        if (QV4::RegExpObject *r = value->as<QV4::RegExpObject>()) {
+            *reinterpret_cast<QRegExp *>(data) = r->toQRegExp();
+            return true;
+        } break;
+    case QMetaType::QObjectStar: {
+        QV4::QObjectWrapper *qobjectWrapper = value->as<QV4::QObjectWrapper>();
+        if (qobjectWrapper || value->isNull()) {
+            *reinterpret_cast<QObject* *>(data) = qtObjectFromJS(scope.engine, value);
+            return true;
+        } break;
+    }
+    case QMetaType::QStringList: {
+        QV4::ScopedArrayObject a(scope, value);
+        if (a) {
+            *reinterpret_cast<QStringList *>(data) = a->toQStringList();
+            return true;
+        }
+        break;
+    }
+    case QMetaType::QVariantList: {
+        QV4::ScopedArrayObject a(scope, value);
+        if (a) {
+            *reinterpret_cast<QVariantList *>(data) = toVariant(scope.engine, a, /*typeHint*/-1, /*createJSValueForObjects*/false).toList();
+            return true;
+        }
+        break;
+    }
+    case QMetaType::QVariantMap: {
+        QV4::ScopedObject o(scope, value);
+        if (o) {
+            *reinterpret_cast<QVariantMap *>(data) = variantMapFromJS(o);
+            return true;
+        }
+        break;
+    }
+    case QMetaType::QVariant:
+        *reinterpret_cast<QVariant*>(data) = toVariant(scope.engine, value, /*typeHint*/-1, /*createJSValueForObjects*/false);
+        return true;
+    case QMetaType::QJsonValue:
+        *reinterpret_cast<QJsonValue *>(data) = QV4::JsonObject::toJsonValue(value);
+        return true;
+    case QMetaType::QJsonObject: {
+        QV4::ScopedObject o(scope, value);
+        *reinterpret_cast<QJsonObject *>(data) = QV4::JsonObject::toJsonObject(o);
+        return true;
+    }
+    case QMetaType::QJsonArray: {
+        QV4::ScopedArrayObject a(scope, value);
+        if (a) {
+            *reinterpret_cast<QJsonArray *>(data) = QV4::JsonObject::toJsonArray(a);
+            return true;
+        }
+        break;
+    }
+    default:
+    ;
+    }
+
+    {
+        QV4::Scoped<QV4::QQmlValueTypeWrapper> vtw(scope, value);
+        if (vtw && vtw->d()->metaType == type) {
+            vtw->toGadget(data);
+            return true;
+        }
+    }
+
+#if 0
+    if (isQtVariant(value)) {
+        const QVariant &var = variantValue(value);
+        // ### Enable once constructInPlace() is in qt master.
+        if (var.userType() == type) {
+            QMetaType::constructInPlace(type, data, var.constData());
+            return true;
+        }
+        if (var.canConvert(type)) {
+            QVariant vv = var;
+            vv.convert(type);
+            Q_ASSERT(vv.userType() == type);
+            QMetaType::constructInPlace(type, data, vv.constData());
+            return true;
+        }
+
+    }
+#endif
+
+    // Try to use magic; for compatibility with qscriptvalue_cast.
+
+    QByteArray name = QMetaType::typeName(type);
+    if (convertToNativeQObject(engine, value, name, reinterpret_cast<void* *>(data)))
+        return true;
+    if (value->as<QV4::VariantObject>() && name.endsWith('*')) {
+        int valueType = QMetaType::type(name.left(name.size()-1));
+        QVariant &var = value->as<QV4::VariantObject>()->d()->data;
+        if (valueType == var.userType()) {
+            // We have T t, T* is requested, so return &t.
+            *reinterpret_cast<void* *>(data) = var.data();
+            return true;
+        } else if (value->isObject()) {
+            // Look in the prototype chain.
+            QV4::ScopedObject proto(scope, value->objectValue()->prototype());
+            while (proto) {
+                bool canCast = false;
+                if (QV4::VariantObject *vo = proto->as<QV4::VariantObject>()) {
+                    const QVariant &v = vo->d()->data;
+                    canCast = (type == v.userType()) || (valueType && (valueType == v.userType()));
+                }
+                else if (proto->as<QV4::QObjectWrapper>()) {
+                    QByteArray className = name.left(name.size()-1);
+                    QV4::ScopedObject p(scope, proto.getPointer());
+                    if (QObject *qobject = qtObjectFromJS(scope.engine, p))
+                        canCast = qobject->qt_metacast(className) != 0;
+                }
+                if (canCast) {
+                    QByteArray varTypeName = QMetaType::typeName(var.userType());
+                    if (varTypeName.endsWith('*'))
+                        *reinterpret_cast<void* *>(data) = *reinterpret_cast<void* *>(var.data());
+                    else
+                        *reinterpret_cast<void* *>(data) = var.data();
+                    return true;
+                }
+                proto = proto->prototype();
+            }
+        }
+    } 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(engine, value));
+        return true;
+    }
+
+    return false;
+}
+
+// Converts a QVariant to JS.
+QV4::ReturnedValue ExecutionEngine::variantToJS(QV4::ExecutionEngine *v4, const QVariant &value)
+{
+    return metaTypeToJS(v4, value.userType(), value.constData());
+}
+
+bool ExecutionEngine::convertToNativeQObject(QV4::ExecutionEngine *e, const QV4::ValueRef value, const QByteArray &targetType, void **result)
+{
+    if (!targetType.endsWith('*'))
+        return false;
+    if (QObject *qobject = qtObjectFromJS(e, value)) {
+        int start = targetType.startsWith("const ") ? 6 : 0;
+        QByteArray className = targetType.mid(start, targetType.size()-start-1);
+        if (void *instance = qobject->qt_metacast(className)) {
+            *result = instance;
+            return true;
+        }
+    }
+    return false;
+}
+
+QObject *ExecutionEngine::qtObjectFromJS(QV4::ExecutionEngine *engine, const QV4::ValueRef value)
+{
+    if (!value->isObject())
+        return 0;
+
+    QV4::Scope scope(engine);
+    QV4::Scoped<QV4::VariantObject> v(scope, value);
+
+    if (v) {
+        QVariant variant = v->d()->data;
+        int type = variant.userType();
+        if (type == QMetaType::QObjectStar)
+            return *reinterpret_cast<QObject* const *>(variant.constData());
+    }
+    QV4::Scoped<QV4::QObjectWrapper> wrapper(scope, value);
+    if (!wrapper)
+        return 0;
+    return wrapper->object();
+}
+
+
 QT_END_NAMESPACE
index 9d8fb54..82753e3 100644 (file)
@@ -352,6 +352,26 @@ public:
     // Use only inside catch(...) -- will re-throw if no JS exception
     QQmlError catchExceptionAsQmlError();
 
+    // variant conversions
+    typedef QSet<QV4::Heap::Object *> V4ObjectSet;
+    static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::ValueRef value, int typeHint, bool createJSValueForObjects = true, V4ObjectSet *visitedObjects = 0);
+    static QV4::ReturnedValue fromVariant(QV4::ExecutionEngine *e, const QVariant &);
+
+    static QVariantMap variantMapFromJS(QV4::Object *o);
+
+    static bool metaTypeFromJS(QV4::ExecutionEngine *e, const QV4::ValueRef value, int type, void *data);
+    static QV4::ReturnedValue metaTypeToJS(QV4::ExecutionEngine *v4, int type, const void *data);
+
+private:
+    static QObject *qtObjectFromJS(QV4::ExecutionEngine *engine, const QV4::ValueRef value);
+    static QVariant objectToVariant(QV4::ExecutionEngine *e, QV4::Object *o, V4ObjectSet *visitedObjects = 0);
+    static bool convertToNativeQObject(QV4::ExecutionEngine *e, const QV4::ValueRef value,
+                                const QByteArray &targetType,
+                                void **result);
+    static QV4::ReturnedValue variantListToJS(QV4::ExecutionEngine *v4, const QVariantList &lst);
+    static QV4::ReturnedValue variantMapToJS(QV4::ExecutionEngine *v4, const QVariantMap &vmap);
+    static QV4::ReturnedValue variantToJS(QV4::ExecutionEngine *v4, const QVariant &value);
+
 private:
     QmlExtensions *m_qmlExtensions;
 };
index 49f9c5d..1e0c8d1 100644 (file)
@@ -204,7 +204,7 @@ static QV4::ReturnedValue LoadProperty(QV4::ExecutionEngine *v4, QObject *object
                 return QV4::QQmlValueTypeWrapper::create(v4, object, property.coreIndex, valueTypeMetaObject, v.userType()); // VariantReference value-type.
         }
 
-        return QV8Engine::fromVariant(scope.engine, v);
+        return QV4::ExecutionEngine::fromVariant(scope.engine, v);
     } else if (QQmlValueTypeFactory::isValueType(property.propType)) {
         Q_ASSERT(notifier == 0);
 
@@ -228,7 +228,7 @@ static QV4::ReturnedValue LoadProperty(QV4::ExecutionEngine *v4, QObject *object
     } else {
         QVariant v(property.propType, (void *)0);
         ReadFunction(object, property, v.data(), notifier);
-        return QV8Engine::fromVariant(scope.engine, v);
+        return QV4::ExecutionEngine::fromVariant(scope.engine, v);
     }
 }
 
@@ -549,9 +549,9 @@ void QObjectWrapper::setProperty(QObject *object, ExecutionContext *ctx, QQmlPro
     } else {
         QVariant v;
         if (property->isQList())
-            v = QV8Engine::toVariant(ctx->d()->engine, value, qMetaTypeId<QList<QObject *> >());
+            v = QV4::ExecutionEngine::toVariant(ctx->d()->engine, value, qMetaTypeId<QList<QObject *> >());
         else
-            v = QV8Engine::toVariant(ctx->d()->engine, value, property->propType);
+            v = QV4::ExecutionEngine::toVariant(ctx->d()->engine, value, property->propType);
 
         QQmlContextData *callingQmlContext = QV4::QmlContextWrapper::callingContext(ctx->d()->engine);
         if (!QQmlPropertyPrivate::write(object, *property, v, callingQmlContext)) {
@@ -806,9 +806,9 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
             for (int ii = 0; ii < argCount; ++ii) {
                 int type = argsTypes[ii + 1];
                 if (type == qMetaTypeId<QVariant>()) {
-                    callData->args[ii] = QV8Engine::fromVariant(v4, *((QVariant *)metaArgs[ii + 1]));
+                    callData->args[ii] = QV4::ExecutionEngine::fromVariant(v4, *((QVariant *)metaArgs[ii + 1]));
                 } else {
-                    callData->args[ii] = QV8Engine::fromVariant(v4, QVariant(type, metaArgs[ii + 1]));
+                    callData->args[ii] = QV4::ExecutionEngine::fromVariant(v4, QVariant(type, metaArgs[ii + 1]));
                 }
             }
 
@@ -1269,7 +1269,7 @@ static int MatchScore(const QV4::ValueRef actual, int conversionType)
         if (obj->as<QV4::VariantObject>()) {
             if (conversionType == qMetaTypeId<QVariant>())
                 return 0;
-            if (QV8Engine::toVariant(obj->engine(), actual, -1).userType() == conversionType)
+            if (QV4::ExecutionEngine::toVariant(obj->engine(), actual, -1).userType() == conversionType)
                 return 0;
             else
                 return 10;
@@ -1285,7 +1285,7 @@ static int MatchScore(const QV4::ValueRef actual, int conversionType)
         }
 
         if (obj->as<QV4::QQmlValueTypeWrapper>()) {
-            if (QV8Engine::toVariant(obj->engine(), actual, -1).userType() == conversionType)
+            if (QV4::ExecutionEngine::toVariant(obj->engine(), actual, -1).userType() == conversionType)
                 return 0;
             return 10;
         } else if (conversionType == QMetaType::QJsonObject) {
@@ -1601,7 +1601,7 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
             queryEngine = qmlTypeWrapper->isSingleton();
         type = callType;
     } else if (callType == qMetaTypeId<QVariant>()) {
-        qvariantPtr = new (&allocData) QVariant(QV8Engine::toVariant(scope.engine, value, -1));
+        qvariantPtr = new (&allocData) QVariant(QV4::ExecutionEngine::toVariant(scope.engine, value, -1));
         type = callType;
     } else if (callType == qMetaTypeId<QList<QObject*> >()) {
         qlistPtr = new (&allocData) QList<QObject *>();
@@ -1649,7 +1649,7 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
         type = -1;
 
         QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : 0;
-        QVariant v = QV8Engine::toVariant(scope.engine, value, callType);
+        QVariant v = QV4::ExecutionEngine::toVariant(scope.engine, value, callType);
 
         if (v.userType() == callType) {
             *qvariantPtr = v;
@@ -1716,7 +1716,7 @@ QV4::ReturnedValue CallArgument::toValue(QV4::ExecutionEngine *engine)
         return QV4::JsonObject::fromJsonValue(scope.engine, *jsonValuePtr);
     } else if (type == -1 || type == qMetaTypeId<QVariant>()) {
         QVariant value = *qvariantPtr;
-        QV4::ScopedValue rv(scope, QV8Engine::fromVariant(scope.engine, value));
+        QV4::ScopedValue rv(scope, QV4::ExecutionEngine::fromVariant(scope.engine, value));
         QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, rv);
         if (!!qobjectWrapper) {
             if (QObject *object = qobjectWrapper->object())
index 60b6235..655b456 100644 (file)
@@ -359,7 +359,7 @@ ReturnedValue Serialize::deserialize(const char *&data, ExecutionEngine *engine)
         // ### Find a better solution then the ugly property
         QQmlListModelWorkerAgent::VariantRef ref(agent);
         QVariant var = qVariantFromValue(ref);
-        QV4::ScopedValue v(scope, QV8Engine::fromVariant(scope.engine, var));
+        QV4::ScopedValue v(scope, QV4::ExecutionEngine::fromVariant(scope.engine, var));
         QV4::ScopedString s(scope, engine->newString(QStringLiteral("__qml:hidden:ref")));
         rv->asObject()->defineReadonlyProperty(s, v);
 
index a4e614f..6e45ca8 100644 (file)
@@ -260,7 +260,7 @@ QVariant QQmlBinding::evaluate()
 
     ep->dereferenceScarceResources();
 
-    return QV8Engine::toVariant(scope.engine, result, qMetaTypeId<QList<QObject*> >());
+    return QV4::ExecutionEngine::toVariant(scope.engine, result, qMetaTypeId<QList<QObject*> >());
 }
 
 QString QQmlBinding::expressionIdentifier(QQmlJavaScriptExpression *e)
index aa1c1f6..d605e1a 100644 (file)
@@ -261,7 +261,7 @@ void QQmlBoundSignalExpression::evaluate(void **a)
             //    for several cases (such as QVariant type and QObject-derived types)
             //args[ii] = engine->metaTypeToJS(type, a[ii + 1]);
             if (type == QMetaType::QVariant) {
-                callData->args[ii] = QV8Engine::fromVariant(scope.engine, *((QVariant *)a[ii + 1]));
+                callData->args[ii] = QV4::ExecutionEngine::fromVariant(scope.engine, *((QVariant *)a[ii + 1]));
             } else if (type == QMetaType::Int) {
                 //### optimization. Can go away if we switch to metaTypeToJS, or be expanded otherwise
                 callData->args[ii] = QV4::Primitive::fromInt32(*reinterpret_cast<const int*>(a[ii + 1]));
@@ -273,7 +273,7 @@ void QQmlBoundSignalExpression::evaluate(void **a)
                 else
                     callData->args[ii] = QV4::QObjectWrapper::wrap(ep->v4engine(), *reinterpret_cast<QObject* const *>(a[ii + 1]));
             } else {
-                callData->args[ii] = QV8Engine::fromVariant(scope.engine, QVariant(type, a[ii + 1]));
+                callData->args[ii] = QV4::ExecutionEngine::fromVariant(scope.engine, QVariant(type, a[ii + 1]));
             }
         }
 
index f735481..5a6bf70 100644 (file)
@@ -227,7 +227,7 @@ ReturnedValue QmlContextWrapper::get(Managed *m, String *name, bool *hasProperty
                                                                QQmlContextPrivate::context_at);
                         return QmlListWrapper::create(v4, prop, qMetaTypeId<QQmlListProperty<QObject> >());
                     } else {
-                        return QV8Engine::fromVariant(scope.engine, cp->propertyValues.at(propertyIdx));
+                        return QV4::ExecutionEngine::fromVariant(scope.engine, cp->propertyValues.at(propertyIdx));
                     }
                 }
             }
index a99ecde..f44357d 100644 (file)
@@ -276,7 +276,7 @@ QVariant QQmlExpressionPrivate::value(bool *isUndefined)
         QV4::Scope scope(QV8Engine::getV4(ep->v8engine()));
         QV4::ScopedValue result(scope, v4value(isUndefined));
         if (!hasError())
-            rv = QV8Engine::toVariant(scope.engine, result, -1);
+            rv = QV4::ExecutionEngine::toVariant(scope.engine, result, -1);
     }
 
     ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
index 3211425..2e25186 100644 (file)
@@ -1513,13 +1513,13 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
 
     if (isUndefined) {
     } else if (core.isQList()) {
-        value = QV8Engine::toVariant(QV8Engine::getV4(v8engine), result, qMetaTypeId<QList<QObject *> >());
+        value = QV4::ExecutionEngine::toVariant(QV8Engine::getV4(v8engine), result, qMetaTypeId<QList<QObject *> >());
     } else if (result->isNull() && core.isQObject()) {
         value = QVariant::fromValue((QObject *)0);
     } else if (core.propType == qMetaTypeId<QList<QUrl> >()) {
-        value = resolvedUrlSequence(QV8Engine::toVariant(QV8Engine::getV4(v8engine), result, qMetaTypeId<QList<QUrl> >()), context);
+        value = resolvedUrlSequence(QV4::ExecutionEngine::toVariant(QV8Engine::getV4(v8engine), result, qMetaTypeId<QList<QUrl> >()), context);
     } else if (!isVarProperty && type != qMetaTypeId<QJSValue>()) {
-        value = QV8Engine::toVariant(QV8Engine::getV4(v8engine), result, type);
+        value = QV4::ExecutionEngine::toVariant(QV8Engine::getV4(v8engine), result, type);
     }
 
     if (expression->hasError()) {
index 85a391f..3918dc1 100644 (file)
@@ -327,8 +327,7 @@ ReturnedValue QQmlValueTypeWrapper::get(Managed *m, String *name, bool *hasPrope
     QVariant v(result->propType, (void *)0);
     void *args[] = { v.data(), 0 };
     metaObject->d.static_metacall(reinterpret_cast<QObject*>(gadget), QMetaObject::ReadProperty, index, args);
-    return QV8Engine::fromVariant(v4, v);
-#undef VALUE_TYPE_LOAD
+    return QV4::ExecutionEngine::fromVariant(v4, v);
 }
 
 void QQmlValueTypeWrapper::put(Managed *m, String *name, const ValueRef value)
@@ -400,7 +399,7 @@ void QQmlValueTypeWrapper::put(Managed *m, String *name, const ValueRef value)
     if (newBinding)
         return;
 
-    QVariant v = QV8Engine::toVariant(v4, value, property.userType());
+    QVariant v = QV4::ExecutionEngine::toVariant(v4, value, property.userType());
 
     if (property.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double)
         v = v.toInt();
index 1f21b21..59fae5f 100644 (file)
@@ -945,7 +945,7 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
                 callData->thisObject = ep->v8engine()->global();
 
                 for (int ii = 0; ii < data->parameterCount; ++ii)
-                    callData->args[ii] = QV8Engine::fromVariant(scope.engine, *(QVariant *)a[ii + 1]);
+                    callData->args[ii] = QV4::ExecutionEngine::fromVariant(scope.engine, *(QVariant *)a[ii + 1]);
 
                 QV4::ScopedValue result(scope);
                 result = function->call(callData);
@@ -955,7 +955,7 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
                         ep->warning(error);
                     if (a[0]) *(QVariant *)a[0] = QVariant();
                 } else {
-                    if (a[0]) *(QVariant *)a[0] = QV8Engine::toVariant(scope.engine, result, 0);
+                    if (a[0]) *(QVariant *)a[0] = QV4::ExecutionEngine::toVariant(scope.engine, result, 0);
                 }
 
                 ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
@@ -1004,7 +1004,7 @@ QVariant QQmlVMEMetaObject::readPropertyAsVariant(int id)
             QV4::Scope scope(v4);
             QV4::ScopedObject o(scope, varProperties.value());
             QV4::ScopedValue val(scope, o->getIndexed(id - firstVarPropertyIndex));
-            return QV8Engine::toVariant(scope.engine, val, -1);
+            return QV4::ExecutionEngine::toVariant(scope.engine, val, -1);
         }
         return QVariant();
     } else {
@@ -1077,7 +1077,7 @@ void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value)
 
         // And, if the new value is a scarce resource, we need to ensure that it does not get
         // automatically released by the engine until no other references to it exist.
-        QV4::ScopedValue newv(scope, QV8Engine::fromVariant(scope.engine, value));
+        QV4::ScopedValue newv(scope, QV4::ExecutionEngine::fromVariant(scope.engine, value));
         QV4::Scoped<QV4::VariantObject> v(scope, newv);
         if (!!v)
             v->addVmePropertyReference();
index 27f31b3..8c57615 100644 (file)
@@ -183,7 +183,7 @@ ReturnedValue QtObject::method_rgba(QV4::CallContext *ctx)
     if (a < 0.0) a=0.0;
     if (a > 1.0) a=1.0;
 
-    return QV8Engine::fromVariant(ctx->engine(), QQml_colorProvider()->fromRgbF(r, g, b, a));
+    return QV4::ExecutionEngine::fromVariant(ctx->engine(), QQml_colorProvider()->fromRgbF(r, g, b, a));
 }
 
 /*!
@@ -212,7 +212,7 @@ ReturnedValue QtObject::method_hsla(QV4::CallContext *ctx)
     if (a < 0.0) a=0.0;
     if (a > 1.0) a=1.0;
 
-    return QV8Engine::fromVariant(ctx->engine(), QQml_colorProvider()->fromHslF(h, s, l, a));
+    return QV4::ExecutionEngine::fromVariant(ctx->engine(), QQml_colorProvider()->fromHslF(h, s, l, a));
 }
 
 /*!
@@ -230,7 +230,7 @@ ReturnedValue QtObject::method_colorEqual(QV4::CallContext *ctx)
 
     bool ok = false;
 
-    QVariant lhs = QV8Engine::toVariant(ctx->d()->engine, ctx->d()->callData->args[0], -1);
+    QVariant lhs = QV4::ExecutionEngine::toVariant(ctx->d()->engine, ctx->d()->callData->args[0], -1);
     if (lhs.userType() == QVariant::String) {
         lhs = QQmlStringConverters::colorFromString(lhs.toString(), &ok);
         if (!ok) {
@@ -240,7 +240,7 @@ ReturnedValue QtObject::method_colorEqual(QV4::CallContext *ctx)
         V4THROW_ERROR("Qt.colorEqual(): Invalid arguments");
     }
 
-    QVariant rhs = QV8Engine::toVariant(ctx->engine(), ctx->d()->callData->args[1], -1);
+    QVariant rhs = QV4::ExecutionEngine::toVariant(ctx->engine(), ctx->d()->callData->args[1], -1);
     if (rhs.userType() == QVariant::String) {
         rhs = QQmlStringConverters::colorFromString(rhs.toString(), &ok);
         if (!ok) {
@@ -271,7 +271,7 @@ ReturnedValue QtObject::method_rect(QV4::CallContext *ctx)
     double w = ctx->d()->callData->args[2].toNumber();
     double h = ctx->d()->callData->args[3].toNumber();
 
-    return QV8Engine::fromVariant(ctx->engine(), QVariant::fromValue(QRectF(x, y, w, h)));
+    return QV4::ExecutionEngine::fromVariant(ctx->engine(), QVariant::fromValue(QRectF(x, y, w, h)));
 }
 
 /*!
@@ -286,7 +286,7 @@ ReturnedValue QtObject::method_point(QV4::CallContext *ctx)
     double x = ctx->d()->callData->args[0].toNumber();
     double y = ctx->d()->callData->args[1].toNumber();
 
-    return QV8Engine::fromVariant(ctx->engine(), QVariant::fromValue(QPointF(x, y)));
+    return QV4::ExecutionEngine::fromVariant(ctx->engine(), QVariant::fromValue(QPointF(x, y)));
 }
 
 /*!
@@ -301,7 +301,7 @@ ReturnedValue QtObject::method_size(QV4::CallContext *ctx)
     double w = ctx->d()->callData->args[0].toNumber();
     double h = ctx->d()->callData->args[1].toNumber();
 
-    return QV8Engine::fromVariant(ctx->engine(), QVariant::fromValue(QSizeF(w, h)));
+    return QV4::ExecutionEngine::fromVariant(ctx->engine(), QVariant::fromValue(QSizeF(w, h)));
 }
 
 /*!
@@ -322,7 +322,7 @@ ReturnedValue QtObject::method_font(QV4::CallContext *ctx)
     QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QFont, QQmlV4Handle(ctx->d()->callData->args[0]), v4, &ok);
     if (!ok)
         V4THROW_ERROR("Qt.font(): Invalid argument: no valid font subproperties specified");
-    return QV8Engine::fromVariant(ctx->engine(), v);
+    return QV4::ExecutionEngine::fromVariant(ctx->engine(), v);
 }
 
 
@@ -341,7 +341,7 @@ ReturnedValue QtObject::method_vector2d(QV4::CallContext *ctx)
     xy[1] = ctx->d()->callData->args[1].toNumber();
 
     const void *params[] = { xy };
-    return QV8Engine::fromVariant(ctx->engine(), QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params));
+    return QV4::ExecutionEngine::fromVariant(ctx->engine(), QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params));
 }
 
 /*!
@@ -359,7 +359,7 @@ ReturnedValue QtObject::method_vector3d(QV4::CallContext *ctx)
     xyz[2] = ctx->d()->callData->args[2].toNumber();
 
     const void *params[] = { xyz };
-    return QV8Engine::fromVariant(ctx->engine(), QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params));
+    return QV4::ExecutionEngine::fromVariant(ctx->engine(), QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params));
 }
 
 /*!
@@ -378,7 +378,7 @@ ReturnedValue QtObject::method_vector4d(QV4::CallContext *ctx)
     xyzw[3] = ctx->d()->callData->args[3].toNumber();
 
     const void *params[] = { xyzw };
-    return QV8Engine::fromVariant(ctx->engine(), QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params));
+    return QV4::ExecutionEngine::fromVariant(ctx->engine(), QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params));
 }
 
 /*!
@@ -397,7 +397,7 @@ ReturnedValue QtObject::method_quaternion(QV4::CallContext *ctx)
     sxyz[3] = ctx->d()->callData->args[3].toNumber();
 
     const void *params[] = { sxyz };
-    return QV8Engine::fromVariant(ctx->engine(), QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params));
+    return QV4::ExecutionEngine::fromVariant(ctx->engine(), QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params));
 }
 
 /*!
@@ -416,7 +416,7 @@ ReturnedValue QtObject::method_matrix4x4(QV4::CallContext *ctx)
         QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV4Handle(ctx->d()->callData->args[0]), v4, &ok);
         if (!ok)
             V4THROW_ERROR("Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array");
-        return QV8Engine::fromVariant(ctx->engine(), v);
+        return QV4::ExecutionEngine::fromVariant(ctx->engine(), v);
     }
 
     if (ctx->d()->callData->argc != 16)
@@ -441,7 +441,7 @@ ReturnedValue QtObject::method_matrix4x4(QV4::CallContext *ctx)
     vals[15] = ctx->d()->callData->args[15].toNumber();
 
     const void *params[] = { vals };
-    return QV8Engine::fromVariant(ctx->engine(), QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params));
+    return QV4::ExecutionEngine::fromVariant(ctx->engine(), QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params));
 }
 
 /*!
@@ -463,7 +463,7 @@ ReturnedValue QtObject::method_lighter(QV4::CallContext *ctx)
     if (ctx->d()->callData->argc != 1 && ctx->d()->callData->argc != 2)
         V4THROW_ERROR("Qt.lighter(): Invalid arguments");
 
-    QVariant v = QV8Engine::toVariant(ctx->engine(), ctx->d()->callData->args[0], -1);
+    QVariant v = QV4::ExecutionEngine::toVariant(ctx->engine(), ctx->d()->callData->args[0], -1);
     if (v.userType() == QVariant::String) {
         bool ok = false;
         v = QQmlStringConverters::colorFromString(v.toString(), &ok);
@@ -478,7 +478,7 @@ ReturnedValue QtObject::method_lighter(QV4::CallContext *ctx)
     if (ctx->d()->callData->argc == 2)
         factor = ctx->d()->callData->args[1].toNumber();
 
-    return QV8Engine::fromVariant(ctx->engine(), QQml_colorProvider()->lighter(v, factor));
+    return QV4::ExecutionEngine::fromVariant(ctx->engine(), QQml_colorProvider()->lighter(v, factor));
 }
 
 /*!
@@ -501,7 +501,7 @@ ReturnedValue QtObject::method_darker(QV4::CallContext *ctx)
     if (ctx->d()->callData->argc != 1 && ctx->d()->callData->argc != 2)
         V4THROW_ERROR("Qt.darker(): Invalid arguments");
 
-    QVariant v = QV8Engine::toVariant(ctx->engine(), ctx->d()->callData->args[0], -1);
+    QVariant v = QV4::ExecutionEngine::toVariant(ctx->engine(), ctx->d()->callData->args[0], -1);
     if (v.userType() == QVariant::String) {
         bool ok = false;
         v = QQmlStringConverters::colorFromString(v.toString(), &ok);
@@ -516,7 +516,7 @@ ReturnedValue QtObject::method_darker(QV4::CallContext *ctx)
     if (ctx->d()->callData->argc == 2)
         factor = ctx->d()->callData->args[1].toNumber();
 
-    return QV8Engine::fromVariant(ctx->engine(), QQml_colorProvider()->darker(v, factor));
+    return QV4::ExecutionEngine::fromVariant(ctx->engine(), QQml_colorProvider()->darker(v, factor));
 }
 
 /*!
@@ -549,7 +549,7 @@ ReturnedValue QtObject::method_tint(QV4::CallContext *ctx)
         V4THROW_ERROR("Qt.tint(): Invalid arguments");
 
     // base color
-    QVariant v1 = QV8Engine::toVariant(ctx->engine(), ctx->d()->callData->args[0], -1);
+    QVariant v1 = QV4::ExecutionEngine::toVariant(ctx->engine(), ctx->d()->callData->args[0], -1);
     if (v1.userType() == QVariant::String) {
         bool ok = false;
         v1 = QQmlStringConverters::colorFromString(v1.toString(), &ok);
@@ -561,7 +561,7 @@ ReturnedValue QtObject::method_tint(QV4::CallContext *ctx)
     }
 
     // tint color
-    QVariant v2 = QV8Engine::toVariant(ctx->engine(), ctx->d()->callData->args[1], -1);
+    QVariant v2 = QV4::ExecutionEngine::toVariant(ctx->engine(), ctx->d()->callData->args[1], -1);
     if (v2.userType() == QVariant::String) {
         bool ok = false;
         v2 = QQmlStringConverters::colorFromString(v2.toString(), &ok);
@@ -572,7 +572,7 @@ ReturnedValue QtObject::method_tint(QV4::CallContext *ctx)
         return QV4::Encode::null();
     }
 
-    return QV8Engine::fromVariant(ctx->engine(), QQml_colorProvider()->tint(v1, v2));
+    return QV4::ExecutionEngine::fromVariant(ctx->engine(), QQml_colorProvider()->tint(v1, v2));
 }
 
 /*!
@@ -598,7 +598,7 @@ ReturnedValue QtObject::method_formatDate(QV4::CallContext *ctx)
     QV4::Scope scope(ctx);
 
     Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
-    QDate date = QV8Engine::toVariant(ctx->engine(), ctx->d()->callData->args[0], -1).toDateTime().date();
+    QDate date = QV4::ExecutionEngine::toVariant(ctx->engine(), ctx->d()->callData->args[0], -1).toDateTime().date();
     QString formattedDate;
     if (ctx->d()->callData->argc == 2) {
         QV4::ScopedString s(scope, ctx->d()->callData->args[1]);
@@ -640,7 +640,7 @@ ReturnedValue QtObject::method_formatTime(QV4::CallContext *ctx)
         V4THROW_ERROR("Qt.formatTime(): Invalid arguments");
     QV4::Scope scope(ctx);
 
-    QVariant argVariant = QV8Engine::toVariant(ctx->engine(), ctx->d()->callData->args[0], -1);
+    QVariant argVariant = QV4::ExecutionEngine::toVariant(ctx->engine(), ctx->d()->callData->args[0], -1);
     QTime time;
     if (ctx->d()->callData->args[0].asDateObject() || (argVariant.type() == QVariant::String))
         time = argVariant.toDateTime().time();
@@ -765,7 +765,7 @@ ReturnedValue QtObject::method_formatDateTime(QV4::CallContext *ctx)
     QV4::Scope scope(ctx);
 
     Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
-    QDateTime dt = QV8Engine::toVariant(ctx->engine(), ctx->d()->callData->args[0], -1).toDateTime();
+    QDateTime dt = QV4::ExecutionEngine::toVariant(ctx->engine(), ctx->d()->callData->args[0], -1).toDateTime();
     QString formattedDt;
     if (ctx->d()->callData->argc == 2) {
         QV4::ScopedString s(scope, ctx->d()->callData->args[1]);
@@ -796,7 +796,7 @@ ReturnedValue QtObject::method_openUrlExternally(QV4::CallContext *ctx)
         return QV4::Encode(false);
 
     QUrl url(Value::fromReturnedValue(method_resolvedUrl(ctx)).toQStringNoThrow());
-    return QV8Engine::fromVariant(ctx->engine(), QQml_guiProvider()->openUrlExternally(url));
+    return QV4::ExecutionEngine::fromVariant(ctx->engine(), QQml_guiProvider()->openUrlExternally(url));
 }
 
 /*!
@@ -807,7 +807,7 @@ ReturnedValue QtObject::method_resolvedUrl(QV4::CallContext *ctx)
 {
     QV8Engine *v8engine = ctx->d()->engine->v8Engine;
 
-    QUrl url = QV8Engine::toVariant(ctx->engine(), ctx->d()->callData->args[0], -1).toUrl();
+    QUrl url = QV4::ExecutionEngine::toVariant(ctx->engine(), ctx->d()->callData->args[0], -1).toUrl();
     QQmlEngine *e = v8engine->engine();
     QQmlEnginePrivate *p = 0;
     if (e) p = QQmlEnginePrivate::get(e);
@@ -831,7 +831,7 @@ ReturnedValue QtObject::method_fontFamilies(CallContext *ctx)
     if (ctx->d()->callData->argc != 0)
         V4THROW_ERROR("Qt.fontFamilies(): Invalid arguments");
 
-    return QV8Engine::fromVariant(ctx->engine(), QVariant(QQml_guiProvider()->fontFamilies()));
+    return QV4::ExecutionEngine::fromVariant(ctx->engine(), QVariant(QQml_guiProvider()->fontFamilies()));
 }
 
 /*!
index 2234d3d..9ea17d8 100644 (file)
@@ -160,309 +160,6 @@ QV8Engine::~QV8Engine()
     delete m_v4Engine;
 }
 
-QVariant QV8Engine::toVariant(QV4::ExecutionEngine *e, const QV4::ValueRef value, int typeHint, bool createJSValueForObjects, V8ObjectSet *visitedObjects)
-{
-    Q_ASSERT (!value->isEmpty());
-    QV4::Scope scope(e);
-
-    if (QV4::VariantObject *v = value->as<QV4::VariantObject>())
-        return v->d()->data;
-
-    if (typeHint == QVariant::Bool)
-        return QVariant(value->toBoolean());
-
-    if (typeHint == QMetaType::QJsonValue)
-        return QVariant::fromValue(QV4::JsonObject::toJsonValue(value));
-
-    if (typeHint == qMetaTypeId<QJSValue>())
-        return QVariant::fromValue(QJSValue(new QJSValuePrivate(e, value)));
-
-    if (value->asObject()) {
-        QV4::ScopedObject object(scope, value);
-        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 (object->as<QV4::QmlContextWrapper>()) {
-            return QVariant();
-        } else if (QV4::QmlTypeWrapper *w = object->as<QV4::QmlTypeWrapper>()) {
-            return w->toVariant();
-        } else if (QV4::QQmlValueTypeWrapper *v = object->as<QV4::QQmlValueTypeWrapper>()) {
-            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 (value->asArrayObject()) {
-        QV4::ScopedArrayObject a(scope, value);
-        if (typeHint == qMetaTypeId<QList<QObject *> >()) {
-            QList<QObject *> list;
-            uint length = a->getLength();
-            QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope);
-            for (uint ii = 0; ii < length; ++ii) {
-                qobjectWrapper = a->getIndexed(ii);
-                if (!!qobjectWrapper) {
-                    list << qobjectWrapper->object();
-                } else {
-                    list << 0;
-                }
-            }
-
-            return qVariantFromValue<QList<QObject*> >(list);
-        } else if (typeHint == QMetaType::QJsonArray) {
-            return QVariant::fromValue(QV4::JsonObject::toJsonArray(a));
-        }
-
-        bool succeeded = false;
-        QVariant retn = QV4::SequencePrototype::toVariant(value, typeHint, &succeeded);
-        if (succeeded)
-            return retn;
-    }
-
-    if (value->isUndefined())
-        return QVariant();
-    if (value->isNull())
-        return QVariant(QMetaType::VoidStar, (void *)0);
-    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::QQmlLocaleData *ld = value->as<QV4::QQmlLocaleData>())
-        return ld->d()->locale;
-    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)!
-
-    QV4::ScopedObject o(scope, value);
-    Q_ASSERT(o);
-
-    if (QV4::RegExpObject *re = o->as<QV4::RegExpObject>())
-        return re->toQRegExp();
-
-    if (createJSValueForObjects)
-        return QVariant::fromValue(QJSValue(new QJSValuePrivate(o->asReturnedValue())));
-
-    return objectToVariant(e, o, visitedObjects);
-}
-
-QVariant QV8Engine::objectToVariant(QV4::ExecutionEngine *e, QV4::Object *o, V8ObjectSet *visitedObjects)
-{
-    Q_ASSERT(o);
-
-    V8ObjectSet recursionGuardSet;
-    if (!visitedObjects) {
-        visitedObjects = &recursionGuardSet;
-    } else if (visitedObjects->contains(o->d())) {
-        // Avoid recursion.
-        // For compatibility with QVariant{List,Map} conversion, we return an
-        // empty object (and no error is thrown).
-        if (o->asArrayObject())
-            return QVariantList();
-        return QVariantMap();
-    }
-    visitedObjects->insert(o->d());
-
-    QVariant result;
-
-    if (o->asArrayObject()) {
-        QV4::Scope scope(e);
-        QV4::ScopedArrayObject a(scope, o->asReturnedValue());
-        QV4::ScopedValue v(scope);
-        QVariantList list;
-
-        int length = a->getLength();
-        for (int ii = 0; ii < length; ++ii) {
-            v = a->getIndexed(ii);
-            list << toVariant(e, v, -1, /*createJSValueForObjects*/false, visitedObjects);
-        }
-
-        result = list;
-    } else if (!o->asFunctionObject()) {
-        QVariantMap map;
-        QV4::Scope scope(e);
-        QV4::ObjectIterator it(scope, o, QV4::ObjectIterator::EnumerableOnly);
-        QV4::ScopedValue name(scope);
-        QV4::ScopedValue val(scope);
-        while (1) {
-            name = it.nextPropertyNameAsString(val);
-            if (name->isNull())
-                break;
-
-            QString key = name->toQStringNoThrow();
-            map.insert(key, toVariant(e, val, /*type hint*/-1, /*createJSValueForObjects*/false, visitedObjects));
-        }
-
-        result = map;
-    }
-
-    visitedObjects->remove(o->d());
-    return result;
-}
-
-static QV4::ReturnedValue arrayFromVariantList(QV4::ExecutionEngine *e, const QVariantList &list)
-{
-    QV4::Scope scope(e);
-    QV4::ScopedArrayObject a(scope, e->newArrayObject());
-    int len = list.count();
-    a->arrayReserve(len);
-    QV4::ScopedValue v(scope);
-    for (int ii = 0; ii < len; ++ii)
-        a->arrayPut(ii, (v = QV8Engine::fromVariant(scope.engine, list.at(ii))));
-
-    a->setArrayLengthUnchecked(len);
-    return a.asReturnedValue();
-}
-
-static QV4::ReturnedValue objectFromVariantMap(QV4::ExecutionEngine *e, const QVariantMap &map)
-{
-    QV4::Scope scope(e);
-    QV4::ScopedObject o(scope, e->newObject());
-    QV4::ScopedString s(scope);
-    QV4::ScopedValue v(scope);
-    for (QVariantMap::ConstIterator iter = map.begin(); iter != map.end(); ++iter) {
-        s = e->newString(iter.key());
-        uint idx = s->asArrayIndex();
-        if (idx > 16 && (!o->arrayData() || idx > o->arrayData()->length() * 2))
-            o->initSparseArray();
-        o->put(s, (v = QV8Engine::fromVariant(e, iter.value())));
-    }
-    return o.asReturnedValue();
-}
-
-Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax);
-
-QV4::ReturnedValue QV8Engine::fromVariant(QV4::ExecutionEngine *e, const QVariant &variant)
-{
-    int type = variant.userType();
-    const void *ptr = variant.constData();
-
-    if (type < QMetaType::User) {
-        switch (QMetaType::Type(type)) {
-            case QMetaType::UnknownType:
-            case QMetaType::Void:
-                return QV4::Encode::undefined();
-            case QMetaType::VoidStar:
-                return QV4::Encode::null();
-            case QMetaType::Bool:
-                return QV4::Encode(*reinterpret_cast<const bool*>(ptr));
-            case QMetaType::Int:
-                return QV4::Encode(*reinterpret_cast<const int*>(ptr));
-            case QMetaType::UInt:
-                return QV4::Encode(*reinterpret_cast<const uint*>(ptr));
-            case QMetaType::LongLong:
-                return QV4::Encode((double)*reinterpret_cast<const qlonglong*>(ptr));
-            case QMetaType::ULongLong:
-                return QV4::Encode((double)*reinterpret_cast<const qulonglong*>(ptr));
-            case QMetaType::Double:
-                return QV4::Encode(*reinterpret_cast<const double*>(ptr));
-            case QMetaType::QString:
-                return e->currentContext()->engine->newString(*reinterpret_cast<const QString*>(ptr))->asReturnedValue();
-            case QMetaType::Float:
-                return QV4::Encode(*reinterpret_cast<const float*>(ptr));
-            case QMetaType::Short:
-                return QV4::Encode((int)*reinterpret_cast<const short*>(ptr));
-            case QMetaType::UShort:
-                return QV4::Encode((int)*reinterpret_cast<const unsigned short*>(ptr));
-            case QMetaType::Char:
-                return QV4::Encode((int)*reinterpret_cast<const char*>(ptr));
-            case QMetaType::UChar:
-                return QV4::Encode((int)*reinterpret_cast<const unsigned char*>(ptr));
-            case QMetaType::QChar:
-                return QV4::Encode((int)(*reinterpret_cast<const QChar*>(ptr)).unicode());
-            case QMetaType::QDateTime:
-                return QV4::Encode(e->newDateObject(*reinterpret_cast<const QDateTime *>(ptr)));
-            case QMetaType::QDate:
-                return QV4::Encode(e->newDateObject(QDateTime(*reinterpret_cast<const QDate *>(ptr))));
-            case QMetaType::QTime:
-            return QV4::Encode(e->newDateObject(QDateTime(QDate(1970,1,1), *reinterpret_cast<const QTime *>(ptr))));
-            case QMetaType::QRegExp:
-                return QV4::Encode(e->newRegExpObject(*reinterpret_cast<const QRegExp *>(ptr)));
-            case QMetaType::QObjectStar:
-                return QV4::QObjectWrapper::wrap(e, *reinterpret_cast<QObject* const *>(ptr));
-            case QMetaType::QStringList:
-                {
-                bool succeeded = false;
-                QV4::Scope scope(e);
-                QV4::ScopedValue retn(scope, QV4::SequencePrototype::fromVariant(e, variant, &succeeded));
-                if (succeeded)
-                    return retn.asReturnedValue();
-                return QV4::Encode(e->newArrayObject(*reinterpret_cast<const QStringList *>(ptr)));
-                }
-            case QMetaType::QVariantList:
-                return arrayFromVariantList(e, *reinterpret_cast<const QVariantList *>(ptr));
-            case QMetaType::QVariantMap:
-                return objectFromVariantMap(e, *reinterpret_cast<const QVariantMap *>(ptr));
-            case QMetaType::QJsonValue:
-                return QV4::JsonObject::fromJsonValue(e, *reinterpret_cast<const QJsonValue *>(ptr));
-            case QMetaType::QJsonObject:
-                return QV4::JsonObject::fromJsonObject(e, *reinterpret_cast<const QJsonObject *>(ptr));
-            case QMetaType::QJsonArray:
-                return QV4::JsonObject::fromJsonArray(e, *reinterpret_cast<const QJsonArray *>(ptr));
-            case QMetaType::QLocale:
-                return QQmlLocale::wrap(e, *reinterpret_cast<const QLocale*>(ptr));
-            default:
-                break;
-        }
-
-        if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(type))
-            return QV4::QQmlValueTypeWrapper::create(e, variant, vtmo, type);
-    } else {
-        QV4::Scope scope(e);
-        if (type == qMetaTypeId<QQmlListReference>()) {
-            typedef QQmlListReferencePrivate QDLRP;
-            QDLRP *p = QDLRP::get((QQmlListReference*)ptr);
-            if (p->object) {
-                return QV4::QmlListWrapper::create(scope.engine, p->property, p->propertyType);
-            } else {
-                return QV4::Encode::null();
-            }
-        } else if (type == qMetaTypeId<QJSValue>()) {
-            const QJSValue *value = reinterpret_cast<const QJSValue *>(ptr);
-            QJSValuePrivate *valuep = QJSValuePrivate::get(*value);
-            return valuep->getValue(e);
-        } 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;
-            QV4::ScopedArrayObject a(scope, e->newArrayObject());
-            a->arrayReserve(list.count());
-            QV4::ScopedValue v(scope);
-            for (int ii = 0; ii < list.count(); ++ii)
-                a->arrayPut(ii, (v = QV4::QObjectWrapper::wrap(e, list.at(ii))));
-            a->setArrayLengthUnchecked(list.count());
-            return a.asReturnedValue();
-        } else if (QMetaType::typeFlags(type) & QMetaType::PointerToQObject) {
-            return QV4::QObjectWrapper::wrap(e, *reinterpret_cast<QObject* const *>(ptr));
-        }
-
-        bool objOk;
-        QObject *obj = QQmlMetaType::toQObject(variant, &objOk);
-        if (objOk)
-            return QV4::QObjectWrapper::wrap(e, obj);
-
-        bool succeeded = false;
-        QV4::ScopedValue retn(scope, QV4::SequencePrototype::fromVariant(e, variant, &succeeded));
-        if (succeeded)
-            return retn.asReturnedValue();
-
-        if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(type))
-            return QV4::QQmlValueTypeWrapper::create(e, variant, vtmo, type);
-    }
-
-    // XXX TODO: To be compatible, we still need to handle:
-    //    + QObjectList
-    //    + QList<int>
-
-    return QV4::Encode(e->newVariantObject(variant));
-}
-
 QNetworkAccessManager *QV8Engine::networkAccessManager()
 {
     return QQmlEnginePrivate::get(m_engine)->getNetworkAccessManager();
@@ -584,376 +281,6 @@ QV4::ReturnedValue QV8Engine::global()
     return m_v4Engine->globalObject()->asReturnedValue();
 }
 
-// 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.
-QV4::ReturnedValue QV8Engine::variantListToJS(QV4::ExecutionEngine *v4, const QVariantList &lst)
-{
-    QV4::Scope scope(v4);
-    QV4::ScopedArrayObject a(scope, v4->newArrayObject());
-    a->arrayReserve(lst.size());
-    QV4::ScopedValue v(scope);
-    for (int i = 0; i < lst.size(); i++)
-        a->arrayPut(i, (v = variantToJS(v4, lst.at(i))));
-    a->setArrayLengthUnchecked(lst.size());
-    return a.asReturnedValue();
-}
-
-// Converts a QVariantMap to JS.
-// 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.
-QV4::ReturnedValue QV8Engine::variantMapToJS(QV4::ExecutionEngine *v4, const QVariantMap &vmap)
-{
-    QV4::Scope scope(v4);
-    QV4::ScopedObject o(scope, v4->newObject());
-    QVariantMap::const_iterator it;
-    QV4::ScopedString s(scope);
-    QV4::ScopedValue v(scope);
-    for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) {
-        s = v4->newIdentifier(it.key());
-        v = variantToJS(v4, it.value());
-        uint idx = s->asArrayIndex();
-        if (idx < UINT_MAX)
-            o->arraySet(idx, v);
-        else
-            o->insertMember(s, v);
-    }
-    return o.asReturnedValue();
-}
-
-// Converts the meta-type defined by the given type and data to JS.
-// Returns the value if conversion succeeded, an empty handle otherwise.
-QV4::ReturnedValue QV8Engine::metaTypeToJS(QV4::ExecutionEngine *v4, int type, const void *data)
-{
-    Q_ASSERT(data != 0);
-
-    // check if it's one of the types we know
-    switch (QMetaType::Type(type)) {
-    case QMetaType::UnknownType:
-    case QMetaType::Void:
-        return QV4::Encode::undefined();
-    case QMetaType::VoidStar:
-        return QV4::Encode::null();
-    case QMetaType::Bool:
-        return QV4::Encode(*reinterpret_cast<const bool*>(data));
-    case QMetaType::Int:
-        return QV4::Encode(*reinterpret_cast<const int*>(data));
-    case QMetaType::UInt:
-        return QV4::Encode(*reinterpret_cast<const uint*>(data));
-    case QMetaType::LongLong:
-        return QV4::Encode(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 QV4::Encode(double((qlonglong)*reinterpret_cast<const qulonglong*>(data)));
-#elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
-        return QV4::Encode(double((qlonglong)*reinterpret_cast<const qulonglong*>(data)));
-#else
-        return QV4::Encode(double(*reinterpret_cast<const qulonglong*>(data)));
-#endif
-    case QMetaType::Double:
-        return QV4::Encode(*reinterpret_cast<const double*>(data));
-    case QMetaType::QString:
-        return v4->currentContext()->engine->newString(*reinterpret_cast<const QString*>(data))->asReturnedValue();
-    case QMetaType::Float:
-        return QV4::Encode(*reinterpret_cast<const float*>(data));
-    case QMetaType::Short:
-        return QV4::Encode((int)*reinterpret_cast<const short*>(data));
-    case QMetaType::UShort:
-        return QV4::Encode((int)*reinterpret_cast<const unsigned short*>(data));
-    case QMetaType::Char:
-        return QV4::Encode((int)*reinterpret_cast<const char*>(data));
-    case QMetaType::UChar:
-        return QV4::Encode((int)*reinterpret_cast<const unsigned char*>(data));
-    case QMetaType::QChar:
-        return QV4::Encode((int)(*reinterpret_cast<const QChar*>(data)).unicode());
-    case QMetaType::QStringList:
-        return QV4::Encode(v4->newArrayObject(*reinterpret_cast<const QStringList *>(data)));
-    case QMetaType::QVariantList:
-        return variantListToJS(v4, *reinterpret_cast<const QVariantList *>(data));
-    case QMetaType::QVariantMap:
-        return variantMapToJS(v4, *reinterpret_cast<const QVariantMap *>(data));
-    case QMetaType::QDateTime:
-        return QV4::Encode(v4->newDateObject(*reinterpret_cast<const QDateTime *>(data)));
-    case QMetaType::QDate:
-        return QV4::Encode(v4->newDateObject(QDateTime(*reinterpret_cast<const QDate *>(data))));
-    case QMetaType::QRegExp:
-        return QV4::Encode(v4->newRegExpObject(*reinterpret_cast<const QRegExp *>(data)));
-    case QMetaType::QObjectStar:
-        return QV4::QObjectWrapper::wrap(v4, *reinterpret_cast<QObject* const *>(data));
-    case QMetaType::QVariant:
-        return variantToJS(v4, *reinterpret_cast<const QVariant*>(data));
-    case QMetaType::QJsonValue:
-        return QV4::JsonObject::fromJsonValue(v4, *reinterpret_cast<const QJsonValue *>(data));
-    case QMetaType::QJsonObject:
-        return QV4::JsonObject::fromJsonObject(v4, *reinterpret_cast<const QJsonObject *>(data));
-    case QMetaType::QJsonArray:
-        return QV4::JsonObject::fromJsonArray(v4, *reinterpret_cast<const QJsonArray *>(data));
-    default:
-        if (type == qMetaTypeId<QJSValue>()) {
-            return QJSValuePrivate::get(*reinterpret_cast<const QJSValue*>(data))->getValue(v4);
-        } else {
-            QByteArray typeName = QMetaType::typeName(type);
-            if (typeName.endsWith('*') && !*reinterpret_cast<void* const *>(data)) {
-                return QV4::Encode::null();
-            }
-            QMetaType mt(type);
-            if (mt.flags() & QMetaType::IsGadget) {
-                Q_ASSERT(mt.metaObject());
-                return QV4::QQmlValueTypeWrapper::create(m_v4Engine, QVariant(type, data), mt.metaObject(), type);
-            }
-            // Fall back to wrapping in a QVariant.
-            return QV4::Encode(m_v4Engine->newVariantObject(QVariant(type, data)));
-        }
-    }
-    Q_UNREACHABLE();
-    return 0;
-}
-
-// 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(QV4::ExecutionEngine *engine, const QV4::ValueRef value, int type, void *data)
-{
-    QV4::Scope scope(engine);
-
-    // check if it's one of the types we know
-    switch (QMetaType::Type(type)) {
-    case QMetaType::Bool:
-        *reinterpret_cast<bool*>(data) = value->toBoolean();
-        return true;
-    case QMetaType::Int:
-        *reinterpret_cast<int*>(data) = value->toInt32();
-        return true;
-    case QMetaType::UInt:
-        *reinterpret_cast<uint*>(data) = value->toUInt32();
-        return true;
-    case QMetaType::LongLong:
-        *reinterpret_cast<qlonglong*>(data) = qlonglong(value->toInteger());
-        return true;
-    case QMetaType::ULongLong:
-        *reinterpret_cast<qulonglong*>(data) = qulonglong(value->toInteger());
-        return true;
-    case QMetaType::Double:
-        *reinterpret_cast<double*>(data) = value->toNumber();
-        return true;
-    case QMetaType::QString:
-        if (value->isUndefined() || value->isNull())
-            *reinterpret_cast<QString*>(data) = QString();
-        else
-            *reinterpret_cast<QString*>(data) = value->toQString();
-        return true;
-    case QMetaType::Float:
-        *reinterpret_cast<float*>(data) = value->toNumber();
-        return true;
-    case QMetaType::Short:
-        *reinterpret_cast<short*>(data) = short(value->toInt32());
-        return true;
-    case QMetaType::UShort:
-        *reinterpret_cast<unsigned short*>(data) = value->toUInt16();
-        return true;
-    case QMetaType::Char:
-        *reinterpret_cast<char*>(data) = char(value->toInt32());
-        return true;
-    case QMetaType::UChar:
-        *reinterpret_cast<unsigned char*>(data) = (unsigned char)(value->toInt32());
-        return true;
-    case QMetaType::QChar:
-        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->toUInt16()));
-        }
-        return true;
-    case QMetaType::QDateTime:
-        if (QV4::DateObject *d = value->asDateObject()) {
-            *reinterpret_cast<QDateTime *>(data) = d->toQDateTime();
-            return true;
-        } break;
-    case QMetaType::QDate:
-        if (QV4::DateObject *d = value->asDateObject()) {
-            *reinterpret_cast<QDate *>(data) = d->toQDateTime().date();
-            return true;
-        } break;
-    case QMetaType::QRegExp:
-        if (QV4::RegExpObject *r = value->as<QV4::RegExpObject>()) {
-            *reinterpret_cast<QRegExp *>(data) = r->toQRegExp();
-            return true;
-        } break;
-    case QMetaType::QObjectStar: {
-        QV4::QObjectWrapper *qobjectWrapper = value->as<QV4::QObjectWrapper>();
-        if (qobjectWrapper || value->isNull()) {
-            *reinterpret_cast<QObject* *>(data) = qtObjectFromJS(scope.engine, value);
-            return true;
-        } break;
-    }
-    case QMetaType::QStringList: {
-        QV4::ScopedArrayObject a(scope, value);
-        if (a) {
-            *reinterpret_cast<QStringList *>(data) = a->toQStringList();
-            return true;
-        }
-        break;
-    }
-    case QMetaType::QVariantList: {
-        QV4::ScopedArrayObject a(scope, value);
-        if (a) {
-            *reinterpret_cast<QVariantList *>(data) = toVariant(scope.engine, a, /*typeHint*/-1, /*createJSValueForObjects*/false).toList();
-            return true;
-        }
-        break;
-    }
-    case QMetaType::QVariantMap: {
-        QV4::ScopedObject o(scope, value);
-        if (o) {
-            *reinterpret_cast<QVariantMap *>(data) = variantMapFromJS(o);
-            return true;
-        }
-        break;
-    }
-    case QMetaType::QVariant:
-        *reinterpret_cast<QVariant*>(data) = toVariant(scope.engine, value, /*typeHint*/-1, /*createJSValueForObjects*/false);
-        return true;
-    case QMetaType::QJsonValue:
-        *reinterpret_cast<QJsonValue *>(data) = QV4::JsonObject::toJsonValue(value);
-        return true;
-    case QMetaType::QJsonObject: {
-        QV4::ScopedObject o(scope, value);
-        *reinterpret_cast<QJsonObject *>(data) = QV4::JsonObject::toJsonObject(o);
-        return true;
-    }
-    case QMetaType::QJsonArray: {
-        QV4::ScopedArrayObject a(scope, value);
-        if (a) {
-            *reinterpret_cast<QJsonArray *>(data) = QV4::JsonObject::toJsonArray(a);
-            return true;
-        }
-        break;
-    }
-    default:
-    ;
-    }
-
-    {
-        QV4::Scoped<QV4::QQmlValueTypeWrapper> vtw(scope, value);
-        if (vtw && vtw->d()->metaType == type) {
-            vtw->toGadget(data);
-            return true;
-        }
-    }
-
-#if 0
-    if (isQtVariant(value)) {
-        const QVariant &var = variantValue(value);
-        // ### Enable once constructInPlace() is in qt master.
-        if (var.userType() == type) {
-            QMetaType::constructInPlace(type, data, var.constData());
-            return true;
-        }
-        if (var.canConvert(type)) {
-            QVariant vv = var;
-            vv.convert(type);
-            Q_ASSERT(vv.userType() == type);
-            QMetaType::constructInPlace(type, data, vv.constData());
-            return true;
-        }
-
-    }
-#endif
-
-    // Try to use magic; for compatibility with qscriptvalue_cast.
-
-    QByteArray name = QMetaType::typeName(type);
-    if (convertToNativeQObject(engine, value, name, reinterpret_cast<void* *>(data)))
-        return true;
-    if (value->as<QV4::VariantObject>() && name.endsWith('*')) {
-        int valueType = QMetaType::type(name.left(name.size()-1));
-        QVariant &var = value->as<QV4::VariantObject>()->d()->data;
-        if (valueType == var.userType()) {
-            // We have T t, T* is requested, so return &t.
-            *reinterpret_cast<void* *>(data) = var.data();
-            return true;
-        } else if (value->isObject()) {
-            // Look in the prototype chain.
-            QV4::ScopedObject proto(scope, value->objectValue()->prototype());
-            while (proto) {
-                bool canCast = false;
-                if (QV4::VariantObject *vo = proto->as<QV4::VariantObject>()) {
-                    const QVariant &v = vo->d()->data;
-                    canCast = (type == v.userType()) || (valueType && (valueType == v.userType()));
-                }
-                else if (proto->as<QV4::QObjectWrapper>()) {
-                    QByteArray className = name.left(name.size()-1);
-                    QV4::ScopedObject p(scope, proto.getPointer());
-                    if (QObject *qobject = qtObjectFromJS(scope.engine, p))
-                        canCast = qobject->qt_metacast(className) != 0;
-                }
-                if (canCast) {
-                    QByteArray varTypeName = QMetaType::typeName(var.userType());
-                    if (varTypeName.endsWith('*'))
-                        *reinterpret_cast<void* *>(data) = *reinterpret_cast<void* *>(var.data());
-                    else
-                        *reinterpret_cast<void* *>(data) = var.data();
-                    return true;
-                }
-                proto = proto->prototype();
-            }
-        }
-    } 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(engine, value));
-        return true;
-    }
-
-    return false;
-}
-
-// Converts a QVariant to JS.
-QV4::ReturnedValue QV8Engine::variantToJS(QV4::ExecutionEngine *v4, const QVariant &value)
-{
-    return metaTypeToJS(v4, value.userType(), value.constData());
-}
-
-bool QV8Engine::convertToNativeQObject(QV4::ExecutionEngine *e, const QV4::ValueRef value, const QByteArray &targetType, void **result)
-{
-    if (!targetType.endsWith('*'))
-        return false;
-    if (QObject *qobject = qtObjectFromJS(e, value)) {
-        int start = targetType.startsWith("const ") ? 6 : 0;
-        QByteArray className = targetType.mid(start, targetType.size()-start-1);
-        if (void *instance = qobject->qt_metacast(className)) {
-            *result = instance;
-            return true;
-        }
-    }
-    return false;
-}
-
-QObject *QV8Engine::qtObjectFromJS(QV4::ExecutionEngine *engine, const QV4::ValueRef value)
-{
-    if (!value->isObject())
-        return 0;
-
-    QV4::Scope scope(engine);
-    QV4::Scoped<QV4::VariantObject> v(scope, value);
-
-    if (v) {
-        QVariant variant = v->d()->data;
-        int type = variant.userType();
-        if (type == QMetaType::QObjectStar)
-            return *reinterpret_cast<QObject* const *>(variant.constData());
-    }
-    QV4::Scoped<QV4::QObjectWrapper> wrapper(scope, value);
-    if (!wrapper)
-        return 0;
-    return wrapper->object();
-}
-
 void QV8Engine::startTimer(const QString &timerName)
 {
     if (!m_time.isValid())
index f8e8624..1d3e427 100644 (file)
@@ -210,24 +210,6 @@ public:
     inline Deletable *extensionData(int) const;
     void setExtensionData(int, Deletable *);
 
-    static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::ValueRef value, int typeHint, bool createJSValueForObjects = true, V8ObjectSet *visitedObjects = 0);
-    static QV4::ReturnedValue fromVariant(QV4::ExecutionEngine *e, const QVariant &);
-
-    static QVariantMap variantMapFromJS(QV4::Object *o)
-    { return objectToVariant(o->engine(), o).toMap(); }
-
-    static bool metaTypeFromJS(QV4::ExecutionEngine *e, const QV4::ValueRef value, int type, void *data);
-
-private:
-    static QVariant objectToVariant(QV4::ExecutionEngine *e, QV4::Object *o, V8ObjectSet *visitedObjects = 0);
-    static bool convertToNativeQObject(QV4::ExecutionEngine *e, const QV4::ValueRef value,
-                                const QByteArray &targetType,
-                                void **result);
-    static QV4::ReturnedValue variantListToJS(QV4::ExecutionEngine *v4, const QVariantList &lst);
-    static QV4::ReturnedValue variantMapToJS(QV4::ExecutionEngine *v4, const QVariantMap &vmap);
-    static QV4::ReturnedValue metaTypeToJS(QV4::ExecutionEngine *v4, int type, const void *data);
-    static QV4::ReturnedValue variantToJS(QV4::ExecutionEngine *v4, const QVariant &value);
-
 public:
     // used for console.time(), console.timeEnd()
     void startTimer(const QString &timerName);
@@ -236,8 +218,6 @@ public:
     // used for console.count()
     int consoleCountHelper(const QString &file, quint16 line, quint16 column);
 
-    static QObject *qtObjectFromJS(QV4::ExecutionEngine *engine, const QV4::ValueRef value);
-
 protected:
     QJSEngine* q;
     QQmlEngine *m_engine;
index 1468169..1095f29 100644 (file)
@@ -1646,7 +1646,7 @@ bool QQmlDelegateModelPrivate::insert(Compositor::insert_iterator &before, const
         propertyName = it.nextPropertyNameAsString(v);
         if (propertyName->isNull())
             break;
-        cacheItem->setValue(propertyName->toQStringNoThrow(), QV8Engine::toVariant(scope.engine, v, QVariant::Invalid));
+        cacheItem->setValue(propertyName->toQStringNoThrow(), QV4::ExecutionEngine::toVariant(scope.engine, v, QVariant::Invalid));
     }
 
     cacheItem->groups = groups | Compositor::UnresolvedFlag | Compositor::CacheFlag;
@@ -1825,7 +1825,7 @@ QV4::ReturnedValue QQmlDelegateModelItem::get_groups(QV4::CallContext *ctx)
             groups.append(o->d()->item->metaType->groupNames.at(i - 1));
     }
 
-    return QV8Engine::fromVariant(scope.engine, groups);
+    return QV4::ExecutionEngine::fromVariant(scope.engine, groups);
 }
 
 QV4::ReturnedValue QQmlDelegateModelItem::set_groups(QV4::CallContext *ctx)
index d09be1b..7613ba7 100644 (file)
@@ -885,7 +885,7 @@ int ListElement::setVariantMapProperty(const ListLayout::Role &role, QV4::Object
             QVariantMap *map = reinterpret_cast<QVariantMap *>(mem);
             map->~QMap();
         }
-        new (mem) QVariantMap(QV8Engine::variantMapFromJS(o));
+        new (mem) QVariantMap(QV4::ExecutionEngine::variantMapFromJS(o));
         roleIndex = role.index;
     }
 
@@ -966,7 +966,7 @@ void ListElement::setVariantMapFast(const ListLayout::Role &role, QV4::Object *o
 {
     char *mem = getPropertyMemory(role);
     QVariantMap *map = new (mem) QVariantMap;
-    *map = QV8Engine::variantMapFromJS(o);
+    *map = QV4::ExecutionEngine::variantMapFromJS(o);
 }
 
 void ListElement::setDateTimePropertyFast(const ListLayout::Role &role, const QDateTime &dt)
@@ -1262,7 +1262,7 @@ void ModelNodeMetaObject::propertyWritten(int index)
     QVariant value = operator[](index);
 
     QV4::Scope scope(m_obj->m_model->engine());
-    QV4::ScopedValue v(scope, QV8Engine::fromVariant(scope.engine, value));
+    QV4::ScopedValue v(scope, QV4::ExecutionEngine::fromVariant(scope.engine, value));
 
     int roleIndex = m_obj->m_model->m_listModel->setExistingProperty(m_obj->m_elementIndex, propName, v, scope.engine);
     if (roleIndex != -1) {
@@ -1983,7 +1983,7 @@ void QQmlListModel::insert(QQmlV4Function *args)
                 argObject = objectArray->getIndexed(i);
 
                 if (m_dynamicRoles) {
-                    m_modelObjects.insert(index+i, DynamicRoleModelNode::create(QV8Engine::variantMapFromJS(argObject), this));
+                    m_modelObjects.insert(index+i, DynamicRoleModelNode::create(QV4::ExecutionEngine::variantMapFromJS(argObject), this));
                 } else {
                     m_listModel->insert(index+i, argObject);
                 }
@@ -1993,7 +1993,7 @@ void QQmlListModel::insert(QQmlV4Function *args)
             emitItemsAboutToBeInserted(index, 1);
 
             if (m_dynamicRoles) {
-                m_modelObjects.insert(index, DynamicRoleModelNode::create(QV8Engine::variantMapFromJS(argObject), this));
+                m_modelObjects.insert(index, DynamicRoleModelNode::create(QV4::ExecutionEngine::variantMapFromJS(argObject), this));
             } else {
                 m_listModel->insert(index, argObject);
             }
@@ -2093,7 +2093,7 @@ void QQmlListModel::append(QQmlV4Function *args)
                 argObject = objectArray->getIndexed(i);
 
                 if (m_dynamicRoles) {
-                    m_modelObjects.append(DynamicRoleModelNode::create(QV8Engine::variantMapFromJS(argObject), this));
+                    m_modelObjects.append(DynamicRoleModelNode::create(QV4::ExecutionEngine::variantMapFromJS(argObject), this));
                 } else {
                     m_listModel->append(argObject);
                 }
@@ -2106,7 +2106,7 @@ void QQmlListModel::append(QQmlV4Function *args)
             if (m_dynamicRoles) {
                 index = m_modelObjects.count();
                 emitItemsAboutToBeInserted(index, 1);
-                m_modelObjects.append(DynamicRoleModelNode::create(QV8Engine::variantMapFromJS(argObject), this));
+                m_modelObjects.append(DynamicRoleModelNode::create(QV4::ExecutionEngine::variantMapFromJS(argObject), this));
             } else {
                 index = m_listModel->elementCount();
                 emitItemsAboutToBeInserted(index, 1);
@@ -2207,7 +2207,7 @@ void QQmlListModel::set(int index, const QQmlV4Handle &handle)
         emitItemsAboutToBeInserted(index, 1);
 
         if (m_dynamicRoles) {
-            m_modelObjects.append(DynamicRoleModelNode::create(QV8Engine::variantMapFromJS(object), this));
+            m_modelObjects.append(DynamicRoleModelNode::create(QV4::ExecutionEngine::variantMapFromJS(object), this));
         } else {
             m_listModel->insert(index, object);
         }
@@ -2218,7 +2218,7 @@ void QQmlListModel::set(int index, const QQmlV4Handle &handle)
         QVector<int> roles;
 
         if (m_dynamicRoles) {
-            m_modelObjects[index]->updateValues(QV8Engine::variantMapFromJS(object), roles);
+            m_modelObjects[index]->updateValues(QV4::ExecutionEngine::variantMapFromJS(object), roles);
         } else {
             m_listModel->set(index, object, &roles);
         }
index 580641a..ef60754 100644 (file)
@@ -345,11 +345,11 @@ QV4::ReturnedValue QQmlDMCachedModelData::get_property(QV4::CallContext *ctx, ui
     QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(o->d()->item);
     if (o->d()->item->index == -1) {
         if (!modelData->cachedData.isEmpty()) {
-            return QV8Engine::fromVariant(scope.engine,
+            return QV4::ExecutionEngine::fromVariant(scope.engine,
                     modelData->cachedData.at(modelData->type->hasModelData ? 0 : propertyId));
         }
     } else if (*modelData->type->model) {
-        return QV8Engine::fromVariant(scope.engine,
+        return QV4::ExecutionEngine::fromVariant(scope.engine,
                 modelData->value(modelData->type->propertyRoles.at(propertyId)));
     }
     return QV4::Encode::undefined();
@@ -368,10 +368,10 @@ QV4::ReturnedValue QQmlDMCachedModelData::set_property(QV4::CallContext *ctx, ui
         QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(o->d()->item);
         if (!modelData->cachedData.isEmpty()) {
             if (modelData->cachedData.count() > 1) {
-                modelData->cachedData[propertyId] = QV8Engine::toVariant(scope.engine, ctx->d()->callData->args[0], QVariant::Invalid);
+                modelData->cachedData[propertyId] = QV4::ExecutionEngine::toVariant(scope.engine, ctx->d()->callData->args[0], QVariant::Invalid);
                 QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), propertyId, 0);
             } else if (modelData->cachedData.count() == 1) {
-                modelData->cachedData[0] = QV8Engine::toVariant(scope.engine, ctx->d()->callData->args[0], QVariant::Invalid);
+                modelData->cachedData[0] = QV4::ExecutionEngine::toVariant(scope.engine, ctx->d()->callData->args[0], QVariant::Invalid);
                 QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), 0, 0);
                 QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), 1, 0);
             }
@@ -584,7 +584,7 @@ public:
         if (!o)
             return ctx->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
 
-        return QV8Engine::fromVariant(scope.engine, static_cast<QQmlDMListAccessorData *>(o->d()->item)->cachedData);
+        return QV4::ExecutionEngine::fromVariant(scope.engine, static_cast<QQmlDMListAccessorData *>(o->d()->item)->cachedData);
     }
 
     static QV4::ReturnedValue set_modelData(QV4::CallContext *ctx)
@@ -596,7 +596,7 @@ public:
         if (!ctx->d()->callData->argc)
             return ctx->engine()->throwTypeError();
 
-        static_cast<QQmlDMListAccessorData *>(o->d()->item)->setModelData(QV8Engine::toVariant(scope.engine, ctx->d()->callData->args[0], QVariant::Invalid));
+        static_cast<QQmlDMListAccessorData *>(o->d()->item)->setModelData(QV4::ExecutionEngine::toVariant(scope.engine, ctx->d()->callData->args[0], QVariant::Invalid));
         return QV4::Encode::undefined();
     }
 
index e94986f..8b6a8e2 100644 (file)
@@ -480,7 +480,7 @@ void QuickTestResult::stringify(QQmlV4Function *args)
     if (value->isObject()
         && !value->asFunctionObject()
         && !value->asArrayObject()) {
-        QVariant v = QV8Engine::toVariant(scope.engine, value, QMetaType::UnknownType);
+        QVariant v = QV4::ExecutionEngine::toVariant(scope.engine, value, QMetaType::UnknownType);
         if (v.isValid()) {
             switch (v.type()) {
             case QVariant::Vector3D:
index a0fc283..5cc57f9 100644 (file)
@@ -1386,7 +1386,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(QV4::CallContext *ctx
     QV4::ScopedValue value(scope, ctx->argument(0));
 
    if (value->asObject()) {
-       QColor color = QV8Engine::toVariant(scope.engine, value, qMetaTypeId<QColor>()).value<QColor>();
+       QColor color = QV4::ExecutionEngine::toVariant(scope.engine, value, qMetaTypeId<QColor>()).value<QColor>();
        if (color.isValid()) {
            r->d()->context->state.fillStyle = color;
            r->d()->context->buffer()->setFillStyle(color);
@@ -1429,7 +1429,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_get_fillRule(QV4::CallContext *ctx)
     QV4::Scoped<QQuickJSContext2D> r(scope, ctx->d()->callData->thisObject.as<QQuickJSContext2D>());
     CHECK_CONTEXT(r)
 
-    return QV8Engine::fromVariant(scope.engine, r->d()->context->state.fillRule);
+    return QV4::ExecutionEngine::fromVariant(scope.engine, r->d()->context->state.fillRule);
 }
 
 QV4::ReturnedValue QQuickJSContext2D::method_set_fillRule(QV4::CallContext *ctx)
@@ -1495,7 +1495,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_strokeStyle(QV4::CallContext *c
     QV4::ScopedValue value(scope, ctx->argument(0));
 
     if (value->asObject()) {
-        QColor color = QV8Engine::toVariant(scope.engine, value, qMetaTypeId<QColor>()).value<QColor>();
+        QColor color = QV4::ExecutionEngine::toVariant(scope.engine, value, qMetaTypeId<QColor>()).value<QColor>();
         if (color.isValid()) {
             r->d()->context->state.fillStyle = color;
             r->d()->context->buffer()->setStrokeStyle(color);
@@ -1714,7 +1714,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(QV4::CallCon
     if (ctx->d()->callData->argc >= 2) {
         QV4::Scoped<QQuickContext2DStyle> pattern(scope, scope.engine->memoryManager->alloc<QQuickContext2DStyle>(scope.engine));
 
-        QColor color = QV8Engine::toVariant(scope.engine, ctx->d()->callData->args[0], qMetaTypeId<QColor>()).value<QColor>();
+        QColor color = QV4::ExecutionEngine::toVariant(scope.engine, ctx->d()->callData->args[0], qMetaTypeId<QColor>()).value<QColor>();
         if (color.isValid()) {
             int patternMode = ctx->d()->callData->args[1].toInt32();
             Qt::BrushStyle style = Qt::SolidPattern;
@@ -3364,7 +3364,7 @@ QV4::ReturnedValue QQuickContext2DStyle::gradient_proto_addColorStop(QV4::CallCo
         QColor color;
 
         if (ctx->d()->callData->args[1].asObject()) {
-            color = QV8Engine::toVariant(scope.engine, ctx->d()->callData->args[1], qMetaTypeId<QColor>()).value<QColor>();
+            color = QV4::ExecutionEngine::toVariant(scope.engine, ctx->d()->callData->args[1], qMetaTypeId<QColor>()).value<QColor>();
         } else {
             color = qt_color_from_string(ctx->d()->callData->args[1]);
         }
index d4c39e9..dd8c688 100644 (file)
@@ -2464,7 +2464,7 @@ void tst_qqmlecmascript::callQtInvokables()
     {
     QV4::ScopedValue ret(scope, EVALUATE("object.method_NoArgs_QPointF()"));
     QVERIFY(!ret->isUndefined());
-    QCOMPARE(QV8Engine::toVariant(scope.engine, ret, -1), QVariant(QPointF(123, 4.5)));
+    QCOMPARE(QV4::ExecutionEngine::toVariant(scope.engine, ret, -1), QVariant(QPointF(123, 4.5)));
     QCOMPARE(o->error(), false);
     QCOMPARE(o->invoked(), 3);
     QCOMPARE(o->actuals().count(), 0);