Support and use parameters in QQmlNotifierEndpoint.
[profile/ivi/qtdeclarative.git] / src / qml / qml / v4 / qv4bindings.cpp
index b875bcd..5bb993f 100644 (file)
@@ -46,6 +46,7 @@
 #include "qv4compiler_p.h"
 #include "qv4compiler_p_p.h"
 
+#include <private/qqmlglobal_p.h>
 #include <private/qqmlaccessors_p.h>
 #include <private/qqmlprofilerservice_p.h>
 #include <private/qqmlmetatype_p.h>
@@ -66,46 +67,45 @@ namespace {
 struct Register {
     typedef QQmlRegisterType Type;
 
-    void setUndefined() { dataType = UndefinedType; }
-    void setNull() { dataType = NullType; }
-    void setNaN() { setnumber(qSNaN()); }
-    bool isUndefined() const { return dataType == UndefinedType; }
+    inline void setUndefined() { dataType = UndefinedType; }
+    inline void setNull() { dataType = NullType; }
+    inline void setNaN() { setnumber(qSNaN()); }
+    inline bool isUndefined() const { return dataType == UndefinedType; }
 
-    void setQObject(QObject *o) { qobjectValue = o; dataType = QObjectStarType; }
-    QObject *getQObject() const { return qobjectValue; }
+    inline void setQObject(QObject *o) { qobjectValue = o; dataType = QObjectStarType; }
+    inline QObject *getQObject() const { return qobjectValue; }
 
-    void setnumber(double v) { numberValue = v; dataType = NumberType; }
-    double getnumber() const { return numberValue; }
-    double &getnumberref() { return numberValue; }
+    inline void setnumber(double v) { numberValue = v; dataType = NumberType; }
+    inline double getnumber() const { return numberValue; }
+    inline double &getnumberref() { return numberValue; }
 
-    void setfloat(float v) { floatValue = v; dataType = FloatType; }
-    float getfloat() const { return floatValue; }
-    float &getfloatref() { return floatValue; }
+    inline void setfloat(float v) { floatValue = v; dataType = FloatType; }
+    inline float getfloat() const { return floatValue; }
+    inline float &getfloatref() { return floatValue; }
 
-    void setint(int v) { intValue = v; dataType = IntType; }
-    int getint() const { return intValue; }
-    int &getintref() { return intValue; }
+    inline void setint(int v) { intValue = v; dataType = IntType; }
+    inline int getint() const { return intValue; }
+    inline int &getintref() { return intValue; }
 
-    void setbool(bool v) { boolValue = v; dataType = BoolType; }
-    bool getbool() const { return boolValue; }
-    bool &getboolref() { return boolValue; }
+    inline void setbool(bool v) { boolValue = v; dataType = BoolType; }
+    inline bool getbool() const { return boolValue; }
+    inline bool &getboolref() { return boolValue; }
 
-    QVariant *getvariantptr() { return (QVariant *)typeDataPtr(); }
-    QString *getstringptr() { return (QString *)typeDataPtr(); }
-    QUrl *geturlptr() { return (QUrl *)typeDataPtr(); }
-    QColor *getcolorptr() { return (QColor *)typeDataPtr(); }
-    const QVariant *getvariantptr() const { return (QVariant *)typeDataPtr(); }
-    const QString *getstringptr() const { return (QString *)typeDataPtr(); }
-    const QUrl *geturlptr() const { return (QUrl *)typeDataPtr(); }
-    const QColor *getcolorptr() const { return (QColor *)typeDataPtr(); }
+    inline QVariant *getvariantptr() { return (QVariant *)typeDataPtr(); }
+    inline QString *getstringptr() { return (QString *)typeDataPtr(); }
+    inline QUrl *geturlptr() { return (QUrl *)typeDataPtr(); }
+    inline const QVariant *getvariantptr() const { return (QVariant *)typeDataPtr(); }
+    inline const QString *getstringptr() const { return (QString *)typeDataPtr(); }
+    inline const QUrl *geturlptr() const { return (QUrl *)typeDataPtr(); }
 
-    void *typeDataPtr() { return (void *)&data; }
-    void *typeMemory() { return (void *)data; }
-    const void *typeDataPtr() const { return (void *)&data; }
-    const void *typeMemory() const { return (void *)data; }
+    size_t dataSize() { return sizeof(data); }
+    inline void *typeDataPtr() { return (void *)&data; }
+    inline void *typeMemory() { return (void *)data; }
+    inline const void *typeDataPtr() const { return (void *)&data; }
+    inline const void *typeMemory() const { return (void *)data; }
 
-    Type gettype() const { return dataType; }
-    void settype(Type t) { dataType = t; }
+    inline Type gettype() const { return dataType; }
+    inline void settype(Type t) { dataType = t; }
 
     Type dataType;     // Type of data
     union {
@@ -147,7 +147,7 @@ void Register::cleanup()
         } else if (dataType == QUrlType) {
             geturlptr()->~QUrl();
         } else if (dataType == QColorType) {
-            getcolorptr()->~QColor();
+            QQml_valueTypeProvider()->destroyValueType(QMetaType::QColor, typeDataPtr(), dataSize());
         } else if (dataType == QVariantType) {
             getvariantptr()->~QVariant();
         }
@@ -169,7 +169,7 @@ void Register::cleanupUrl()
 
 void Register::cleanupColor()
 {
-    getcolorptr()->~QColor();
+    QQml_valueTypeProvider()->destroyValueType(QMetaType::QColor, typeDataPtr(), dataSize());
     setUndefined();
 }
 
@@ -188,7 +188,7 @@ void Register::copy(const Register &other)
         else if (other.dataType == QUrlType)
             new (geturlptr()) QUrl(*other.geturlptr());
         else if (other.dataType == QColorType)
-            new (getcolorptr()) QColor(*other.getcolorptr());
+            QQml_valueTypeProvider()->copyValueType(QMetaType::QColor, other.typeDataPtr(), typeDataPtr(), dataSize());
         else if (other.dataType == QVariantType)
             new (getvariantptr()) QVariant(*other.getvariantptr());
     } 
@@ -203,7 +203,7 @@ void Register::init(Type type)
         else if (dataType == QUrlType)
             new (geturlptr()) QUrl();
         else if (dataType == QColorType)
-            new (getcolorptr()) QColor();
+            QQml_valueTypeProvider()->initValueType(QMetaType::QColor, typeDataPtr(), dataSize());
         else if (dataType == QVariantType)
             new (getvariantptr()) QVariant();
     }
@@ -288,7 +288,7 @@ QObject *QV4Bindings::Binding::object() const
     return target;
 }
 
-void QV4Bindings::Subscription::subscriptionCallback(QQmlNotifierEndpoint *e
+void QV4Bindings::Subscription::subscriptionCallback(QQmlNotifierEndpoint *e, void **)
 {
     Subscription *s = static_cast<Subscription *>(e);
     s->bindings->subscriptionNotify(s->method);
@@ -456,7 +456,7 @@ static void testBindingResult(const QString &binding, int line, int column,
     if (expression.hasError()) {
         iserror = true;
         qtscriptResult = "exception";
-    } else if (value.userType() != resultType) {
+    } else if ((value.userType() != resultType) && (resultType != QMetaType::QVariant)) {
         // Override the QMetaType conversions to make them more JS friendly.
         if (value.userType() == QMetaType::Double && (resultType == QMetaType::QString ||
                                                         resultType == QMetaType::QUrl)) {
@@ -506,6 +506,12 @@ static void testBindingResult(const QString &binding, int line, int column,
         case QMetaType::Double:
             v4value = result.getnumber();
             break;
+        case QMetaType::QColor:
+            v4value = QVariant(QMetaType::QColor, result.typeDataPtr());
+            break;
+        case QMetaType::QVariant:
+            v4value = *result.getvariantptr();
+            break;
         default:
             if (resultType == QQmlMetaType::QQuickAnchorLineMetaTypeId()) {
                 v4value = QVariant(QQmlMetaType::QQuickAnchorLineMetaTypeId(), result.typeDataPtr());
@@ -882,6 +888,19 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
     }
     QML_V4_END_INSTR(ConvertBoolToString, unaryop)
 
+    QML_V4_BEGIN_INSTR(ConvertBoolToVariant, unaryop)
+    {
+        const Register &src = registers[instr->unaryop.src];
+        Register &output = registers[instr->unaryop.output];
+        if (src.isUndefined()) {
+            output.setUndefined();
+        } else {
+            new (output.getvariantptr()) QVariant(src.getbool());
+            VARIANT_REGISTER(instr->unaryop.output);
+        }
+    }
+    QML_V4_END_INSTR(ConvertBoolToVariant, unaryop)
+
     QML_V4_BEGIN_INSTR(ConvertIntToBool, unaryop)
     {
         const Register &src = registers[instr->unaryop.src];
@@ -906,13 +925,26 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
         Register &output = registers[instr->unaryop.output];
         if (src.isUndefined()) {
             output.setUndefined();
-        } else { 
+        } else {
             new (output.getstringptr()) QString(QString::number(src.getint()));
             STRING_REGISTER(instr->unaryop.output);
         }
     }
     QML_V4_END_INSTR(ConvertIntToString, unaryop)
 
+    QML_V4_BEGIN_INSTR(ConvertIntToVariant, unaryop)
+    {
+        const Register &src = registers[instr->unaryop.src];
+        Register &output = registers[instr->unaryop.output];
+        if (src.isUndefined()) {
+            output.setUndefined();
+        } else {
+            new (output.getvariantptr()) QVariant(src.getint());
+            VARIANT_REGISTER(instr->unaryop.output);
+        }
+    }
+    QML_V4_END_INSTR(ConvertIntToVariant, unaryop)
+
     QML_V4_BEGIN_INSTR(ConvertNumberToBool, unaryop)
     {
         const Register &src = registers[instr->unaryop.src];
@@ -945,6 +977,19 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
     }
     QML_V4_END_INSTR(ConvertNumberToString, unaryop)
 
+    QML_V4_BEGIN_INSTR(ConvertNumberToVariant, unaryop)
+    {
+        const Register &src = registers[instr->unaryop.src];
+        Register &output = registers[instr->unaryop.output];
+        if (src.isUndefined()) {
+            output.setUndefined();
+        } else {
+            new (output.getvariantptr()) QVariant(src.getnumber());
+            VARIANT_REGISTER(instr->unaryop.output);
+        }
+    }
+    QML_V4_END_INSTR(ConvertNumberToVariant, unaryop)
+
     QML_V4_BEGIN_INSTR(ConvertStringToBool, unaryop)
     {
         const Register &src = registers[instr->unaryop.src];
@@ -1018,9 +1063,7 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
                 output.cleanupString();
                 MARK_CLEAN_REGISTER(instr->unaryop.output);
             }
-            QUrl *urlPtr = output.geturlptr();
-            new (urlPtr) QUrl();
-            urlPtr->setEncodedUrl(tmp.toUtf8(), QUrl::TolerantMode);
+            new (output.geturlptr()) QUrl(tmp);
 
             URL_REGISTER(instr->unaryop.output);
         }
@@ -1040,14 +1083,32 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
                 output.cleanupString();
                 MARK_CLEAN_REGISTER(instr->unaryop.output);
             }
-            QColor *colorPtr = output.getcolorptr();
-            new (colorPtr) QColor(QQmlStringConverters::colorFromString(tmp));
+            QQml_valueTypeProvider()->createValueFromString(QMetaType::QColor, tmp, output.typeDataPtr(), output.dataSize());
 
             COLOR_REGISTER(instr->unaryop.output);
         }
     }
     QML_V4_END_INSTR(ConvertStringToUrl, unaryop)
 
+    QML_V4_BEGIN_INSTR(ConvertStringToVariant, unaryop)
+    {
+        const Register &src = registers[instr->unaryop.src];
+        Register &output = registers[instr->unaryop.output];
+        if (src.isUndefined()) {
+            output.setUndefined();
+        } else {
+            const QString tmp(*src.getstringptr());
+            if (instr->unaryop.src == instr->unaryop.output) {
+                output.cleanupString();
+                MARK_CLEAN_REGISTER(instr->unaryop.output);
+            }
+            new (output.getvariantptr()) QVariant(tmp);
+
+            VARIANT_REGISTER(instr->unaryop.output);
+        }
+    }
+    QML_V4_END_INSTR(ConvertStringToVariant, unaryop)
+
     QML_V4_BEGIN_INSTR(ConvertUrlToBool, unaryop)
     {
         const Register &src = registers[instr->unaryop.src];
@@ -1085,6 +1146,25 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
     }
     QML_V4_END_INSTR(ConvertUrlToString, unaryop)
 
+    QML_V4_BEGIN_INSTR(ConvertUrlToVariant, unaryop)
+    {
+        const Register &src = registers[instr->unaryop.src];
+        Register &output = registers[instr->unaryop.output];
+        // ### NaN
+        if (src.isUndefined()) {
+            output.setUndefined();
+        } else {
+            const QUrl tmp(*src.geturlptr());
+            if (instr->unaryop.src == instr->unaryop.output) {
+                output.cleanupUrl();
+                MARK_CLEAN_REGISTER(instr->unaryop.output);
+            }
+            new (output.getvariantptr()) QVariant(tmp);
+            VARIANT_REGISTER(instr->unaryop.output);
+        }
+    }
+    QML_V4_END_INSTR(ConvertUrlToVariant, unaryop)
+
     QML_V4_BEGIN_INSTR(ConvertColorToBool, unaryop)
     {
         const Register &src = registers[instr->unaryop.src];
@@ -1107,17 +1187,30 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
         if (src.isUndefined()) {
             output.setUndefined();
         } else {
-            const QColor tmp(*src.getcolorptr());
+            QQml_valueTypeProvider()->createStringFromValue(QMetaType::QColor, src.typeDataPtr(), output.getstringptr());
+            STRING_REGISTER(instr->unaryop.output);
+        }
+    }
+    QML_V4_END_INSTR(ConvertColorToString, unaryop)
+
+    QML_V4_BEGIN_INSTR(ConvertColorToVariant, unaryop)
+    {
+        const Register &src = registers[instr->unaryop.src];
+        Register &output = registers[instr->unaryop.output];
+        // ### NaN
+        if (src.isUndefined()) {
+            output.setUndefined();
+        } else {
+            QVariant tmp(QMetaType::QColor, src.typeDataPtr());
             if (instr->unaryop.src == instr->unaryop.output) {
                 output.cleanupColor();
                 MARK_CLEAN_REGISTER(instr->unaryop.output);
             }
-            // to maintain behaviour with QtQuick 1.0, we just output normal toString() value.
-            new (output.getstringptr()) QString(QVariant(tmp).toString());
-            STRING_REGISTER(instr->unaryop.output);
+            new (output.getvariantptr()) QVariant(tmp);
+            VARIANT_REGISTER(instr->unaryop.output);
         }
     }
-    QML_V4_END_INSTR(ConvertColorToString, unaryop)
+    QML_V4_END_INSTR(ConvertColorToVariant, unaryop)
 
     QML_V4_BEGIN_INSTR(ConvertObjectToBool, unaryop)
     {
@@ -1131,6 +1224,20 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
     }
     QML_V4_END_INSTR(ConvertObjectToBool, unaryop)
 
+    QML_V4_BEGIN_INSTR(ConvertObjectToVariant, unaryop)
+    {
+        const Register &src = registers[instr->unaryop.src];
+        Register &output = registers[instr->unaryop.output];
+        // ### NaN
+        if (src.isUndefined())
+            output.setUndefined();
+        else {
+            new (output.getvariantptr()) QVariant(qVariantFromValue<QObject *>(src.getQObject()));
+            VARIANT_REGISTER(instr->unaryop.output);
+        }
+    }
+    QML_V4_END_INSTR(ConvertObjectToVariant, unaryop)
+
     QML_V4_BEGIN_INSTR(ConvertNullToObject, unaryop)
     {
         Register &output = registers[instr->unaryop.output];
@@ -1138,6 +1245,14 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
     }
     QML_V4_END_INSTR(ConvertNullToObject, unaryop)
 
+    QML_V4_BEGIN_INSTR(ConvertNullToVariant, unaryop)
+    {
+        Register &output = registers[instr->unaryop.output];
+        new (output.getvariantptr()) QVariant();
+        VARIANT_REGISTER(instr->unaryop.output);
+    }
+    QML_V4_END_INSTR(ConvertNullToVariant, unaryop)
+
     QML_V4_BEGIN_INSTR(ResolveUrl, unaryop)
     {
         const Register &src = registers[instr->unaryop.src];