aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-05-30 15:42:44 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2013-05-30 16:44:25 +0200
commitacde568e10e3d60e02443762540461f35879fb77 (patch)
tree2a37fc2e44f2dbc788d54e511d744aff869677fc
parentca7ddc345ec4df017b7db6aee5a823f817e6e708 (diff)
Port the value type wrapper over to use V4
Change-Id: I0c566d0ab8cdd0ddbc688b7a1462c4b21084b30a Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
-rw-r--r--src/qml/qml/qml.pri2
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp396
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper_p.h (renamed from src/qml/qml/v8/qv8valuetypewrapper_p.h)64
-rw-r--r--src/qml/qml/v4/qv4managed_p.h5
-rw-r--r--src/qml/qml/v4/qv4value_p.h5
-rw-r--r--src/qml/qml/v8/qv8engine.cpp68
-rw-r--r--src/qml/qml/v8/qv8engine_p.h31
-rw-r--r--src/qml/qml/v8/qv8objectresource_p.h2
-rw-r--r--src/qml/qml/v8/qv8qobjectwrapper.cpp13
-rw-r--r--src/qml/qml/v8/qv8valuetypewrapper.cpp447
-rw-r--r--src/qml/qml/v8/v8.pri2
11 files changed, 483 insertions, 552 deletions
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 <private/qv8engine_p.h>
+
+#include <private/qqmlvaluetype_p.h>
+#include <private/qqmlbinding_p.h>
+#include <private/qqmlglobal_p.h>
+
+#include <private/qv4engine_p.h>
+#include <private/qv4functionobject_p.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QV4;
+
+DEFINE_MANAGED_VTABLE(QmlValueTypeWrapper);
+
+PersistentValue QmlValueTypeWrapper::proto;
+
+
+class QmlValueTypeReference : public QmlValueTypeWrapper
+{
+public:
+ QmlValueTypeReference(QV8Engine *engine);
+
+ QQmlGuard<QObject> 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<const QmlValueTypeReference *>(this);
+
+ if (reference->object && readReferenceValue(reference)) {
+ return reference->type->value();
+ } else {
+ return QVariant();
+ }
+ } else {
+ Q_ASSERT(objectType == QmlValueTypeWrapper::Copy);
+ return static_cast<const QmlValueTypeCopy *>(this)->value;
+ }
+}
+
+void QmlValueTypeWrapper::destroy(Managed *that)
+{
+ QmlValueTypeWrapper *w = that->asQmlValueTypeWrapper();
+ assert(w);
+ if (w->objectType == Reference)
+ static_cast<QmlValueTypeReference *>(w)->~QmlValueTypeReference();
+ else
+ static_cast<QmlValueTypeCopy *>(w)->~QmlValueTypeCopy();
+}
+
+//QVariant QV8ValueTypeWrapper::toVariant(v8::Handle<v8::Object> obj, int typeHint, bool *succeeded)
+//{
+// // NOTE: obj must not be an external resource object (ie, wrapper object)
+// // instead, it is a normal js object which one of the value-type providers
+// // may know how to convert to the given type.
+// return QQml_valueTypeProvider()->createVariantFromJsObject(typeHint, QQmlV4Handle(obj->v4Value()), m_engine, succeeded);
+//}
+
+bool QmlValueTypeWrapper::isEqual(const QVariant& value)
+{
+ if (objectType == QmlValueTypeWrapper::Reference) {
+ QmlValueTypeReference *reference = static_cast<QmlValueTypeReference *>(this);
+ if (reference->object && readReferenceValue(reference)) {
+ return reference->type->isEqual(value);
+ } else {
+ return false;
+ }
+ } else {
+ Q_ASSERT(objectType == QmlValueTypeWrapper::Copy);
+ QmlValueTypeCopy *copy = static_cast<QmlValueTypeCopy *>(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<QmlValueTypeReference *>(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<QmlValueTypeCopy *>(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<QmlValueTypeReference *>(r);
+
+ if (!reference->object || !readReferenceValue(reference))
+ return Value::undefinedValue();
+
+ } else {
+ Q_ASSERT(r->objectType == QmlValueTypeWrapper::Copy);
+
+ QmlValueTypeCopy *copy = static_cast<QmlValueTypeCopy *>(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<QmlValueTypeReference *>(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<QmlValueTypeCopy *>(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/v8/qv8valuetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h
index c6c87750fa..ca30d006f2 100644
--- a/src/qml/qml/v8/qv8valuetypewrapper_p.h
+++ b/src/qml/qml/qqmlvaluetypewrapper_p.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QV8VALUETYPEWRAPPER_P_H
-#define QV8VALUETYPEWRAPPER_P_H
+#ifndef QQMLVALUETYPEWRAPPER_P_H
+#define QQMLVALUETYPEWRAPPER_P_H
//
// W A R N I N G
@@ -54,55 +54,53 @@
//
#include <QtCore/qglobal.h>
-#include <QtQml/qqmllist.h>
#include <private/qtqmlglobal_p.h>
-#include <private/qv8_p.h>
-#include <private/qhashedstring_p.h>
#include <private/qv4value_p.h>
+#include <private/qv4object_p.h>
QT_BEGIN_NAMESPACE
-class QV8Engine;
-class QV8ObjectResource;
class QQmlValueType;
-class Q_QML_PRIVATE_EXPORT QV8ValueTypeWrapper
+class QV8Engine;
+
+namespace QV4 {
+
+struct Q_QML_EXPORT QmlValueTypeWrapper : Object
{
+protected:
+ enum ObjectType { Reference, Copy };
+ QmlValueTypeWrapper(QV8Engine *engine, ObjectType type);
+ ~QmlValueTypeWrapper();
+
public:
- QV8ValueTypeWrapper();
- ~QV8ValueTypeWrapper();
- void init(QV8Engine *);
- void destroy();
+ static Value create(QV8Engine *v8, QObject *, int, QQmlValueType *);
+ static Value create(QV8Engine *v8, const QVariant &, QQmlValueType *);
+
+ QVariant toVariant() const;
+ bool isEqual(const QVariant& value);
- v8::Handle<v8::Object> newValueType(QObject *, int, QQmlValueType *);
- v8::Handle<v8::Object> newValueType(const QVariant &, QQmlValueType *);
- bool isValueType(v8::Handle<v8::Object>) const;
+ 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);
- QVariant toVariant(v8::Handle<v8::Object>, int typeHint, bool *succeeded);
- QVariant toVariant(v8::Handle<v8::Object>);
- QVariant toVariant(QV8ObjectResource *);
+ static QV4::Value method_toString(SimpleCallContext *ctx);
- static bool isEqual(QV8ObjectResource *, const QVariant& value);
+ QV8Engine *v8;
+ ObjectType objectType;
+ mutable QQmlValueType *type;
private:
- static v8::Handle<v8::Value> ToStringGetter(v8::Handle<v8::String> property,
- const v8::AccessorInfo &info);
- static QV4::Value ToString(const v8::Arguments &args);
- static v8::Handle<v8::Value> Getter(v8::Handle<v8::String> property,
- const v8::AccessorInfo &info);
- static v8::Handle<v8::Value> Setter(v8::Handle<v8::String> property,
- v8::Handle<v8::Value> value,
- const v8::AccessorInfo &info);
-
- QV8Engine *m_engine;
- QV4::PersistentValue m_constructor;
- QV4::PersistentValue m_toString;
- QV4::PersistentValue m_toStringSymbol;
- QHashedV4String m_toStringString;
+ 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<QtObject *>(this) : 0; }
QmlContextWrapper *asQmlContext() { return type == Type_QmlContext ? reinterpret_cast<QmlContextWrapper *>(this) : 0; }
QmlTypeWrapper *asQmlTypeWrapper() { return type == Type_QmlTypeWrapper ? reinterpret_cast<QmlTypeWrapper *>(this) : 0; }
+ QmlValueTypeWrapper *asQmlValueTypeWrapper() { return type == Type_QmlValueTypeWrapper ? reinterpret_cast<QmlValueTypeWrapper *>(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 <private/qjsvalue_p.h>
#include <private/qqmltypewrapper_p.h>
#include <private/qqmlcontextwrapper_p.h>
+#include <private/qqmlvaluetypewrapper_p.h>
#include "qv4domerrors_p.h"
#include "qv4sqlerrors_p.h"
@@ -91,39 +91,22 @@ static bool ObjectComparisonCallback(v8::Handle<v8::Object> lhs, v8::Handle<v8::
if (lhs.IsEmpty() || rhs.IsEmpty())
return false;
- QV4::VariantObject *lv = lhs->v4Value().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<QV8ObjectResource*>(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<QV8ObjectResource*>(lhs->GetExternalResource());
- QV8ObjectResource *rhsr = static_cast<QV8ObjectResource*>(rhs->GetExternalResource());
-
- if (lhsr && rhsr) {
- Q_ASSERT(lhsr->engine == rhsr->engine);
- QV8ObjectResource::ResourceType lhst = lhsr->resourceType();
- QV8ObjectResource::ResourceType rhst = rhsr->resourceType();
-
- switch (lhst) {
- case QV8ObjectResource::ValueTypeType:
- // a value type might be equal to a variant or another value type
- if (rhst == QV8ObjectResource::ValueTypeType) {
- return lhsr->engine->valueTypeWrapper()->isEqual(lhsr, lhsr->engine->valueTypeWrapper()->toVariant(rhsr));
- } else if (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<QQmlListReference>()) {
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 <private/qv4sequenceobject_p.h>
#include "qv4jsonwrapper_p.h"
#include <private/qv4value_p.h>
@@ -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<v8::Object>::Cast(v8::Value::fromV4Value(value))) : false;
-}
-
-QVariant QV8Engine::toValueType(const QV4::Value &obj)
-{
- return obj.isObject() ? m_valueTypeWrapper.toVariant(v8::Handle<v8::Object>::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<v8::Value> actual, int conversionType)
}
}
} else if (actual->IsObject()) {
- v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::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<QVariant>())
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<v8::Value> actual, int conversionType)
}
}
- QV8ObjectResource *r = static_cast<QV8ObjectResource *>(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 <private/qqmlvaluetype_p.h>
-#include <private/qqmlbinding_p.h>
-#include <private/qqmlglobal_p.h>
-
-#include <private/qv4engine_p.h>
-#include <private/qv4functionobject_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QV8ValueTypeResource : public QV8ObjectResource
-{
- V8_RESOURCE_TYPE(ValueTypeType);
-
-public:
- enum ObjectType { Reference, Copy };
-
- QV8ValueTypeResource(QV8Engine *engine, ObjectType objectType);
-
- ObjectType objectType;
- QQmlValueType *type;
-};
-
-class QV8ValueTypeReferenceResource : public QV8ValueTypeResource
-{
-public:
- QV8ValueTypeReferenceResource(QV8Engine *engine);
-
- QQmlGuard<QObject> object;
- int property;
-};
-
-class QV8ValueTypeCopyResource : public QV8ValueTypeResource
-{
-public:
- QV8ValueTypeCopyResource(QV8Engine *engine);
-
- QVariant value;
-};
-
-QV8ValueTypeResource::QV8ValueTypeResource(QV8Engine *engine, ObjectType objectType)
-: QV8ObjectResource(engine), objectType(objectType)
-{
-}
-
-QV8ValueTypeReferenceResource::QV8ValueTypeReferenceResource(QV8Engine *engine)
-: QV8ValueTypeResource(engine, Reference)
-{
-}
-
-QV8ValueTypeCopyResource::QV8ValueTypeCopyResource(QV8Engine *engine)
-: QV8ValueTypeResource(engine, Copy)
-{
-}
-
-QV8ValueTypeWrapper::QV8ValueTypeWrapper()
-: m_engine(0)
-{
-}
-
-QV8ValueTypeWrapper::~QV8ValueTypeWrapper()
-{
-}
-
-void QV8ValueTypeWrapper::destroy()
-{
-}
-
-static quint32 toStringHash = -1;
-
-void QV8ValueTypeWrapper::init(QV8Engine *engine)
-{
- m_engine = engine;
- m_toString = v8::FunctionTemplate::New(ToString)->GetFunction()->v4Value();
- v8::Handle<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
- ft->InstanceTemplate()->SetNamedPropertyHandler(Getter, Setter);
- ft->InstanceTemplate()->SetHasExternalResource(true);
- ft->InstanceTemplate()->MarkAsUseUserObjectComparison();
- ft->InstanceTemplate()->SetAccessor(v8::String::New("toString"), ToStringGetter, 0,
- m_toString.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<v8::Object> QV8ValueTypeWrapper::newValueType(QObject *object, int property, QQmlValueType *type)
-{
- // XXX NewInstance() should be optimized
- v8::Handle<v8::Object> 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<v8::Object> QV8ValueTypeWrapper::newValueType(const QVariant &value, QQmlValueType *type)
-{
- // XXX NewInstance() should be optimized
- v8::Handle<v8::Object> 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<v8::Object> obj) const
-{
- QV8ValueTypeResource *r = v8_resource_cast<QV8ValueTypeResource>(obj);
- return (r != 0);
-}
-
-QVariant QV8ValueTypeWrapper::toVariant(v8::Handle<v8::Object> obj, int typeHint, bool *succeeded)
-{
- // NOTE: obj must not be an external resource object (ie, wrapper object)
- // instead, it is a normal js object which one of the value-type providers
- // may know how to convert to the given type.
- return QQml_valueTypeProvider()->createVariantFromJsObject(typeHint, QQmlV4Handle(obj->v4Value()), m_engine, succeeded);
-}
-
-QVariant QV8ValueTypeWrapper::toVariant(v8::Handle<v8::Object> obj)
-{
- QV8ValueTypeResource *r = v8_resource_cast<QV8ValueTypeResource>(obj);
- if (r) return toVariant(r);
- else return QVariant();
-}
-
-QVariant QV8ValueTypeWrapper::toVariant(QV8ObjectResource *r)
-{
- Q_ASSERT(r->resourceType() == QV8ObjectResource::ValueTypeType);
- QV8ValueTypeResource *resource = static_cast<QV8ValueTypeResource *>(r);
-
- if (resource->objectType == QV8ValueTypeResource::Reference) {
- QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(resource);
-
- if (reference->object && readReferenceValue(reference)) {
- return reference->type->value();
- } else {
- return QVariant();
- }
-
- } else {
- Q_ASSERT(resource->objectType == QV8ValueTypeResource::Copy);
-
- QV8ValueTypeCopyResource *copy = static_cast<QV8ValueTypeCopyResource *>(resource);
-
- return copy->value;
- }
-}
-
-bool QV8ValueTypeWrapper::isEqual(QV8ObjectResource *r, const QVariant& value)
-{
- Q_ASSERT(r->resourceType() == QV8ObjectResource::ValueTypeType);
- QV8ValueTypeResource *resource = static_cast<QV8ValueTypeResource *>(r);
-
- if (resource->objectType == QV8ValueTypeResource::Reference) {
- QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(resource);
- if (reference->object && readReferenceValue(reference)) {
- return reference->type->isEqual(value);
- } else {
- return false;
- }
- } else {
- Q_ASSERT(resource->objectType == QV8ValueTypeResource::Copy);
- QV8ValueTypeCopyResource *copy = static_cast<QV8ValueTypeCopyResource *>(resource);
- resource->type->setValue(copy->value);
- if (resource->type->isEqual(value))
- return true;
- return (value == copy->value);
- }
-}
-
-v8::Handle<v8::Value> QV8ValueTypeWrapper::ToStringGetter(v8::Handle<v8::String> property,
- const v8::AccessorInfo &info)
-{
- Q_UNUSED(property);
- return info.Data();
-}
-
-QV4::Value QV8ValueTypeWrapper::ToString(const v8::Arguments &args)
-{
- QV8ValueTypeResource *resource = v8_resource_cast<QV8ValueTypeResource>(args.This());
- if (resource) {
- if (resource->objectType == QV8ValueTypeResource::Reference) {
- QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(resource);
- if (reference->object && readReferenceValue(reference)) {
- return resource->engine->toString(resource->type->toString());
- } else {
- return QV4::Value::undefinedValue();
- }
- } else {
- Q_ASSERT(resource->objectType == QV8ValueTypeResource::Copy);
- QV8ValueTypeCopyResource *copy = static_cast<QV8ValueTypeCopyResource *>(resource);
- resource->type->setValue(copy->value);
- return resource->engine->toString(resource->type->toString());
- }
- } else {
- return QV4::Value::undefinedValue();
- }
-}
-
-v8::Handle<v8::Value> QV8ValueTypeWrapper::Getter(v8::Handle<v8::String> property,
- const v8::AccessorInfo &info)
-{
- QV8ValueTypeResource *r = v8_resource_cast<QV8ValueTypeResource>(info.This());
- if (!r) return v8::Handle<v8::Value>();
-
- 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<QV8ValueTypeReferenceResource *>(r);
-
- if (!reference->object || !readReferenceValue(reference))
- return v8::Handle<v8::Value>();
-
- } else {
- Q_ASSERT(r->objectType == QV8ValueTypeResource::Copy);
-
- QV8ValueTypeCopyResource *copy = static_cast<QV8ValueTypeCopyResource *>(r);
-
- r->type->setValue(copy->value);
- }
-
- QQmlPropertyData local;
- QQmlPropertyData *result = 0;
- {
- QQmlData *ddata = QQmlData::get(r->type, false);
- if (ddata && ddata->propertyCache)
- result = ddata->propertyCache->property(propertystring, 0, 0);
- else
- result = QQmlPropertyCache::property(r->engine->engine(), r->type,
- propertystring, 0, local);
- }
-
- if (!result)
- return v8::Handle<v8::Value>();
-
- if (result->isFunction()) {
- // calling a Q_INVOKABLE function of a value type
- QQmlContextData *context = r->engine->callingContext();
- return r->engine->qobjectWrapper()->getProperty(r->type, propertystring, context, QV8QObjectWrapper::IgnoreRevision);
- }
-
-#define VALUE_TYPE_LOAD(metatype, cpptype, constructor) \
- if (result->propType == metatype) { \
- cpptype v; \
- void *args[] = { &v, 0 }; \
- r->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args); \
- return constructor(v); \
- }
-
- // These four types are the most common used by the value type wrappers
- VALUE_TYPE_LOAD(QMetaType::QReal, qreal, 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<v8::Value> QV8ValueTypeWrapper::Setter(v8::Handle<v8::String> property,
- v8::Handle<v8::Value> value,
- const v8::AccessorInfo &info)
-{
- QV8ValueTypeResource *r = v8_resource_cast<QV8ValueTypeResource>(info.This());
- if (!r) return value;
-
- QByteArray propName = property->v4Value().toQString().toUtf8();
- if (r->objectType == QV8ValueTypeResource::Reference) {
- QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(r);
- QMetaProperty writebackProperty = reference->object->metaObject()->property(reference->property);
-
- if (!reference->object || !writebackProperty.isWritable() || !readReferenceValue(reference))
- return value;
-
- // we lookup the index after readReferenceValue() since it can change the reference->type.
- int index = r->type->metaObject()->indexOfProperty(propName.constData());
- if (index == -1)
- return value;
- QMetaProperty p = r->type->metaObject()->property(index);
-
- QQmlBinding *newBinding = 0;
-
- if (value->IsFunction()) {
- 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<v8::Function> function = v8::Handle<v8::Function>::Cast(value);
-
- QQmlPropertyData cacheData;
- cacheData.setFlags(QQmlPropertyData::IsWritable |
- QQmlPropertyData::IsValueTypeVirtual);
- cacheData.propType = reference->object->metaObject()->property(reference->property).userType();
- cacheData.coreIndex = reference->property;
- cacheData.valueTypeFlags = 0;
- cacheData.valueTypeCoreIndex = index;
- cacheData.valueTypePropType = p.userType();
-
- 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<QV8ValueTypeCopyResource *>(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/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 \