Crash fix after QMetaType change.
authorJędrzej Nowacki <jedrzej.nowacki@nokia.com>
Mon, 5 Mar 2012 13:45:34 +0000 (14:45 +0100)
committerQt by Nokia <qt-info@nokia.com>
Tue, 13 Mar 2012 11:58:48 +0000 (12:58 +0100)
QMetaType::UnknownType was added so we can distinguish between "void"
and an unregistered type.

Change-Id: If8cee21b3f84bf129343dc457d10ab31a9bfc8b8
Reviewed-by: Kent Hansen <kent.hansen@nokia.com>
src/qml/qml/qqmlboundsignal.cpp
src/qml/qml/qqmlcompiler.cpp
src/qml/qml/qqmlproperty.cpp
src/qml/qml/v8/qv8engine.cpp
src/qml/qml/v8/qv8qobjectwrapper.cpp
tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp

index 02f4941..aa130d9 100644 (file)
@@ -226,14 +226,14 @@ QQmlBoundSignalParameters::QQmlBoundSignalParameters(const QMetaMethod &method,
             continue;
         }
 
-        QVariant::Type t = (QVariant::Type)QMetaType::type(type.constData());
+        int t = QMetaType::type(type.constData());
         if (QQmlMetaType::isQObject(t)) {
             types[ii] = QMetaType::QObjectStar;
             QMetaPropertyBuilder prop = mob.addProperty(name, "QObject*");
             prop.setWritable(false);
         } else {
             QByteArray propType = type;
-            if (t >= QVariant::UserType || t == QVariant::Invalid) {
+            if (t >= int(QVariant::UserType) || t == QMetaType::UnknownType || t == QMetaType::Void) {
                 QByteArray scope;
                 QByteArray name;
                 int scopeIdx = propType.lastIndexOf("::");
index a524c74..51343b6 100644 (file)
@@ -2920,7 +2920,8 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod
                 }
 
                 metaType = QMetaType::type(customTypeName);
-                Q_ASSERT(metaType != 0);
+                Q_ASSERT(metaType != QMetaType::UnknownType);
+                Q_ASSERT(metaType != QMetaType::Void);
             }
 
             if (p->type == Object::DynamicProperty::Var)
@@ -3293,10 +3294,11 @@ bool QQmlCompiler::compileAlias(QFastMetaBuilder &builder,
     if (typeName.endsWith('*'))
         flags |= QML_ALIAS_FLAG_PTR;
 
-    if (!type) {
+    if (type == QMetaType::UnknownType) {
         Q_ASSERT(!typeName.isEmpty());
         type = QMetaType::type(typeName);
-        Q_ASSERT(type != 0);
+        Q_ASSERT(type != QMetaType::UnknownType);
+        Q_ASSERT(type != QMetaType::Void);
     }
 
     QQmlVMEMetaData::AliasData aliasData = { idObject->idIndex, propIdx, flags };
index 86e1822..34d9d0a 100644 (file)
@@ -1147,7 +1147,7 @@ bool QQmlPropertyPrivate::writeEnumProperty(const QMetaProperty &prop, int idx,
                 return false;
         } else if (v.userType() != QVariant::Int && v.userType() != QVariant::UInt) {
             int enumMetaTypeId = QMetaType::type(QByteArray(menum.scope() + QByteArray("::") + menum.name()));
-            if ((enumMetaTypeId == 0) || (v.userType() != enumMetaTypeId) || !v.constData())
+            if ((enumMetaTypeId == QMetaType::UnknownType) || (v.userType() != enumMetaTypeId) || !v.constData())
                 return false;
             v = QVariant(*reinterpret_cast<const int *>(v.constData()));
         }
index e49bc62..ab3283f 100644 (file)
@@ -318,6 +318,7 @@ v8::Handle<v8::Value> QV8Engine::fromVariant(const QVariant &variant)
 
     if (type < QMetaType::User) {
         switch (QMetaType::Type(type)) {
+            case QMetaType::UnknownType:
             case QMetaType::Void:
                 return v8::Undefined();
             case QMetaType::Bool:
@@ -1117,6 +1118,7 @@ v8::Handle<v8::Value> QV8Engine::metaTypeToJS(int type, const void *data)
 
     // check if it's one of the types we know
     switch (QMetaType::Type(type)) {
+    case QMetaType::UnknownType:
     case QMetaType::Void:
         return v8::Undefined();
     case QMetaType::Bool:
index d61ca8b..61cfa24 100644 (file)
@@ -449,7 +449,7 @@ static v8::Handle<v8::Value> LoadProperty(QV8Engine *engine, QObject *object,
             return retn;
     }
 
-    if (property.propType == QVariant::Invalid) {
+    if (property.propType == QMetaType::UnknownType) {
         QMetaProperty p = object->metaObject()->property(property.coreIndex);
         qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property "
                  "'%s::%s'", p.typeName(), object->metaObject()->className(), p.name());
@@ -687,10 +687,14 @@ static inline void StoreProperty(QV8Engine *engine, QObject *object, QQmlPropert
             if (v.userType() == QVariant::Invalid) valueType = "null";
             else valueType = QMetaType::typeName(v.userType());
 
+            const char *targetTypeName = QMetaType::typeName(property->propType);
+            if (!targetTypeName)
+                targetTypeName = "an unregistered type";
+
             QString error = QLatin1String("Cannot assign ") +
                             QLatin1String(valueType) +
                             QLatin1String(" to ") +
-                            QLatin1String(QMetaType::typeName(property->propType));
+                            QLatin1String(targetTypeName);
             v8::ThrowException(v8::Exception::Error(engine->toString(error)));
         }
     }
@@ -1986,7 +1990,7 @@ void *CallArgument::dataPtr()
 void CallArgument::initAsType(int callType)
 {
     if (type != 0) { cleanup(); type = 0; }
-    if (callType == 0) return;
+    if (callType == QMetaType::UnknownType) return;
 
     if (callType == qMetaTypeId<QJSValue>()) {
         qjsValuePtr = new (&allocData) QJSValue();
@@ -2012,6 +2016,9 @@ void CallArgument::initAsType(int callType)
     } else if (callType == qMetaTypeId<QQmlV8Handle>()) {
         type = callType;
         handlePtr = new (&allocData) QQmlV8Handle;
+    } else if (callType == QMetaType::Void) {
+        type = -1;
+        qvariantPtr = new (&allocData) QVariant();
     } else {
         type = -1;
         qvariantPtr = new (&allocData) QVariant(callType, (void *)0);
@@ -2066,6 +2073,8 @@ void CallArgument::fromValue(int callType, QV8Engine *engine, v8::Handle<v8::Val
     } else if (callType == qMetaTypeId<QQmlV8Handle>()) {
         handlePtr = new (&allocData) QQmlV8Handle(QQmlV8Handle::fromHandle(value));
         type = callType;
+    } else if (callType == QMetaType::Void) {
+        *qvariantPtr = QVariant();
     } else {
         qvariantPtr = new (&allocData) QVariant();
         type = -1;
index 4389fe5..b475e99 100644 (file)
@@ -4613,7 +4613,7 @@ void tst_qqmlecmascript::sequenceConversionWrite()
         QVERIFY(seq != 0);
 
         // we haven't registered QList<QPoint> as a sequence type, so writing shouldn't work.
-        QString warningOne = qmlFile.toString() + QLatin1String(":16: Error: Cannot assign QVariantList to void");
+        QString warningOne = qmlFile.toString() + QLatin1String(":16: Error: Cannot assign QVariantList to an unregistered type");
         QTest::ignoreMessage(QtWarningMsg, warningOne.toAscii().constData());
 
         QMetaObject::invokeMethod(object, "performTest");