#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>
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 {
} 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();
}
void Register::cleanupColor()
{
- getcolorptr()->~QColor();
+ QQml_valueTypeProvider()->destroyValueType(QMetaType::QColor, typeDataPtr(), dataSize());
setUndefined();
}
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());
}
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();
}
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);
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)) {
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());
}
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];
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];
}
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];
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);
}
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];
}
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];
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)
{
}
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];
}
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];