aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/qml/v4/qv4bindings.cpp128
-rw-r--r--src/qml/qml/v4/qv4compiler.cpp21
-rw-r--r--src/qml/qml/v4/qv4instruction.cpp24
-rw-r--r--src/qml/qml/v4/qv4instruction_p.h8
-rw-r--r--src/qml/qml/v4/qv4ir.cpp2
-rw-r--r--src/qml/qml/v4/qv4ir_p.h2
-rw-r--r--src/qml/qml/v4/qv4irbuilder.cpp12
-rw-r--r--tests/auto/qml/v4/data/variantHandling.qml67
-rw-r--r--tests/auto/qml/v4/tst_v4.cpp9
9 files changed, 269 insertions, 4 deletions
diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp
index e5d98e63fa..db015b07d6 100644
--- a/src/qml/qml/v4/qv4bindings.cpp
+++ b/src/qml/qml/v4/qv4bindings.cpp
@@ -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 = *result.getcolorptr();
+ 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];
@@ -1048,6 +1093,25 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
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 +1149,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];
@@ -1119,6 +1202,25 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
}
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 {
+ const QColor tmp(*src.getcolorptr());
+ if (instr->unaryop.src == instr->unaryop.output) {
+ output.cleanupColor();
+ MARK_CLEAN_REGISTER(instr->unaryop.output);
+ }
+ new (output.getvariantptr()) QVariant(tmp);
+ VARIANT_REGISTER(instr->unaryop.output);
+ }
+ }
+ QML_V4_END_INSTR(ConvertColorToVariant, unaryop)
+
QML_V4_BEGIN_INSTR(ConvertObjectToBool, unaryop)
{
const Register &src = registers[instr->unaryop.src];
@@ -1131,6 +1233,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 +1254,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];
diff --git a/src/qml/qml/v4/qv4compiler.cpp b/src/qml/qml/v4/qv4compiler.cpp
index 045a14fbb5..e03270cf1d 100644
--- a/src/qml/qml/v4/qv4compiler.cpp
+++ b/src/qml/qml/v4/qv4compiler.cpp
@@ -377,6 +377,9 @@ void QV4CompilerPrivate::visitName(IR::Name *e)
case QMetaType::QColor:
regType = QColorType;
break;
+ case QMetaType::QVariant:
+ regType = QVariantType;
+ break;
default:
if (propTy == QQmlMetaType::QQuickAnchorLineMetaTypeId()) {
@@ -966,6 +969,7 @@ void QV4CompilerPrivate::visitMove(IR::Move *s)
switch (targetTy) {
case IR::BoolType:
case IR::StringType:
+ case IR::VariantType:
// nothing to do. V4 will generate optimized
// url-to-xxx conversions.
break;
@@ -1068,6 +1072,20 @@ void QV4CompilerPrivate::visitMove(IR::Move *s)
case IR::NullType: opcode = V4Instr::ConvertNullToObject; break;
default: break;
} // switch
+ } else if (targetTy == IR::VariantType) {
+ if (s->isMoveForReturn) {
+ switch (sourceTy) {
+ case IR::BoolType: opcode = V4Instr::ConvertBoolToVariant; break;
+ case IR::IntType: opcode = V4Instr::ConvertIntToVariant; break;
+ case IR::NumberType: opcode = V4Instr::ConvertNumberToVariant; break;
+ case IR::UrlType: opcode = V4Instr::ConvertUrlToVariant; break;
+ case IR::ColorType: opcode = V4Instr::ConvertColorToVariant; break;
+ case IR::StringType: opcode = V4Instr::ConvertStringToVariant; break;
+ case IR::ObjectType: opcode = V4Instr::ConvertObjectToVariant; break;
+ case IR::NullType: opcode = V4Instr::ConvertNullToVariant; break;
+ default: break;
+ } // switch
+ }
}
if (opcode != V4Instr::Noop) {
V4Instr conv;
@@ -1141,6 +1159,9 @@ void QV4CompilerPrivate::visitRet(IR::Ret *s)
case IR::ObjectType:
test.regType = QMetaType::QObjectStar;
break;
+ case IR::VariantType:
+ test.regType = QMetaType::QVariant;
+ break;
case IR::BoolType:
test.regType = QMetaType::Bool;
break;
diff --git a/src/qml/qml/v4/qv4instruction.cpp b/src/qml/qml/v4/qv4instruction.cpp
index ecd4f01ef3..c20297975d 100644
--- a/src/qml/qml/v4/qv4instruction.cpp
+++ b/src/qml/qml/v4/qv4instruction.cpp
@@ -144,6 +144,9 @@ void Bytecode::dump(const V4Instr *i, int address) const
case V4Instr::ConvertBoolToString:
INSTR_DUMP << "\t" << "ConvertBoolToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertBoolToVariant:
+ INSTR_DUMP << "\t" << "ConvertBoolToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertIntToBool:
INSTR_DUMP << "\t" << "ConvertIntToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
@@ -153,6 +156,9 @@ void Bytecode::dump(const V4Instr *i, int address) const
case V4Instr::ConvertIntToString:
INSTR_DUMP << "\t" << "ConvertIntToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertIntToVariant:
+ INSTR_DUMP << "\t" << "ConvertIntToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertNumberToBool:
INSTR_DUMP << "\t" << "ConvertNumberToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
@@ -162,6 +168,9 @@ void Bytecode::dump(const V4Instr *i, int address) const
case V4Instr::ConvertNumberToString:
INSTR_DUMP << "\t" << "ConvertNumberToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertNumberToVariant:
+ INSTR_DUMP << "\t" << "ConvertNumberToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertStringToBool:
INSTR_DUMP << "\t" << "ConvertStringToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
@@ -177,24 +186,39 @@ void Bytecode::dump(const V4Instr *i, int address) const
case V4Instr::ConvertStringToColor:
INSTR_DUMP << "\t" << "ConvertStringToColor" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertStringToVariant:
+ INSTR_DUMP << "\t" << "ConvertStringToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertUrlToBool:
INSTR_DUMP << "\t" << "ConvertUrlToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
case V4Instr::ConvertUrlToString:
INSTR_DUMP << "\t" << "ConvertUrlToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertUrlToVariant:
+ INSTR_DUMP << "\t" << "ConvertUrlToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertColorToBool:
INSTR_DUMP << "\t" << "ConvertColorToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
case V4Instr::ConvertColorToString:
INSTR_DUMP << "\t" << "ConvertColorToString" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertColorToVariant:
+ INSTR_DUMP << "\t" << "ConvertColorToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertObjectToBool:
INSTR_DUMP << "\t" << "ConvertObjectToBool" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertObjectToVariant:
+ INSTR_DUMP << "\t" << "ConvertObjectToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ConvertNullToObject:
INSTR_DUMP << "\t" << "ConvertNullToObject" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
+ case V4Instr::ConvertNullToVariant:
+ INSTR_DUMP << "\t" << "ConvertNullToVariant" << "\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
+ break;
case V4Instr::ResolveUrl:
INSTR_DUMP << "\t" << "ResolveUrl" << "\t\t" << "Input_Reg(" << i->unaryop.src << ") -> Output_Reg(" << i->unaryop.output << ")";
break;
diff --git a/src/qml/qml/v4/qv4instruction_p.h b/src/qml/qml/v4/qv4instruction_p.h
index 310bfbaff5..6eb9efa50f 100644
--- a/src/qml/qml/v4/qv4instruction_p.h
+++ b/src/qml/qml/v4/qv4instruction_p.h
@@ -83,23 +83,31 @@ QT_BEGIN_NAMESPACE
F(ConvertBoolToInt, unaryop) \
F(ConvertBoolToNumber, unaryop) \
F(ConvertBoolToString, unaryop) \
+ F(ConvertBoolToVariant, unaryop) \
F(ConvertIntToBool, unaryop) \
F(ConvertIntToNumber, unaryop) \
F(ConvertIntToString, unaryop) \
+ F(ConvertIntToVariant, unaryop) \
F(ConvertNumberToBool, unaryop) \
F(ConvertNumberToInt, unaryop) \
F(ConvertNumberToString, unaryop) \
+ F(ConvertNumberToVariant, unaryop) \
F(ConvertStringToBool, unaryop) \
F(ConvertStringToInt, unaryop) \
F(ConvertStringToNumber, unaryop) \
F(ConvertStringToUrl, unaryop) \
F(ConvertStringToColor, unaryop) \
+ F(ConvertStringToVariant, unaryop) \
F(ConvertUrlToBool, unaryop) \
F(ConvertUrlToString, unaryop) \
+ F(ConvertUrlToVariant, unaryop) \
F(ConvertColorToBool, unaryop) \
F(ConvertColorToString, unaryop) \
+ F(ConvertColorToVariant, unaryop) \
F(ConvertObjectToBool, unaryop) \
+ F(ConvertObjectToVariant, unaryop) \
F(ConvertNullToObject, unaryop) \
+ F(ConvertNullToVariant, unaryop) \
F(ResolveUrl, unaryop) \
F(MathSinNumber, unaryop) \
F(MathCosNumber, unaryop) \
diff --git a/src/qml/qml/v4/qv4ir.cpp b/src/qml/qml/v4/qv4ir.cpp
index ba0faec80e..45e909f54b 100644
--- a/src/qml/qml/v4/qv4ir.cpp
+++ b/src/qml/qml/v4/qv4ir.cpp
@@ -63,6 +63,8 @@ const char *typeName(Type t)
case SGAnchorLineType: return "SGAnchorLine";
case AttachType: return "AttachType";
case ObjectType: return "object";
+ case VariantType: return "variant";
+ case VarType: return "var";
case BoolType: return "bool";
case IntType: return "int";
case FloatType: return "float";
diff --git a/src/qml/qml/v4/qv4ir_p.h b/src/qml/qml/v4/qv4ir_p.h
index 26bd43c406..254b810403 100644
--- a/src/qml/qml/v4/qv4ir_p.h
+++ b/src/qml/qml/v4/qv4ir_p.h
@@ -146,6 +146,8 @@ enum Type {
SGAnchorLineType,
AttachType,
ObjectType,
+ VariantType,
+ VarType,
FirstNumberType,
BoolType = FirstNumberType,
diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp
index 31ed9a5a6a..82da09f485 100644
--- a/src/qml/qml/v4/qv4irbuilder.cpp
+++ b/src/qml/qml/v4/qv4irbuilder.cpp
@@ -116,8 +116,16 @@ bool QV4IRBuilder::operator()(QQmlJS::IR::Function *function,
//_block->MOVE(_block->TEMP(IR::InvalidType), r.code);
if (r.code) {
- const QMetaObject *m = 0;
- const IR::Type targetType = irTypeFromVariantType(m_expression->property->type, m_engine, m);
+ IR::Type targetType = IR::InvalidType;
+
+ // This is the only operation where variant is supported:
+ QQmlPropertyData *data = &m_expression->property->core;
+ if (data->propType == QMetaType::QVariant) {
+ targetType = (data->isVMEProperty() ? IR::VarType : IR::VariantType);
+ } else {
+ targetType = irTypeFromVariantType(data->propType, m_engine, 0);
+ }
+
if (targetType != r.type()) {
IR::Expr *x = _block->TEMP(targetType);
_block->MOVE(x, r, true);
diff --git a/tests/auto/qml/v4/data/variantHandling.qml b/tests/auto/qml/v4/data/variantHandling.qml
new file mode 100644
index 0000000000..3d48eef57e
--- /dev/null
+++ b/tests/auto/qml/v4/data/variantHandling.qml
@@ -0,0 +1,67 @@
+import QtQuick 2.0
+
+QtObject {
+ property bool pBool: true
+ property int pInt: 666
+ property real pReal: 3.1415927
+ property string pString: 'foo'
+ property url pUrl: 'http://tools.ietf.org/html/rfc3986#section-1.1.2'
+ property color pColor: Qt.rgba(1, 0, 0, 0.5)
+ property QtObject pObject: QtObject { property string foo: 'bar' }
+
+ // Test assignment to variant
+ property variant pBoolVar: pBool
+ property variant pIntVar: pInt
+ property variant pRealVar: pReal
+ property variant pStringVar: pString
+ property variant pUrlVar: pUrl
+ property variant pColorVar: pColor
+ property variant pObjectVar: pObject
+ property variant pNullVar: null
+ property variant pVarVar: pUrlVar
+
+ // Test equivalence
+ property bool boolConversionSuccess: (pBoolVar == true)
+ property bool intConversionSuccess: (pIntVar == 666)
+ property bool realConversionSuccess: (pRealVar == 3.1415927)
+ property bool stringConversionSuccess: (pStringVar == 'foo')
+
+ property url comparisonUrl: 'http://tools.ietf.org/html/rfc3986#section-1.1.2'
+ property bool urlConversionSuccess: (pUrlVar == comparisonUrl)
+
+ property color comparisonColor: Qt.rgba(1, 0, 0, 0.5)
+ property bool colorConversionSuccess: (pColorVar == comparisonColor)
+
+ property bool objectConversionSuccess: (pObjectVar == pObject)
+ property bool nullConversionSuccess: (pNullVar == null)
+
+ property bool variantConversionSuccess: (pVarVar == comparisonUrl)
+
+ // Operations are not handled by V4 - they should pass through correctly
+ property variant pVarNot: !pBoolVar
+ property variant pVarComplement: ~pIntVar
+ property variant pVarEqual: (pBoolVar == pBoolVar)
+ property variant pVarLiteralEqual: (pBoolVar == true)
+ property variant pVarUnequal: (pUrlVar == pColorVar)
+ property variant pVarComparison: (pIntVar <= pIntVar)
+ property variant pVarShift: (pIntVar >> 1)
+
+ Component.onCompleted: {
+ if (!boolConversionSuccess) console.warn('QV4: bool conversion failed');
+ if (!intConversionSuccess) console.warn('QV4: int conversion failed');
+ if (!realConversionSuccess) console.warn('QV4: real conversion failed');
+ if (!stringConversionSuccess) console.warn('QV4: string conversion failed');
+ if (!urlConversionSuccess) console.warn('QV4: url conversion failed');
+ if (!colorConversionSuccess) console.warn('QV4: color conversion failed');
+ if (!objectConversionSuccess) console.warn('QV4: object conversion failed');
+ if (!nullConversionSuccess) console.warn('QV4: null conversion failed');
+ if (!variantConversionSuccess) console.warn('QV4: variant conversion failed');
+ if (pVarNot != false) console.warn('QV4: variant negation impeded');
+ if (pVarComplement != ~666) console.warn('QV4: variant complement impeded');
+ if (pVarEqual != true) console.warn('QV4: variant equality impeded');
+ if (pVarLiteralEqual != true) console.warn('QV4: variant/literal equality impeded');
+ if (pVarUnequal != false) console.warn('QV4: variant unequality impeded');
+ if (pVarComparison != true) console.warn('QV4: variant comparison impeded');
+ if (pVarShift != 333) console.warn('QV4: variant shift impeded');
+ }
+}
diff --git a/tests/auto/qml/v4/tst_v4.cpp b/tests/auto/qml/v4/tst_v4.cpp
index dfb7cc48c7..99a4405afa 100644
--- a/tests/auto/qml/v4/tst_v4.cpp
+++ b/tests/auto/qml/v4/tst_v4.cpp
@@ -150,6 +150,7 @@ void tst_v4::qtscript_data()
QTest::newRow("conversion from string") << "conversions.6.qml"; // QTBUG-24706
QTest::newRow("conversion from url") << "conversions.7.qml"; // QTBUG-24706
QTest::newRow("conversion from vec3") << "conversions.8.qml";
+ QTest::newRow("variantHandling") << "variantHandling.qml";
}
void tst_v4::unnecessaryReeval()
@@ -856,23 +857,31 @@ void tst_v4::debuggingDumpInstructions()
expectedPreAddress << "\t\tConvertBoolToInt\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertBoolToNumber\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertBoolToString\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertBoolToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertIntToBool\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertIntToNumber\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertIntToString\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertIntToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertNumberToBool\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertNumberToInt\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertNumberToString\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertNumberToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertStringToBool\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertStringToInt\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertStringToNumber\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertStringToUrl\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertStringToColor\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertStringToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertUrlToBool\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertUrlToString\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertUrlToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertColorToBool\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertColorToString\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertColorToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertObjectToBool\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertObjectToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tConvertNullToObject\tInput_Reg(0) -> Output_Reg(0)";
+ expectedPreAddress << "\t\tConvertNullToVariant\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tResolveUrl\t\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tMathSinNumber\t\tInput_Reg(0) -> Output_Reg(0)";
expectedPreAddress << "\t\tMathCosNumber\t\tInput_Reg(0) -> Output_Reg(0)";