From acde568e10e3d60e02443762540461f35879fb77 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 30 May 2013 15:42:44 +0200 Subject: Port the value type wrapper over to use V4 Change-Id: I0c566d0ab8cdd0ddbc688b7a1462c4b21084b30a Reviewed-by: Simon Hausmann --- src/qml/qml/qml.pri | 2 + src/qml/qml/qqmlvaluetypewrapper.cpp | 396 +++++++++++++++++++++++++++++ src/qml/qml/qqmlvaluetypewrapper_p.h | 108 ++++++++ src/qml/qml/v4/qv4managed_p.h | 5 +- src/qml/qml/v4/qv4value_p.h | 5 + src/qml/qml/v8/qv8engine.cpp | 68 ++--- src/qml/qml/v8/qv8engine_p.h | 31 +-- src/qml/qml/v8/qv8objectresource_p.h | 2 +- src/qml/qml/v8/qv8qobjectwrapper.cpp | 13 +- src/qml/qml/v8/qv8valuetypewrapper.cpp | 447 --------------------------------- src/qml/qml/v8/qv8valuetypewrapper_p.h | 110 -------- src/qml/qml/v8/v8.pri | 2 - 12 files changed, 560 insertions(+), 629 deletions(-) create mode 100644 src/qml/qml/qqmlvaluetypewrapper.cpp create mode 100644 src/qml/qml/qqmlvaluetypewrapper_p.h delete mode 100644 src/qml/qml/v8/qv8valuetypewrapper.cpp delete mode 100644 src/qml/qml/v8/qv8valuetypewrapper_p.h (limited to 'src/qml/qml') diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri index ae73265ad7..bae783105d 100644 --- a/src/qml/qml/qml.pri +++ b/src/qml/qml/qml.pri @@ -53,6 +53,7 @@ SOURCES += \ $$PWD/qqmlbinding.cpp \ $$PWD/qqmlapplicationengine.cpp \ $$PWD/qqmlcontextwrapper.cpp \ + $$PWD/qqmlvaluetypewrapper.cpp \ $$PWD/qqmltypewrapper.cpp HEADERS += \ @@ -128,6 +129,7 @@ HEADERS += \ $$PWD/qqmlapplicationengine_p.h \ $$PWD/qqmlapplicationengine.h \ $$PWD/qqmlcontextwrapper_p.h \ + $$PWD/qqmlvaluetypewrapper_p.h \ $$PWD/qqmltypewrapper_p.h JS_CLASS_SOURCES += \ diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp new file mode 100644 index 0000000000..36b9994660 --- /dev/null +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -0,0 +1,396 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qqmlvaluetypewrapper_p.h" +#include + +#include +#include +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +using namespace QV4; + +DEFINE_MANAGED_VTABLE(QmlValueTypeWrapper); + +PersistentValue QmlValueTypeWrapper::proto; + + +class QmlValueTypeReference : public QmlValueTypeWrapper +{ +public: + QmlValueTypeReference(QV8Engine *engine); + + QQmlGuard object; + int property; +}; + +class QmlValueTypeCopy : public QmlValueTypeWrapper +{ +public: + QmlValueTypeCopy(QV8Engine *engine); + + QVariant value; +}; + +QmlValueTypeWrapper::QmlValueTypeWrapper(QV8Engine *engine, ObjectType objectType) + : Object(QV8Engine::getV4(engine)), objectType(objectType) +{ + v8 = engine; + Managed::type = Type_QmlValueTypeWrapper; + vtbl = &static_vtbl; +} + +QmlValueTypeWrapper::~QmlValueTypeWrapper() +{ +} + +QmlValueTypeReference::QmlValueTypeReference(QV8Engine *engine) +: QmlValueTypeWrapper(engine, Reference) +{ +} + +QmlValueTypeCopy::QmlValueTypeCopy(QV8Engine *engine) +: QmlValueTypeWrapper(engine, Copy) +{ +} + + +static bool readReferenceValue(const QmlValueTypeReference *reference) +{ + // A reference resource may be either a "true" reference (eg, to a QVector3D property) + // or a "variant" reference (eg, to a QVariant property which happens to contain a value-type). + QMetaProperty writebackProperty = reference->object->metaObject()->property(reference->property); + if (writebackProperty.userType() == QMetaType::QVariant) { + // variant-containing-value-type reference + QVariant variantReferenceValue; + reference->type->readVariantValue(reference->object, reference->property, &variantReferenceValue); + int variantReferenceType = variantReferenceValue.userType(); + if (variantReferenceType != reference->type->userType()) { + // This is a stale VariantReference. That is, the variant has been + // overwritten with a different type in the meantime. + // We need to modify this reference to the updated value type, if + // possible, or return false if it is not a value type. + if (QQmlValueTypeFactory::isValueType(variantReferenceType)) { + reference->type = QQmlValueTypeFactory::valueType(variantReferenceType); + if (!reference->type) { + return false; + } + } else { + return false; + } + } + reference->type->setValue(variantReferenceValue); + } else { + // value-type reference + reference->type->read(reference->object, reference->property); + } + return true; +} + +void QmlValueTypeWrapper::initProto(ExecutionEngine *v4) +{ + if (!proto.isEmpty()) + return; + + Object *o = v4->newObject(); + o->defineDefaultProperty(v4, QStringLiteral("toString"), method_toString); + proto = Value::fromObject(o); +} + +Value QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int property, QQmlValueType *type) +{ + ExecutionEngine *v4 = QV8Engine::getV4(v8); + initProto(v4); + + QmlValueTypeReference *r = new (v4->memoryManager) QmlValueTypeReference(v8); + r->prototype = proto.value().objectValue(); + r->type = type; r->object = object; r->property = property; + return Value::fromObject(r); +} + +Value QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value, QQmlValueType *type) +{ + ExecutionEngine *v4 = QV8Engine::getV4(v8); + initProto(v4); + + QmlValueTypeCopy *r = new (v4->memoryManager) QmlValueTypeCopy(v8); + r->prototype = proto.value().objectValue(); + r->type = type; r->value = value; + return Value::fromObject(r); +} + +QVariant QmlValueTypeWrapper::toVariant() const +{ + if (objectType == QmlValueTypeWrapper::Reference) { + const QmlValueTypeReference *reference = static_cast(this); + + if (reference->object && readReferenceValue(reference)) { + return reference->type->value(); + } else { + return QVariant(); + } + } else { + Q_ASSERT(objectType == QmlValueTypeWrapper::Copy); + return static_cast(this)->value; + } +} + +void QmlValueTypeWrapper::destroy(Managed *that) +{ + QmlValueTypeWrapper *w = that->asQmlValueTypeWrapper(); + assert(w); + if (w->objectType == Reference) + static_cast(w)->~QmlValueTypeReference(); + else + static_cast(w)->~QmlValueTypeCopy(); +} + +//QVariant QV8ValueTypeWrapper::toVariant(v8::Handle obj, int typeHint, bool *succeeded) +//{ +// // NOTE: obj must not be an external resource object (ie, wrapper object) +// // instead, it is a normal js object which one of the value-type providers +// // may know how to convert to the given type. +// return QQml_valueTypeProvider()->createVariantFromJsObject(typeHint, QQmlV4Handle(obj->v4Value()), m_engine, succeeded); +//} + +bool QmlValueTypeWrapper::isEqual(const QVariant& value) +{ + if (objectType == QmlValueTypeWrapper::Reference) { + QmlValueTypeReference *reference = static_cast(this); + if (reference->object && readReferenceValue(reference)) { + return reference->type->isEqual(value); + } else { + return false; + } + } else { + Q_ASSERT(objectType == QmlValueTypeWrapper::Copy); + QmlValueTypeCopy *copy = static_cast(this); + type->setValue(copy->value); + if (type->isEqual(value)) + return true; + return (value == copy->value); + } +} + +Value QmlValueTypeWrapper::method_toString(SimpleCallContext *ctx) +{ + Object *o = ctx->thisObject.asObject(); + if (!o) + ctx->throwTypeError(); + QmlValueTypeWrapper *w = o->asQmlValueTypeWrapper(); + if (!w) + ctx->throwTypeError(); + + if (w->objectType == QmlValueTypeWrapper::Reference) { + QmlValueTypeReference *reference = static_cast(w); + if (reference->object && readReferenceValue(reference)) { + return w->v8->toString(w->type->toString()); + } else { + return QV4::Value::undefinedValue(); + } + } else { + Q_ASSERT(w->objectType == QmlValueTypeWrapper::Copy); + QmlValueTypeCopy *copy = static_cast(w); + w->type->setValue(copy->value); + return w->v8->toString(w->type->toString()); + } +} + +Value QmlValueTypeWrapper::get(Managed *m, ExecutionContext *ctx, String *name, bool *hasProperty) +{ + QmlValueTypeWrapper *r = m->asQmlValueTypeWrapper(); + + if (!r) + ctx->throwTypeError(); + + QHashedV4String propertystring(Value::fromString(name)); + + // Note: readReferenceValue() can change the reference->type. + if (r->objectType == QmlValueTypeWrapper::Reference) { + QmlValueTypeReference *reference = static_cast(r); + + if (!reference->object || !readReferenceValue(reference)) + return Value::undefinedValue(); + + } else { + Q_ASSERT(r->objectType == QmlValueTypeWrapper::Copy); + + QmlValueTypeCopy *copy = static_cast(r); + + r->type->setValue(copy->value); + } + + QQmlPropertyData local; + QQmlPropertyData *result = 0; + { + QQmlData *ddata = QQmlData::get(r->type, false); + if (ddata && ddata->propertyCache) + result = ddata->propertyCache->property(propertystring, 0, 0); + else + result = QQmlPropertyCache::property(r->v8->engine(), r->type, propertystring, 0, local); + } + + if (!result) + return Value::undefinedValue(); + + if (result->isFunction()) { + // calling a Q_INVOKABLE function of a value type + QQmlContextData *context = r->v8->callingContext(); + return r->v8->qobjectWrapper()->getProperty(r->type, propertystring, context, QV8QObjectWrapper::IgnoreRevision)->v4Value(); + } + +#define VALUE_TYPE_LOAD(metatype, cpptype, constructor) \ + if (result->propType == metatype) { \ + cpptype v; \ + void *args[] = { &v, 0 }; \ + r->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args); \ + return constructor(v); \ + } + + // These four types are the most common used by the value type wrappers + VALUE_TYPE_LOAD(QMetaType::QReal, qreal, QV4::Value::fromDouble); + VALUE_TYPE_LOAD(QMetaType::Int, int, QV4::Value::fromInt32); + VALUE_TYPE_LOAD(QMetaType::QString, QString, r->v8->toString); + VALUE_TYPE_LOAD(QMetaType::Bool, bool, QV4::Value::fromBoolean); + + QVariant v(result->propType, (void *)0); + void *args[] = { v.data(), 0 }; + r->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args); + return r->v8->fromVariant(v); +#undef VALUE_TYPE_ACCESSOR +} + +void QmlValueTypeWrapper::put(Managed *m, ExecutionContext *ctx, String *name, const Value &value) +{ + QmlValueTypeWrapper *r = m->asQmlValueTypeWrapper(); + if (!r) + ctx->throwTypeError(); + + QByteArray propName = name->toQString().toUtf8(); + if (r->objectType == QmlValueTypeWrapper::Reference) { + QmlValueTypeReference *reference = static_cast(r); + QMetaProperty writebackProperty = reference->object->metaObject()->property(reference->property); + + if (!reference->object || !writebackProperty.isWritable() || !readReferenceValue(reference)) + return; + + // we lookup the index after readReferenceValue() since it can change the reference->type. + int index = r->type->metaObject()->indexOfProperty(propName.constData()); + if (index == -1) + return; + QMetaProperty p = r->type->metaObject()->property(index); + + QQmlBinding *newBinding = 0; + + QV4::FunctionObject *f = value.asFunctionObject(); + if (f) { + if (!f->bindingKeyFlag) { + // assigning a JS function to a non-var-property is not allowed. + QString error = QLatin1String("Cannot assign JavaScript function to value-type property"); + ctx->throwError(r->v8->toString(error)); + } + + QQmlContextData *context = r->v8->callingContext(); + + QQmlPropertyData cacheData; + cacheData.setFlags(QQmlPropertyData::IsWritable | + QQmlPropertyData::IsValueTypeVirtual); + cacheData.propType = reference->object->metaObject()->property(reference->property).userType(); + cacheData.coreIndex = reference->property; + cacheData.valueTypeFlags = 0; + cacheData.valueTypeCoreIndex = index; + cacheData.valueTypePropType = p.userType(); + + QV4::ExecutionEngine *v4 = ctx->engine; + QV4::ExecutionEngine::StackFrame frame = v4->currentStackFrame(); + + newBinding = new QQmlBinding(value, reference->object, context, + frame.source, qmlSourceCoordinate(frame.line), qmlSourceCoordinate(frame.column)); + newBinding->setTarget(reference->object, cacheData, context); + newBinding->setEvaluateFlags(newBinding->evaluateFlags() | + QQmlBinding::RequiresThisObject); + } + + QQmlAbstractBinding *oldBinding = + QQmlPropertyPrivate::setBinding(reference->object, reference->property, index, newBinding); + if (oldBinding) + oldBinding->destroy(); + + if (!f) { + QVariant v = r->v8->toVariant(value, -1); + + if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double) + v = v.toInt(); + + p.write(reference->type, v); + + if (writebackProperty.userType() == QMetaType::QVariant) { + QVariant variantReferenceValue = r->type->value(); + reference->type->writeVariantValue(reference->object, reference->property, 0, &variantReferenceValue); + } else { + reference->type->write(reference->object, reference->property, 0); + } + } + + } else { + Q_ASSERT(r->objectType == QmlValueTypeWrapper::Copy); + + QmlValueTypeCopy *copy = static_cast(r); + + int index = r->type->metaObject()->indexOfProperty(propName.constData()); + if (index == -1) + return; + + QVariant v = r->v8->toVariant(value, -1); + + r->type->setValue(copy->value); + QMetaProperty p = r->type->metaObject()->property(index); + p.write(r->type, v); + copy->value = r->type->value(); + } +} + +QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h new file mode 100644 index 0000000000..ca30d006f2 --- /dev/null +++ b/src/qml/qml/qqmlvaluetypewrapper_p.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQMLVALUETYPEWRAPPER_P_H +#define QQMLVALUETYPEWRAPPER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +class QQmlValueType; +class QV8Engine; + +namespace QV4 { + +struct Q_QML_EXPORT QmlValueTypeWrapper : Object +{ +protected: + enum ObjectType { Reference, Copy }; + QmlValueTypeWrapper(QV8Engine *engine, ObjectType type); + ~QmlValueTypeWrapper(); + +public: + + static Value create(QV8Engine *v8, QObject *, int, QQmlValueType *); + static Value create(QV8Engine *v8, const QVariant &, QQmlValueType *); + + QVariant toVariant() const; + bool isEqual(const QVariant& value); + + + static Value get(Managed *m, ExecutionContext *ctx, String *name, bool *hasProperty); + static void put(Managed *m, ExecutionContext *ctx, String *name, const Value &value); + static void destroy(Managed *that); + + static QV4::Value method_toString(SimpleCallContext *ctx); + + QV8Engine *v8; + ObjectType objectType; + mutable QQmlValueType *type; + +private: + const static ManagedVTable static_vtbl; + + static void initProto(ExecutionEngine *v4); + static PersistentValue proto; +}; + +} + +QT_END_NAMESPACE + +#endif // QV8VALUETYPEWRAPPER_P_H + + diff --git a/src/qml/qml/v4/qv4managed_p.h b/src/qml/qml/v4/qv4managed_p.h index fdcbcd49ce..d4239ee915 100644 --- a/src/qml/qml/v4/qv4managed_p.h +++ b/src/qml/qml/v4/qv4managed_p.h @@ -83,6 +83,7 @@ struct QObjectWrapper; struct QtObject; struct QmlContextWrapper; struct QmlTypeWrapper; +struct QmlValueTypeWrapper; struct ManagedVTable { @@ -188,7 +189,8 @@ public: // Qt Object Type_QtObject, Type_QmlContext, - Type_QmlTypeWrapper + Type_QmlTypeWrapper, + Type_QmlValueTypeWrapper }; ExecutionEngine *engine() const; @@ -224,6 +226,7 @@ public: QtObject *asQtObject() { return type == Type_QtObject ? reinterpret_cast(this) : 0; } QmlContextWrapper *asQmlContext() { return type == Type_QmlContext ? reinterpret_cast(this) : 0; } QmlTypeWrapper *asQmlTypeWrapper() { return type == Type_QmlTypeWrapper ? reinterpret_cast(this) : 0; } + QmlValueTypeWrapper *asQmlValueTypeWrapper() { return type == Type_QmlValueTypeWrapper ? reinterpret_cast(this) : 0; } bool isListType() const { return type >= Type_QmlIntList && type <= Type_QmlUrlList; } diff --git a/src/qml/qml/v4/qv4value_p.h b/src/qml/qml/v4/qv4value_p.h index cc0f1c2ea7..9914467c39 100644 --- a/src/qml/qml/v4/qv4value_p.h +++ b/src/qml/qml/v4/qv4value_p.h @@ -271,6 +271,7 @@ struct Q_QML_EXPORT Value ErrorObject *asErrorObject() const; VariantObject *asVariantObject() const; QObjectWrapper *asQObjectWrapper() const; + QmlValueTypeWrapper *asQmlValueType() const; uint asArrayIndex() const; uint asArrayLength(bool *ok) const; @@ -553,6 +554,10 @@ inline QObjectWrapper *Value::asQObjectWrapper() const return isObject() ? managed()->asQObjectWrapper() : 0; } +inline QmlValueTypeWrapper *Value::asQmlValueType() const +{ + return isObject() ? managed()->asQmlValueTypeWrapper() : 0; +} // ### inline Value Managed::construct(ExecutionContext *context, Value *args, int argc) { return vtbl->construct(this, context, args, argc); diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index b359ff0d48..2111e87fc9 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -41,7 +41,6 @@ #include "qv8engine_p.h" -#include "qv8valuetypewrapper_p.h" #include "qv4sequenceobject_p.h" #include "qjsengine_p.h" @@ -56,6 +55,7 @@ #include #include #include +#include #include "qv4domerrors_p.h" #include "qv4sqlerrors_p.h" @@ -91,39 +91,22 @@ static bool ObjectComparisonCallback(v8::Handle lhs, v8::Handlev4Value().asVariantObject(); - if (lv) { - QV4::VariantObject *rv = rhs->v4Value().asVariantObject(); - if (rv) + if (QV4::VariantObject *lv = lhs->v4Value().asVariantObject()) { + if (QV4::VariantObject *rv = rhs->v4Value().asVariantObject()) return lv->data == rv->data; - QV8ObjectResource *rhsr = static_cast(rhs->GetExternalResource()); - if (rhsr->resourceType() == QV8ObjectResource::ValueTypeType) - return rhsr->engine->valueTypeWrapper()->isEqual(rhsr, lv->data); + if (QV4::QmlValueTypeWrapper *v = rhs->v4Value().asQmlValueType()) + return v->isEqual(lv->data); return false; } - QV8ObjectResource *lhsr = static_cast(lhs->GetExternalResource()); - QV8ObjectResource *rhsr = static_cast(rhs->GetExternalResource()); - - if (lhsr && rhsr) { - Q_ASSERT(lhsr->engine == rhsr->engine); - QV8ObjectResource::ResourceType lhst = lhsr->resourceType(); - QV8ObjectResource::ResourceType rhst = rhsr->resourceType(); - - switch (lhst) { - case QV8ObjectResource::ValueTypeType: - // a value type might be equal to a variant or another value type - if (rhst == QV8ObjectResource::ValueTypeType) { - return lhsr->engine->valueTypeWrapper()->isEqual(lhsr, lhsr->engine->valueTypeWrapper()->toVariant(rhsr)); - } else if (QV4::VariantObject *rv = rhs->v4Value().asVariantObject()) { - return lhsr->engine->valueTypeWrapper()->isEqual(lhsr, rv->data); - } - break; - default: - break; - } + if (QV4::QmlValueTypeWrapper *lv = rhs->v4Value().asQmlValueType()) { + if (QV4::VariantObject *rv = rhs->v4Value().asVariantObject()) + return lv->isEqual(rv->data); + + if (QV4::QmlValueTypeWrapper *v = rhs->v4Value().asQmlValueType()) + return lv->isEqual(v->toVariant()); } return false; @@ -154,7 +137,6 @@ QV8Engine::QV8Engine(QJSEngine* qq) m_qobjectWrapper.init(this); m_listWrapper.init(this); - m_valueTypeWrapper.init(this); m_jsonWrapper.init(m_v4Engine); } @@ -171,7 +153,6 @@ QV8Engine::~QV8Engine() m_listModelData = 0; m_jsonWrapper.destroy(); - m_valueTypeWrapper.destroy(); m_listWrapper.destroy(); m_qobjectWrapper.destroy(); @@ -214,8 +195,6 @@ QVariant QV8Engine::toVariant(const QV4::Value &value, int typeHint) return QVariant(); case QV8ObjectResource::ListType: return m_listWrapper.toVariant(r); - case QV8ObjectResource::ValueTypeType: - return m_valueTypeWrapper.toVariant(r); } } else if (typeHint == QMetaType::QJsonObject && !value.asArrayObject() && !value.asFunctionObject()) { @@ -226,6 +205,8 @@ QVariant QV8Engine::toVariant(const QV4::Value &value, int typeHint) return QVariant(); } else if (QV4::QmlTypeWrapper *w = object->asQmlTypeWrapper()) { return w->toVariant(); + } else if (QV4::QmlValueTypeWrapper *v = object->asQmlValueTypeWrapper()) { + return v->toVariant(); } else if (object->isListType()) return QV4::SequencePrototype::toVariant(object); } @@ -364,7 +345,7 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant) } if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(type)) - return m_valueTypeWrapper.newValueType(variant, vt)->v4Value(); + return QV4::QmlValueTypeWrapper::create(this, variant, vt); } else { if (type == qMetaTypeId()) { typedef QQmlListReferencePrivate QDLRP; @@ -400,7 +381,7 @@ QV4::Value QV8Engine::fromVariant(const QVariant &variant) return retn->v4Value(); if (QQmlValueType *vt = QQmlValueTypeFactory::valueType(type)) - return m_valueTypeWrapper.newValueType(variant, vt)->v4Value(); + return QV4::QmlValueTypeWrapper::create(this, variant, vt); } // XXX TODO: To be compatible, we still need to handle: @@ -1286,6 +1267,25 @@ QV4::Value QV8Engine::toString(const QString &string) return QV4::Value::fromString(m_v4Engine->newString(string)); } +QV4::Value QV8Engine::newValueType(QObject *object, int property, QQmlValueType *type) +{ + return QV4::QmlValueTypeWrapper::create(this, object, property, type); +} + +QV4::Value QV8Engine::newValueType(const QVariant &value, QQmlValueType *type) +{ + return QV4::QmlValueTypeWrapper::create(this, value, type); +} + +bool QV8Engine::isValueType(const QV4::Value &value) const +{ + return value.isObject() ? value.objectValue()->asQmlValueTypeWrapper() : 0; +} + +QVariant QV8Engine::toValueType(const QV4::Value &obj) +{ + return obj.isObject() ? obj.objectValue()->asQmlValueTypeWrapper()->toVariant() : QVariant(); +} QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index 2981e4ce57..3b3ed9472e 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -73,7 +73,6 @@ #include "qv8objectresource_p.h" #include "qv8qobjectwrapper_p.h" #include "qv8listwrapper_p.h" -#include "qv8valuetypewrapper_p.h" #include #include "qv4jsonwrapper_p.h" #include @@ -274,7 +273,6 @@ public: QV8QObjectWrapper *qobjectWrapper() { return &m_qobjectWrapper; } QV8ListWrapper *listWrapper() { return &m_listWrapper; } - QV8ValueTypeWrapper *valueTypeWrapper() { return &m_valueTypeWrapper; } void *xmlHttpRequestData() { return m_xmlHttpRequestData; } @@ -299,10 +297,10 @@ public: QV4::Value toString(const QString &string); // Create a new value type object - inline QV4::Value newValueType(QObject *, int coreIndex, QQmlValueType *); - inline QV4::Value newValueType(const QVariant &, QQmlValueType *); - inline bool isValueType(const QV4::Value &value) const; - inline QVariant toValueType(const QV4::Value &obj); + QV4::Value newValueType(QObject *, int coreIndex, QQmlValueType *); + QV4::Value newValueType(const QVariant &, QQmlValueType *); + bool isValueType(const QV4::Value &value) const; + QVariant toValueType(const QV4::Value &obj); // Create a new sequence type object inline QV4::Value newSequence(int sequenceType, QObject *, int coreIndex, bool *succeeded); @@ -391,7 +389,6 @@ protected: QV8QObjectWrapper m_qobjectWrapper; QV8ListWrapper m_listWrapper; - QV8ValueTypeWrapper m_valueTypeWrapper; QV4JsonWrapper m_jsonWrapper; QV4::PersistentValue m_freezeObject; @@ -451,26 +448,6 @@ QV4::Value QV8Engine::newQObject(QObject *object, const ObjectOwnership ownershi return result; } -QV4::Value QV8Engine::newValueType(QObject *object, int property, QQmlValueType *type) -{ - return m_valueTypeWrapper.newValueType(object, property, type)->v4Value(); -} - -QV4::Value QV8Engine::newValueType(const QVariant &value, QQmlValueType *type) -{ - return m_valueTypeWrapper.newValueType(value, type)->v4Value(); -} - -bool QV8Engine::isValueType(const QV4::Value &value) const -{ - return value.isObject() ? m_valueTypeWrapper.isValueType(v8::Handle::Cast(v8::Value::fromV4Value(value))) : false; -} - -QVariant QV8Engine::toValueType(const QV4::Value &obj) -{ - return obj.isObject() ? m_valueTypeWrapper.toVariant(v8::Handle::Cast(v8::Value::fromV4Value(obj))) : QVariant(); -} - QV4::Value QV8Engine::newSequence(int sequenceType, QObject *object, int property, bool *succeeded) { return QV4::SequencePrototype::newSequence(m_v4Engine, sequenceType, object, property, succeeded); diff --git a/src/qml/qml/v8/qv8objectresource_p.h b/src/qml/qml/v8/qv8objectresource_p.h index d6471188bb..019178b0df 100644 --- a/src/qml/qml/v8/qv8objectresource_p.h +++ b/src/qml/qml/v8/qv8objectresource_p.h @@ -70,7 +70,7 @@ class QV8ObjectResource : public v8::Object::ExternalResource public: QV8ObjectResource(QV8Engine *engine) : engine(engine) { Q_ASSERT(engine); } enum ResourceType { ListType, - ValueTypeType, XMLHttpRequestType, DOMNodeType, SQLDatabaseType, + XMLHttpRequestType, DOMNodeType, SQLDatabaseType, ListModelType, Context2DStyleType, Context2DPixelArrayType, ParticleDataType, SignalHandlerType, IncubatorType, VisualDataItemType, ChangeSetArrayType }; diff --git a/src/qml/qml/v8/qv8qobjectwrapper.cpp b/src/qml/qml/v8/qv8qobjectwrapper.cpp index 2329bcfc63..79f221e8bc 100644 --- a/src/qml/qml/v8/qv8qobjectwrapper.cpp +++ b/src/qml/qml/v8/qv8qobjectwrapper.cpp @@ -1412,19 +1412,19 @@ static int MatchScore(v8::Handle actual, int conversionType) } } } else if (actual->IsObject()) { - v8::Handle obj = v8::Handle::Cast(actual); + QV4::Object *obj = actual->v4Value().asObject(); + QV8Engine *engine = obj->engine()->publicEngine->handle(); - if (QV4::VariantObject *v = obj->v4Value().asVariantObject()) { + if (QV4::VariantObject *v = obj->asVariantObject()) { if (conversionType == qMetaTypeId()) return 0; - QV8Engine *engine = v->engine()->publicEngine->handle(); if (engine->toVariant(actual->v4Value(), -1).userType() == conversionType) return 0; else return 10; } - if (obj->v4Value().asQObjectWrapper()) { + if (obj->asQObjectWrapper()) { switch (conversionType) { case QMetaType::QObjectStar: return 0; @@ -1433,9 +1433,8 @@ static int MatchScore(v8::Handle actual, int conversionType) } } - QV8ObjectResource *r = static_cast(obj->GetExternalResource()); - if (r && r->resourceType() == QV8ObjectResource::ValueTypeType) { - if (r->engine->toVariant(actual->v4Value(), -1).userType() == conversionType) + if (QV4::QmlValueTypeWrapper *w = obj->asQmlValueTypeWrapper()) { + if (engine->toVariant(actual->v4Value(), -1).userType() == conversionType) return 0; return 10; } else if (conversionType == QMetaType::QJsonObject) { diff --git a/src/qml/qml/v8/qv8valuetypewrapper.cpp b/src/qml/qml/v8/qv8valuetypewrapper.cpp deleted file mode 100644 index c51be06d1f..0000000000 --- a/src/qml/qml/v8/qv8valuetypewrapper.cpp +++ /dev/null @@ -1,447 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv8valuetypewrapper_p.h" -#include "qv8engine_p.h" - -#include -#include -#include - -#include -#include - -QT_BEGIN_NAMESPACE - -class QV8ValueTypeResource : public QV8ObjectResource -{ - V8_RESOURCE_TYPE(ValueTypeType); - -public: - enum ObjectType { Reference, Copy }; - - QV8ValueTypeResource(QV8Engine *engine, ObjectType objectType); - - ObjectType objectType; - QQmlValueType *type; -}; - -class QV8ValueTypeReferenceResource : public QV8ValueTypeResource -{ -public: - QV8ValueTypeReferenceResource(QV8Engine *engine); - - QQmlGuard object; - int property; -}; - -class QV8ValueTypeCopyResource : public QV8ValueTypeResource -{ -public: - QV8ValueTypeCopyResource(QV8Engine *engine); - - QVariant value; -}; - -QV8ValueTypeResource::QV8ValueTypeResource(QV8Engine *engine, ObjectType objectType) -: QV8ObjectResource(engine), objectType(objectType) -{ -} - -QV8ValueTypeReferenceResource::QV8ValueTypeReferenceResource(QV8Engine *engine) -: QV8ValueTypeResource(engine, Reference) -{ -} - -QV8ValueTypeCopyResource::QV8ValueTypeCopyResource(QV8Engine *engine) -: QV8ValueTypeResource(engine, Copy) -{ -} - -QV8ValueTypeWrapper::QV8ValueTypeWrapper() -: m_engine(0) -{ -} - -QV8ValueTypeWrapper::~QV8ValueTypeWrapper() -{ -} - -void QV8ValueTypeWrapper::destroy() -{ -} - -static quint32 toStringHash = -1; - -void QV8ValueTypeWrapper::init(QV8Engine *engine) -{ - m_engine = engine; - m_toString = v8::FunctionTemplate::New(ToString)->GetFunction()->v4Value(); - v8::Handle ft = v8::FunctionTemplate::New(); - ft->InstanceTemplate()->SetNamedPropertyHandler(Getter, Setter); - ft->InstanceTemplate()->SetHasExternalResource(true); - ft->InstanceTemplate()->MarkAsUseUserObjectComparison(); - ft->InstanceTemplate()->SetAccessor(v8::String::New("toString"), ToStringGetter, 0, - m_toString.value(), v8::DEFAULT, - v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete)); - m_constructor = ft->GetFunction()->v4Value(); - - m_toStringSymbol = QV4::Value::fromString(QV8Engine::getV4(engine)->newIdentifier(QStringLiteral("toString"))); - m_toStringString = QHashedV4String(m_toStringSymbol.value()); - toStringHash = m_toStringString.hash(); -} - -v8::Handle QV8ValueTypeWrapper::newValueType(QObject *object, int property, QQmlValueType *type) -{ - // XXX NewInstance() should be optimized - v8::Handle rv = m_constructor.value().asFunctionObject()->newInstance(); - QV8ValueTypeReferenceResource *r = new QV8ValueTypeReferenceResource(m_engine); - r->type = type; r->object = object; r->property = property; - rv->SetExternalResource(r); - return rv; -} - -v8::Handle QV8ValueTypeWrapper::newValueType(const QVariant &value, QQmlValueType *type) -{ - // XXX NewInstance() should be optimized - v8::Handle rv = m_constructor.value().asFunctionObject()->newInstance(); - QV8ValueTypeCopyResource *r = new QV8ValueTypeCopyResource(m_engine); - r->type = type; r->value = value; - rv->SetExternalResource(r); - return rv; -} - -static bool readReferenceValue(QV8ValueTypeReferenceResource *reference) -{ - // A reference resource may be either a "true" reference (eg, to a QVector3D property) - // or a "variant" reference (eg, to a QVariant property which happens to contain a value-type). - QMetaProperty writebackProperty = reference->object->metaObject()->property(reference->property); - if (writebackProperty.userType() == QMetaType::QVariant) { - // variant-containing-value-type reference - QVariant variantReferenceValue; - reference->type->readVariantValue(reference->object, reference->property, &variantReferenceValue); - int variantReferenceType = variantReferenceValue.userType(); - if (variantReferenceType != reference->type->userType()) { - // This is a stale VariantReference. That is, the variant has been - // overwritten with a different type in the meantime. - // We need to modify this reference to the updated value type, if - // possible, or return false if it is not a value type. - if (QQmlValueTypeFactory::isValueType(variantReferenceType)) { - reference->type = QQmlValueTypeFactory::valueType(variantReferenceType); - if (!reference->type) { - return false; - } - } else { - return false; - } - } - reference->type->setValue(variantReferenceValue); - } else { - // value-type reference - reference->type->read(reference->object, reference->property); - } - return true; -} - -bool QV8ValueTypeWrapper::isValueType(v8::Handle obj) const -{ - QV8ValueTypeResource *r = v8_resource_cast(obj); - return (r != 0); -} - -QVariant QV8ValueTypeWrapper::toVariant(v8::Handle obj, int typeHint, bool *succeeded) -{ - // NOTE: obj must not be an external resource object (ie, wrapper object) - // instead, it is a normal js object which one of the value-type providers - // may know how to convert to the given type. - return QQml_valueTypeProvider()->createVariantFromJsObject(typeHint, QQmlV4Handle(obj->v4Value()), m_engine, succeeded); -} - -QVariant QV8ValueTypeWrapper::toVariant(v8::Handle obj) -{ - QV8ValueTypeResource *r = v8_resource_cast(obj); - if (r) return toVariant(r); - else return QVariant(); -} - -QVariant QV8ValueTypeWrapper::toVariant(QV8ObjectResource *r) -{ - Q_ASSERT(r->resourceType() == QV8ObjectResource::ValueTypeType); - QV8ValueTypeResource *resource = static_cast(r); - - if (resource->objectType == QV8ValueTypeResource::Reference) { - QV8ValueTypeReferenceResource *reference = static_cast(resource); - - if (reference->object && readReferenceValue(reference)) { - return reference->type->value(); - } else { - return QVariant(); - } - - } else { - Q_ASSERT(resource->objectType == QV8ValueTypeResource::Copy); - - QV8ValueTypeCopyResource *copy = static_cast(resource); - - return copy->value; - } -} - -bool QV8ValueTypeWrapper::isEqual(QV8ObjectResource *r, const QVariant& value) -{ - Q_ASSERT(r->resourceType() == QV8ObjectResource::ValueTypeType); - QV8ValueTypeResource *resource = static_cast(r); - - if (resource->objectType == QV8ValueTypeResource::Reference) { - QV8ValueTypeReferenceResource *reference = static_cast(resource); - if (reference->object && readReferenceValue(reference)) { - return reference->type->isEqual(value); - } else { - return false; - } - } else { - Q_ASSERT(resource->objectType == QV8ValueTypeResource::Copy); - QV8ValueTypeCopyResource *copy = static_cast(resource); - resource->type->setValue(copy->value); - if (resource->type->isEqual(value)) - return true; - return (value == copy->value); - } -} - -v8::Handle QV8ValueTypeWrapper::ToStringGetter(v8::Handle property, - const v8::AccessorInfo &info) -{ - Q_UNUSED(property); - return info.Data(); -} - -QV4::Value QV8ValueTypeWrapper::ToString(const v8::Arguments &args) -{ - QV8ValueTypeResource *resource = v8_resource_cast(args.This()); - if (resource) { - if (resource->objectType == QV8ValueTypeResource::Reference) { - QV8ValueTypeReferenceResource *reference = static_cast(resource); - if (reference->object && readReferenceValue(reference)) { - return resource->engine->toString(resource->type->toString()); - } else { - return QV4::Value::undefinedValue(); - } - } else { - Q_ASSERT(resource->objectType == QV8ValueTypeResource::Copy); - QV8ValueTypeCopyResource *copy = static_cast(resource); - resource->type->setValue(copy->value); - return resource->engine->toString(resource->type->toString()); - } - } else { - return QV4::Value::undefinedValue(); - } -} - -v8::Handle QV8ValueTypeWrapper::Getter(v8::Handle property, - const v8::AccessorInfo &info) -{ - QV8ValueTypeResource *r = v8_resource_cast(info.This()); - if (!r) return v8::Handle(); - - QHashedV4String propertystring(property->v4Value()); - - { - // Comparing the hash first actually makes a measurable difference here, at least on x86 - quint32 hash = propertystring.hash(); - if (hash == toStringHash && - r->engine->valueTypeWrapper()->m_toStringString == propertystring) { - return r->engine->valueTypeWrapper()->m_toString.value(); - } - } - - // Note: readReferenceValue() can change the reference->type. - if (r->objectType == QV8ValueTypeResource::Reference) { - QV8ValueTypeReferenceResource *reference = static_cast(r); - - if (!reference->object || !readReferenceValue(reference)) - return v8::Handle(); - - } else { - Q_ASSERT(r->objectType == QV8ValueTypeResource::Copy); - - QV8ValueTypeCopyResource *copy = static_cast(r); - - r->type->setValue(copy->value); - } - - QQmlPropertyData local; - QQmlPropertyData *result = 0; - { - QQmlData *ddata = QQmlData::get(r->type, false); - if (ddata && ddata->propertyCache) - result = ddata->propertyCache->property(propertystring, 0, 0); - else - result = QQmlPropertyCache::property(r->engine->engine(), r->type, - propertystring, 0, local); - } - - if (!result) - return v8::Handle(); - - if (result->isFunction()) { - // calling a Q_INVOKABLE function of a value type - QQmlContextData *context = r->engine->callingContext(); - return r->engine->qobjectWrapper()->getProperty(r->type, propertystring, context, QV8QObjectWrapper::IgnoreRevision); - } - -#define VALUE_TYPE_LOAD(metatype, cpptype, constructor) \ - if (result->propType == metatype) { \ - cpptype v; \ - void *args[] = { &v, 0 }; \ - r->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args); \ - return constructor(v); \ - } - - // These four types are the most common used by the value type wrappers - VALUE_TYPE_LOAD(QMetaType::QReal, qreal, QV4::Value::fromDouble); - VALUE_TYPE_LOAD(QMetaType::Int, int, QV4::Value::fromInt32); - VALUE_TYPE_LOAD(QMetaType::QString, QString, r->engine->toString); - VALUE_TYPE_LOAD(QMetaType::Bool, bool, QV4::Value::fromBoolean); - - QVariant v(result->propType, (void *)0); - void *args[] = { v.data(), 0 }; - r->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args); - return r->engine->fromVariant(v); -#undef VALUE_TYPE_ACCESSOR -} - -v8::Handle QV8ValueTypeWrapper::Setter(v8::Handle property, - v8::Handle value, - const v8::AccessorInfo &info) -{ - QV8ValueTypeResource *r = v8_resource_cast(info.This()); - if (!r) return value; - - QByteArray propName = property->v4Value().toQString().toUtf8(); - if (r->objectType == QV8ValueTypeResource::Reference) { - QV8ValueTypeReferenceResource *reference = static_cast(r); - QMetaProperty writebackProperty = reference->object->metaObject()->property(reference->property); - - if (!reference->object || !writebackProperty.isWritable() || !readReferenceValue(reference)) - return value; - - // we lookup the index after readReferenceValue() since it can change the reference->type. - int index = r->type->metaObject()->indexOfProperty(propName.constData()); - if (index == -1) - return value; - QMetaProperty p = r->type->metaObject()->property(index); - - QQmlBinding *newBinding = 0; - - if (value->IsFunction()) { - QV4::FunctionObject *f = value->v4Value().asFunctionObject(); - if (f->bindingKeyFlag) { - // assigning a JS function to a non-var-property is not allowed. - QString error = QLatin1String("Cannot assign JavaScript function to value-type property"); - v8::ThrowException(v8::Exception::Error(r->engine->toString(error))); - return value; - } - - QQmlContextData *context = r->engine->callingContext(); - v8::Handle function = v8::Handle::Cast(value); - - QQmlPropertyData cacheData; - cacheData.setFlags(QQmlPropertyData::IsWritable | - QQmlPropertyData::IsValueTypeVirtual); - cacheData.propType = reference->object->metaObject()->property(reference->property).userType(); - cacheData.coreIndex = reference->property; - cacheData.valueTypeFlags = 0; - cacheData.valueTypeCoreIndex = index; - cacheData.valueTypePropType = p.userType(); - - QV4::ExecutionEngine *v4 = QV8Engine::getV4(r->engine); - QV4::ExecutionEngine::StackFrame frame = v4->currentStackFrame(); - - newBinding = new QQmlBinding(function->v4Value(), reference->object, context, - frame.source, qmlSourceCoordinate(frame.line), qmlSourceCoordinate(frame.column)); - newBinding->setTarget(reference->object, cacheData, context); - newBinding->setEvaluateFlags(newBinding->evaluateFlags() | - QQmlBinding::RequiresThisObject); - } - - QQmlAbstractBinding *oldBinding = - QQmlPropertyPrivate::setBinding(reference->object, reference->property, index, newBinding); - if (oldBinding) - oldBinding->destroy(); - - if (!value->IsFunction()) { - QVariant v = r->engine->toVariant(value->v4Value(), -1); - - if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double) - v = v.toInt(); - - p.write(reference->type, v); - - if (writebackProperty.userType() == QMetaType::QVariant) { - QVariant variantReferenceValue = r->type->value(); - reference->type->writeVariantValue(reference->object, reference->property, 0, &variantReferenceValue); - } else { - reference->type->write(reference->object, reference->property, 0); - } - } - - } else { - Q_ASSERT(r->objectType == QV8ValueTypeResource::Copy); - - QV8ValueTypeCopyResource *copy = static_cast(r); - - int index = r->type->metaObject()->indexOfProperty(propName.constData()); - if (index == -1) - return value; - - QVariant v = r->engine->toVariant(value->v4Value(), -1); - - r->type->setValue(copy->value); - QMetaProperty p = r->type->metaObject()->property(index); - p.write(r->type, v); - copy->value = r->type->value(); - } - - return value; -} - -QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qv8valuetypewrapper_p.h b/src/qml/qml/v8/qv8valuetypewrapper_p.h deleted file mode 100644 index c6c87750fa..0000000000 --- a/src/qml/qml/v8/qv8valuetypewrapper_p.h +++ /dev/null @@ -1,110 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV8VALUETYPEWRAPPER_P_H -#define QV8VALUETYPEWRAPPER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -class QV8Engine; -class QV8ObjectResource; -class QQmlValueType; -class Q_QML_PRIVATE_EXPORT QV8ValueTypeWrapper -{ -public: - QV8ValueTypeWrapper(); - ~QV8ValueTypeWrapper(); - - void init(QV8Engine *); - void destroy(); - - v8::Handle newValueType(QObject *, int, QQmlValueType *); - v8::Handle newValueType(const QVariant &, QQmlValueType *); - - bool isValueType(v8::Handle) const; - - QVariant toVariant(v8::Handle, int typeHint, bool *succeeded); - QVariant toVariant(v8::Handle); - QVariant toVariant(QV8ObjectResource *); - - static bool isEqual(QV8ObjectResource *, const QVariant& value); - -private: - static v8::Handle ToStringGetter(v8::Handle property, - const v8::AccessorInfo &info); - static QV4::Value ToString(const v8::Arguments &args); - static v8::Handle Getter(v8::Handle property, - const v8::AccessorInfo &info); - static v8::Handle Setter(v8::Handle property, - v8::Handle value, - const v8::AccessorInfo &info); - - QV8Engine *m_engine; - QV4::PersistentValue m_constructor; - QV4::PersistentValue m_toString; - QV4::PersistentValue m_toStringSymbol; - QHashedV4String m_toStringString; -}; - -QT_END_NAMESPACE - -#endif // QV8VALUETYPEWRAPPER_P_H - - diff --git a/src/qml/qml/v8/v8.pri b/src/qml/qml/v8/v8.pri index 072db48ad0..6748753bb1 100644 --- a/src/qml/qml/v8/v8.pri +++ b/src/qml/qml/v8/v8.pri @@ -7,7 +7,6 @@ HEADERS += \ $$PWD/qv8engine_p.h \ $$PWD/qv8qobjectwrapper_p.h \ $$PWD/qv8listwrapper_p.h \ - $$PWD/qv8valuetypewrapper_p.h \ $$PWD/qv4jsonwrapper_p.h \ $$PWD/qv4domerrors_p.h \ $$PWD/qv4sqlerrors_p.h \ @@ -18,7 +17,6 @@ SOURCES += \ $$PWD/qv8engine.cpp \ $$PWD/qv8qobjectwrapper.cpp \ $$PWD/qv8listwrapper.cpp \ - $$PWD/qv8valuetypewrapper.cpp \ $$PWD/qv4jsonwrapper.cpp \ $$PWD/qv4domerrors.cpp \ $$PWD/qv4sqlerrors.cpp \ -- cgit v1.2.3