diff options
24 files changed, 794 insertions, 780 deletions
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp index 2df859c104..726b7d8874 100644 --- a/src/imports/localstorage/plugin.cpp +++ b/src/imports/localstorage/plugin.cpp @@ -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()) { diff --git a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp index 7cd1a2f651..b3fa14c662 100644 --- a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp +++ b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp @@ -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); } diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp index 49f1dab977..b9283c9d9e 100644 --- a/src/qml/jsapi/qjsengine.cpp +++ b/src/qml/jsapi/qjsengine.cpp @@ -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(); diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index 11b7dad8eb..0ad943bd21 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -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()); diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 474fc889f4..4aff72ab79 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -65,6 +65,14 @@ #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 diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 9d8fb54388..82753e3ab4 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -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; }; diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 49f9c5d266..1e0c8d1887 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -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()) diff --git a/src/qml/jsruntime/qv4serialize.cpp b/src/qml/jsruntime/qv4serialize.cpp index 60b6235ffe..655b456086 100644 --- a/src/qml/jsruntime/qv4serialize.cpp +++ b/src/qml/jsruntime/qv4serialize.cpp @@ -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); diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index a4e614f934..6e45ca8bbb 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -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) diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index aa1c1f6a33..d605e1a829 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -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])); } } diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp index f73548100d..5a6bf70727 100644 --- a/src/qml/qml/qqmlcontextwrapper.cpp +++ b/src/qml/qml/qqmlcontextwrapper.cpp @@ -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)); } } } diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp index a99ecde0e9..f44357d4f8 100644 --- a/src/qml/qml/qqmlexpression.cpp +++ b/src/qml/qml/qqmlexpression.cpp @@ -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. diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 32114254e8..2e25186f5c 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -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()) { diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index 85a391fd98..3918dc1cae 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -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(); diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 1f21b21aad..59fae5fcbd 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -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(); diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 27f31b3eb4..8c57615d90 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -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())); } /*! diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index 2234d3d0ca..9ea17d8418 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -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()) diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index f8e8624496..1d3e427877 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -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; diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index 146816920a..1095f29a52 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -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) diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp index d09be1bb37..7613ba7ce6 100644 --- a/src/qml/types/qqmllistmodel.cpp +++ b/src/qml/types/qqmllistmodel.cpp @@ -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); } diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp index 580641a4d6..ef60754268 100644 --- a/src/qml/util/qqmladaptormodel.cpp +++ b/src/qml/util/qqmladaptormodel.cpp @@ -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(); } diff --git a/src/qmltest/quicktestresult.cpp b/src/qmltest/quicktestresult.cpp index e94986fff2..8b6a8e2f37 100644 --- a/src/qmltest/quicktestresult.cpp +++ b/src/qmltest/quicktestresult.cpp @@ -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: diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index a0fc283cf9..5cc57f9bba 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -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]); } diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index d4c39e9112..dd8c68859e 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -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); |